diff --git a/src/dialogxml/widgets/pict.cpp b/src/dialogxml/widgets/pict.cpp index 1dfe658c..f1bd9dad 100644 --- a/src/dialogxml/widgets/pict.cpp +++ b/src/dialogxml/widgets/pict.cpp @@ -18,6 +18,7 @@ #include "gfx/tiling.hpp" #include "location.hpp" #include "dialogxml/dialogs/dialog.hpp" +#include "dialogxml/dialogs/strdlog.hpp" #include "fileio/resmgr/res_image.hpp" extern sf::Texture bg_gworld; @@ -96,6 +97,8 @@ bool cPict::manageFormat(eFormat prop, bool set, boost::any* val) { } void cPict::setPict(pic_num_t num, ePicType type){ + sheetCached.reset(); + sheetCachedType = NUM_SHEET_TYPES; picNum = num; picType = type; if(picType == PIC_MONST && picNum < 1000) { @@ -108,6 +111,8 @@ void cPict::setPict(pic_num_t num, ePicType type){ picType += PIC_PARTY; } else { picType += PIC_CUSTOM; + if(picNum >= 2000 && picType == PIC_CUSTOM_TER) + picType = PIC_CUSTOM_TER_ANIM; if(picType != PIC_CUSTOM_TER_MAP) picNum %= 1000; } @@ -586,6 +591,16 @@ void cPict::recalcRect() { } std::shared_ptr cPict::getSheet(eSheetType type, size_t n) { + if(type == sheetCachedType && n == sheetCachedNum) { + return sheetCached; + } + sheetCachedType = type; + sheetCachedNum = n; + sheetCached = getSheetInternal(type, n); + return sheetCached; +} + +std::shared_ptr cPict::getSheetInternal(eSheetType type, size_t n) { std::ostringstream sout; bool purgeable = false; switch(type) { @@ -672,7 +687,13 @@ std::shared_ptr cPict::getSheet(eSheetType type, size_t n) { sout << "sheet" << n; } } - return &ResMgr::graphics.get(sout.str(), purgeable); + auto name = sout.str(); + try { + return &ResMgr::graphics.get(name, purgeable); + } catch(ResMgr::xError& e) { + showError(e.what()); + return nullptr; + } } void cPict::draw(){ @@ -690,6 +711,10 @@ void cPict::draw(){ } void cPict::drawPresetTer(short num, rectangle to_rect){ + if(num >= 960) { + drawPresetTerAnim(num - 960, to_rect); + return; + } auto from_gw = getSheet(SHEET_TER, num / 50); if(!from_gw) return; num = num % 50; @@ -702,6 +727,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); auto from_gw = getSheet(SHEET_TER_ANIM); + if(!from_gw) return; if(to_rect.right - to_rect.left > 28) { to_rect.inset(4,0); to_rect.right = to_rect.left + 28; diff --git a/src/dialogxml/widgets/pict.hpp b/src/dialogxml/widgets/pict.hpp index 0fc6cb2a..2e173937 100644 --- a/src/dialogxml/widgets/pict.hpp +++ b/src/dialogxml/widgets/pict.hpp @@ -88,7 +88,11 @@ public: cPict& operator=(cPict& other) = delete; cPict(cPict& other) = delete; private: - static std::shared_ptr getSheet(eSheetType type, size_t n = 0); + static std::shared_ptr getSheetInternal(eSheetType type, size_t n); + std::shared_ptr getSheet(eSheetType type, size_t n = 0); + std::shared_ptr sheetCached; + eSheetType sheetCachedType; + size_t sheetCachedNum; static short animFrame; pic_num_t picNum; ePicType picType; diff --git a/src/gfx/render_image.cpp b/src/gfx/render_image.cpp index 7437abdf..c7b773ac 100644 --- a/src/gfx/render_image.cpp +++ b/src/gfx/render_image.cpp @@ -78,6 +78,10 @@ void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::Re } void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::RenderStates mode) { + rectangle src_gworld_rect(src_gworld), targ_gworld_rect(targ_gworld); + src_rect &= src_gworld_rect; + targ_rect &= targ_gworld_rect; + if(src_rect.empty() || targ_rect.empty()) return; setActiveRenderTarget(targ_gworld); sf::Sprite tile(src_gworld, src_rect); tile.setPosition(targ_rect.left, targ_rect.top); diff --git a/src/location.cpp b/src/location.cpp index b5debd39..2448b4c7 100644 --- a/src/location.cpp +++ b/src/location.cpp @@ -98,6 +98,10 @@ bool rectangle::contains(int x, int y) const { return contains(location(x,y)); } +bool rectangle::empty() const { + return height() == 0 && width() == 0; +} + rectangle_size_delegate::rectangle_size_delegate(rectangle& rect, int rectangle::* first, int rectangle::* last) : forRect(rect), b1(first), b2(last) {} diff --git a/src/location.hpp b/src/location.hpp index a5721a92..014d15a2 100644 --- a/src/location.hpp +++ b/src/location.hpp @@ -88,6 +88,7 @@ struct rectangle { location bottomRight() const; bool contains(location p) const; bool contains(int x, int y) const; + bool empty() const; void offset(int h, int v); void offset(location diff); void move_to(int x, int y);