From 6d80e657839fab3feae74ced67dc4861218213f4 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 21 Aug 2019 21:21:08 +0100 Subject: [PATCH] Increase the capacity of dynamic / object images --- src/openrct2/drawing/Drawing.Sprite.cpp | 93 +++++++++++++++++-------- src/openrct2/drawing/Image.cpp | 5 +- src/openrct2/sprites.h | 17 +++-- 3 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 855de4ce9d..c86574cf90 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -223,6 +223,7 @@ static rct_gx _csg = {}; static bool _csgLoaded = false; static rct_g1_element _g1Temp = {}; +static std::vector _imageListElements; bool gTinyFontAntiAliased = false; /** @@ -246,8 +247,8 @@ bool gfx_load_g1(const IPlatformEnvironment& env) } // Read element headers - _g1.elements.resize(324206); bool is_rctc = _g1.header.num_entries == SPR_RCTC_G1_END; + _g1.elements.resize(_g1.header.num_entries); read_and_convert_gxdat(&fs, _g1.header.num_entries, is_rctc, _g1.elements.data()); gTinyFontAntiAliased = is_rctc; @@ -834,65 +835,97 @@ const rct_g1_element* gfx_get_g1_element(int32_t image_id) { openrct2_assert(!gOpenRCT2NoGraphics, "gfx_get_g1_element called on headless instance"); - if (image_id == (-1 & 0x7FFFF)) + auto offset = (size_t)image_id; + if (offset == 0x7FFFF) { return nullptr; } - - if (image_id == SPR_TEMP) + else if (offset == SPR_TEMP) { return &_g1Temp; } - else if (image_id < SPR_G2_BEGIN) + else if (offset < SPR_RCTC_G1_END) { - if (image_id >= (int32_t)_g1.elements.size()) + if (offset < _g1.elements.size()) { - return nullptr; + return &_g1.elements[offset]; } - return &_g1.elements[image_id]; } - if (image_id < SPR_CSG_BEGIN) + else if (offset < SPR_G2_END) { - const uint32_t idx = image_id - SPR_G2_BEGIN; - if (idx >= _g2.header.num_entries) + size_t idx = offset - SPR_G2_BEGIN; + if (idx < _g2.header.num_entries) + { + return &_g2.elements[idx]; + } + else { log_warning("Invalid entry in g2.dat requested, idx = %u. You may have to update your g2.dat.", idx); - return nullptr; } - return &_g2.elements[idx]; } - - if (is_csg_loaded()) + else if (offset < SPR_CSG_END) { - const uint32_t idx = image_id - SPR_CSG_BEGIN; - if (idx >= _csg.header.num_entries) + if (is_csg_loaded()) { - openrct2_assert(idx < _csg.header.num_entries, "Invalid entry in csg.dat requested, idx = %u.", idx); - return nullptr; + size_t idx = offset - SPR_CSG_BEGIN; + if (idx < _csg.header.num_entries) + { + return &_csg.elements[idx]; + } + else + { + log_warning("Invalid entry in csg.dat requested, idx = %u.", idx); + } + } + } + else if (offset < SPR_IMAGE_LIST_END) + { + size_t idx = offset - SPR_IMAGE_LIST_BEGIN; + if (idx < _imageListElements.size()) + { + return &_imageListElements[idx]; } - return &_csg.elements[idx]; } return nullptr; } void gfx_set_g1_element(int32_t imageId, const rct_g1_element* g1) { - openrct2_assert(!gOpenRCT2NoGraphics, "gfx_set_g1_element called on headless instance"); + bool isTemp = imageId == SPR_TEMP; + bool isValid = (imageId >= SPR_IMAGE_LIST_BEGIN && imageId < SPR_IMAGE_LIST_END) + || (imageId >= SPR_SCROLLING_TEXT_START && imageId < SPR_SCROLLING_TEXT_END); + #ifdef DEBUG - openrct2_assert( - (imageId >= 0 && imageId < SPR_G2_BEGIN) || imageId == SPR_TEMP, "gfx_set_g1_element called with unexpected image id"); + openrct2_assert(!gOpenRCT2NoGraphics, "gfx_set_g1_element called on headless instance"); + openrct2_assert(isValid || isTemp, "gfx_set_g1_element called with unexpected image id"); openrct2_assert(g1 != nullptr, "g1 was nullptr"); #endif - if (imageId == SPR_TEMP) + if (g1 != nullptr) { - _g1Temp = *g1; - } - else if (imageId >= 0 && imageId < SPR_G2_BEGIN) - { - if (imageId < (int32_t)_g1.elements.size()) + if (isTemp) { - _g1.elements[imageId] = *g1; + _g1Temp = *g1; + } + else if (isValid) + { + if (imageId < SPR_RCTC_G1_END) + { + if (imageId < (int32_t)_g1.elements.size()) + { + _g1.elements[imageId] = *g1; + } + } + else + { + size_t idx = (size_t)imageId - SPR_IMAGE_LIST_BEGIN; + // Grow the element buffer if necessary + while (idx >= _imageListElements.size()) + { + _imageListElements.resize(std::max(256, _imageListElements.size() * 2)); + } + _imageListElements[idx] = *g1; + } } } } diff --git a/src/openrct2/drawing/Image.cpp b/src/openrct2/drawing/Image.cpp index 2c05826a80..ee374e6ad5 100644 --- a/src/openrct2/drawing/Image.cpp +++ b/src/openrct2/drawing/Image.cpp @@ -10,13 +10,14 @@ #include "../OpenRCT2.h" #include "../core/Console.hpp" #include "../core/Guard.hpp" +#include "../sprites.h" #include "Drawing.h" #include #include -constexpr uint32_t BASE_IMAGE_ID = 29294; -constexpr uint32_t MAX_IMAGES = 262144; +constexpr uint32_t BASE_IMAGE_ID = SPR_IMAGE_LIST_BEGIN; +constexpr uint32_t MAX_IMAGES = SPR_IMAGE_LIST_END - BASE_IMAGE_ID; constexpr uint32_t INVALID_IMAGE_ID = UINT32_MAX; struct ImageList diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 8c37667de7..71780a140b 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -14,12 +14,13 @@ enum { - SPR_NONE = -1, + SPR_NONE = -1, // 0x7FFFF // Used for on-demand drawing of dynamic memory - SPR_TEMP = 0x70000, + SPR_TEMP = 0x7FFFE, SPR_SCROLLING_TEXT_START = 1542, + SPR_SCROLLING_TEXT_END = SPR_SCROLLING_TEXT_START + 32, SPR_SCROLLING_TEXT_DEFAULT = 1574, SPR_EDGE_ROCK_BASE = 1579, @@ -738,7 +739,7 @@ enum SPR_G1_END = 29294, SPR_RCTC_G1_END = 29357, // The number of elements in RCTC's g1.dat file - SPR_G2_BEGIN = 324288, + SPR_G2_BEGIN = 29357, SPR_G2_LOGO = SPR_G2_BEGIN + 0, SPR_G2_TITLE = SPR_G2_BEGIN + 1, SPR_G2_FASTFORWARD = SPR_G2_BEGIN + 2, @@ -955,10 +956,9 @@ enum SPR_G2_ROUBLE_SIGN = SPR_G2_CHAR_BEGIN + 86, SPR_G2_CHAR_END = SPR_G2_ROUBLE_SIGN, SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1, + SPR_G2_END = SPR_G2_CHAR_END, - // 0x60000, chosen because it's a round hex number - // of the last possible range of image ID values that is large enough to fit all csg1 sprites. - SPR_CSG_BEGIN = 393216, + SPR_CSG_BEGIN = SPR_G2_END, SPR_CSG_ICE_CREAM_STALL_BEGIN = SPR_CSG_BEGIN + 60625, SPR_CSG_TOILETS_BEGIN = SPR_CSG_BEGIN + 61289, @@ -966,6 +966,11 @@ enum SPR_CSG_RIDE_PREVIEWS_BEGIN = SPR_CSG_BEGIN + 64195, SPR_CSG_RIDE_PREVIEW_ICE_CREAM_STALL = SPR_CSG_RIDE_PREVIEWS_BEGIN + RCT1_RIDE_TYPE_ICE_CREAM_STALL, SPR_CSG_RIDE_PREVIEW_TOILETS = SPR_CSG_RIDE_PREVIEWS_BEGIN + RCT1_RIDE_TYPE_TOILETS, + + SPR_CSG_END = SPR_CSG_BEGIN + 69917, + + SPR_IMAGE_LIST_BEGIN = SPR_CSG_END, + SPR_IMAGE_LIST_END = 0x7FFFE }; #endif