From 5a05bd51e5dac22f7d110e1e519a251b7168868a Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 26 Oct 2017 13:14:37 +0100 Subject: [PATCH] Use get_g1_element and add null checks --- .../engines/opengl/OpenGLDrawingEngine.cpp | 4 + src/openrct2-ui/windows/InstallTrack.cpp | 4 +- src/openrct2-ui/windows/Map.cpp | 25 ++-- src/openrct2/Context.cpp | 5 - src/openrct2/cmdline_sprite.c | 2 - src/openrct2/drawing/Sprite.cpp | 39 +++++- src/openrct2/drawing/X8DrawingEngine.cpp | 26 ++-- src/openrct2/drawing/drawing.c | 58 ++++---- src/openrct2/drawing/font.c | 16 ++- src/openrct2/drawing/scrolling_text.c | 38 ++++-- src/openrct2/drawing/string.c | 46 ++++--- src/openrct2/game.c | 127 +++++++++++------- src/openrct2/interface/colour.c | 35 +++-- src/openrct2/interface/viewport.c | 8 +- src/openrct2/paint/Paint.cpp | 9 +- 15 files changed, 259 insertions(+), 183 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index c72cb56da1..c2460a1ffb 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -543,6 +543,10 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t { sint32 g1Id = image & 0x7FFFF; rct_g1_element * g1Element = gfx_get_g1_element(g1Id); + if (g1Element == nullptr) + { + return; + } if (_dpi->zoom_level != 0) { diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index 970426b405..3219b8add6 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -228,8 +228,8 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) sint32 colour = ColourMapA[w->colours[0]].darkest; gfx_fill_rect(dpi, x, y, x + 369, y + 216, colour); - rct_g1_element *substituteElement = &g1Elements[SPR_TEMP]; - rct_g1_element tmpElement = *substituteElement; + rct_g1_element * substituteElement = &g1Elements[SPR_TEMP]; + rct_g1_element tmpElement = * substituteElement; substituteElement->offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); substituteElement->width = 370; substituteElement->height = 217; diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index d9498494a5..876c75fedf 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -880,29 +880,30 @@ static void window_map_paint(rct_window *w, rct_drawpixelinfo *dpi) */ static void window_map_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex) { - rct_g1_element *g1_element, pushed_g1_element; - gfx_clear(dpi, PALETTE_INDEX_10); - g1_element = &g1Elements[SPR_TEMP]; - pushed_g1_element = *g1_element; + rct_g1_element * g1 = &g1Elements[SPR_TEMP]; + rct_g1_element g1backup = *g1; - g1_element->offset = (uint8 *) _mapImageData; - g1_element->width = MAP_WINDOW_MAP_SIZE; - g1_element->height = MAP_WINDOW_MAP_SIZE; - g1_element->x_offset = -8; - g1_element->y_offset = -8; - g1_element->flags = 0; + g1->offset = (uint8 *) _mapImageData; + g1->width = MAP_WINDOW_MAP_SIZE; + g1->height = MAP_WINDOW_MAP_SIZE; + g1->x_offset = -8; + g1->y_offset = -8; + g1->flags = 0; gfx_draw_sprite(dpi, SPR_TEMP, 0, 0, 0); - *g1_element = pushed_g1_element; + *g1 = g1backup; if (w->selected_tab == PAGE_PEEPS) + { window_map_paint_peep_overlay(dpi); + } else + { window_map_paint_train_overlay(dpi); - + } window_map_paint_hud_rectangle(dpi); } diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 466862c0ee..c44c164bd9 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -327,11 +327,6 @@ namespace OpenRCT2 _uiContext->CreateWindow(); } - - - - - // TODO Ideally we want to delay this until we show the title so that we can // still open the game window and draw a progress screen for the creation // of the object cache. diff --git a/src/openrct2/cmdline_sprite.c b/src/openrct2/cmdline_sprite.c index 66ecb9d424..5e06dae041 100644 --- a/src/openrct2/cmdline_sprite.c +++ b/src/openrct2/cmdline_sprite.c @@ -797,8 +797,6 @@ sint32 cmdline_for_sprite(const char **argv, sint32 argc) } } - - static rct_sprite_file_palette_entry _standardPalette[256] = { // 0 (unused) { 0, 0, 0, 255 }, diff --git a/src/openrct2/drawing/Sprite.cpp b/src/openrct2/drawing/Sprite.cpp index 12abead28f..91e21da25a 100644 --- a/src/openrct2/drawing/Sprite.cpp +++ b/src/openrct2/drawing/Sprite.cpp @@ -162,7 +162,8 @@ extern "C" static bool _csgLoaded = false; #ifdef NO_RCT2 - rct_g1_element * g1Elements = nullptr; + size_t g1ElementsCount = 0; + rct_g1_element * g1Elements = nullptr; #else rct_g1_element * g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); #endif @@ -189,8 +190,9 @@ extern "C" } // Read element headers + g1ElementsCount = 324206; #ifdef NO_RCT2 - g1Elements = Memory::AllocateArray(324206); + g1Elements = Memory::AllocateArray(g1ElementsCount); #endif bool is_rctc = header.num_entries == SPR_RCTC_G1_END; read_and_convert_gxdat(&fs, header.num_entries, is_rctc, g1Elements); @@ -464,7 +466,15 @@ extern "C" } uint16 palette_offset = palette_to_g1_offset[palette_ref]; - return g1Elements[palette_offset].offset; + auto g1 = gfx_get_g1_element(palette_offset); + if (g1 == NULL) + { + return nullptr; + } + else + { + return g1->offset; + } } else { uint8* palette_pointer = gPeepPalette; @@ -746,21 +756,36 @@ extern "C" if (image_id < SPR_G2_BEGIN) { + if (image_id >= (sint32)g1ElementsCount) + { + return nullptr; + } return &g1Elements[image_id]; } if (image_id < SPR_CSG_BEGIN) { const uint32 idx = image_id - SPR_G2_BEGIN; - openrct2_assert(idx < _g2.header.num_entries, - "Invalid entry in g2.dat requested, idx = %u. You may have to update your g2.dat.", idx); + if (idx >= _g2.header.num_entries) + { + // TODO I guess we still want to warn the user, but an assert is not very good. + // Logging to stdout isn't ideal either as it would flood the console with + // the same message. + // openrct2_assert(idx < _g2.header.num_entries, + // "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()) { const uint32 idx = image_id - SPR_CSG_BEGIN; - openrct2_assert(idx < _csg.header.num_entries, - "Invalid entry in csg.dat requested, idx = %u.", idx); + if (idx >= _csg.header.num_entries) + { + openrct2_assert(idx < _csg.header.num_entries, + "Invalid entry in csg.dat requested, idx = %u.", idx); + return nullptr; + } return &_csg.elements[idx]; } return nullptr; diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 1ad7446fb2..4b8567bb7b 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -711,20 +711,22 @@ void X8DrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, sint32 uint8 * dst = dpi->bits + (uint32)((startY >> (dpi->zoom_level)) * ((dpi->width >> dpi->zoom_level) + dpi->pitch) + (startX >> dpi->zoom_level)); // Find colour in colour table? - uint16 g1Index = palette_to_g1_offset[palette]; - rct_g1_element * g1Element = &g1Elements[g1Index]; - uint8 * g1Bits = g1Element->offset; - - const sint32 scaled_width = width >> dpi->zoom_level; - const sint32 step = ((dpi->width >> dpi->zoom_level) + dpi->pitch); - - // Fill the rectangle with the colours from the colour table - for (sint32 i = 0; i < height >> dpi->zoom_level; i++) + uint16 g1Index = palette_to_g1_offset[palette]; + auto g1Element = gfx_get_g1_element(g1Index); + if (g1Element != nullptr) { - uint8 * nextdst = dst + step * i; - for (sint32 j = 0; j < scaled_width; j++) + auto g1Bits = g1Element->offset; + const sint32 scaled_width = width >> dpi->zoom_level; + const sint32 step = ((dpi->width >> dpi->zoom_level) + dpi->pitch); + + // Fill the rectangle with the colours from the colour table + for (sint32 i = 0; i < height >> dpi->zoom_level; i++) { - *(nextdst + j) = g1Bits[*(nextdst + j)]; + uint8 * nextdst = dst + step * i; + for (sint32 j = 0; j < scaled_width; j++) + { + *(nextdst + j) = g1Bits[*(nextdst + j)]; + } } } } diff --git a/src/openrct2/drawing/drawing.c b/src/openrct2/drawing/drawing.c index c1ad36ae5d..b7e047940c 100644 --- a/src/openrct2/drawing/drawing.c +++ b/src/openrct2/drawing/drawing.c @@ -492,11 +492,11 @@ void gfx_filter_pixel(rct_drawpixelinfo *dpi, sint32 x, sint32 y, FILTER_PALETTE */ void gfx_transpose_palette(sint32 pal, uint8 product) { - rct_g1_element g1 = g1Elements[pal]; - sint32 width = g1.width; - sint32 x = g1.x_offset; - uint8* dest_pointer = &gGamePalette[x * 4]; - uint8* source_pointer = g1.offset; + rct_g1_element * g1 = gfx_get_g1_element(pal); + sint32 width = g1->width; + sint32 x = g1->x_offset; + uint8 * dest_pointer = &gGamePalette[x * 4]; + uint8 * source_pointer = g1->offset; for (; width > 0; width--) { dest_pointer[0] = (source_pointer[0] * product) >> 8; @@ -527,18 +527,21 @@ void load_palette() palette = water_type->image_id; } - rct_g1_element g1 = g1Elements[palette]; - sint32 width = g1.width; - sint32 x = g1.x_offset; - uint8* dest_pointer = &gGamePalette[x * 4]; - uint8* source_pointer = g1.offset; - - for (; width > 0; width--) { - dest_pointer[0] = source_pointer[0]; - dest_pointer[1] = source_pointer[1]; - dest_pointer[2] = source_pointer[2]; - source_pointer += 3; - dest_pointer += 4; + const rct_g1_element * g1 = gfx_get_g1_element(palette); + if (g1 != NULL) + { + sint32 width = g1->width; + sint32 x = g1->x_offset; + uint8 * src = g1->offset; + uint8 * dst = &gGamePalette[x * 4]; + for (; width > 0; width--) + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src += 3; + dst += 4; + } } platform_update_palette(gGamePalette, 10, 236); gfx_invalidate_screen(); @@ -642,16 +645,17 @@ bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, sint32 x void gfx_invalidate_pickedup_peep() { uint32 sprite = gPickupPeepImage; - if (sprite != UINT32_MAX) { - sprite = sprite & 0x7FFFF; - - rct_g1_element *g1_elements = &g1Elements[sprite]; - sint32 left = gPickupPeepX + g1_elements->x_offset; - sint32 top = gPickupPeepY + g1_elements->y_offset; - sint32 right = left + g1_elements->width; - sint32 bottom = top + g1_elements->height; - - gfx_set_dirty_blocks(left, top, right, bottom); + if (sprite != UINT32_MAX) + { + rct_g1_element * g1 = gfx_get_g1_element(sprite & 0x7FFFF); + if (g1 != NULL) + { + sint32 left = gPickupPeepX + g1->x_offset; + sint32 top = gPickupPeepY + g1->y_offset; + sint32 right = left + g1->width; + sint32 bottom = top + g1->height; + gfx_set_dirty_blocks(left, top, right, bottom); + } } } diff --git a/src/openrct2/drawing/font.c b/src/openrct2/drawing/font.c index c83f50953b..841d0708a2 100644 --- a/src/openrct2/drawing/font.c +++ b/src/openrct2/drawing/font.c @@ -43,14 +43,16 @@ void font_sprite_initialise_characters() for (sint32 fontSize = 0; fontSize < FONT_SIZE_COUNT; fontSize++) { sint32 glyphOffset = fontSize * FONT_SPRITE_GLYPH_COUNT; for (uint8 glyphIndex = 0; glyphIndex < FONT_SPRITE_GLYPH_COUNT; glyphIndex++) { - rct_g1_element g1 = g1Elements[glyphIndex + SPR_CHAR_START + glyphOffset]; - - sint32 width = g1.width + 2 * g1.x_offset; - width += fontSize == FONT_SIZE_BIG ? 1 : -1; - if (glyphIndex >= (FORMAT_ARGUMENT_CODE_START - 32) && glyphIndex < (FORMAT_COLOUR_CODE_END - 32)) { - width = 0; + rct_g1_element * g1 = gfx_get_g1_element(glyphIndex + SPR_CHAR_START + glyphOffset); + if (g1 != NULL) + { + sint32 width = g1->width + 2 * g1->x_offset; + width += fontSize == FONT_SIZE_BIG ? 1 : -1; + if (glyphIndex >= (FORMAT_ARGUMENT_CODE_START - 32) && glyphIndex < (FORMAT_COLOUR_CODE_END - 32)) { + width = 0; + } + *pCharacterWidth++ = (uint8)width; } - *pCharacterWidth++ = (uint8)width; } } diff --git a/src/openrct2/drawing/scrolling_text.c b/src/openrct2/drawing/scrolling_text.c index 8607432199..9d59a62c08 100644 --- a/src/openrct2/drawing/scrolling_text.c +++ b/src/openrct2/drawing/scrolling_text.c @@ -77,17 +77,21 @@ void scrolling_text_initialise_bitmaps() } } - for (sint32 i = 0; i < MAX_SCROLLING_TEXT_ENTRIES; i++) { - rct_g1_element *g1 = &g1Elements[SPR_SCROLLING_TEXT_START + i]; - g1->offset = _drawScrollTextList[i].bitmap; - g1->width = 64; - g1->height = 40; - g1->offset[0] = 0xFF; - g1->offset[1] = 0xFF; - g1->offset[14] = 0; - g1->offset[15] = 0; - g1->offset[16] = 0; - g1->offset[17] = 0; + for (sint32 i = 0; i < MAX_SCROLLING_TEXT_ENTRIES; i++) + { + rct_g1_element * g1 = gfx_get_g1_element(SPR_SCROLLING_TEXT_START + i); + if (g1 != NULL) + { + g1->offset = _drawScrollTextList[i].bitmap; + g1->width = 64; + g1->height = 40; + g1->offset[0] = 0xFF; + g1->offset[1] = 0xFF; + g1->offset[14] = 0; + g1->offset[15] = 0; + g1->offset[16] = 0; + g1->offset[17] = 0; + } } } @@ -1478,7 +1482,11 @@ void scrolling_text_set_bitmap_for_sprite(utf8 *text, sint32 scroll, uint8 *bitm // Set any change in colour if (codepoint <= FORMAT_COLOUR_CODE_END && codepoint >= FORMAT_COLOUR_CODE_START){ codepoint -= FORMAT_COLOUR_CODE_START; - characterColour = g1Elements[SPR_TEXT_PALETTE].offset[codepoint * 4]; + rct_g1_element * g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); + if (g1 != NULL) + { + characterColour = g1->offset[codepoint * 4]; + } continue; } @@ -1539,7 +1547,11 @@ void scrolling_text_set_bitmap_for_ttf(utf8 *text, sint32 scroll, uint8 *bitmap, if (colour == 0) { colour = scrolling_text_get_colour(gCommonFormatArgs[7]); } else { - colour = g1Elements[SPR_TEXT_PALETTE].offset[(colour - FORMAT_COLOUR_CODE_START) * 4]; + rct_g1_element * g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); + if (g1 != NULL) + { + colour = g1->offset[(colour - FORMAT_COLOUR_CODE_START) * 4]; + } } TTFSurface * surface = ttf_surface_cache_get_or_add(fontDesc->font, text); diff --git a/src/openrct2/drawing/string.c b/src/openrct2/drawing/string.c index 50ec294baa..ad79537b34 100644 --- a/src/openrct2/drawing/string.c +++ b/src/openrct2/drawing/string.c @@ -228,19 +228,22 @@ void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format, */ static void colour_char(uint8 colour, uint16* current_font_flags, uint8* palette_pointer) { - sint32 eax; + sint32 colour32 = 0; + rct_g1_element * g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); + if (g1 != NULL) + { + colour32 = ((uint32 *)g1->offset)[colour & 0xFF]; + } - rct_g1_element g1_element = g1Elements[SPR_TEXT_PALETTE]; - eax = ((uint32*)g1_element.offset)[colour & 0xFF]; - - if (!(*current_font_flags & 2)) { - eax = eax & 0x0FF0000FF; + if (!(*current_font_flags & 2)) + { + colour32 = colour32 & 0x0FF0000FF; } // Adjust text palette. Store current colour? - palette_pointer[1] = eax & 0xFF; - palette_pointer[2] = (eax >> 8) & 0xFF; - palette_pointer[3] = (eax >> 16) & 0xFF; - palette_pointer[4] = (eax >> 24) & 0xFF; + palette_pointer[1] = colour32 & 0xFF; + palette_pointer[2] = (colour32 >> 8) & 0xFF; + palette_pointer[3] = (colour32 >> 16) & 0xFF; + palette_pointer[4] = (colour32 >> 24) & 0xFF; } /** @@ -602,17 +605,20 @@ static const utf8 *ttf_process_format_code(rct_drawpixelinfo *dpi, const utf8 *t case FORMAT_ADJUST_PALETTE: { uint16 eax = palette_to_g1_offset[(uint8)*nextCh++]; - rct_g1_element *g1Element = &g1Elements[eax]; - uint32 ebx = g1Element->offset[249] + 256; - if (!(info->flags & TEXT_DRAW_FLAG_OUTLINE)) { - ebx = ebx & 0xFF; - } - info->palette[1] = ebx & 0xFF; - info->palette[2] = (ebx >> 8) & 0xFF; + rct_g1_element * g1 = gfx_get_g1_element(eax); + if (g1 != NULL) + { + uint32 ebx = g1->offset[249] + 256; + if (!(info->flags & TEXT_DRAW_FLAG_OUTLINE)) { + ebx = ebx & 0xFF; + } + info->palette[1] = ebx & 0xFF; + info->palette[2] = (ebx >> 8) & 0xFF; - // Adjust the text palette - memcpy(info->palette + 3, &(g1Element->offset[247]), 2); - memcpy(info->palette + 5, &(g1Element->offset[250]), 2); + // Adjust the text palette + memcpy(info->palette + 3, &(g1->offset[247]), 2); + memcpy(info->palette + 5, &(g1->offset[250]), 2); + } break; } case FORMAT_3: diff --git a/src/openrct2/game.c b/src/openrct2/game.c index fc213ec935..b55291b445 100644 --- a/src/openrct2/game.c +++ b/src/openrct2/game.c @@ -178,16 +178,20 @@ void update_palette_effects() if (water_type != NULL) { palette = water_type->image_id; } - rct_g1_element g1_element = g1Elements[palette]; - sint32 xoffset = g1_element.x_offset; - xoffset = xoffset * 4; - uint8 *paletteOffset = gGamePalette + xoffset; - for (sint32 i = 0; i < g1_element.width; i++) { - paletteOffset[(i * 4) + 0] = -((0xFF - g1_element.offset[(i * 3) + 0]) / 2) - 1; - paletteOffset[(i * 4) + 1] = -((0xFF - g1_element.offset[(i * 3) + 1]) / 2) - 1; - paletteOffset[(i * 4) + 2] = -((0xFF - g1_element.offset[(i * 3) + 2]) / 2) - 1; + rct_g1_element * g1 = gfx_get_g1_element(palette); + if (g1 != NULL) + { + sint32 xoffset = g1->x_offset; + xoffset = xoffset * 4; + uint8 * paletteOffset = gGamePalette + xoffset; + for (sint32 i = 0; i < g1->width; i++) + { + paletteOffset[(i * 4) + 0] = -((0xFF - g1->offset[(i * 3) + 0]) / 2) - 1; + paletteOffset[(i * 4) + 1] = -((0xFF - g1->offset[(i * 3) + 1]) / 2) - 1; + paletteOffset[(i * 4) + 2] = -((0xFF - g1->offset[(i * 3) + 2]) / 2) - 1; + } + platform_update_palette(gGamePalette, 10, 236); } - platform_update_palette(gGamePalette, 10, 236); gClimateLightningFlash++; } else { if (gClimateLightningFlash == 2) { @@ -198,14 +202,18 @@ void update_palette_effects() palette = water_type->image_id; } - rct_g1_element g1_element = g1Elements[palette]; - sint32 xoffset = g1_element.x_offset; - xoffset = xoffset * 4; - uint8 *paletteOffset = gGamePalette + xoffset; - for (sint32 i = 0; i < g1_element.width; i++) { - paletteOffset[(i * 4) + 0] = g1_element.offset[(i * 3) + 0]; - paletteOffset[(i * 4) + 1] = g1_element.offset[(i * 3) + 1]; - paletteOffset[(i * 4) + 2] = g1_element.offset[(i * 3) + 2]; + rct_g1_element * g1 = gfx_get_g1_element(palette); + if (g1 != NULL) + { + sint32 xoffset = g1->x_offset; + xoffset = xoffset * 4; + uint8 * paletteOffset = gGamePalette + xoffset; + for (sint32 i = 0; i < g1->width; i++) + { + paletteOffset[(i * 4) + 0] = g1->offset[(i * 3) + 0]; + paletteOffset[(i * 4) + 1] = g1->offset[(i * 3) + 1]; + paletteOffset[(i * 4) + 2] = g1->offset[(i * 3) + 2]; + } } } @@ -227,54 +235,69 @@ void update_palette_effects() if (water_type != NULL) { waterId = water_type->palette_index_1; } - rct_g1_element g1_element = g1Elements[shade + waterId]; - uint8* vs = &g1_element.offset[j * 3]; - uint8* vd = &gGamePalette[230 * 4]; - sint32 n = 5; - for (sint32 i = 0; i < n; i++) { - vd[0] = vs[0]; - vd[1] = vs[1]; - vd[2] = vs[2]; - vs += 9; - if (vs >= &g1_element.offset[9 * n]) { - vs -= 9 * n; + rct_g1_element * g1 = gfx_get_g1_element(shade + waterId); + if (g1 != NULL) + { + uint8 * vs = &g1->offset[j * 3]; + uint8 * vd = &gGamePalette[230 * 4]; + sint32 n = 5; + for (sint32 i = 0; i < n; i++) + { + vd[0] = vs[0]; + vd[1] = vs[1]; + vd[2] = vs[2]; + vs += 9; + if (vs >= &g1->offset[9 * n]) + { + vs -= 9 * n; + } + vd += 4; } - vd += 4; } waterId = SPR_GAME_PALETTE_3; if (water_type != NULL) { waterId = water_type->palette_index_2; } - g1_element = g1Elements[shade + waterId]; - vs = &g1_element.offset[j * 3]; - n = 5; - for (sint32 i = 0; i < n; i++) { - vd[0] = vs[0]; - vd[1] = vs[1]; - vd[2] = vs[2]; - vs += 9; - if (vs >= &g1_element.offset[9 * n]) { - vs -= 9 * n; + g1 = gfx_get_g1_element(shade + waterId); + if (g1 != NULL) + { + uint8 * vs = &g1->offset[j * 3]; + uint8 * vd = &gGamePalette[235 * 4]; + sint32 n = 5; + for (sint32 i = 0; i < n; i++) + { + vd[0] = vs[0]; + vd[1] = vs[1]; + vd[2] = vs[2]; + vs += 9; + if (vs >= &g1->offset[9 * n]) + { + vs -= 9 * n; + } + vd += 4; } - vd += 4; } j = ((uint16)(gPaletteEffectFrame * -960) * 3) >> 16; waterId = SPR_GAME_PALETTE_4; - g1_element = g1Elements[shade + waterId]; - vs = &g1_element.offset[j * 3]; - vd += 12; - n = 3; - for (sint32 i = 0; i < n; i++) { - vd[0] = vs[0]; - vd[1] = vs[1]; - vd[2] = vs[2]; - vs += 3; - if (vs >= &g1_element.offset[3 * n]) { - vs -= 3 * n; + g1 = gfx_get_g1_element(shade + waterId); + if (g1 != NULL) + { + uint8 * vs = &g1->offset[j * 3]; + uint8 * vd = &gGamePalette[243 * 4]; + sint32 n = 3; + for (sint32 i = 0; i < n; i++) + { + vd[0] = vs[0]; + vd[1] = vs[1]; + vd[2] = vs[2]; + vs += 3; + if (vs >= &g1->offset[3 * n]) { + vs -= 3 * n; + } + vd += 4; } - vd += 4; } platform_update_palette(gGamePalette, 230, 16); diff --git a/src/openrct2/interface/colour.c b/src/openrct2/interface/colour.c index f46c1b0fdb..3f822d4bed 100644 --- a/src/openrct2/interface/colour.c +++ b/src/openrct2/interface/colour.c @@ -38,28 +38,25 @@ enum void colours_init_maps() { - if (g1Elements == NULL) - { - return; - } - // Get colour maps from g1 for (sint32 i = 0; i < COLOUR_COUNT; i++) { - rct_g1_element *g1Element = &g1Elements[SPR_PALETTE_2_START + i]; - - ColourMapA[i].colour_0 = g1Element->offset[INDEX_COLOUR_0]; - ColourMapA[i].colour_1 = g1Element->offset[INDEX_COLOUR_1]; - ColourMapA[i].darkest = g1Element->offset[INDEX_DARKEST]; - ColourMapA[i].darker = g1Element->offset[INDEX_DARKER]; - ColourMapA[i].dark = g1Element->offset[INDEX_DARK]; - ColourMapA[i].mid_dark = g1Element->offset[INDEX_MID_DARK]; - ColourMapA[i].mid_light = g1Element->offset[INDEX_MID_LIGHT]; - ColourMapA[i].light = g1Element->offset[INDEX_LIGHT]; - ColourMapA[i].lighter = g1Element->offset[INDEX_LIGHTER]; - ColourMapA[i].lightest = g1Element->offset[INDEX_LIGHTEST]; - ColourMapA[i].colour_10 = g1Element->offset[INDEX_COLOUR_10]; - ColourMapA[i].colour_11 = g1Element->offset[INDEX_COLOUR_11]; + rct_g1_element * g1 = gfx_get_g1_element(SPR_PALETTE_2_START + i); + if (g1 != NULL) + { + ColourMapA[i].colour_0 = g1->offset[INDEX_COLOUR_0]; + ColourMapA[i].colour_1 = g1->offset[INDEX_COLOUR_1]; + ColourMapA[i].darkest = g1->offset[INDEX_DARKEST]; + ColourMapA[i].darker = g1->offset[INDEX_DARKER]; + ColourMapA[i].dark = g1->offset[INDEX_DARK]; + ColourMapA[i].mid_dark = g1->offset[INDEX_MID_DARK]; + ColourMapA[i].mid_light = g1->offset[INDEX_MID_LIGHT]; + ColourMapA[i].light = g1->offset[INDEX_LIGHT]; + ColourMapA[i].lighter = g1->offset[INDEX_LIGHTER]; + ColourMapA[i].lightest = g1->offset[INDEX_LIGHTEST]; + ColourMapA[i].colour_10 = g1->offset[INDEX_COLOUR_10]; + ColourMapA[i].colour_11 = g1->offset[INDEX_COLOUR_11]; + } } } diff --git a/src/openrct2/interface/viewport.c b/src/openrct2/interface/viewport.c index 53d61c5892..4930d31bec 100644 --- a/src/openrct2/interface/viewport.c +++ b/src/openrct2/interface/viewport.c @@ -1287,7 +1287,7 @@ static bool sub_679074(rct_drawpixelinfo *dpi, sint32 imageId, sint16 x, sint16 */ static bool sub_679023(rct_drawpixelinfo *dpi, sint32 imageId, sint32 x, sint32 y) { - uint8 *palette = NULL; + uint8 * palette = NULL; imageId &= 0xBFFFFFFF; if (imageId & IMAGE_TYPE_REMAP) { _currentImageType = IMAGE_TYPE_REMAP; @@ -1296,7 +1296,11 @@ static bool sub_679023(rct_drawpixelinfo *dpi, sint32 imageId, sint32 x, sint32 index &= 0x1F; } sint32 g1Index = palette_to_g1_offset[index]; - palette = g1Elements[g1Index].offset; + rct_g1_element * g1 = gfx_get_g1_element(g1Index); + if (g1 != NULL) + { + palette = g1->offset; + } } else { _currentImageType = 0; } diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index c877d29f14..f47c20b05d 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -760,12 +760,15 @@ extern "C" return nullptr; } + auto g1Element = gfx_get_g1_element(image_id & 0x7FFFF); + if (g1Element == nullptr) + { + return nullptr; + } + paint_struct *ps = &session->NextFreePaintStruct->basic; ps->image_id = image_id; - uint32 image_element = image_id & 0x7FFFF; - rct_g1_element *g1Element = gfx_get_g1_element(image_element); - LocationXYZ16 coord_3d = { x_offset, // ax