diff --git a/proj/vs2013/Common/Common.vcxproj b/proj/vs2013/Common/Common.vcxproj index bc97548a..e57d8195 100644 --- a/proj/vs2013/Common/Common.vcxproj +++ b/proj/vs2013/Common/Common.vcxproj @@ -214,7 +214,6 @@ - @@ -223,6 +222,11 @@ + + + + + diff --git a/proj/vs2013/Common/Common.vcxproj.filters b/proj/vs2013/Common/Common.vcxproj.filters index 46c45f6b..c711ab7d 100644 --- a/proj/vs2013/Common/Common.vcxproj.filters +++ b/proj/vs2013/Common/Common.vcxproj.filters @@ -710,12 +710,24 @@ FileIO\TinyXML - - FileIO\ResMgr - FileIO\GZStream + + FileIO\ResMgr + + + FileIO\ResMgr + + + FileIO\ResMgr + + + FileIO\ResMgr + + + FileIO\ResMgr + DialogXML\Widgets @@ -755,12 +767,6 @@ DialogXML\Dialogs - - DialogXML\Dialogs - - - DialogXML\Dialogs - @@ -909,21 +915,6 @@ FileIO\ResMgr - - FileIO\ResMgr - - - FileIO\ResMgr - - - FileIO\ResMgr - - - FileIO\ResMgr - - - FileIO\ResMgr - FileIO\GZStream @@ -975,12 +966,24 @@ DialogXML\Dialogs - - DialogXML\Dialogs - Tools + + FileIO\ResMgr + + + FileIO\ResMgr + + + FileIO\ResMgr + + + FileIO\ResMgr + + + FileIO\ResMgr + diff --git a/src/dialogxml/widgets/button.cpp b/src/dialogxml/widgets/button.cpp index 8fd532d2..0b030e77 100644 --- a/src/dialogxml/widgets/button.cpp +++ b/src/dialogxml/widgets/button.cpp @@ -70,7 +70,7 @@ void cButton::draw(){ to_rect.right = to_rect.left + 14; to_rect.bottom = to_rect.top + 10; } - rect_draw_some_item(*ResMgr::get(buttons[btnGW[type]]),from_rect,*inWindow,to_rect,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get(buttons[btnGW[type]]),from_rect,*inWindow,to_rect,sf::BlendAlpha); style.colour = sf::Color::Black; style.lineHeight = 8; eTextMode textMode = eTextMode::CENTRE; @@ -376,7 +376,7 @@ void cLed::draw(){ to_rect = frame; to_rect.right = to_rect.left + 14; to_rect.bottom = to_rect.top + 10; - rect_draw_some_item(*ResMgr::get(buttons[btnGW[BTN_LED]]),from_rect,*inWindow,to_rect); + rect_draw_some_item(*ResMgr::graphics.get(buttons[btnGW[BTN_LED]]),from_rect,*inWindow,to_rect); style.colour = textClr; to_rect.right = frame.right; to_rect.left = frame.left + 18; // Possibly could be 20 diff --git a/src/dialogxml/widgets/pict.cpp b/src/dialogxml/widgets/pict.cpp index c225ed5f..12398b3e 100644 --- a/src/dialogxml/widgets/pict.cpp +++ b/src/dialogxml/widgets/pict.cpp @@ -632,7 +632,7 @@ void cPict::recalcRect() { setBounds(bounds); } -std::shared_ptr cPict::getSheet(eSheetType type, size_t n) { +const sf::Texture* cPict::getSheet(eSheetType type, size_t n) { std::ostringstream sout; switch(type) { case NUM_SHEET_TYPES: @@ -716,7 +716,7 @@ std::shared_ptr cPict::getSheet(eSheetType type, size_t n) { sout << "sheet" << n; } } - return ResMgr::get(sout.str()); + return &ResMgr::graphics.get(sout.str()); } void cPict::draw(){ @@ -734,7 +734,7 @@ void cPict::draw(){ } void cPict::drawPresetTer(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_TER, num / 50); + const sf::Texture* from_gw = getSheet(SHEET_TER, num / 50); if(!from_gw) return; num = num % 50; rectangle from_rect = calc_rect(num % 10, num / 10); @@ -745,7 +745,7 @@ void cPict::drawPresetTer(short num, rectangle to_rect){ void cPict::drawPresetTerAnim(short num, rectangle to_rect){ rectangle from_rect = calc_rect(4 * (num / 5) + animFrame % 4, num % 5); - std::shared_ptr from_gw = getSheet(SHEET_TER_ANIM); + const sf::Texture* from_gw = getSheet(SHEET_TER_ANIM); if(to_rect.right - to_rect.left > 28) { to_rect.inset(4,0); to_rect.right = to_rect.left + 28; @@ -771,7 +771,7 @@ static rectangle calcDefMonstRect(short i, short animFrame){ void cPict::drawPresetMonstSm(short num, rectangle to_rect){ short m_start_pic = m_pic_index[num].i; - std::shared_ptr from_gw = getSheet(SHEET_MONST, m_start_pic / 20); + const sf::Texture* from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; m_start_pic = m_start_pic % 20; rectangle from_rect = calcDefMonstRect(m_start_pic, animFrame); @@ -787,7 +787,7 @@ void cPict::drawPresetMonstWide(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); short m_start_pic = m_pic_index[num].i; - std::shared_ptr from_gw = getSheet(SHEET_MONST, m_start_pic / 20); + const sf::Texture* from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; rectangle from_rect = calcDefMonstRect(m_start_pic % 20, animFrame); small_monst_rect.offset(to_rect.left,to_rect.top + 7); @@ -808,7 +808,7 @@ void cPict::drawPresetMonstTall(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); short m_start_pic = m_pic_index[num].i; - std::shared_ptr from_gw = getSheet(SHEET_MONST, m_start_pic / 20); + const sf::Texture* from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; rectangle from_rect = calcDefMonstRect(m_start_pic % 20, animFrame); small_monst_rect.offset(to_rect.left + 7,to_rect.top); @@ -829,7 +829,7 @@ void cPict::drawPresetMonstLg(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); short m_start_pic = m_pic_index[num].i; - std::shared_ptr from_gw = getSheet(SHEET_MONST, m_start_pic / 20); + const sf::Texture* from_gw = getSheet(SHEET_MONST, m_start_pic / 20); if(!from_gw) return; rectangle from_rect = calcDefMonstRect(m_start_pic % 20, animFrame); small_monst_rect.offset(to_rect.left,to_rect.top); @@ -860,7 +860,7 @@ void cPict::drawPresetMonstLg(short num, rectangle to_rect){ void cPict::drawPresetDlog(short num, rectangle to_rect){ to_rect.right = to_rect.left + 36; to_rect.bottom = to_rect.top + 36; - std::shared_ptr from_gw = getSheet(SHEET_DLOG); + const sf::Texture* from_gw = getSheet(SHEET_DLOG); rectangle from_rect = {0,0,36,36}; from_rect.offset(36 * (num % 4),36 * (num / 4)); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect); @@ -869,7 +869,7 @@ void cPict::drawPresetDlog(short num, rectangle to_rect){ void cPict::drawPresetDlogLg(short num, rectangle to_rect){ to_rect.right = to_rect.left + (drawScaled ? getBounds().width() : 72); to_rect.bottom = to_rect.top + (drawScaled ? getBounds().height() : 72); - std::shared_ptr from_gw = getSheet(SHEET_DLOG); + const sf::Texture* from_gw = getSheet(SHEET_DLOG); rectangle from_rect = {0,0,72,72}; from_rect.offset(36 * (num % 4),36 * (num / 4)); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect); @@ -878,14 +878,14 @@ void cPict::drawPresetDlogLg(short num, rectangle to_rect){ void cPict::drawPresetTalk(short num, rectangle to_rect){ to_rect.right = to_rect.left + 32; to_rect.bottom = to_rect.top + 32; - std::shared_ptr from_gw = getSheet(SHEET_TALK); + const sf::Texture* from_gw = getSheet(SHEET_TALK); rectangle from_rect = {0,0,32,32}; from_rect.offset(32 * (num % 10),32 * (num / 10)); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect); } void cPict::drawPresetScen(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_SCEN); + const sf::Texture* from_gw = getSheet(SHEET_SCEN); rectangle from_rect = {0,0,32,32}; from_rect.offset(32 * (num % 5),32 * (num / 5)); to_rect.right = to_rect.left + 32; @@ -894,7 +894,7 @@ void cPict::drawPresetScen(short num, rectangle to_rect){ } void cPict::drawPresetScenLg(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_SCEN_LG); + const sf::Texture* from_gw = getSheet(SHEET_SCEN_LG); to_rect.right = to_rect.left + (drawScaled ? getBounds().width() : 64); to_rect.bottom = to_rect.top + (drawScaled ? getBounds().height() : 64); rectangle from_rect = {0,0,64,64}; @@ -906,7 +906,7 @@ void cPict::drawPresetItem(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; fill_rect(*inWindow, to_rect, sf::Color::Black); - std::shared_ptr from_gw; + const sf::Texture* from_gw; rectangle from_rect = {0,0,18,18}; if(num < 55) { from_gw = getSheet(SHEET_ITEM); @@ -923,7 +923,7 @@ void cPict::drawPresetTinyItem(short num, rectangle to_rect){ to_rect.right = to_rect.left + 18; to_rect.bottom = to_rect.top + 18; fill_rect(*inWindow, to_rect, sf::Color::Black); - std::shared_ptr from_gw; + const sf::Texture* from_gw; rectangle from_rect = {0,0,18,18}; from_gw = getSheet(SHEET_TINY_ITEM); from_rect.offset(18 * (num % 10), 18 * (num / 10)); @@ -931,7 +931,7 @@ void cPict::drawPresetTinyItem(short num, rectangle to_rect){ } void cPict::drawPresetPc(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_PC); + const sf::Texture* from_gw = getSheet(SHEET_PC); rectangle from_rect = calc_rect(2 * (num / 8), num % 8); to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; @@ -940,7 +940,7 @@ void cPict::drawPresetPc(short num, rectangle to_rect){ } void cPict::drawPresetField(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_FIELD); + const sf::Texture* from_gw = getSheet(SHEET_FIELD); rectangle from_rect = calc_rect(num % 8, num / 8); to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; @@ -949,7 +949,7 @@ void cPict::drawPresetField(short num, rectangle to_rect){ } void cPict::drawPresetBoom(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_BOOM); + const sf::Texture* from_gw = getSheet(SHEET_BOOM); if(num >= 8) num = 8 * (num - 7) + animFrame % 8; rectangle from_rect = calc_rect(num % 8, num / 8); @@ -962,7 +962,7 @@ void cPict::drawPresetBoom(short num, rectangle to_rect){ void cPict::drawFullSheet(short num, rectangle to_rect){ rectangle from_rect; - std::shared_ptr from_gw = getSheet(SHEET_FULL, num); + const sf::Texture* from_gw = getSheet(SHEET_FULL, num); from_rect = rectangle(*from_gw); if(!drawScaled) { to_rect.right = to_rect.left + (from_rect.right - from_rect.left); @@ -973,7 +973,7 @@ void cPict::drawFullSheet(short num, rectangle to_rect){ void cPict::drawPresetMissile(short num, rectangle to_rect){ rectangle from_rect = {0,0,18,18}; - std::shared_ptr from_gw = getSheet(SHEET_MISSILE); + const sf::Texture* from_gw = getSheet(SHEET_MISSILE); to_rect.right = to_rect.left + 18; to_rect.bottom = to_rect.top + 18; fill_rect(*inWindow, to_rect, sf::Color::Black); @@ -984,7 +984,7 @@ void cPict::drawPresetMissile(short num, rectangle to_rect){ void cPict::drawPresetTerMap(short num, rectangle to_rect){ rectangle from_rect = {0,0,12,12}; - std::shared_ptr from_gw = getSheet(SHEET_TER_MAP); + const sf::Texture* from_gw = getSheet(SHEET_TER_MAP); // TODO: Should probably fill black somewhere in here...? to_rect.right = to_rect.left + 24; to_rect.bottom = to_rect.top + 24; @@ -996,7 +996,7 @@ void cPict::drawPresetTerMap(short num, rectangle to_rect){ void cPict::drawStatusIcon(short num, rectangle to_rect){ rectangle from_rect = {0,0,12,12}; - std::shared_ptr from_gw = getSheet(SHEET_STATUS); + const sf::Texture* from_gw = getSheet(SHEET_STATUS); to_rect.right = to_rect.left + 12; to_rect.bottom = to_rect.top + 12; from_rect.offset(12 * (num % 3), 12 * (num / 3)); @@ -1012,7 +1012,7 @@ void cPict::drawCustomTer(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect); } @@ -1022,7 +1022,7 @@ void cPict::drawCustomTerAnim(short num, rectangle to_rect){ to_rect.bottom = to_rect.top + 36; num += animFrame % 4; rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect); } @@ -1035,7 +1035,7 @@ void cPict::drawCustomMonstSm(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha); } @@ -1049,7 +1049,7 @@ void cPict::drawCustomMonstWide(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); small_monst_rect.offset(to_rect.left,to_rect.top + 7); rect_draw_some_item(*from_gw, from_rect, *inWindow, small_monst_rect, sf::BlendAlpha); @@ -1068,7 +1068,7 @@ void cPict::drawCustomMonstTall(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); small_monst_rect.offset(to_rect.left + 7,to_rect.top); rect_draw_some_item(*from_gw, from_rect, *inWindow, small_monst_rect, sf::BlendAlpha); @@ -1087,7 +1087,7 @@ void cPict::drawCustomMonstLg(short num, rectangle to_rect){ fill_rect(*inWindow, to_rect, sf::Color::Black); rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); small_monst_rect.offset(to_rect.left,to_rect.top); rect_draw_some_item(*from_gw, from_rect, *inWindow, small_monst_rect, sf::BlendAlpha); @@ -1110,7 +1110,7 @@ static int dlog_to_w = 18, dlog_to_h = 36; void cPict::drawCustomDlog(short num, rectangle to_rect){ rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); to_rect.right = to_rect.left + dlog_to_w; to_rect.bottom = to_rect.top + dlog_to_h; @@ -1145,7 +1145,7 @@ void cPict::drawCustomDlogLg(short num, rectangle to_rect){ void cPict::drawCustomTalk(short num, rectangle to_rect){ rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); to_rect.right = to_rect.left + 16; to_rect.bottom = to_rect.top + 32; @@ -1164,7 +1164,7 @@ void cPict::drawCustomItem(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); fill_rect(*inWindow, to_rect, sf::Color::Black); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha); @@ -1174,7 +1174,7 @@ void cPict::drawCustomTinyItem(short num, rectangle to_rect){ to_rect.right = to_rect.left + 18; to_rect.bottom = to_rect.top + 18; rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); fill_rect(*inWindow, to_rect, sf::Color::Black); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha); @@ -1184,7 +1184,7 @@ void cPict::drawCustomBoom(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num + animFrame % 8); fill_rect(*inWindow, to_rect, sf::Color::Black); rect_draw_some_item(*from_gw, from_rect, *inWindow, to_rect, sf::BlendAlpha); @@ -1193,7 +1193,7 @@ void cPict::drawCustomBoom(short num, rectangle to_rect){ void cPict::drawCustomMissile(short num, rectangle to_rect){ num += animFrame % 8; rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num); from_rect.right = from_rect.left + 18; from_rect.bottom = from_rect.top + 18; @@ -1205,7 +1205,7 @@ void cPict::drawCustomMissile(short num, rectangle to_rect){ void cPict::drawCustomTerMap(short num, rectangle to_rect){ rectangle from_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num % 1000); from_rect.right = from_rect.left + 12; from_rect.bottom = from_rect.top + 12; @@ -1219,7 +1219,7 @@ void cPict::drawCustomTerMap(short num, rectangle to_rect){ void cPict::drawPartyMonstSm(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - sf::Texture* from_gw; + const sf::Texture* from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); @@ -1232,7 +1232,7 @@ void cPict::drawPartyMonstWide(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; fill_rect(*inWindow, to_rect, sf::Color::Black); - sf::Texture* from_gw; + const sf::Texture* from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); @@ -1249,7 +1249,7 @@ void cPict::drawPartyMonstTall(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; fill_rect(*inWindow, to_rect, sf::Color::Black); - sf::Texture* from_gw; + const sf::Texture* from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); @@ -1266,7 +1266,7 @@ void cPict::drawPartyMonstLg(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; fill_rect(*inWindow, to_rect, sf::Color::Black); - sf::Texture* from_gw; + const sf::Texture* from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); @@ -1287,7 +1287,7 @@ void cPict::drawPartyMonstLg(short num, rectangle to_rect){ } void cPict::drawPartyScen(short num, rectangle to_rect){ - std::shared_ptr from_gw = getSheet(SHEET_HEADER); + const sf::Texture* from_gw = getSheet(SHEET_HEADER); rectangle from_rect = {0,0,32,32}; from_rect.offset(32 * (num % 5),32 * (num / 5)); to_rect.right = to_rect.left + 32; @@ -1298,7 +1298,7 @@ void cPict::drawPartyScen(short num, rectangle to_rect){ void cPict::drawPartyItem(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - sf::Texture* from_gw; + const sf::Texture* from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); @@ -1309,7 +1309,7 @@ void cPict::drawPartyItem(short num, rectangle to_rect){ void cPict::drawPartyPc(short num, rectangle to_rect){ to_rect.right = to_rect.left + 28; to_rect.bottom = to_rect.top + 36; - sf::Texture* from_gw; + const sf::Texture* from_gw; rectangle from_rect; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num, true); diff --git a/src/dialogxml/widgets/pict.hpp b/src/dialogxml/widgets/pict.hpp index 01629b95..635f3845 100644 --- a/src/dialogxml/widgets/pict.hpp +++ b/src/dialogxml/widgets/pict.hpp @@ -89,7 +89,7 @@ public: cPict& operator=(cPict& other) = delete; cPict(cPict& other) = delete; private: - static std::shared_ptr getSheet(eSheetType type, size_t n = 0); + static const sf::Texture* getSheet(eSheetType type, size_t n = 0); static short animFrame; pic_num_t picNum; ePicType picType; diff --git a/src/dialogxml/widgets/scrollbar.cpp b/src/dialogxml/widgets/scrollbar.cpp index dc954213..57caeee7 100644 --- a/src/dialogxml/widgets/scrollbar.cpp +++ b/src/dialogxml/widgets/scrollbar.cpp @@ -207,7 +207,7 @@ void cScrollbar::draw_horizontal() { draw_rect.width() = btn_size; if(depressed && pressedPart == PART_UP) from_rect = up_rect[style][HORZ_PRESSED]; - sf::Texture scroll_gw = *ResMgr::get(scroll_textures[style]); + sf::Texture scroll_gw = *ResMgr::graphics.get(scroll_textures[style]); rect_draw_some_item(scroll_gw, from_rect, *inWindow, draw_rect); if(pos > 0) { from_rect = bar_rect[style][HORZ]; @@ -270,7 +270,7 @@ void cScrollbar::draw_vertical() { draw_rect.height() = btn_size; if(depressed && pressedPart == PART_UP) from_rect = up_rect[style][VERT_PRESSED]; - sf::Texture scroll_gw = *ResMgr::get(scroll_textures[style]); + sf::Texture scroll_gw = *ResMgr::graphics.get(scroll_textures[style]); rect_draw_some_item(scroll_gw, from_rect, *inWindow, draw_rect); if(pos > 0) { from_rect = bar_rect[style][VERT]; diff --git a/src/fileio/fileio.cpp b/src/fileio/fileio.cpp index 1ed56786..ecf01b01 100644 --- a/src/fileio/fileio.cpp +++ b/src/fileio/fileio.cpp @@ -9,6 +9,7 @@ #include "fileio.hpp" #include +#include #include #include @@ -35,11 +36,11 @@ void init_directories(const char* exec_path) { #endif progDir = progDir.parent_path(); // Initialize the resource manager paths - ResMgr::pushPath(progDir/"data"/"graphics"); - ResMgr::pushPath(progDir/"data"/"cursors"); - ResMgr::pushPath(progDir/"data"/"fonts"); - ResMgr::pushPath(progDir/"data"/"strings"); - ResMgr::pushPath(progDir/"data"/"sounds"); + ResMgr::graphics.pushPath(progDir/"data"/"graphics"); + ResMgr::cursors.pushPath(progDir/"data"/"cursors"); + ResMgr::fonts.pushPath(progDir/"data"/"fonts"); + ResMgr::strings.pushPath(progDir/"data"/"strings"); + ResMgr::sounds.pushPath(progDir/"data"/"sounds"); // We need a location for temporary files, primarily for loading and saving operations // The scenario editor may also use this location as "scratch space" diff --git a/src/fileio/fileio_scen.cpp b/src/fileio/fileio_scen.cpp index 94bd699c..d3f06c64 100644 --- a/src/fileio/fileio_scen.cpp +++ b/src/fileio/fileio_scen.cpp @@ -101,17 +101,17 @@ fs::path locate_scenario(std::string scen_name) { bool load_scenario(fs::path file_to_load, cScenario& scenario, bool only_header) { // Before loading a scenario, we may need to pop scenario resource paths. - fs::path graphics_path = ResMgr::popPath(); + fs::path graphics_path = ResMgr::graphics.popPath(); for(auto p : graphics_path) { if(p.string() == "data") { - ResMgr::pushPath(graphics_path); + ResMgr::graphics.pushPath(graphics_path); break; } } - fs::path sounds_path = ResMgr::popPath(); + fs::path sounds_path = ResMgr::sounds.popPath(); for(auto p : sounds_path) { if(p.string() == "data") { - ResMgr::pushPath(sounds_path); + ResMgr::sounds.pushPath(sounds_path); break; } } @@ -2191,13 +2191,13 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head // This is a bit of trickery to get it to only count the first consecutive range of sheets while(have_pic[num_graphic_sheets]) num_graphic_sheets++; - ResMgr::pushPath(tempDir/scenario_temp_dir_name/"graphics"); - ResMgr::pushPath(tempDir/scenario_temp_dir_name/"sounds"); + ResMgr::graphics.pushPath(tempDir/scenario_temp_dir_name/"graphics"); + ResMgr::sounds.pushPath(tempDir/scenario_temp_dir_name/"sounds"); } else { if(fs::is_directory(file_to_load/"graphics")) - ResMgr::pushPath(file_to_load/"graphics"); + ResMgr::graphics.pushPath(file_to_load/"graphics"); if(fs::is_directory(file_to_load/"sounds")) - ResMgr::pushPath(file_to_load/"sounds"); + ResMgr::sounds.pushPath(file_to_load/"sounds"); std::string fname; while(fname = "sheet" + std::to_string(num_graphic_sheets) + ".png", fs::exists(file_to_load/"graphics"/fname)) num_graphic_sheets++; @@ -2469,7 +2469,7 @@ void load_spec_graphics_v2(int num_sheets) { } while(num_sheets-- > 0) { std::string name = "sheet" + std::to_string(num_sheets); - ResMgr::free(name); - spec_scen_g.sheets[num_sheets] = *ResMgr::get(name); + ResMgr::graphics.free(name); + spec_scen_g.sheets[num_sheets] = *ResMgr::graphics.get(name); } } diff --git a/src/fileio/resmgr/res_cursor.cpp b/src/fileio/resmgr/res_cursor.cpp new file mode 100644 index 00000000..da8f209f --- /dev/null +++ b/src/fileio/resmgr/res_cursor.cpp @@ -0,0 +1,74 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#include +#include +#include +#include "res_cursor.hpp" + +class CursorLoader : public ResMgr::cLoader { + /// Load a cursor from a GIF file. + /// The cursor's hotspot location is stored in a GIF comment, with the following syntax (case-sensitive): + /// "Hotspot(x,y)" + Cursor* operator() (const fs::path& fpath) const override { + if(!fs::exists(fpath)) + throw ResMgr::xError(ResMgr::ERR_LOAD, "Failed to load GIF cursor: " + fpath.string()); + int x = 0, y = 0, f_sz; + std::ifstream fin(fpath.string().c_str(), std::ios::binary); + fin.seekg(0, std::ios::end); + f_sz = fin.tellg(); + fin.clear(); + fin.seekg(0, std::ios::beg); + bool found_hotspot = false; + while(fin && !found_hotspot) { + unsigned char c = fin.get(); + if(c != 0x21) continue; + c = fin.get(); + if(c != 0xfe) continue; + // If we get here, we've probably found a GIF comment + std::string str; + int count; + found_hotspot = true; + do { + count = fin.get(); + if(count + fin.tellg() >= f_sz) { + found_hotspot = false; + break; + } + std::copy_n(std::istream_iterator(fin), count, std::back_inserter(str)); + } while(count > 0); + if(found_hotspot) { + if(str.substr(0,7) == "Hotspot") { + size_t open_paren = str.find_first_of('('), comma = str.find_first_of(','), close_paren = str.find_first_of(')'); + std::string x_str = str.substr(open_paren + 1, comma - open_paren - 1); + std::string y_str = str.substr(comma + 1, close_paren - comma - 1); + x = std::stoi(x_str); + y = std::stoi(y_str); + } else found_hotspot = false; + } + } + if(!found_hotspot) + std::cerr << "Cursor hotspot missing: " << fpath.string() << std::endl; + // TODO: Handle errors? + Cursor* cur = new Cursor(fpath.string(),x,y); + return cur; + } + + ResourceList expand(const std::string& name) const override { + return {name + ".gif"}; + } + + std::string typeName() const override { + return "cursor"; + } +}; + +// We'll allow all cursors to be loaded simultaneously (and leave some leeway in case a few more cursors are added) +CursorLoader loader; +ResMgr::cPool ResMgr::cursors(loader, 30); + diff --git a/src/fileio/resmgr/res_cursor.hpp b/src/fileio/resmgr/res_cursor.hpp index 6a9045e3..865d0443 100644 --- a/src/fileio/resmgr/res_cursor.hpp +++ b/src/fileio/resmgr/res_cursor.hpp @@ -9,64 +9,13 @@ #ifndef BOE_RES_CURSOR_HPP #define BOE_RES_CURSOR_HPP -#include -#include -#include #include "resmgr.hpp" #include "cursors.hpp" -using CursorRsrc = Cursor; - -// Redeclare this instead of including "fileio.h" -extern std::ostream& std_fmterr(std::ostream& out); +using CursorRsrc = ResMgr::cPointer; namespace ResMgr { - /// Load a cursor from a GIF file. - /// The cursor's hotspot location is stored in a GIF comment, with the following syntax (case-sensitive): - /// "Hotspot(x,y)" - template<> inline CursorRsrc* resLoader::operator() (fs::path fpath) { - if(!fs::exists(fpath)) - throw xResMgrErr("Failed to load GIF cursor: " + fpath.string()); - int x = 0, y = 0, f_sz; - std::ifstream fin(fpath.string().c_str(), std::ios::binary); - fin.seekg(0, std::ios::end); - f_sz = fin.tellg(); - fin.clear(); - fin.seekg(0, std::ios::beg); - bool found_hotspot = false; - while(fin && !found_hotspot) { - unsigned char c = fin.get(); - if(c != 0x21) continue; - c = fin.get(); - if(c != 0xfe) continue; - // If we get here, we've probably found a GIF comment - std::string str; - int count; - found_hotspot = true; - do { - count = fin.get(); - if(count + fin.tellg() >= f_sz) { - found_hotspot = false; - break; - } - std::copy_n(std::istream_iterator(fin), count, std::back_inserter(str)); - } while(count > 0); - if(found_hotspot) { - if(str.substr(0,7) == "Hotspot") { - size_t open_paren = str.find_first_of('('), comma = str.find_first_of(','), close_paren = str.find_first_of(')'); - std::string x_str = str.substr(open_paren + 1, comma - open_paren - 1); - std::string y_str = str.substr(comma + 1, close_paren - comma - 1); - x = std::stoi(x_str); - y = std::stoi(y_str); - } else found_hotspot = false; - } - } - if(!found_hotspot) - std::cerr << "Cursor hotspot missing: " << fpath.string() << std::endl; - // TODO: Handle errors? - CursorRsrc* cur = new Cursor(fpath.string(),x,y); - return cur; - } + extern cPool cursors; } #endif diff --git a/src/fileio/resmgr/res_font.cpp b/src/fileio/resmgr/res_font.cpp new file mode 100644 index 00000000..9105ae0b --- /dev/null +++ b/src/fileio/resmgr/res_font.cpp @@ -0,0 +1,31 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#include "res_font.hpp" + +class FontLoader : public ResMgr::cLoader { + /// Load a font from a TTF or BDF file. + sf::Font* operator() (const fs::path& fpath) const override { + sf::Font* theFont = new sf::Font; + if(theFont->loadFromFile(fpath.string())) return theFont; + delete theFont; + throw ResMgr::xError(ResMgr::ERR_LOAD, "Failed to find font: " + fpath.string()); + } + + ResourceList expand(const std::string& name) const override { + return {name + ".ttf", name + ".bdf"}; + } + + std::string typeName() const override { + return "font"; + } +}; + +// We'll allow all fonts to be loaded simultaneously (and leave some leeway in case a few more fonts are added) +FontLoader loader; +ResMgr::cPool ResMgr::fonts(loader, 10); diff --git a/src/fileio/resmgr/res_font.hpp b/src/fileio/resmgr/res_font.hpp index 36457f19..44aaeaf9 100644 --- a/src/fileio/resmgr/res_font.hpp +++ b/src/fileio/resmgr/res_font.hpp @@ -10,22 +10,12 @@ #define BOE_RES_FONT_HPP #include "resmgr.hpp" -#include #include -using FontRsrc = sf::Font; - -// Redeclare this instead of including "fileio.h" -extern std::ostream& std_fmterr(std::ostream& out); +using FontRsrc = ResMgr::cPointer; namespace ResMgr { - /// Load a font from a TTF file. - template<> inline FontRsrc* resLoader::operator() (fs::path fpath) { - FontRsrc* theFont = new FontRsrc; - if(theFont->loadFromFile(fpath.string())) return theFont; - delete theFont; - throw xResMgrErr("Failed to find font: " + fpath.string()); - } + extern cPool fonts; } #endif diff --git a/src/fileio/resmgr/res_image.cpp b/src/fileio/resmgr/res_image.cpp new file mode 100644 index 00000000..1bdde64b --- /dev/null +++ b/src/fileio/resmgr/res_image.cpp @@ -0,0 +1,31 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#include "res_image.hpp" + +class ImageLoader : public ResMgr::cLoader { + /// Load an image from a PNG file. + sf::Texture* operator() (const fs::path& fpath) const override { + sf::Texture* img = new sf::Texture(); + if(img->loadFromFile(fpath.string())) return img; + delete img; + throw ResMgr::xError(ResMgr::ERR_LOAD, "Failed to load PNG image: " + fpath.string()); + } + + ResourceList expand(const std::string& name) const override { + return {name + ".png", name + ".bmp"}; + } + + std::string typeName() const override { + return "image"; + } +}; + +// TODO: What's a good max texture count? +ImageLoader loader; +ResMgr::cPool ResMgr::graphics(loader, 50); diff --git a/src/fileio/resmgr/res_image.hpp b/src/fileio/resmgr/res_image.hpp index cb9510a4..11d1d038 100644 --- a/src/fileio/resmgr/res_image.hpp +++ b/src/fileio/resmgr/res_image.hpp @@ -9,23 +9,13 @@ #ifndef BOE_RES_IMAGE_HPP #define BOE_RES_IMAGE_HPP -#include #include #include "resmgr.hpp" -using ImageRsrc = sf::Texture; - -// Redeclare this instead of including "fileio.h" -extern std::ostream& std_fmterr(std::ostream& out); +using ImageRsrc = ResMgr::cPointer; namespace ResMgr { - /// Load an image from a PNG file. - template<> inline ImageRsrc* resLoader::operator() (fs::path fpath) { - ImageRsrc* img = new ImageRsrc(); - if(img->loadFromFile(fpath.string())) return img; - delete img; - throw xResMgrErr("Failed to load PNG image: " + fpath.string()); - } + extern cPool graphics; } #endif diff --git a/src/fileio/resmgr/res_sound.cpp b/src/fileio/resmgr/res_sound.cpp new file mode 100644 index 00000000..25930354 --- /dev/null +++ b/src/fileio/resmgr/res_sound.cpp @@ -0,0 +1,31 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#include "res_sound.hpp" + +class SoundLoader : public ResMgr::cLoader { + /// Load a sound from a WAV file. + sf::SoundBuffer* operator() (const fs::path& fpath) const override { + sf::SoundBuffer* snd = new sf::SoundBuffer; + if(snd->loadFromFile(fpath.string())) return snd; + delete snd; + throw ResMgr::xError(ResMgr::ERR_LOAD, "Failed to load WAV sound: " + fpath.string()); + } + + ResourceList expand(const std::string& name) const override { + return {name + ".wav"}; + } + + std::string typeName() const override { + return "sound"; + } +}; + +// TODO: What's a good max sound count? +SoundLoader loader; +ResMgr::cPool ResMgr::sounds(loader, 50); diff --git a/src/fileio/resmgr/res_sound.hpp b/src/fileio/resmgr/res_sound.hpp index 4d48bb3a..b79ebc70 100644 --- a/src/fileio/resmgr/res_sound.hpp +++ b/src/fileio/resmgr/res_sound.hpp @@ -9,23 +9,13 @@ #ifndef BOE_RES_SOUND_HPP #define BOE_RES_SOUND_HPP -#include #include #include "resmgr.hpp" -using SoundRsrc = sf::SoundBuffer; - -// Redeclare this instead of including "fileio.h" -extern std::ostream& std_fmterr(std::ostream& out); +using SoundRsrc = ResMgr::cPointer; namespace ResMgr { - /// Load a sound from a WAV file. - template<> inline SoundRsrc* resLoader::operator() (fs::path fpath) { - SoundRsrc* snd = new SoundRsrc; - if(snd->loadFromFile(fpath.string())) return snd; - delete snd; - throw xResMgrErr("Failed to load WAV sound: " + fpath.string()); - } + extern cPool sounds; } #endif diff --git a/src/fileio/resmgr/res_strings.cpp b/src/fileio/resmgr/res_strings.cpp new file mode 100644 index 00000000..19346a92 --- /dev/null +++ b/src/fileio/resmgr/res_strings.cpp @@ -0,0 +1,45 @@ +/* + * restypes.h + * BoE + * + * Created by Celtic Minstrel on 10-08-25. + * + */ + +#include "res_strings.hpp" +#include + +// Redeclare this instead of including "fileio.h" +extern std::ostream& std_fmterr(std::ostream& out); + +class StringsLoader : public ResMgr::cLoader { + /// Load a list of strings from a TXT file. + /// Each line in the file becomes one string in the resulting list. + /// (Empty lines are included too.) + StringList* operator() (const fs::path& fpath) const override { + std::ifstream fin(fpath.string().c_str()); + if(fin.fail()) { + std::cerr << std_fmterr << ": Error opening file"; + throw ResMgr::xError(ResMgr::ERR_LOAD, "Failed to load string list: " + fpath.string()); + } + std::string next; + StringList* strlist = new StringList; + while(!fin.eof()) { + getline(fin,next); + strlist->push_back(next); + } + return strlist; + } + + ResourceList expand(const std::string& name) const override { + return {name + ".txt"}; + } + + std::string typeName() const override { + return "string list"; + } +}; + +// TODO: What's a good max strings count? +StringsLoader loader; +ResMgr::cPool ResMgr::strings(loader, 100); diff --git a/src/fileio/resmgr/res_strings.hpp b/src/fileio/resmgr/res_strings.hpp index e1bfa132..b08e4e42 100644 --- a/src/fileio/resmgr/res_strings.hpp +++ b/src/fileio/resmgr/res_strings.hpp @@ -9,33 +9,15 @@ #ifndef BOE_RES_STRINGS_HPP #define BOE_RES_STRINGS_HPP -#include -#include +#include +#include #include "resmgr.hpp" -using StringRsrc = std::vector; - -// Redeclare this instead of including "fileio.h" -extern std::ostream& std_fmterr(std::ostream& out); +using StringList = std::vector; +using StringRsrc = ResMgr::cPointer; namespace ResMgr { - /// Load a list of strings from a TXT file. - /// Each line in the file becomes one string in the resulting list. - /// (Empty lines are included too.) - template<> inline StringRsrc* resLoader::operator() (fs::path fpath) { - std::ifstream fin(fpath.string().c_str()); - if(fin.fail()) { - std::cerr << std_fmterr << ": Error opening file"; - throw xResMgrErr("Failed to load string list: " + fpath.string()); - } - std::string next; - StringRsrc* strlist = new StringRsrc; - while(!fin.eof()) { - getline(fin,next); - strlist->push_back(next); - } - return strlist; - } + extern cPool strings; } #endif diff --git a/src/fileio/resmgr/resmgr.hpp b/src/fileio/resmgr/resmgr.hpp index 82a0c515..2ab8ebd4 100644 --- a/src/fileio/resmgr/resmgr.hpp +++ b/src/fileio/resmgr/resmgr.hpp @@ -2,232 +2,244 @@ * resmgr.h * BoE * - * Created by Celtic Minstrel on 10-08-24. + * Created by Celtic Minstrel on 16-09-21. * */ #ifndef BOE_RESMGR_H #define BOE_RESMGR_H -#include -#include +#include +#include #include -#include +#include #include -#include -#include -#include -#include +#include -namespace std { - template<> struct hash { - size_t operator()(const boost::filesystem::path& p) const { - return boost::filesystem::hash_value(p); - } - }; -} - -/// A simple resource manager. -/// Handles loading, retaining, and releasing of resources as necessary. -/// Resources include sounds, images, fonts, and cursors. -/// -/// To implement a new resource type, all you have to do is specialize -/// @ref ResMgr::resLoader::operator()() and declare @ref ResMgr::resLoader::file_ext -/// for the desired resource type. The operator() receives the -/// full file path with the extension already applied. namespace ResMgr { - /// The signature of an ID map function. - using idMapFn = std::function; + namespace fs = boost::filesystem; - /// A resource pool. - /// @tparam type The type of resource that this pool manages. - template struct resPool { - /// Get the map of all currently-loaded resources from this resource pool. - static std::unordered_map >& resources() { - static std::unordered_map > data; - return data; - } - /// Get the current search path stack for this resource pool. - static std::stack& resPaths() { - static std::stack data; - return data; - } - /// Get the current function used to map numerical IDs to string keys (filenames). - static idMapFn& mapFn() { - static idMapFn data; - return data; - } - /// Get the map of past path resolutions. - /// @return A map of relative paths to the absolute path they most recently resolved to. - static std::unordered_map& pathFound() { - static std::unordered_map data; - return data; - } - /// Convert a relative path to an absolute path by checking the current search path stack. - /// @param path The path to resolve. - /// @return The resolved absolute path, or the relative path unchanged if resolution failed. - static fs::path find(std::string name, std::string ext) { - fs::path path = name + "." + ext; - std::stack tmpPaths = resPaths(); - while(!tmpPaths.empty()) { - fs::path thisPath = tmpPaths.top()/path; - if(fs::exists(thisPath)) { - pathFound()[name] = thisPath; - return thisPath; - } - tmpPaths.pop(); - } - // If we got this far, it wasn't found. - // Just return the original filename unchanged; - // maybe it can be resolved anyway. - return path; - } + enum eErrorCode { + ERR_RESOLVE, + ERR_LOAD, }; - /// Handles all the legwork of loading a specific resource. - /// Must be implemented for each resource you want to manage. - /// @tparam type The type of resource. - template struct resLoader { - /// Load a resource of this type from the given file. - /// @param fpath The path to the resource; this will be an absolute path unless resolution failed. - /// @return A pointer to the loaded resource. The resource manager takes responsibility for freeing it, - /// so it must be a pointer allocated with `new` rather than `new[]`. - type* operator() (fs::path path); - /// The standard file extension for this resource type; - static const std::string file_ext; - }; - - /// Thrown if an error occurs while loading a resource. - class xResMgrErr : public std::exception { - std::string msg; + class xError : public std::exception { + eErrorCode code; + const std::string explanation; public: - xResMgrErr() throw() {} - xResMgrErr(const std::string& str) throw() : msg(str) {} - ~xResMgrErr() throw() {} - /// @return The error message. - virtual const char* what() const throw() { - return msg.c_str(); + xError(eErrorCode code, const std::string& explanation) : code(code), explanation(explanation) {} + const char* what() const throw() override { + return explanation.c_str(); } }; - /// Free a single resource. - /// @tparam type The type of resource to free. - /// @param name The key of the resource to free (usually the filename without an extension). - template void free(std::string name) { - if(resPool::resources().find(name) != resPool::resources().end()) - resPool::resources().erase(name); - } + template + class cLoader { + protected: + using ResourceList = std::vector; + public: + /// Loads a resource from the requested path + virtual T* operator()(const fs::path& from) const = 0; + /// Returns a string identifying the type of the resource handled by this loader + virtual std::string typeName() const = 0; + /// Expands a resource name into a list of possible resources to attempt resolution on, eg adding possible file extensions + virtual ResourceList expand(const std::string& resourceName) const = 0; + virtual ~cLoader() {} + }; + + template class cPool; - /// Free a single resource by numerical ID. - /// In order for this to work, an ID map function must have first been set with setIdMapFn(). - /// @tparam type The type of resource to free. - /// @param id The numerical ID of the resource to free. - /// @throw std::bad_function_call if the ID map function was not set. - template void free(int id) { - std::string name = resPool::mapFn()(id); - if(name != "") free(name); - } + template + class cPointer { + friend class cPool; + bool purgeable, orphaned = false; + std::unique_ptr> res_ptr = nullptr; + std::string path; + cPointer(bool p = false) : purgeable(p) {} + public: + // By explicitly declaring it deleted the error messages may improve + cPointer(const cPointer& other) = delete; + cPointer(cPointer&& other) + : purgeable(other.purgeable) + , orphaned(other.orphaned) + , res_ptr(std::move(other.res_ptr)) + , path(std::move(other.path)) + {} + const std::shared_ptr& operator->() const { + return *res_ptr; + } + T& operator*() const { + return **res_ptr; + } + // Overloading the address operator... + const T*const operator&() const { + return res_ptr.get()->get(); + } + }; - /// Free all resources of a particular type. - /// @tparam type The type of resource to free. - template void freeAll() { - resPool::resources().clear(); - } - - /// Fetch a single resource, loading it into memory if necessary. - /// If the resource already exists in memory, it first checks to see if the path resolution has changed, - /// which could happen if a new path has been pushed on the stack, or a path has been removed. - /// If it would resolve to a different file than the one currently loaded, the resource is reloaded. - /// @tparam type The type of the resource to fetch. - /// @param name The key of the resource to fetch (usually the filename without an extension). - /// @return A smart pointer to the fetched resource. - /// @throw xResMgrErr if the resource could not be found or there was an error loading it. - template std::shared_ptr get(std::string name) { - if(resPool::resources().find(name) != resPool::resources().end()) { - if(resPool::pathFound().find(name) != resPool::pathFound().end()) { - resLoader load; - std::string curPath = resPool::pathFound()[name].string(); - std::string checkPath = resPool::find(name, load.file_ext).string(); - if(checkPath != curPath) { - free(name); - type* tmp = load(checkPath); - return resPool::resources()[name] = std::shared_ptr(tmp); + template + class cPool { + std::string directory; + size_t overflow; + std::unordered_map> resources; + std::unordered_map resolvedPaths; + std::stack paths; + cLoader& load; + /// Converts a resource name to an absolute file path referencing the resource + fs::path find(const std::string& resourceName) { + for(const std::string name : load.expand(resourceName)) { + fs::path path = name; + if(!directory.empty()) path = directory/path; + std::stack tmpPaths = paths; + while(!tmpPaths.empty()) { + fs::path thisPath = tmpPaths.top()/path; + if(fs::exists(thisPath)) { + resolvedPaths[name] = thisPath; + return thisPath; + } + tmpPaths.pop(); } } - return resPool::resources()[name]; - } else { - resLoader load; - type* tmp = load(resPool::find(name, load.file_ext)); - return resPool::resources()[name] = std::shared_ptr(tmp); + std::ostringstream err; + err << "Error! Could not load resource '" << resourceName << "' of type '" << load.typeName() << "'\n"; + if(paths.empty()) err << " (No resource paths are present on the stack.)\n"; + throw xError(ERR_RESOLVE, err.str()); } - } - - /// Fetch a single resource by numerical ID. - /// In order for this to work, an ID map function must have first been set with setIdMapFn(). - /// @tparam type The type of the resource to fetch. - /// @param id The numerical ID of the resource to fetch. - /// @return A smart pointer to the fetched resource. - /// @throw xResMgrErr if the ID map function returned an empty string. - /// @throw std::bad_function_call if the ID map function was not set. - template std::shared_ptr get(int id) { - std::string name = resPool::mapFn()(id); - if(name == "") throw xResMgrErr("Invalid resource ID."); - return get(name); - } - - /// Check if a resource with the given name exists. - /// Calling this causes the path to be remembered, same as with get(std::string). - /// @tparam type The type of the resource to fetch. - /// @param name The key of the resource to fetch (usually the filename without an extension). - /// @return True if it exists, false otherwise. - template bool have(std::string name) { - if(resPool::resources().find(name) != resPool::resources().end()) - return true; - return resPool::find(name, resLoader::file_ext).is_absolute(); - } - - /// Check if a resource with the given numerical ID exists - /// In order for this to work, an ID map function must have first been set with setIdMapFn(). - /// @tparam type The type of the resource to fetch. - /// @param id The numerical ID of the resource to fetch. - /// @throw xResMgrErr if the ID map function returned an empty string. - /// @throw std::bad_function_call if the ID map function was not set - template bool have(int id) { - std::string name = resPool::mapFn()(id); - if(name == "") throw xResMgrErr("Invalid resource ID."); - return have(name); - } - - /// Push a new path onto the path resolution stack - /// @tparam type The type of resource the path applies to. - /// @param path The path at which resources of this type may be found. - template void pushPath(fs::path path) { - resPool::resPaths().push(path); - if(resPool::resPaths().empty()) std::cerr << "A problem occurred.\n"; - } - - /// Pop a path from the path resolution stack. - /// @tparam type The type of resource the path applies to. - /// @return The removed path from the top of the stack. - template fs::path popPath() { - fs::path path = resPool::resPaths().top(); - resPool::resPaths().pop(); - return path; - } - - /// Set an ID map function. - /// @tparam type The type of resource for which an ID map function should be set. - /// @param f The new ID map function. - template void setIdMapFn(idMapFn f) { - resPool::mapFn() = f; - } - - /// Get the ID map function for a resource type. - /// @tparam type The type of resource to fetch the ID map function for. - /// @return The currend ID map function for this resource type. - template idMapFn getIdMapFn() { - return resPool::mapFn(); - } + /// Runs garbage collection to free up some resources. + /// First it attempts to free orphaned resources - those whose path was popped but haven't yet been reloaded. + /// Then, if necessary, it may free some resources marked as purgeable. + void gc() { + auto iter = resources.begin(); + while(iter != resources.end()) { + if(iter->second.orphaned) { + iter = resources.erase(iter); + } else { + ++iter; + } + } + iter = resources.begin(); + while(iter != resources.end() && resources.size() >= overflow) { + if(iter->second.purgeable) { + iter = resources.erase(iter); + } else { + ++iter; + } + } + } + public: + cPool(cLoader& loader, size_t max, std::string dir = "") + : directory(dir), overflow(max), load(loader) + {} + /// Gets a resource from the pool, loading it if it is not already cached. + /// @param resourceName The name of the resource to fetch + /// @param purgeable If true, this resource may be removed from the cache in order to + /// reduce cache space. If the resource is not held elsewhere, this will result in its + /// destruction. Best used for resources that are expected to be used once and then discarded. + /// This parameter is ignored if the resource is already cached. + /// @return A handle to the resource. This handle is dynamically updated - in the event that the + /// resource needs to be reloaded, it will be changed to point to the up-to-date version. + const cPointer& get(const std::string& resourceName, bool purgeable = false) { + if(false) { + ERROR_THROW: + std::ostringstream err; + err << "Error! Could not load resource '" << resourceName << "' of type '" << load.typeName() << "'\n"; + err << " (The resource loader returned a null pointer.)\n"; + throw xError(ERR_LOAD, err.str()); + } + auto resIter = resources.find(resourceName); + if(resIter != resources.end()) { + auto pathIter = resolvedPaths.find(resourceName); + if(pathIter != resolvedPaths.end()) { + // Resource is good, so return it + return resIter->second; + } + // If we get here, the resource's path has been removed from the stack, so it must be re-resolved. + fs::path newPath = find(resourceName); + if(newPath == resIter->second.path) { + // Path didn't change, so remember the path and return it + resolvedPaths[resourceName] = newPath; + return resIter->second; + } + T* ptr = load(newPath); + if(!ptr) { + resources.erase(resIter); + goto ERROR_THROW; + } + resIter->second.res_ptr->reset(ptr); + resIter->second.path = newPath.string(); + resIter->second.orphaned = false; + return resIter->second; + } + // If we get here, it hasn't even been loaded yet. + fs::path path = find(resourceName); + T* ptr = load(path); + if(!ptr) goto ERROR_THROW; + resIter = resources.emplace(resourceName, cPointer(purgeable)).first; + resIter->second.res_ptr.reset(new std::shared_ptr(ptr)); + resIter->second.path = path.string(); + if(resources.size() > overflow) gc(); + return resIter->second; + } + /// Forcibly remove a resource from the pool. This does not destroy the resource unless other + /// pointers to it are also released. If the resource is not cached, this does nothing. + /// @param resourceName The name of the resource to free + void free(const std::string& name) { + auto iter = resources.find(name); + if(iter != resources.end()) { + resources.erase(iter); + resolvedPaths.erase(name); + } + } + /// Removes all cached resources, freeing them if not held by other code. + void drain() { + resources.clear(); + } + /// Check if a resource with the given name exists. + /// Calling this caches the resolved path but does not load the resource. + /// @param resourceName The name of the resource to fetch + bool have(const std::string& resourceName) { + auto iter = resources.find(resourceName); + if(iter != resources.end() && !iter->second.orphaned) + return true; + try { + return find(resourceName).is_absolute(); + } catch(xError&) { + return false; + } + } + /// Pushes a new path onto the resolution stack. + /// Calling this causes any cached resolved paths to be forgotten. + void pushPath(const fs::path& path) { + paths.push(path); + resolvedPaths.clear(); + } + /// Pops the top path from the resolution stack and returns it. + /// Any resources previously resolved to this path are marked as orphaned. + fs::path popPath() { + fs::path p = paths.top(); + paths.pop(); + std::string pstr = p.string(); + auto iter = resolvedPaths.begin(); + while(iter != resolvedPaths.end()) { + std::string cmp = iter->second.string(); + if(cmp.compare(0, pstr.size(), pstr) == 0) { + auto resIter = resources.find(iter->first); + if(resIter != resources.end()) + resIter->second.orphaned = true; + iter = resolvedPaths.erase(iter); + } else { + ++iter; + } + } + return p; + } + /// Returns the path at the top of the resolution stack + fs::path topPath() { + return paths.top(); + } + }; } + #endif diff --git a/src/fileio/resmgr/restypes.cpp b/src/fileio/resmgr/restypes.cpp deleted file mode 100644 index 230b54b6..00000000 --- a/src/fileio/resmgr/restypes.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// restypes.cpp -// BoE -// -// Created by Celtic Minstrel on 15-09-25. -// -// - -#include "res_image.hpp" -#include "res_cursor.hpp" -#include "res_font.hpp" -#include "res_strings.hpp" -#include "res_sound.hpp" - -namespace ResMgr { - template<> const std::string resLoader::file_ext = "png"; - template<> const std::string resLoader::file_ext = "gif"; - template<> const std::string resLoader::file_ext = "ttf"; - template<> const std::string resLoader::file_ext = "txt"; - template<> const std::string resLoader::file_ext = "wav"; -} diff --git a/src/game/boe.dlgutil.cpp b/src/game/boe.dlgutil.cpp index 3c925bbb..a268dd08 100644 --- a/src/game/boe.dlgutil.cpp +++ b/src/game/boe.dlgutil.cpp @@ -1313,7 +1313,7 @@ static bool tip_of_day_event_filter(cDialog& me, std::string item_hit, short& pa me.toast(true); } else if(item_hit == "next") { page++; - if(page == ResMgr::get("tips")->size() - 50) + if(page == ResMgr::strings.get("tips")->size() - 50) page = 0; place_str = get_str("tips",50 + page); me["tip"].setText(place_str); @@ -1324,7 +1324,7 @@ static bool tip_of_day_event_filter(cDialog& me, std::string item_hit, short& pa void tip_of_day() { using namespace std::placeholders; - short page = get_ran(1,0,ResMgr::get("tips")->size() - 51); + short page = get_ran(1,0,ResMgr::strings.get("tips")->size() - 51); set_cursor(sword_curs); diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 32fa9dc1..87593f93 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -165,8 +165,8 @@ void adjust_window_mode() { mainView.setViewport(mainPort); #ifndef __APPLE__ // This overrides Dock icon on OSX, which isn't what we want at all - ImageRsrc& icon = *ResMgr::get("icon"); - mainPtr.setIcon(icon.getSize().x, icon.getSize().y, icon.copyToImage().getPixelsPtr()); + const ImageRsrc& icon = ResMgr::graphics.get("icon"); + mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr()); #endif if(text_sbar) { text_sbar->relocate({560,285}); @@ -245,13 +245,13 @@ sf::FloatRect compute_viewport(const sf::RenderWindow& mainPtr, int mode, float void init_startup() { // Preload the main startup images - ResMgr::get("startup"); - ResMgr::get("startbut"); - ResMgr::get("startanim"); + ResMgr::graphics.get("startup"); + ResMgr::graphics.get("startbut"); + ResMgr::graphics.get("startanim"); } void draw_startup(short but_type) { - sf::Texture& startup_gworld = *ResMgr::get("startup"); + sf::Texture& startup_gworld = *ResMgr::graphics.get("startup"); rect_draw_some_item(startup_gworld,startup_from[0],mainPtr,startup_top); for(auto btn : startup_button.keys()) { @@ -271,9 +271,9 @@ void draw_startup_anim(bool advance) { anim_from = anim_to; anim_from.offset(-1,-4 + startup_anim_pos); if(advance) startup_anim_pos = (startup_anim_pos + 1) % 542; - rect_draw_some_item(*ResMgr::get("startbut"),anim_size,mainPtr,startup_button[STARTBTN_SCROLL]); + rect_draw_some_item(*ResMgr::graphics.get("startbut"),anim_size,mainPtr,startup_button[STARTBTN_SCROLL]); anim_to.offset(startup_button[STARTBTN_SCROLL].left, startup_button[STARTBTN_SCROLL].top); - rect_draw_some_item(*ResMgr::get("startanim"),anim_from,mainPtr,anim_to,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("startanim"),anim_from,mainPtr,anim_to,sf::BlendAlpha); } void draw_startup_stats() { @@ -317,7 +317,7 @@ void draw_startup_stats() { to_rect.offset(pc_rect.left,pc_rect.top); pic_num_t pic = univ.party[i].which_graphic; if(pic >= 1000) { - sf::Texture* gw; + const sf::Texture* gw; graf_pos_ref(gw, from_rect) = spec_scen_g.find_graphic(pic % 1000, pic >= 10000); rect_draw_some_item(*gw,from_rect,mainPtr,to_rect,sf::BlendAlpha); } else if(pic >= 100) { @@ -326,11 +326,11 @@ void draw_startup_stats() { // PCs can't be larger than that, but we leave it to the scenario designer to avoid assigning larger graphics. from_rect = get_monster_template_rect(pic, 0, 0); int which_sheet = m_pic_index[pic].i / 20; - sf::Texture& monst_gworld = *ResMgr::get("monst" + std::to_string(1 + which_sheet)); + sf::Texture& monst_gworld = *ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); rect_draw_some_item(monst_gworld,from_rect,mainPtr,to_rect,sf::BlendAlpha); } else { from_rect = calc_rect(2 * (pic / 8), pic % 8); - sf::Texture& pc_gworld = *ResMgr::get("pcs"); + sf::Texture& pc_gworld = *ResMgr::graphics.get("pcs"); rect_draw_some_item(pc_gworld,from_rect,mainPtr,to_rect,sf::BlendAlpha); } @@ -429,7 +429,7 @@ void draw_start_button(eStartButton which_position,short which_button) { to_rect.left += 4; to_rect.top += 4; to_rect.right = to_rect.left + 40; to_rect.bottom = to_rect.top + 40; - rect_draw_some_item(*ResMgr::get("startup"),from_rect,mainPtr,to_rect); + rect_draw_some_item(*ResMgr::graphics.get("startup"),from_rect,mainPtr,to_rect); TextStyle style; style.font = FONT_DUNGEON; @@ -491,7 +491,7 @@ void end_startup() { } static void loadImageToRenderTexture(sf::RenderTexture& tex, std::string imgName) { - sf::Texture& temp_gworld = *ResMgr::get(imgName); + sf::Texture& temp_gworld = *ResMgr::graphics.get(imgName); rectangle texrect(temp_gworld); tex.create(texrect.width(), texrect.height()); rect_draw_some_item(temp_gworld, texrect, tex, texrect, sf::BlendNone); @@ -499,13 +499,13 @@ static void loadImageToRenderTexture(sf::RenderTexture& tex, std::string imgName void load_main_screen() { // Preload the main game interface images - ResMgr::get("invenbtns"); + ResMgr::graphics.get("invenbtns"); loadImageToRenderTexture(terrain_screen_gworld, "terscreen"); loadImageToRenderTexture(pc_stats_gworld, "statarea"); loadImageToRenderTexture(item_stats_gworld, "inventory"); loadImageToRenderTexture(text_area_gworld, "transcript"); loadImageToRenderTexture(text_bar_gworld, "textbar"); - ResMgr::get("buttons"); + ResMgr::graphics.get("buttons"); } void redraw_screen(int refresh) { @@ -620,7 +620,7 @@ void draw_buttons(short mode) { button_gw.create(266,38); } - sf::Texture& buttons_gworld = *ResMgr::get("buttons"); + sf::Texture& buttons_gworld = *ResMgr::graphics.get("buttons"); dest_rec = lg_rect; bool bottom_half = false; @@ -713,7 +713,7 @@ void draw_text_bar() { void put_text_bar(std::string str) { text_bar_gworld.setActive(); - rect_draw_some_item(*ResMgr::get("textbar"), win_from_rects[WINRECT_STATUS], text_bar_gworld, win_from_rects[WINRECT_STATUS]); + rect_draw_some_item(*ResMgr::graphics.get("textbar"), win_from_rects[WINRECT_STATUS], text_bar_gworld, win_from_rects[WINRECT_STATUS]); TextStyle style; style.colour = sf::Color::White; style.font = FONT_BOLD; @@ -725,7 +725,7 @@ void put_text_bar(std::string str) { win_draw_string(text_bar_gworld, to_rect, str, eTextMode::LEFT_TOP, style); if(!monsters_going) { - sf::Texture& status_gworld = *ResMgr::get("staticons"); + sf::Texture& status_gworld = *ResMgr::graphics.get("staticons"); to_rect.top -= 2; to_rect.left = to_rect.right - 15; to_rect.width() = 12; @@ -991,7 +991,7 @@ void draw_terrain(short mode) { // Draw top half of forcecages (this list is populated by draw_fields) // TODO: Move into the above loop to eliminate global variable for(location fc_loc : forcecage_locs) - Draw_Some_Item(*ResMgr::get("fields"),calc_rect(2,0),terrain_screen_gworld,fc_loc,1,0); + Draw_Some_Item(*ResMgr::graphics.get("fields"),calc_rect(2,0),terrain_screen_gworld,fc_loc,1,0); // Draw any posted labels, then clear them out clip_rect(terrain_screen_gworld, {13, 13, 337, 265}); for(text_label_t lbl : posted_labels) @@ -1158,7 +1158,7 @@ static void init_trim_mask(std::unique_ptr& mask, rectangle src_rec std::tie(dest_rect.top, dest_rect.bottom) = std::make_tuple(36 - dest_rect.top, 36 - dest_rect.bottom); render.create(28, 36); render.clear(sf::Color::White); - rect_draw_some_item(*ResMgr::get("trim"), src_rect, render, dest_rect); + rect_draw_some_item(*ResMgr::graphics.get("trim"), src_rect, render, dest_rect); render.display(); mask.reset(new sf::Texture); mask->create(28, 36); @@ -1191,7 +1191,7 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { }; static std::unique_ptr trim_masks[12], walkway_masks[9]; rectangle from_rect = {0,0,36,28},to_rect; - sf::Texture* from_gworld; + const sf::Texture* from_gworld; sf::Texture* mask; static bool inited = false; if(!inited){ @@ -1219,11 +1219,11 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { unsigned short pic = univ.scenario.ter_types[ground_ter].picture; if(pic < 960){ int which_sheet = pic / 50; - from_gworld = ResMgr::get("ter" + std::to_string(1 + which_sheet)).get(); + from_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); pic %= 50; from_rect.offset(28 * (pic % 10), 36 * (pic / 10)); }else if(pic < 1000){ - from_gworld = ResMgr::get("teranim").get(); + from_gworld = &ResMgr::graphics.get("teranim"); pic -= 960; from_rect.offset(112 * (pic / 5),36 * (pic % 5)); }else{ @@ -1305,7 +1305,7 @@ void place_road(short q,short r,location where,bool here) { {16,12,20,16}, // central spot }; - sf::Texture& roads_gworld = *ResMgr::get("trim"); + sf::Texture& roads_gworld = *ResMgr::graphics.get("trim"); if(here){ to_rect = road_dest_rects[6]; @@ -1482,7 +1482,7 @@ void boom_space(location where,short mode,short type,short damage,short sound) { dest_rect.offset(win_to_rects[WINRECT_TERVIEW].topLeft()); source_rect.offset(-store_rect.left + 28 * type,-store_rect.top); - rect_draw_some_item(*ResMgr::get("booms"),source_rect,mainPtr,dest_rect,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("booms"),source_rect,mainPtr,dest_rect,sf::BlendAlpha); if(damage > 0 && dest_rect.right - dest_rect.left >= 28 && dest_rect.bottom - dest_rect.top >= 36) { TextStyle style; @@ -1573,7 +1573,7 @@ void draw_targets(location center) { if(!univ.party.is_alive()) return; - sf::Texture& src_gworld = *ResMgr::get("trim"); + sf::Texture& src_gworld = *ResMgr::graphics.get("trim"); for(short i = 0; i < 8; i++) if((spell_targets[i].x != -1) && (point_onscreen(center,spell_targets[i]))) { rectangle dest_rect = coord_to_rect(spell_targets[i].x - center.x + 4,spell_targets[i].y - center.y + 4); diff --git a/src/game/boe.graphutil.cpp b/src/game/boe.graphutil.cpp index 6bf55357..295c3958 100644 --- a/src/game/boe.graphutil.cpp +++ b/src/game/boe.graphutil.cpp @@ -62,7 +62,7 @@ bool gave_no_g_error = false; void draw_one_terrain_spot (short i,short j,short terrain_to_draw) { rectangle where_draw; rectangle source_rect; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; short anim_type = 0; location l; @@ -80,7 +80,7 @@ void draw_one_terrain_spot (short i,short j,short terrain_to_draw) { if(terrain_to_draw >= 10000) { // force using a specific graphic terrain_to_draw -= 10000; int which_sheet = terrain_to_draw / 50; - source_gworld = ResMgr::get("ter" + std::to_string(1 + which_sheet)).get(); + source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); terrain_to_draw %= 50; source_rect = calc_rect(terrain_to_draw % 10, terrain_to_draw / 10); anim_type = -1; @@ -93,7 +93,7 @@ void draw_one_terrain_spot (short i,short j,short terrain_to_draw) { graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(univ.scenario.ter_types[terrain_to_draw].picture - 1000); } else if(univ.scenario.ter_types[terrain_to_draw].picture >= 960) { // animated - source_gworld = ResMgr::get("teranim").get(); + source_gworld = &ResMgr::graphics.get("teranim"); terrain_to_draw = univ.scenario.ter_types[terrain_to_draw].picture; source_rect = calc_rect(4 * ((terrain_to_draw - 960) / 5) + (anim_ticks % 4),(terrain_to_draw - 960) % 5); anim_type = 0; @@ -101,7 +101,7 @@ void draw_one_terrain_spot (short i,short j,short terrain_to_draw) { else { terrain_to_draw = univ.scenario.ter_types[terrain_to_draw].picture; int which_sheet = terrain_to_draw / 50; - source_gworld = ResMgr::get("ter" + std::to_string(1 + which_sheet)).get(); + source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); terrain_to_draw %= 50; source_rect = calc_rect(terrain_to_draw % 10, terrain_to_draw / 10); anim_type = -1; @@ -146,7 +146,7 @@ void draw_monsters() { if(picture_wanted >= 0) { if(picture_wanted >= 1000) { for(short k = 0; k < width * height; k++) { - sf::Texture* src_gw; + const sf::Texture* src_gw; graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000 + ((enc.direction < 4) ? 0 : (width * height)) + k); to_rect = monst_rects[(width - 1) * 2 + height - 1][k]; @@ -160,7 +160,7 @@ void draw_monsters() { to_rect = monst_rects[(width - 1) * 2 + height - 1][k]; to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y); int which_sheet = m_pic_index[picture_wanted].i / 20; - sf::Texture& monst_gworld = *ResMgr::get("monst" + std::to_string(1 + which_sheet)); + sf::Texture& monst_gworld = *ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); rect_draw_some_item(monst_gworld, source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha); } } @@ -189,7 +189,7 @@ void draw_monsters() { draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1); else if(monst.picture_num >= 1000) { bool isParty = monst.picture_num >= 10000; - sf::Texture* src_gw; + const sf::Texture* src_gw; pic_num_t need_pic = (monst.picture_num % 1000) + k; if(monst.direction >= 4) need_pic += width * height; if(combat_posing_monster == i + 100) need_pic += (2 * width * height); @@ -201,7 +201,7 @@ void draw_monsters() { pic_mode += (combat_posing_monster == i + 100) ? 10 : 0; source_rect = get_monster_template_rect(this_monst, pic_mode, k); int which_sheet = m_pic_index[this_monst].i / 20; - sf::Texture& monst_gworld = *ResMgr::get("monst" + std::to_string(1 + which_sheet)); + sf::Texture& monst_gworld = *ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); Draw_Some_Item(monst_gworld, source_rect, terrain_screen_gworld, store_loc, 1, 0); } } @@ -228,7 +228,7 @@ void draw_combat_pc(cPlayer& who, location center, bool attacking) { if(point_onscreen(center, who.combat_pos) && (cartoon_happening || party_can_see(who.combat_pos) < 6)) { location where_draw(who.combat_pos.x - center.x + 4, who.combat_pos.y - center.y + 4); rectangle source_rect; - sf::Texture* from_gw; + const sf::Texture* from_gw; pic_num_t pic = who.which_graphic; if(pic >= 1000) { bool isParty = pic >= 10000; @@ -249,14 +249,14 @@ void draw_combat_pc(cPlayer& who, location center, bool attacking) { mode += 10; source_rect = get_monster_template_rect(need_pic, mode, 0); int which_sheet = m_pic_index[need_pic].i / 20; - from_gw = ResMgr::get("monst" + std::to_string(1 + which_sheet)).get(); + from_gw = &ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); } else { source_rect = calc_rect(2 * (pic / 8), pic % 8); if(who.direction >= 4) source_rect.offset(28,0); if(attacking) source_rect.offset(0,288); - from_gw = ResMgr::get("pcs").get(); + from_gw = &ResMgr::graphics.get("pcs"); } Draw_Some_Item(*from_gw, source_rect, terrain_screen_gworld, where_draw, 1, 0); @@ -303,7 +303,7 @@ void draw_items(location where){ if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where) { if(univ.town.items[i].contained) continue; if(party_can_see(where) >= 6) continue; - sf::Texture* src_gw; + const sf::Texture* src_gw; to_rect = coord_to_rect(where_draw.x,where_draw.y); if(univ.town.items[i].graphic_num >= 10000){ graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(univ.town.items[i].graphic_num - 10000, true); @@ -318,7 +318,7 @@ void draw_items(location where){ void draw_outd_boats(location center) { location where_draw; rectangle source_rect; - sf::Texture& vehicle_gworld = *ResMgr::get("vehicle"); + sf::Texture& vehicle_gworld = *ResMgr::graphics.get("vehicle"); for(auto& boat : univ.party.boats) { if(!boat.exists) continue; @@ -347,7 +347,7 @@ void draw_outd_boats(location center) { void draw_town_boat(location center) { location where_draw; rectangle source_rect; - sf::Texture& vehicle_gworld = *ResMgr::get("vehicle"); + sf::Texture& vehicle_gworld = *ResMgr::graphics.get("vehicle"); for(auto& boat : univ.party.boats) { if(!boat.exists) continue; @@ -377,7 +377,7 @@ void draw_fields(location where){ if(!point_onscreen(center,where)) return; if(party_can_see(where) >= 6) return; location where_draw(4 + where.x - center.x, 4 + where.y - center.y); - sf::Texture& fields_gworld = *ResMgr::get("fields"); + sf::Texture& fields_gworld = *ResMgr::graphics.get("fields"); if(is_out()){ if(univ.out.is_spot(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(4,0),terrain_screen_gworld,where_draw,1,0); @@ -408,7 +408,7 @@ void draw_fields(location where){ if(univ.town.is_barrel(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(7,0),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_fire_barr(where.x,where.y) || univ.town.is_force_barr(where.x,where.y)) - Draw_Some_Item(*ResMgr::get("teranim"),calc_rect(8+(anim_ticks%4),4),terrain_screen_gworld,where_draw,1,0); + Draw_Some_Item(*ResMgr::graphics.get("teranim"),calc_rect(8+(anim_ticks%4),4),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_quickfire(where.x,where.y)) Draw_Some_Item(fields_gworld,calc_rect(7,1),terrain_screen_gworld,where_draw,1,0); if(univ.town.is_sm_blood(where.x,where.y)) @@ -451,7 +451,7 @@ void draw_party_symbol(location center) { if((univ.party.in_boat < 0) && (univ.party.in_horse < 0)) { i = first_active_pc(); - sf::Texture* from_gw; + const sf::Texture* from_gw; pic_num_t pic = univ.party[i].which_graphic; if(pic >= 1000) { bool isParty = pic >= 10000; @@ -468,12 +468,12 @@ void draw_party_symbol(location center) { mode++; source_rect = get_monster_template_rect(need_pic, mode, 0); int which_sheet = m_pic_index[need_pic].i / 20; - from_gw = ResMgr::get("monst" + std::to_string(1 + which_sheet)).get(); + from_gw = &ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); } else { source_rect = calc_rect(2 * (pic / 8), pic % 8); if(univ.party.direction >= 4) source_rect.offset(28,0); - from_gw = ResMgr::get("pcs").get(); + from_gw = &ResMgr::graphics.get("pcs"); } ter_num_t ter = 0; if(is_out()) @@ -489,10 +489,10 @@ void draw_party_symbol(location center) { if(univ.party.direction == DIR_N) i = 2; else if(univ.party.direction == DIR_S) i = 3; else i = univ.party.direction > DIR_S; - Draw_Some_Item(*ResMgr::get("vehicle"), calc_rect(i,0), terrain_screen_gworld, target, 1, 0); + Draw_Some_Item(*ResMgr::graphics.get("vehicle"), calc_rect(i,0), terrain_screen_gworld, target, 1, 0); }else { i = univ.party.direction > 3; - Draw_Some_Item(*ResMgr::get("vehicle"), calc_rect(i + 2, 1), terrain_screen_gworld, target, 1, 0); + Draw_Some_Item(*ResMgr::graphics.get("vehicle"), calc_rect(i + 2, 1), terrain_screen_gworld, target, 1, 0); } } diff --git a/src/game/boe.newgraph.cpp b/src/game/boe.newgraph.cpp index 463d65fb..419a060b 100644 --- a/src/game/boe.newgraph.cpp +++ b/src/game/boe.newgraph.cpp @@ -389,7 +389,7 @@ void do_missile_anim(short num_steps,location missile_origin,short sound_num) { play_sound(-1 * sound_num); - sf::Texture& missiles_gworld = *ResMgr::get("missiles"); + sf::Texture& missiles_gworld = *ResMgr::graphics.get("missiles"); // Now, at last, launch missile for(short t = 0; t < num_steps; t++) { draw_terrain(); @@ -424,7 +424,7 @@ void do_missile_anim(short num_steps,location missile_origin,short sound_num) { base -= 10000; } else base -= 1000; base += step % 4; - sf::Texture* from_gw = nullptr; + const sf::Texture* from_gw = nullptr; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(base, isParty); if(from_gw == nullptr) continue; from_rect.width() = 18; @@ -547,7 +547,7 @@ void do_explosion_anim(short /*sound_num*/,short special_draw, short snd) { play_sound(-1 * snd_num); } - sf::Texture& boom_gworld = *ResMgr::get("booms"); + sf::Texture& boom_gworld = *ResMgr::graphics.get("booms"); // Now, at last, do explosion for(short t = (special_draw == 2) ? 6 : 0; t < ((special_draw == 1) ? 6 : 11); t++) { // t goes up to 10 to make sure screen gets cleaned up draw_terrain(); @@ -557,7 +557,7 @@ void do_explosion_anim(short /*sound_num*/,short special_draw, short snd) { if(store_booms[i].boom_type >= 0) { if((t + store_booms[i].offset >= 0) && (t + store_booms[i].offset <= 7)) { if(cur_boom_type >= 1000) { - sf::Texture* src_gworld; + const sf::Texture* src_gworld; graf_pos_ref(src_gworld, from_rect) = spec_scen_g.find_graphic(cur_boom_type - 1000 + t); rect_draw_some_item(*src_gworld, from_rect, mainPtr, explode_place_rect[i], sf::BlendAlpha); } else { @@ -606,12 +606,12 @@ void click_shop_rect(rectangle area_rect) { graf_pos calc_item_rect(int num,rectangle& to_rect) { if(num >= 1000) return spec_scen_g.find_graphic(num - 1000); rectangle from_rect = {0,0,18,18}; - sf::Texture *from_gw; + const sf::Texture *from_gw; if(num < 55) { - from_gw = ResMgr::get("objects").get(); + from_gw = &ResMgr::graphics.get("objects"); from_rect = calc_rect(num % 5, num / 5); }else{ - from_gw = ResMgr::get("tinyobj").get(); + from_gw = &ResMgr::graphics.get("tinyobj"); to_rect.inset(5,9); from_rect.offset(18 * (num % 10), 18 * (num / 10)); } @@ -666,13 +666,13 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) { // Place store icon if(!pressed) { rectangle from_rect = {0,0,32,32}; - sf::Texture* from_gw; + const sf::Texture* from_gw; int i = std::max(0, active_shop.getFace()); if(i >= 1000) { graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(i - 1000); } else { from_rect.offset(32 * (i % 10),32 * (i / 10)); - from_gw = ResMgr::get("talkportraits").get(); + from_gw = &ResMgr::graphics.get("talkportraits"); } rect_draw_some_item(*from_gw, from_rect, talk_gworld, face_rect); } @@ -722,7 +722,7 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) { style.colour = c[4]; else style.colour = sf::Color::Black; - sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); + sf::Texture& invenbtn_gworld = *ResMgr::graphics.get("invenbtns"); // Place all the items for(short i = 0; i < 8; i++) { current_pos = i + shop_sbar->getPosition(); @@ -734,7 +734,7 @@ void draw_shop_graphics(bool pressed,rectangle clip_area_rect) { base_item = item.item; std::string cur_name = base_item.full_name, cur_info_str; rectangle from_rect, to_rect = shopping_rects[i][SHOPRECT_GRAPHIC]; - sf::Texture* from_gw; + const sf::Texture* from_gw; switch(item.type) { case eShopItemType::ITEM: base_item.ident = true; diff --git a/src/game/boe.startup.cpp b/src/game/boe.startup.cpp index 9ce1904c..44d6678d 100644 --- a/src/game/boe.startup.cpp +++ b/src/game/boe.startup.cpp @@ -143,7 +143,7 @@ void show_logo() { whole_window = rectangle(mainPtr); logo_from.offset((whole_window.right - logo_from.right) / 2,(whole_window.bottom - logo_from.bottom) / 2); - sf::Texture& pict_to_draw = *ResMgr::get("spidlogo"); + sf::Texture& pict_to_draw = *ResMgr::graphics.get("spidlogo"); from_rect = rectangle(pict_to_draw); play_sound(-95); @@ -165,7 +165,7 @@ void plop_fancy_startup() { whole_window = rectangle(mainPtr); sf::Time delay = time_in_ticks(220); intro_from.offset((whole_window.right - intro_from.right) / 2,(whole_window.bottom - intro_from.bottom) / 2); - sf::Texture& pict_to_draw = *ResMgr::get("startsplash"); + sf::Texture& pict_to_draw = *ResMgr::graphics.get("startsplash"); play_sound(-22); sf::Clock timer; diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index a144567c..1955eb30 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -95,7 +95,7 @@ void put_pc_screen() { pc_stats_gworld.setActive(); // First clean up gworld with pretty patterns - sf::Texture& orig = *ResMgr::get("statarea"); + sf::Texture& orig = *ResMgr::graphics.get("statarea"); rect_draw_some_item(orig, rectangle(orig), pc_stats_gworld, rectangle(pc_stats_gworld)); tileImage(pc_stats_gworld, erase_rect,bg[6]); @@ -119,7 +119,7 @@ void put_pc_screen() { win_draw_string(pc_stats_gworld,day_rect[0],std::to_string(univ.party.calc_day()),eTextMode::WRAP,style); style.colour = sf::Color::Black; - sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); + sf::Texture& invenbtn_gworld = *ResMgr::graphics.get("invenbtns"); for(short i = 0; i < 6; i++) { if(univ.party[i].main_status != eMainStatus::ABSENT) { for(auto& flag : pc_area_button_active[i]) @@ -216,7 +216,7 @@ void put_item_screen(eItemWinMode screen_num) { item_stats_gworld.setActive(); // First clean up gworld with pretty patterns - sf::Texture& orig = *ResMgr::get("inventory"); + sf::Texture& orig = *ResMgr::graphics.get("inventory"); rect_draw_some_item(orig, rectangle(orig), item_stats_gworld, rectangle(item_stats_gworld)); tileImage(item_stats_gworld, erase_rect,bg[6]); @@ -408,7 +408,7 @@ void place_buy_button(short position,short pc_num,short item_num) { return; } if(item_area_button_active[position][ITEMBTN_SPEC]) { - sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); + sf::Texture& invenbtn_gworld = *ResMgr::graphics.get("invenbtns"); store_selling_values[position] = val_to_place; dest_rect = item_buttons[position][ITEMBTN_SPEC]; dest_rect.right = dest_rect.left + 30; @@ -435,22 +435,21 @@ void place_item_graphic(short which_slot,short graphic) { to_rect.inset(-1,-1); to_rect.offset(20,1); from_rect.inset(2,2); + const sf::Texture* src_gw; if(graphic >= 10000) { - sf::Texture* src_gw; graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(graphic - 10000, true); rect_draw_some_item(*src_gw, from_rect, item_stats_gworld, to_rect,sf::BlendAlpha); } else if(graphic >= 1000) { - sf::Texture* src_gw; graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(graphic - 1000); rect_draw_some_item(*src_gw, from_rect, item_stats_gworld, to_rect,sf::BlendAlpha); } - else rect_draw_some_item(*ResMgr::get("tinyobj"), from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); + else rect_draw_some_item(*ResMgr::graphics.get("tinyobj"), from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); } void place_item_button(short button_position,short which_slot,eItemButton button_type) { rectangle from_rect = {0,0,18,18},to_rect; - sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); + sf::Texture& invenbtn_gworld = *ResMgr::graphics.get("invenbtns"); switch(button_position) { default: // this means put a regular item button item_area_button_active[which_slot][button_type] = true; @@ -490,14 +489,14 @@ void place_item_bottom_buttons() { style.font = FONT_BOLD; style.colour = sf::Color::Yellow; - sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); + sf::Texture& invenbtn_gworld = *ResMgr::graphics.get("invenbtns"); for(short i = 0; i < 6; i++) { if(univ.party[i].main_status == eMainStatus::ALIVE) { item_bottom_button_active[i] = true; to_rect = item_screen_button_rects[i]; rect_draw_some_item(invenbtn_gworld, but_from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); pic_num_t pic = univ.party[i].which_graphic; - sf::Texture* from_gw; + const sf::Texture* from_gw; if(pic >= 1000) { bool isParty = pic >= 10000; pic_num_t need_pic = pic % 1000; @@ -509,10 +508,10 @@ void place_item_bottom_buttons() { int mode = 0; pc_from_rect = get_monster_template_rect(need_pic, mode, 0); int which_sheet = m_pic_index[need_pic].i / 20; - from_gw = ResMgr::get("monst" + std::to_string(1 + which_sheet)).get(); + from_gw = &ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); } else { pc_from_rect = calc_rect(2 * (pic / 8), pic % 8); - from_gw = ResMgr::get("pcs").get(); + from_gw = &ResMgr::graphics.get("pcs"); } to_rect.inset(2,2); rect_draw_some_item(*from_gw, pc_from_rect, item_stats_gworld, to_rect, sf::BlendAlpha); @@ -625,7 +624,7 @@ void draw_pc_effects(short pc) { return; univ.party[pc].status[eStatus::HASTE_SLOW]; // This just makes sure it exists in the map, without changing its value if it does - sf::Texture& status_gworld = *ResMgr::get("staticons"); + sf::Texture& status_gworld = *ResMgr::graphics.get("staticons"); for(auto next : univ.party[pc].status) { short placedIcon = -1; if(next.first == eStatus::POISON && next.second > 4) placedIcon = 1; @@ -1055,7 +1054,7 @@ void print_buf () { location moveTo; while((line_to_print!= buf_pointer) && (num_lines_printed < LINES_IN_TEXT_WIN)) { moveTo = location(4, 1 + 12 * num_lines_printed); - sf::Text text(text_buffer[line_to_print].line, *ResMgr::get("plain"), 12); + sf::Text text(text_buffer[line_to_print].line, *ResMgr::fonts.get("plain"), 12); text.setColor(sf::Color::Black); text.setPosition(moveTo); text_area_gworld.draw(text); @@ -1093,7 +1092,7 @@ void through_sending() { /* Draw a bitmap in the world window. hor in 0 .. 8, vert in 0 .. 8, object is ptr. to bitmap to be drawn, and masking is for Copybits. */ -void Draw_Some_Item (sf::Texture& src_gworld, rectangle src_rect, sf::RenderTarget& targ_gworld,location target, char masked, short main_win) { +void Draw_Some_Item(const sf::Texture& src_gworld, rectangle src_rect, sf::RenderTarget& targ_gworld,location target, char masked, short main_win) { rectangle destrec = {0,0,36,28}; if((target.x < 0) || (target.y < 0) || (target.x > 8) || (target.y > 8)) diff --git a/src/game/boe.text.hpp b/src/game/boe.text.hpp index 253cfb7a..df065ee0 100644 --- a/src/game/boe.text.hpp +++ b/src/game/boe.text.hpp @@ -36,7 +36,7 @@ void restore_mode(); void through_sending(); rectangle coord_to_rect(short i,short j); bool day_reached(unsigned short which_day, unsigned short which_event); -void Draw_Some_Item (sf::Texture& src_gworld, rectangle src_rect, sf::RenderTarget& targ_gworld, location target, char masked, short main_win); +void Draw_Some_Item(const sf::Texture& src_gworld, rectangle src_rect, sf::RenderTarget& targ_gworld, location target, char masked, short main_win); rectangle get_stat_effect_rect(int which_effect); struct text_label_t { diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 1092d76f..a43c1f85 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -1402,7 +1402,7 @@ void draw_map(bool need_refresh) { else out_mode = false; // TODO: It could be possible to draw the entire map here and then only refresh if a spot actually changes terrain type - sf::Texture& small_ter_gworld = *ResMgr::get("termap"); + sf::Texture& small_ter_gworld = *ResMgr::graphics.get("termap"); for(where.x = redraw_rect.left; where.x < redraw_rect.right; where.x++) for(where.y = redraw_rect.top; where.y < redraw_rect.bottom; where.y++) { draw_rect = orig_draw_rect; @@ -1428,7 +1428,7 @@ void draw_map(bool need_refresh) { if(pic >= 1000) { if(spec_scen_g) { //print_nums(0,99,pic); - sf::Texture* src_gw; + const sf::Texture* src_gw; if(drawLargeIcon) { pic = pic % 1000; graf_pos_ref(src_gw, custom_from) = spec_scen_g.find_graphic(pic); @@ -1445,10 +1445,10 @@ void draw_map(bool need_refresh) { } else if(drawLargeIcon) { if(pic >= 960) { custom_from = calc_rect(4 * ((pic - 960) / 5),(pic - 960) % 5); - rect_draw_some_item(*ResMgr::get("teranim"), custom_from, map_gworld, draw_rect); + rect_draw_some_item(*ResMgr::graphics.get("teranim"), custom_from, map_gworld, draw_rect); } else { int which_sheet = pic / 50; - sf::Texture* src_gw = ResMgr::get("ter" + std::to_string(1 + which_sheet)).get(); + const sf::Texture* src_gw = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); pic %= 50; custom_from = calc_rect(pic % 10, pic / 10); rect_draw_some_item(*src_gw, custom_from, map_gworld, draw_rect); @@ -1464,7 +1464,7 @@ void draw_map(bool need_refresh) { if(is_out() ? univ.out->roads[where.x][where.y] : univ.town.is_road(where.x,where.y)) { draw_rect.inset(1,1); - rect_draw_some_item(*ResMgr::get("trim"),{8,112,12,116},map_gworld,draw_rect); + rect_draw_some_item(*ResMgr::graphics.get("trim"),{8,112,12,116},map_gworld,draw_rect); } } } diff --git a/src/gfx/gfxsheets.cpp b/src/gfx/gfxsheets.cpp index f01d062b..bf9e93c5 100644 --- a/src/gfx/gfxsheets.cpp +++ b/src/gfx/gfxsheets.cpp @@ -29,7 +29,7 @@ graf_pos cCustomGraphics::find_graphic(pic_num_t which_rect, bool party) { else if(numSheets == 0) valid = false; if(!valid) { INVALID: - sf::Texture* blank = ResMgr::get("blank").get(); + const sf::Texture* blank = &ResMgr::graphics.get("blank"); return {blank, {0,0,36,28}}; } short sheet = which_rect / 100; @@ -81,8 +81,8 @@ void cCustomGraphics::copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlot rect_draw_some_item(*party_sheet, rectangle(*party_sheet), temp, rectangle(*party_sheet)); *party_sheet = temp.getTexture(); } - sf::Texture* from_sheet; - sf::Texture* to_sheet; + const sf::Texture* from_sheet; + const sf::Texture* to_sheet; sf::Texture* last_src = nullptr; sf::RenderTexture temp; rectangle from_rect, to_rect; @@ -91,7 +91,7 @@ void cCustomGraphics::copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlot graf_pos_ref(to_sheet, to_rect) = find_graphic(dest + i, true); if(to_sheet != last_src) { if(last_src) *last_src = temp.getTexture(); - last_src = to_sheet; + last_src = const_cast(to_sheet); temp.create(to_sheet->getSize().x, to_sheet->getSize().y); rect_draw_some_item(*to_sheet, rectangle(*to_sheet), temp, rectangle(*to_sheet)); } @@ -128,7 +128,7 @@ void cCustomGraphics::convert_sheets() { fs::path sheetPath = pic_dir/("sheet" + std::to_string(i) + ".png"); sheets[i].copyToImage().saveToFile(sheetPath.string().c_str()); } - ResMgr::pushPath(pic_dir); + ResMgr::graphics.pushPath(pic_dir); } void cCustomGraphics::replace_sheet(size_t num, sf::Image& newSheet) { @@ -139,7 +139,7 @@ void cCustomGraphics::replace_sheet(size_t num, sf::Image& newSheet) { std::string sheetname = "sheet" + std::to_string(num); fs::path tmpPath = tempDir/scenario_temp_dir_name/"graphics"/(sheetname + ".png"); newSheet.saveToFile(tmpPath.string().c_str()); - ResMgr::free(sheetname); + ResMgr::graphics.free(sheetname); } void cCustomGraphics::init_sheet(size_t num) { diff --git a/src/gfx/gfxsheets.hpp b/src/gfx/gfxsheets.hpp index c347f554..3befb3b0 100644 --- a/src/gfx/gfxsheets.hpp +++ b/src/gfx/gfxsheets.hpp @@ -16,8 +16,8 @@ #include "location.hpp" static const pic_num_t NO_PIC = -1; -using graf_pos = std::pair; -using graf_pos_ref = std::pair; +using graf_pos = std::pair; +using graf_pos_ref = std::pair; struct m_pic_index_t { unsigned char i, x, y; diff --git a/src/gfx/render_text.cpp b/src/gfx/render_text.cpp index 1e69e4ec..a3f7a982 100644 --- a/src/gfx/render_text.cpp +++ b/src/gfx/render_text.cpp @@ -14,16 +14,16 @@ void TextStyle::applyTo(sf::Text& text) { switch(font) { case FONT_PLAIN: - text.setFont(*ResMgr::get("plain")); + text.setFont(*ResMgr::fonts.get("plain")); break; case FONT_BOLD: - text.setFont(*ResMgr::get("bold")); + text.setFont(*ResMgr::fonts.get("bold")); break; case FONT_DUNGEON: - text.setFont(*ResMgr::get("dungeon")); + text.setFont(*ResMgr::fonts.get("dungeon")); break; case FONT_MAIDWORD: - text.setFont(*ResMgr::get("maidenword")); + text.setFont(*ResMgr::fonts.get("maidenword")); break; } text.setCharacterSize(pointSize); diff --git a/src/gfx/tiling.cpp b/src/gfx/tiling.cpp index 1d823e4b..0a9ff9d4 100644 --- a/src/gfx/tiling.cpp +++ b/src/gfx/tiling.cpp @@ -101,8 +101,8 @@ void init_tiling() { bg_rects[7].top += 32; rectangle bw_rect = {0,0,8,8}; - sf::Texture& bg_gworld = *ResMgr::get("pixpats"); - sf::Texture& bw_gworld = *ResMgr::get("bwpats"); + sf::Texture& bg_gworld = *ResMgr::graphics.get("pixpats"); + sf::Texture& bw_gworld = *ResMgr::graphics.get("bwpats"); for(int i = 0; i < 21; i++) { if(i < 6) { bw_pats[i] = prepareForTiling(bw_gworld, bw_rect); diff --git a/src/pcedit/pc.graphics.cpp b/src/pcedit/pc.graphics.cpp index 7762da00..48292a9e 100644 --- a/src/pcedit/pc.graphics.cpp +++ b/src/pcedit/pc.graphics.cpp @@ -186,13 +186,13 @@ void init_main_buttons() { void Set_up_win () { // Preload the main PC editor interface images - ResMgr::get("pcedtitle"); - ResMgr::get("icon"); - ResMgr::get("invenbtns"); - ResMgr::get("staticons"); - ResMgr::get("dlogpics"); - ResMgr::get("pcedbuttons"); - ResMgr::get("pcs"); + ResMgr::graphics.get("pcedtitle"); + ResMgr::graphics.get("icon"); + ResMgr::graphics.get("invenbtns"); + ResMgr::graphics.get("staticons"); + ResMgr::graphics.get("dlogpics"); + ResMgr::graphics.get("pcedbuttons"); + ResMgr::graphics.get("pcs"); } static void draw_main_screen(); @@ -228,12 +228,12 @@ void draw_main_screen() { tileImage(mainPtr,whole_win_rect,bg[12]); // fill whole window with background texture - sf::Texture& icon_gworld = *ResMgr::get("icon"); + sf::Texture& icon_gworld = *ResMgr::graphics.get("icon"); dest_rec = source_rect = rectangle(icon_gworld); dest_rec.offset(23, 16); rect_draw_some_item(icon_gworld,source_rect,mainPtr,dest_rec); - sf::Texture& title_gworld = *ResMgr::get("pcedtitle"); + sf::Texture& title_gworld = *ResMgr::graphics.get("pcedtitle"); dest_rec = source_rect = rectangle(title_gworld); dest_rec.offset(66, 0); rect_draw_some_item(title_gworld,source_rect,mainPtr,dest_rec,sf::BlendAlpha); @@ -331,7 +331,7 @@ void draw_items() { frame_dlog_rect(mainPtr,name_rect); // draw the frame return; // If PC is dead, it has no items } - sf::Texture& invenbtn_gworld = *ResMgr::get("invenbtns"); + sf::Texture& invenbtn_gworld = *ResMgr::graphics.get("invenbtns"); for(short i = 0; i < univ.party[current_active_pc].items.size(); i++) // Loop through items and draw each if(univ.party[current_active_pc].items[i].variety != eItemType::NO_ITEM) { // i.e. does item exist std::string to_draw = std::to_string(i + 1) + ". "; @@ -373,7 +373,7 @@ void display_party() { win_draw_string(mainPtr,no_party_rect,"No party loaded.",eTextMode::WRAP,style); } else { - sf::Texture& buttons_gworld = *ResMgr::get("pcedbuttons"); + sf::Texture& buttons_gworld = *ResMgr::graphics.get("pcedbuttons"); from_rect = pc_info_rect; from_rect.top = from_rect.bottom - 11; if(!party_in_scen) @@ -392,7 +392,7 @@ void display_party() { if(univ.party[i].main_status != eMainStatus::ABSENT) { // PC exists? // draw PC graphic pic_num_t pic = univ.party[i].which_graphic; - sf::Texture* from_gw; + const sf::Texture* from_gw; if(pic >= 1000) { bool isParty = pic >= 10000; pic_num_t need_pic = pic % 1000; @@ -404,10 +404,10 @@ void display_party() { pic_num_t picture_wanted = m_pic_index[need_pic].i % 20; from_rect = calc_rect(2 * (picture_wanted / 10), picture_wanted % 10); int which_sheet = m_pic_index[need_pic].i / 20; - from_gw = ResMgr::get("monst" + std::to_string(1 + which_sheet)).get(); + from_gw = &ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); } else { from_rect = calc_rect(2 * (pic / 8), pic % 8); - from_gw = ResMgr::get("pcs").get(); + from_gw = &ResMgr::graphics.get("pcs"); } rect_draw_some_item(*from_gw,from_rect,mainPtr,pc_area_buttons[i][1],sf::BlendAlpha); diff --git a/src/pcedit/pc.main.cpp b/src/pcedit/pc.main.cpp index b7069d1a..6266e425 100644 --- a/src/pcedit/pc.main.cpp +++ b/src/pcedit/pc.main.cpp @@ -115,8 +115,8 @@ void Initialize(void) { int height = 440 + getMenubarHeight(); mainPtr.create(sf::VideoMode(590, height), "Blades of Exile Character Editor", sf::Style::Titlebar | sf::Style::Close); #ifndef __APPLE__ // This overrides Dock icon on OSX, which isn't what we want at all - ImageRsrc& icon = *ResMgr::get("icon"); - mainPtr.setIcon(icon.getSize().x, icon.getSize().y, icon.copyToImage().getPixelsPtr()); + const ImageRsrc& icon = ResMgr::graphics.get("icon"); + mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr()); #endif init_menubar(); } diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index dfa2298c..198ea794 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -211,7 +211,7 @@ bool pick_string(std::string from_file, cDialog& parent, std::string result_fld, cTextField& fld_ctrl = dynamic_cast(parent[result_fld]); cur_sel = fld_ctrl.getTextAsNum(); } - StringRsrc strings = *ResMgr::get(from_file); + StringList strings = *ResMgr::strings.get(from_file); // TODO: Does it need a title? cStringChoice str_dlg(strings, "", &parent); size_t result = str_dlg.show(cur_sel); @@ -228,7 +228,7 @@ bool pick_string(std::string from_file, cDialog& parent, std::string result_fld, } static bool show_help(std::string from_file, cDialog& parent, pic_num_t pic){ - StringRsrc strings = *ResMgr::get(from_file); + StringList strings = *ResMgr::strings.get(from_file); cThreeChoice help(strings,basic_buttons[1],pic,PIC_DLOG,&parent); help.show(); return true; @@ -3353,7 +3353,7 @@ void edit_custom_sheets() { spec_scen_g.init_sheet(0); spec_scen_g.sheets[0].copyToImage().saveToFile((pic_dir/"sheet0.png").string().c_str()); all_pics.insert(all_pics.begin(), 0); - ResMgr::pushPath(pic_dir); + ResMgr::graphics.pushPath(pic_dir); } set_cursor(watch_curs); @@ -3392,7 +3392,7 @@ void edit_custom_sheets() { std::string resName = "sheet" + std::to_string(all_pics[cur]); fs::path toPath = pic_dir/(resName + ".png"); img->saveToFile(toPath.string().c_str()); - ResMgr::free(resName); + ResMgr::graphics.free(resName); return true; } sheets[cur] = *img; @@ -3411,7 +3411,7 @@ void edit_custom_sheets() { std::string resName = "sheet" + std::to_string(all_pics[cur]); fs::path toPath = pic_dir/(resName + ".png"); img.saveToFile(toPath.string().c_str()); - ResMgr::free(resName); + ResMgr::graphics.free(resName); return true; } sheets[cur] = img; @@ -3482,7 +3482,7 @@ void edit_custom_sheets() { if(!fs::exists(from)) continue; // Just in case fs::remove(to); fs::rename(from, to); - ResMgr::free("sheet" + std::to_string(which_pic)); + ResMgr::graphics.free("sheet" + std::to_string(which_pic)); } auto end = std::find(all_pics.begin() + cur, all_pics.end(), which_pic - 1); if(end != all_pics.end()) @@ -3496,7 +3496,7 @@ void edit_custom_sheets() { spec_scen_g.numSheets = which_pic; spec_scen_g.sheets = new sf::Texture[which_pic]; std::copy_n(wasSheets, which_pic, spec_scen_g.sheets); - ResMgr::free("sheet" + std::to_string(which_pic)); + ResMgr::graphics.free("sheet" + std::to_string(which_pic)); } delete[] wasSheets; } @@ -3578,7 +3578,7 @@ static bool edit_custom_sound_action(cDialog& me, std::string action, std::vecto return true; } fs::copy_file(fpath, sndfile, fs::copy_option::overwrite_if_exists); - ResMgr::free(which_snd); + ResMgr::sounds.free(sound_to_fname(which_snd)); if(which_snd > max_snd) max_snd = which_snd; if(max_snd % 10 == 9) { diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index cfc193b7..06a7a3e0 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -354,7 +354,7 @@ void Set_up_win() { void run_startup_g() { sf::Event event; - sf::Texture& pict_to_draw = *ResMgr::get("edsplash"); + sf::Texture& pict_to_draw = *ResMgr::graphics.get("edsplash"); rectangle dest_rect = rectangle(pict_to_draw); play_sound(-95); @@ -370,17 +370,17 @@ void run_startup_g() { } // It's never needed again, so don't keep it in GPU memory - ResMgr::free("edsplash"); + ResMgr::graphics.free("edsplash"); } void load_graphics(){ // Preload the main editor interface graphics - ResMgr::get("edbuttons"); - ResMgr::get("teranim"); - ResMgr::get("fields"); - ResMgr::get("objects"); - ResMgr::get("tinyobj"); - ResMgr::get("termap"); + ResMgr::graphics.get("edbuttons"); + ResMgr::graphics.get("teranim"); + ResMgr::graphics.get("fields"); + ResMgr::graphics.get("objects"); + ResMgr::graphics.get("tinyobj"); + ResMgr::graphics.get("termap"); } void redraw_screen() { @@ -440,7 +440,7 @@ void draw_lb_slot (short which,short mode) { from_rect = blue_button_from; if(mode > 0) from_rect.offset(0,from_rect.height()); - rect_draw_some_item(*ResMgr::get("edbuttons"),from_rect,mainPtr,left_buttons[which][1]); + rect_draw_some_item(*ResMgr::graphics.get("edbuttons"),from_rect,mainPtr,left_buttons[which][1]); } if(left_button_status[which].mode == LB_INDENT) text_rect.left += 16; @@ -505,7 +505,7 @@ void set_up_terrain_buttons(bool reset) { int end = min(first + 256, max); // first make terrain buttons - sf::Texture& editor_mixed = *ResMgr::get("edbuttons"); + sf::Texture& editor_mixed = *ResMgr::graphics.get("edbuttons"); for(short i = first; i < end; i++) { rectangle draw_rect = terrain_rects[i - first]; draw_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y); @@ -518,7 +518,7 @@ void set_up_terrain_buttons(bool reset) { ter_from = ter_from_base; pic = scenario.ter_types[i].picture; if(pic >= 1000) { - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000); rect_draw_some_item(*source_gworld, ter_from, mainPtr, draw_rect); } @@ -526,7 +526,7 @@ void set_up_terrain_buttons(bool reset) { pic = pic % 50; ter_from.offset(28 * (pic % 10), 36 * (pic / 10)); int which_sheet = scenario.ter_types[i].picture / 50; - rect_draw_some_item(*ResMgr::get("ter" + std::to_string(1 + which_sheet)), + rect_draw_some_item(*ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)), ter_from, mainPtr, draw_rect); } else { @@ -535,7 +535,7 @@ void set_up_terrain_buttons(bool reset) { ter_from.right = ter_from.left + 28; ter_from.top = 36 * (pic % 5); ter_from.bottom = ter_from.top + 36; - rect_draw_some_item(*ResMgr::get("teranim"), ter_from, mainPtr, draw_rect); + rect_draw_some_item(*ResMgr::graphics.get("teranim"), ter_from, mainPtr, draw_rect); } small_i = get_small_icon(i); @@ -555,7 +555,7 @@ void set_up_terrain_buttons(bool reset) { pic %= 1000; tiny_to.width() = tiny_to.width() / 2; tiny_to.height() = tiny_to.height() / 2; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic); rect_draw_some_item(*source_gworld, ter_from, mainPtr, tiny_to, sf::BlendAlpha); pic++; @@ -575,7 +575,7 @@ void set_up_terrain_buttons(bool reset) { tiny_to.width() = tiny_to.width() / 2; tiny_to.height() = tiny_to.height() / 2; tiny_to.offset(tiny_to.width() / 2, 0); - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic); rect_draw_some_item(*source_gworld, ter_from, mainPtr, tiny_to, sf::BlendAlpha); pic++; @@ -587,7 +587,7 @@ void set_up_terrain_buttons(bool reset) { tiny_to.width() = tiny_to.width() / 2; tiny_to.height() = tiny_to.height() / 2; tiny_to.offset(0, tiny_to.height() / 2); - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic); rect_draw_some_item(*source_gworld, ter_from, mainPtr, tiny_to, sf::BlendAlpha); pic++; @@ -596,14 +596,14 @@ void set_up_terrain_buttons(bool reset) { rect_draw_some_item(*source_gworld, ter_from, mainPtr, tiny_to, sf::BlendAlpha); } else if(pic >= 1000) { pic %= 1000; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic); rect_draw_some_item(*source_gworld, ter_from, mainPtr, tiny_to, sf::BlendAlpha); } else { auto pic_info = m_pic_index[pic]; pic = pic_info.i; auto monst_gworld = [](pic_num_t sheet_num) { - return *ResMgr::get("monst" + std::to_string(1 + sheet_num)); + return *ResMgr::graphics.get("monst" + std::to_string(1 + sheet_num)); }; if(pic_info.x == 2 && pic_info.y == 2) { tiny_to.width() = tiny_to.width() / 2; @@ -653,13 +653,13 @@ void set_up_terrain_buttons(bool reset) { tiny_to = draw_rect; frame_rect(mainPtr, tiny_to, sf::Color::Black); if(pic >= 1000) { - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000); rect_draw_some_item(*source_gworld, ter_from, mainPtr, tiny_to, sf::BlendAlpha); } else { tiny_from = {0,0,18,18}; tiny_from.offset((pic % 10) * 18,(pic / 10) * 18); - rect_draw_some_item(*ResMgr::get("tinyobj"), tiny_from, mainPtr, tiny_to, sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("tinyobj"), tiny_from, mainPtr, tiny_to, sf::BlendAlpha); } break; } @@ -738,8 +738,8 @@ void draw_terrain(){ destrec.bottom = destrec.top + BITMAP_HEIGHT; destrec.offset(TER_RECT_UL_X,TER_RECT_UL_Y); - sf::Texture& fields_gworld = *ResMgr::get("fields"); - sf::Texture& vehicle_gworld = *ResMgr::get("vehicle"); + sf::Texture& fields_gworld = *ResMgr::graphics.get("fields"); + sf::Texture& vehicle_gworld = *ResMgr::graphics.get("vehicle"); if(is_road(cen_x + q - 4,cen_y + r - 4)) rect_draw_some_item(fields_gworld, calc_rect(0, 2), mainPtr, destrec, sf::BlendAlpha); @@ -797,7 +797,7 @@ void draw_terrain(){ } if(is_field_type(cen_x + q - 4,cen_y + r - 4, BARRIER_FIRE)) { from_rect = calc_rect(8,4); - rect_draw_some_item(*ResMgr::get("teranim"),from_rect,mainPtr,destrec,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("teranim"),from_rect,mainPtr,destrec,sf::BlendAlpha); } if(is_field_type(cen_x + q - 4,cen_y + r - 4, FIELD_QUICKFIRE)) { from_rect = calc_rect(7,1); @@ -805,7 +805,7 @@ void draw_terrain(){ } if(is_field_type(cen_x + q - 4,cen_y + r - 4, BARRIER_FORCE)) { from_rect = calc_rect(10,4); - rect_draw_some_item(*ResMgr::get("teranim"),from_rect,mainPtr,destrec,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("teranim"),from_rect,mainPtr,destrec,sf::BlendAlpha); } if(is_field_type(cen_x + q - 4,cen_y + r - 4, OBJECT_BLOCK)) { from_rect = calc_rect(3,0); @@ -833,7 +833,7 @@ void draw_terrain(){ if(!icons.empty()) { bool has_start = icons[0] == -1; rectangle tiny_from_base = {120, 0, 127, 7}; - sf::Texture& editor_mixed = *ResMgr::get("edbuttons"); + sf::Texture& editor_mixed = *ResMgr::graphics.get("edbuttons"); for(short icon : icons) { rectangle tiny_from = tiny_from_base; if(icon == -1) { @@ -976,7 +976,7 @@ void draw_terrain(){ void draw_monsts() { short width,height,m_start_pic; - sf::Texture* from_gworld = nullptr; + const sf::Texture* from_gworld = nullptr; rectangle source_rect; location where_draw,store_loc; @@ -999,7 +999,7 @@ void draw_monsts() { else if(scenario.scen_monsters[town->creatures[i].number].picture_num < 1000) { m_start_pic = m_pic_index[scenario.scen_monsters[town->creatures[i].number].picture_num].i + k; int which_sheet = m_start_pic / 20; - from_gworld = ResMgr::get("monst" + std::to_string(1 + which_sheet)).get(); + from_gworld = &ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet)); m_start_pic = m_start_pic % 20; source_rect = calc_rect(2 * (m_start_pic / 10), m_start_pic % 10); store_loc.x += k % width; @@ -1059,7 +1059,7 @@ void draw_items() { (where_draw.y >= 0) && (where_draw.y <= 8)) { if(pic_num >= 1000) { - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(pic_num - 1000); dest_rect = calc_rect(where_draw.x,where_draw.y); dest_rect.offset(8+TER_RECT_UL_X,8+TER_RECT_UL_Y); @@ -1075,7 +1075,7 @@ void draw_items() { dest_rect.left += 5; dest_rect.right -= 5; } - rect_draw_some_item(*ResMgr::get((pic_num < 55) ? "objects" : "tinyobj"), + rect_draw_some_item(*ResMgr::graphics.get((pic_num < 55) ? "objects" : "tinyobj"), source_rect, mainPtr, dest_rect,sf::BlendAlpha); } } @@ -1095,7 +1095,7 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { location where_draw; rectangle source_rect; short picture_wanted; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; if(i < 0 || i > 8 || j < 0 || j > 8) return; @@ -1109,7 +1109,7 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); } else if(picture_wanted >= 960) { - source_gworld = ResMgr::get("teranim").get(); + source_gworld = &ResMgr::graphics.get("teranim"); picture_wanted -= 960; source_rect.left = 112 * (picture_wanted / 5); source_rect.right = source_rect.left + 28; @@ -1119,7 +1119,7 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { else { source_rect = get_template_rect(terrain_to_draw); int which_sheet = picture_wanted / 50; - source_gworld = ResMgr::get("ter" + std::to_string(1 + which_sheet)).get(); + source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); } rectangle destrec; @@ -1136,7 +1136,7 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short rectangle dest_rect = {0,0,size,size},from_rect = {0,0,12,12}; short picture_wanted; bool drawLargeIcon = false; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; picture_wanted = scenario.ter_types[terrain_to_draw].map_pic; if(picture_wanted == NO_PIC) { @@ -1149,18 +1149,18 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short if(picture_wanted >= 1000) { graf_pos_ref(source_gworld, from_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); } else if(picture_wanted >= 960) { - source_gworld = ResMgr::get("teranim").get(); + source_gworld = &ResMgr::graphics.get("teranim"); from_rect = calc_rect(4 * ((picture_wanted - 960) / 5),(picture_wanted - 960) % 5); } else { int which_sheet = picture_wanted / 50; - source_gworld = ResMgr::get("ter" + std::to_string(1 + which_sheet)).get(); + source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); picture_wanted %= 50; from_rect = calc_rect(picture_wanted % 10, picture_wanted / 10); } rect_draw_some_item(*source_gworld, from_rect, mainPtr, dest_rect); } else { if(picture_wanted >= 1000) { - sf::Texture* from_gw; + const sf::Texture* from_gw; graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); from_rect.right = from_rect.left + 12; from_rect.bottom = from_rect.top + 12; @@ -1168,7 +1168,7 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short from_rect.offset((picture_wanted / 3) * 12, (picture_wanted % 3) * 12); rect_draw_some_item(*from_gw, from_rect, mainPtr, dest_rect); } else { - sf::Texture& small_ter_gworld = *ResMgr::get("termap"); + sf::Texture& small_ter_gworld = *ResMgr::graphics.get("termap"); if(picture_wanted >= 960) { picture_wanted -= 960; from_rect.offset(12 * 20, (picture_wanted - 960) * 12); @@ -1183,7 +1183,7 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short rectangle road_rect = dest_rect; int border = (size - 4) / 2; road_rect.inset(border,border); - rect_draw_some_item(*ResMgr::get("edbuttons"), {120, 231, 124, 235}, mainPtr, road_rect); + rect_draw_some_item(*ResMgr::graphics.get("edbuttons"), {120, 231, 124, 235}, mainPtr, road_rect); } if(mouse_spot.x >= 0 && mouse_spot.y >= 0) { location where_draw(i,j); @@ -1261,7 +1261,7 @@ static void place_selected_terrain(ter_num_t ter, rectangle draw_rect) { pic_num_t picture_wanted = scenario.ter_types[ter].picture; rectangle source_rect; if(picture_wanted >= 1000) { - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); rect_draw_some_item(*source_gworld, source_rect,mainPtr,draw_rect); } @@ -1271,12 +1271,12 @@ static void place_selected_terrain(ter_num_t ter, rectangle draw_rect) { source_rect.right = source_rect.left + 28; source_rect.top = 36 * (picture_wanted % 5); source_rect.bottom = source_rect.top + 36; - rect_draw_some_item(*ResMgr::get("teranim"),source_rect,mainPtr,draw_rect); + rect_draw_some_item(*ResMgr::graphics.get("teranim"),source_rect,mainPtr,draw_rect); } else { source_rect = get_template_rect(ter); int which_sheet = picture_wanted / 50; - sf::Texture& terrain_gworld = *ResMgr::get("ter" + std::to_string(1 + which_sheet)); + sf::Texture& terrain_gworld = *ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); rect_draw_some_item(terrain_gworld,source_rect, mainPtr,draw_rect); } @@ -1287,7 +1287,7 @@ static void place_selected_terrain(ter_num_t ter, rectangle draw_rect) { rectangle tiny_from = base_small_button_from; tiny_from.offset(7 * (small_i % 30),7 * (small_i / 30)); if(small_i >= 0 && small_i < 255) - rect_draw_some_item(*ResMgr::get("edbuttons"),tiny_from,mainPtr,tiny_to); + rect_draw_some_item(*ResMgr::graphics.get("edbuttons"),tiny_from,mainPtr,tiny_to); } void place_location() { @@ -1377,7 +1377,7 @@ void place_location() { picture_wanted %= 1000; to_rect.width() = to_rect.width() / 2; to_rect.height() = to_rect.height() / 2; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted); rect_draw_some_item(*source_gworld, source_rect, mainPtr, to_rect, sf::BlendAlpha); picture_wanted++; @@ -1397,7 +1397,7 @@ void place_location() { to_rect.width() = to_rect.width() / 2; to_rect.height() = to_rect.height() / 2; to_rect.offset(to_rect.width() / 2, 0); - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted); rect_draw_some_item(*source_gworld, source_rect, mainPtr, to_rect, sf::BlendAlpha); picture_wanted++; @@ -1409,7 +1409,7 @@ void place_location() { to_rect.width() = to_rect.width() / 2; to_rect.height() = to_rect.height() / 2; to_rect.offset(0, to_rect.height() / 2); - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted); rect_draw_some_item(*source_gworld, source_rect, mainPtr, to_rect, sf::BlendAlpha); picture_wanted++; @@ -1418,14 +1418,14 @@ void place_location() { rect_draw_some_item(*source_gworld, source_rect, mainPtr, to_rect, sf::BlendAlpha); } else if(picture_wanted >= 1000) { picture_wanted %= 1000; - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted); rect_draw_some_item(*source_gworld, source_rect, mainPtr, to_rect, sf::BlendAlpha); } else { auto pic_info = m_pic_index[picture_wanted]; picture_wanted = pic_info.i; auto monst_gworld = [](pic_num_t sheet_num) { - return *ResMgr::get("monst" + std::to_string(1 + sheet_num)); + return *ResMgr::graphics.get("monst" + std::to_string(1 + sheet_num)); }; if(pic_info.x == 2 && pic_info.y == 2) { to_rect.width() = to_rect.width() / 2; @@ -1472,17 +1472,17 @@ void place_location() { } else if(overall_mode == MODE_PLACE_ITEM || overall_mode == MODE_PLACE_SAME_ITEM) { picture_wanted = scenario.scen_items[mode_count].graphic_num; if(picture_wanted >= 1000) { - sf::Texture* source_gworld; + const sf::Texture* source_gworld; graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); rect_draw_some_item(*source_gworld,source_rect,mainPtr,draw_rect,sf::BlendAlpha); } else if(picture_wanted < 55) { source_rect = calc_rect(picture_wanted % 5,picture_wanted / 5); - rect_draw_some_item(*ResMgr::get("objects"),source_rect,mainPtr,draw_rect,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("objects"),source_rect,mainPtr,draw_rect,sf::BlendAlpha); } else { draw_rect.inset(5, 9); rectangle tiny_from = {0,0,18,18}; tiny_from.offset((picture_wanted % 10) * 18,(picture_wanted / 10) * 18); - rect_draw_some_item(*ResMgr::get("tinyobj"),tiny_from,mainPtr,draw_rect,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("tinyobj"),tiny_from,mainPtr,draw_rect,sf::BlendAlpha); } } else if(overall_mode == MODE_TOGGLE_SPECIAL_DOT) { draw_field = true; @@ -1501,10 +1501,10 @@ void place_location() { source_rect = calc_rect(7, 0); } else if(overall_mode == MODE_PLACE_FIRE_BARRIER) { source_rect = calc_rect(8, 4); - rect_draw_some_item(*ResMgr::get("teranim"),source_rect,mainPtr,draw_rect,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("teranim"),source_rect,mainPtr,draw_rect,sf::BlendAlpha); } else if(overall_mode == MODE_PLACE_FORCE_BARRIER) { source_rect = calc_rect(8, 4); - rect_draw_some_item(*ResMgr::get("teranim"),source_rect,mainPtr,draw_rect,sf::BlendAlpha); + rect_draw_some_item(*ResMgr::graphics.get("teranim"),source_rect,mainPtr,draw_rect,sf::BlendAlpha); } else if(overall_mode == MODE_PLACE_QUICKFIRE) { draw_field = true; source_rect = calc_rect(7, 1); @@ -1516,7 +1516,7 @@ void place_location() { source_rect = calc_rect(mode_count, 3); } if(draw_field) { - sf::Texture& fields_gworld = *ResMgr::get("fields"); + const sf::Texture& fields_gworld = *ResMgr::graphics.get("fields"); rect_draw_some_item(fields_gworld,source_rect,mainPtr,draw_rect,sf::BlendAlpha); } draw_rect.offset(0,40); diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index a38762f9..0f6acc7e 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -269,7 +269,7 @@ short choose_text_res(std::string res_list,short first_t,short last_t,unsigned s cur_choice = -1; else cur_choice -= first_t; - StringRsrc strings = *ResMgr::get(res_list); + StringList strings = *ResMgr::strings.get(res_list); cStringChoice dlog(strings.begin() + first_t - 1, strings.begin() + last_t, title, parent); return dlog.show(cur_choice); @@ -354,13 +354,13 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std } break; case STRT_PICT: - strings = *ResMgr::get("picture-types"); + strings = *ResMgr::strings.get("picture-types"); break; case STRT_TRAP: - strings = *ResMgr::get("trap-types"); + strings = *ResMgr::strings.get("trap-types"); break; case STRT_HEALING: - strings = *ResMgr::get("shop-specials"); + strings = *ResMgr::strings.get("shop-specials"); break; case STRT_BUTTON: for(auto btn : basic_buttons) { @@ -391,7 +391,7 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std } break; case STRT_CONTEXT: - strings = *ResMgr::get("special-contexts"); + strings = *ResMgr::strings.get("special-contexts"); break; case STRT_SHOP: for(cShop& shop : scenario.shops) { @@ -791,7 +791,7 @@ pic_num_t choose_status_effect(short cur, bool party, cDialog* parent) { snd_num_t choose_sound(short cur, cDialog* parent, std::string title) { if(cur < 0) cur = 0; - StringRsrc snd_names = *ResMgr::get("sound-names"); + StringList snd_names = *ResMgr::strings.get("sound-names"); std::copy(scenario.snd_names.begin(), scenario.snd_names.end(), std::back_inserter(snd_names)); cStringChoice snd_dlg(snd_names, title, parent); snd_dlg.attachSelectHandler([](cStringChoice&, int n) { diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index 6e323b6e..0cf4e273 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -118,8 +118,8 @@ void init_scened(int argc, char* argv[]) { mainPtr.create(sf::VideoMode(windRect.width(), windRect.height()), "Blades of Exile Scenario Editor", sf::Style::Titlebar | sf::Style::Close); mainPtr.setPosition(windRect.topLeft()); #ifndef __APPLE__ // This overrides Dock icon on OSX, which isn't what we want at all - ImageRsrc& icon = *ResMgr::get("icon"); - mainPtr.setIcon(icon.getSize().x, icon.getSize().y, icon.copyToImage().getPixelsPtr()); + const ImageRsrc& icon = ResMgr::graphics.get("icon"); + mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr()); #endif init_menubar(); // This is called twice because Windows and Mac have different ordering requirements mainPtr.clear(sf::Color::Black); diff --git a/src/sounds.cpp b/src/sounds.cpp index f5cdf9e2..dfacc925 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ bool sound_going(snd_num_t which_s) { return false; } -static std::string sound_to_fname_map(snd_num_t snd_num) { +std::string sound_to_fname(snd_num_t snd_num) { std::ostringstream sout; sout << "SND" << snd_num; return sout.str(); @@ -57,25 +58,20 @@ static void exit_snd_tool() { void init_snd_tool(){ for(auto& ch : chan) ch.reset(new sf::Sound); - ResMgr::setIdMapFn(sound_to_fname_map); atexit(exit_snd_tool); } void play_sound(snd_num_t which, sf::Time delay) { // if < 0, play asynch - static bool inited = false; - if(!inited) { - inited = true; - ResMgr::setIdMapFn(sound_to_fname_map); - } - - std::shared_ptr sndhandle; + const sf::SoundBuffer* sndhandle; if(!get_bool_pref("PlaySounds", true)) { if(which >= 0) sf::sleep(delay); return; } - if(abs(which) >= 100 && !ResMgr::have(abs(which))) { + std::string sndname = sound_to_fname(abs(which)); + + if(abs(which) >= 100 && !ResMgr::sounds.have(sndname)) { std::cerr << "Error: Sound #" << abs(which) << " does not exist." << std::endl; return; } @@ -85,7 +81,7 @@ void play_sound(snd_num_t which, sf::Time delay) { // if < 0, play asynch if(channel >= numchannel) channel = 0; if(!sound_going(abs(which))) - sndhandle = ResMgr::get(abs(which)); + sndhandle = &ResMgr::sounds.get(sndname); if(which > 0) if(always_async.find(which) != always_async.end()) diff --git a/src/sounds.hpp b/src/sounds.hpp index d48fce2c..8c6d901b 100644 --- a/src/sounds.hpp +++ b/src/sounds.hpp @@ -10,11 +10,13 @@ #define _SOUNDTOOL_H #include +#include void init_snd_tool(); bool sound_going(snd_num_t which_s); void play_sound(snd_num_t which, sf::Time delay = sf::Time()); void one_sound(snd_num_t which); +std::string sound_to_fname(snd_num_t snd_num); void clear_sound_memory(); diff --git a/src/tools/cursors.linux.cpp b/src/tools/cursors.linux.cpp index 701ec610..66c65798 100644 --- a/src/tools/cursors.linux.cpp +++ b/src/tools/cursors.linux.cpp @@ -44,7 +44,7 @@ void set_cursor(cursor_type which_c) { if(which_c == text_curs) { // XDefineCursor(NULL, current_window, ibeam); } else { - Cursor& curs = *ResMgr::get(cursors[which_c]); + Cursor& curs = *ResMgr::cursors.get(cursors[which_c]); curs.apply(); } } diff --git a/src/tools/cursors.mac.mm b/src/tools/cursors.mac.mm index e9953879..54ad5555 100644 --- a/src/tools/cursors.mac.mm +++ b/src/tools/cursors.mac.mm @@ -74,7 +74,7 @@ void set_cursor(cursor_type which_c) { if(which_c == text_curs) { [[NSCursor IBeamCursor] set]; } else { - Cursor& curs = *ResMgr::get(cursors[which_c]); + Cursor& curs = *ResMgr::cursors.get(cursors[which_c]); curs.apply(); } } diff --git a/src/tools/cursors.win.cpp b/src/tools/cursors.win.cpp index 3428b6f9..a7042017 100644 --- a/src/tools/cursors.win.cpp +++ b/src/tools/cursors.win.cpp @@ -95,7 +95,7 @@ void set_cursor(cursor_type which_c) { if(which_c == text_curs) { SetCursor(LoadCursor(NULL, IDC_IBEAM)); } else { - Cursor& curs = *ResMgr::get(cursors[which_c]); + Cursor& curs = *ResMgr::cursors.get(cursors[which_c]); curs.apply(); } } diff --git a/src/utility.cpp b/src/utility.cpp index 05a535fc..96d146f4 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -12,7 +12,7 @@ std::string get_str(std::string list, short j){ if(j == 0) return list; - StringRsrc& strings = *ResMgr::get(list); + const StringList& strings = *ResMgr::strings.get(list); return strings[j - 1]; } diff --git a/test/scen_read.cpp b/test/scen_read.cpp index 3e4e3821..c9faf367 100644 --- a/test/scen_read.cpp +++ b/test/scen_read.cpp @@ -384,7 +384,7 @@ TEST_CASE("Loading a new-format scenario record") { SECTION("With a shop") { // Loading shops requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); SECTION("Valid shop") { fin.open("files/scenario/shop.xml"); doc = xmlDocFromStream(fin, "shop.xml"); @@ -472,7 +472,7 @@ TEST_CASE("Loading a new-format scenario record") { doc = xmlDocFromStream(fin, "shop-missing_node.xml"); REQUIRE_THROWS_AS(readScenarioFromXml(move(doc), scen), xMissingElem); } - ResMgr::popPath(); + ResMgr::strings.popPath(); } SECTION("With item storage shortcuts") { SECTION("Valid") { diff --git a/test/scen_write.cpp b/test/scen_write.cpp index efa05673..bc214927 100644 --- a/test/scen_write.cpp +++ b/test/scen_write.cpp @@ -168,7 +168,7 @@ TEST_CASE("Saving a scenario record") { SECTION("With a shop") { // Loading/building shops requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); cItem dummy_item('alch'); scen.shops.resize(3); scen.shops[0] = cShop('junk'); @@ -248,7 +248,7 @@ TEST_CASE("Saving a scenario record") { CHECK(scen.shops[2].getItem(11).item.graphic_num == 24); CHECK(scen.shops[2].getItem(11).item.full_name == "Magic!"); CHECK(scen.shops[2].getItem(11).item.desc == "This is magic!"); - ResMgr::popPath(); + ResMgr::strings.popPath(); } SECTION("With some empty strings, none are stripped") { scen.spec_strs.resize(12); diff --git a/test/spec_legacy.cpp b/test/spec_legacy.cpp index 1e1d439d..2bc59e9f 100644 --- a/test/spec_legacy.cpp +++ b/test/spec_legacy.cpp @@ -30,7 +30,7 @@ TEST_CASE("When converting legacy special nodes (general)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.jumpto = 12; SECTION("Null Special") { @@ -295,7 +295,7 @@ TEST_CASE("When converting legacy special nodes (general)") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting legacy special nodes (one-shot)") { @@ -303,7 +303,7 @@ TEST_CASE("When converting legacy special nodes (one-shot)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.sd1 = 8; oldSpec.sd2 = 7; oldSpec.m1 = 4; oldSpec.m2 = 5; @@ -481,7 +481,7 @@ TEST_CASE("When converting legacy special nodes (one-shot)") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting legacy special nodes (affect)") { @@ -489,7 +489,7 @@ TEST_CASE("When converting legacy special nodes (affect)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.m1 = 4; oldSpec.m2 = 5; oldSpec.jumpto = 12; @@ -761,7 +761,7 @@ TEST_CASE("When converting legacy special nodes (affect)") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting legacy special nodes (if-then)") { @@ -769,7 +769,7 @@ TEST_CASE("When converting legacy special nodes (if-then)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.jumpto = 12; SECTION("Stuff Done Flag?") { @@ -1035,7 +1035,7 @@ TEST_CASE("When converting legacy special nodes (if-then)") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting legacy special nodes (town)") { @@ -1043,7 +1043,7 @@ TEST_CASE("When converting legacy special nodes (town)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.m1 = 4; oldSpec.m2 = 5; oldSpec.jumpto = 12; @@ -1312,7 +1312,7 @@ TEST_CASE("When converting legacy special nodes (town)") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting legacy special nodes (rect)") { @@ -1320,7 +1320,7 @@ TEST_CASE("When converting legacy special nodes (rect)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.m1 = 4; oldSpec.m2 = 5; oldSpec.pic = 1; @@ -1608,7 +1608,7 @@ TEST_CASE("When converting legacy special nodes (rect)") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting legacy special nodes (outdoors)") { @@ -1616,7 +1616,7 @@ TEST_CASE("When converting legacy special nodes (outdoors)") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.jumpto = 12; SECTION("Make Outdoor Wandering") { @@ -1671,7 +1671,7 @@ TEST_CASE("When converting legacy special nodes (outdoors)") { CHECK(newSpec.ex2b == 4); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } TEST_CASE("When converting classic special nodes") { @@ -1679,7 +1679,7 @@ TEST_CASE("When converting classic special nodes") { legacy::special_node_type oldSpec = {0,-1,-1,0,-1,-1,-1,-1,-1,-1,-1}; // Fetching opcodes requires strings to be available // Here we fetch them from the rsrc dir, rather than the data dir - ResMgr::pushPath("../rsrc/strings"); + ResMgr::strings.pushPath("../rsrc/strings"); oldSpec.jumpto = 12; SECTION("If Statistic") { @@ -1744,7 +1744,7 @@ TEST_CASE("When converting classic special nodes") { CHECK(newSpec.jumpto == 12); } // Clean up after ourselves - ResMgr::popPath(); + ResMgr::strings.popPath(); } ostream& operator<< (ostream& out, eSpecType spec) {