diff --git a/src/openrct2/drawing/AVX2Drawing.cpp b/src/openrct2/drawing/AVX2Drawing.cpp index dc2270f9aa..c5153341ac 100644 --- a/src/openrct2/drawing/AVX2Drawing.cpp +++ b/src/openrct2/drawing/AVX2Drawing.cpp @@ -15,8 +15,15 @@ #include -void mask_avx2(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap) +void mask_avx2( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap) { if (width == 32) { @@ -24,14 +31,15 @@ void mask_avx2(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const int32_t colourWrapSIMD = colourWrap + 32; const int32_t dstWrapSIMD = dstWrap + 32; const __m256i zero = {}; - for (int32_t yy = 0; yy < height; yy++) { - const __m256i colour = _mm256_lddqu_si256((const __m256i *)(colourSrc + yy * colourWrapSIMD)); - const __m256i mask = _mm256_lddqu_si256((const __m256i *)(maskSrc + yy * maskWrapSIMD)); - const __m256i dest = _mm256_lddqu_si256((const __m256i *)(dst + yy * dstWrapSIMD)); - const __m256i mc = _mm256_and_si256 (colour, mask); + for (int32_t yy = 0; yy < height; yy++) + { + const __m256i colour = _mm256_lddqu_si256((const __m256i*)(colourSrc + yy * colourWrapSIMD)); + const __m256i mask = _mm256_lddqu_si256((const __m256i*)(maskSrc + yy * maskWrapSIMD)); + const __m256i dest = _mm256_lddqu_si256((const __m256i*)(dst + yy * dstWrapSIMD)); + const __m256i mc = _mm256_and_si256(colour, mask); const __m256i saturate = _mm256_cmpeq_epi8(mc, zero); - const __m256i blended = _mm256_blendv_epi8(mc, dest, saturate); - _mm256_storeu_si256 ((__m256i *)(dst + yy * dstWrapSIMD), blended); + const __m256i blended = _mm256_blendv_epi8(mc, dest, saturate); + _mm256_storeu_si256((__m256i*)(dst + yy * dstWrapSIMD), blended); } } else @@ -46,8 +54,15 @@ void mask_avx2(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, #error You have to compile this file with AVX2 enabled, when targeting x86! #endif -void mask_avx2(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap) +void mask_avx2( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap) { openrct2_assert(false, "AVX2 function called on a CPU that doesn't support AVX2"); } diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 4a33369d8e..79c5043b89 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -7,21 +7,22 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include -#include -#include -#include "../config/Config.h" #include "../Context.h" +#include "../OpenRCT2.h" +#include "../PlatformEnvironment.h" +#include "../config/Config.h" #include "../core/FileStream.hpp" #include "../core/Path.hpp" -#include "../OpenRCT2.h" #include "../platform/platform.h" -#include "../PlatformEnvironment.h" #include "../sprites.h" #include "../ui/UiContext.h" #include "../util/Util.h" #include "Drawing.h" +#include +#include +#include + using namespace OpenRCT2; using namespace OpenRCT2::Ui; @@ -38,7 +39,7 @@ struct rct_gx { rct_g1_header header; std::vector elements; - void * data; + void* data; }; // clang-format off @@ -81,7 +82,7 @@ static inline uint32_t rctc_to_rct2_index(uint32_t image) } // clang-format on -static void read_and_convert_gxdat(IStream * stream, size_t count, bool is_rctc, rct_g1_element *elements) +static void read_and_convert_gxdat(IStream* stream, size_t count, bool is_rctc, rct_g1_element* elements) { auto g1Elements32 = std::make_unique(count); stream->Read(g1Elements32.get(), count * sizeof(rct_g1_element_32bit)); @@ -96,33 +97,37 @@ static void read_and_convert_gxdat(IStream * stream, size_t count, bool is_rctc, // statement skips over the elements we don't want. switch (i) { - case 1542: - rctc += 32; break; - case 23761: - case 24627: - rctc += 4; break; - case 4951: - rctc += 3; break; - case 17154: - case 18084: - case 28197: - rctc += 2; break; + case 1542: + rctc += 32; + break; + case 23761: + case 24627: + rctc += 4; + break; + case 4951: + rctc += 3; + break; + case 17154: + case 18084: + case 28197: + rctc += 2; + break; } - const rct_g1_element_32bit &src = g1Elements32[rctc]; + const rct_g1_element_32bit& src = g1Elements32[rctc]; // Double cast to silence compiler warning about casting to // pointer from integer of mismatched length. - elements[i].offset = (uint8_t*)(uintptr_t)src.offset; - elements[i].width = src.width; - elements[i].height = src.height; - elements[i].x_offset = src.x_offset; - elements[i].y_offset = src.y_offset; - elements[i].flags = src.flags; + elements[i].offset = (uint8_t*)(uintptr_t)src.offset; + elements[i].width = src.width; + elements[i].height = src.height; + elements[i].x_offset = src.x_offset; + elements[i].y_offset = src.y_offset; + elements[i].flags = src.flags; if (src.flags & G1_FLAG_HAS_ZOOM_SPRITE) { - elements[i].zoomed_offset = (uint16_t) (i - rctc_to_rct2_index(rctc - src.zoomed_offset)); + elements[i].zoomed_offset = (uint16_t)(i - rctc_to_rct2_index(rctc - src.zoomed_offset)); } else { @@ -135,9 +140,9 @@ static void read_and_convert_gxdat(IStream * stream, size_t count, bool is_rctc, // The pincer graphic for picking up peeps is different in // RCTC, and the sprites have different offsets to accommodate // the change. This reverts the offsets to their RCT2 values. - for (const auto &animation : sprite_peep_pickup_starts) + for (const auto& animation : sprite_peep_pickup_starts) { - for (int i=0; i < SPR_PEEP_PICKUP_COUNT; ++i) + for (int i = 0; i < SPR_PEEP_PICKUP_COUNT; ++i) { elements[animation.start + i].x_offset -= animation.x_offset; elements[animation.start + i].y_offset -= animation.y_offset; @@ -148,23 +153,30 @@ static void read_and_convert_gxdat(IStream * stream, size_t count, bool is_rctc, { for (size_t i = 0; i < count; i++) { - const rct_g1_element_32bit &src = g1Elements32[i]; + const rct_g1_element_32bit& src = g1Elements32[i]; // Double cast to silence compiler warning about casting to // pointer from integer of mismatched length. - elements[i].offset = (uint8_t*)(uintptr_t)src.offset; - elements[i].width = src.width; - elements[i].height = src.height; - elements[i].x_offset = src.x_offset; - elements[i].y_offset = src.y_offset; - elements[i].flags = src.flags; + elements[i].offset = (uint8_t*)(uintptr_t)src.offset; + elements[i].width = src.width; + elements[i].height = src.height; + elements[i].x_offset = src.x_offset; + elements[i].y_offset = src.y_offset; + elements[i].flags = src.flags; elements[i].zoomed_offset = src.zoomed_offset; } } } -void mask_scalar(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap) +void mask_scalar( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap) { for (int32_t yy = 0; yy < height; yy++) { @@ -210,10 +222,10 @@ static std::string gfx_get_csg_data_path() return path; } -static rct_gx _g1 = {}; -static rct_gx _g2 = {}; -static rct_gx _csg = {}; -static bool _csgLoaded = false; +static rct_gx _g1 = {}; +static rct_gx _g2 = {}; +static rct_gx _csg = {}; +static bool _csgLoaded = false; static rct_g1_element _g1Temp = {}; bool gTinyFontAntiAliased = false; @@ -254,7 +266,7 @@ bool gfx_load_g1(const IPlatformEnvironment& env) } return true; } - catch (const std::exception &) + catch (const std::exception&) { _g1.elements.clear(); _g1.elements.shrink_to_fit(); @@ -317,7 +329,7 @@ bool gfx_load_g2() } return true; } - catch (const std::exception &) + catch (const std::exception&) { _g2.elements.clear(); _g2.elements.shrink_to_fit(); @@ -380,7 +392,7 @@ bool gfx_load_csg() _csgLoaded = true; return true; } - catch (const std::exception &) + catch (const std::exception&) { _csg.elements.clear(); _csg.elements.shrink_to_fit(); @@ -395,7 +407,15 @@ bool gfx_load_csg() * image. * rct2: 0x0067A690 */ -void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* source_pointer, uint8_t* dest_pointer, const rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int32_t height, int32_t width, int32_t image_type) +void FASTCALL gfx_bmp_sprite_to_buffer( + const uint8_t* palette_pointer, + uint8_t* source_pointer, + uint8_t* dest_pointer, + const rct_g1_element* source_image, + rct_drawpixelinfo* dest_dpi, + int32_t height, + int32_t width, + int32_t image_type) { uint16_t zoom_level = dest_dpi->zoom_level; uint8_t zoom_amount = 1 << zoom_level; @@ -403,17 +423,22 @@ void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* uint32_t source_line_width = source_image->width * zoom_amount; // Image uses the palette pointer to remap the colours of the image - if (image_type & IMAGE_TYPE_REMAP){ + if (image_type & IMAGE_TYPE_REMAP) + { assert(palette_pointer != nullptr); // Image with remaps - for (; height > 0; height -= zoom_amount){ + for (; height > 0; height -= zoom_amount) + { uint8_t* next_source_pointer = source_pointer + source_line_width; uint8_t* next_dest_pointer = dest_pointer + dest_line_width; - for (int32_t no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){ + for (int32_t no_pixels = width; no_pixels > 0; + no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++) + { uint8_t pixel = *source_pointer; pixel = palette_pointer[pixel]; - if (pixel){ + if (pixel) + { *dest_pointer = pixel; } } @@ -427,15 +452,20 @@ void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* // Image is transparent. It only uses source pointer for // telling if it needs to be drawn not for colour. Colour provided // by the palette pointer. - if (image_type & IMAGE_TYPE_TRANSPARENT){ // Not tested + if (image_type & IMAGE_TYPE_TRANSPARENT) + { // Not tested assert(palette_pointer != nullptr); - for (; height > 0; height -= zoom_amount){ + for (; height > 0; height -= zoom_amount) + { uint8_t* next_source_pointer = source_pointer + source_line_width; uint8_t* next_dest_pointer = dest_pointer + dest_line_width; - for (int32_t no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++){ + for (int32_t no_pixels = width; no_pixels > 0; + no_pixels -= zoom_amount, source_pointer += zoom_amount, dest_pointer++) + { uint8_t pixel = *source_pointer; - if (pixel){ + if (pixel) + { pixel = *dest_pointer; pixel = palette_pointer[pixel]; *dest_pointer = pixel; @@ -449,12 +479,16 @@ void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* } // Basic bitmap no fancy stuff - if (!(source_image->flags & G1_FLAG_BMP)){ // Not tested - for (; height > 0; height -= zoom_amount){ + if (!(source_image->flags & G1_FLAG_BMP)) + { // Not tested + for (; height > 0; height -= zoom_amount) + { uint8_t* next_source_pointer = source_pointer + source_line_width; uint8_t* next_dest_pointer = dest_pointer + dest_line_width; - for (int32_t no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){ + for (int32_t no_pixels = width; no_pixels > 0; + no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount) + { *dest_pointer = *source_pointer; } @@ -465,13 +499,16 @@ void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* } // Basic bitmap with no draw pixels - for (; height > 0; height -= zoom_amount){ + for (; height > 0; height -= zoom_amount) + { uint8_t* next_source_pointer = source_pointer + source_line_width; uint8_t* next_dest_pointer = dest_pointer + dest_line_width; - for (int32_t no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount){ + for (int32_t no_pixels = width; no_pixels > 0; no_pixels -= zoom_amount, dest_pointer++, source_pointer += zoom_amount) + { uint8_t pixel = *source_pointer; - if (pixel){ + if (pixel) + { *dest_pointer = pixel; } } @@ -480,14 +517,17 @@ void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* } } -uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiary_colour) { +uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiary_colour) +{ int32_t image_type = (image_id & 0xE0000000); if (image_type == 0) return nullptr; - if (!(image_type & IMAGE_TYPE_REMAP_2_PLUS)) { + if (!(image_type & IMAGE_TYPE_REMAP_2_PLUS)) + { uint8_t palette_ref = (image_id >> 19) & 0xFF; - if (!(image_type & IMAGE_TYPE_TRANSPARENT)) { + if (!(image_type & IMAGE_TYPE_TRANSPARENT)) + { palette_ref &= 0x7F; } @@ -502,13 +542,15 @@ uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiar return g1->offset; } } - else { + else + { uint8_t* palette_pointer = gPeepPalette; uint32_t primary_offset = palette_to_g1_offset[(image_id >> 19) & 0x1F]; uint32_t secondary_offset = palette_to_g1_offset[(image_id >> 24) & 0x1F]; - if (!(image_type & IMAGE_TYPE_REMAP)) { + if (!(image_type & IMAGE_TYPE_REMAP)) + { palette_pointer = gOtherPalette; #if defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2 assert(tertiary_colour < PALETTE_TO_G1_OFFSET_COUNT); @@ -551,12 +593,13 @@ uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiar * dpi (esi) * tertiary_colour (ebp) */ -void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour) +void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour) { if (image_id != -1) { uint8_t* palette_pointer = gfx_draw_sprite_get_palette(image_id, tertiary_colour); - if (image_id & IMAGE_TYPE_REMAP_2_PLUS) { + if (image_id & IMAGE_TYPE_REMAP_2_PLUS) + { image_id |= IMAGE_TYPE_REMAP; } @@ -565,26 +608,28 @@ void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int32_t image_id, } /* -* rct: 0x0067A46E -* image_id (ebx) and also (0x00EDF81C) -* palette_pointer (0x9ABDA4) -* unknown_pointer (0x9E3CDC) -* dpi (edi) -* x (cx) -* y (dx) -*/ -void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer) + * rct: 0x0067A46E + * image_id (ebx) and also (0x00EDF81C) + * palette_pointer (0x9ABDA4) + * unknown_pointer (0x9E3CDC) + * dpi (edi) + * x (cx) + * y (dx) + */ +void FASTCALL gfx_draw_sprite_palette_set_software( + rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer) { int32_t image_element = image_id & 0x7FFFF; int32_t image_type = image_id & 0xE0000000; - const rct_g1_element * g1 = gfx_get_g1_element(image_element); + const rct_g1_element* g1 = gfx_get_g1_element(image_element); if (g1 == nullptr) { return; } - if (dpi->zoom_level != 0 && (g1->flags & G1_FLAG_HAS_ZOOM_SPRITE)) { + if (dpi->zoom_level != 0 && (g1->flags & G1_FLAG_HAS_ZOOM_SPRITE)) + { rct_drawpixelinfo zoomed_dpi; zoomed_dpi.bits = dpi->bits; zoomed_dpi.x = dpi->x >> 1; @@ -593,11 +638,13 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 zoomed_dpi.width = dpi->width >> 1; zoomed_dpi.pitch = dpi->pitch; zoomed_dpi.zoom_level = dpi->zoom_level - 1; - gfx_draw_sprite_palette_set_software(&zoomed_dpi, image_type | (image_element - g1->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer); + gfx_draw_sprite_palette_set_software( + &zoomed_dpi, image_type | (image_element - g1->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer); return; } - if (dpi->zoom_level != 0 && (g1->flags & G1_FLAG_NO_ZOOM_DRAW)) { + if (dpi->zoom_level != 0 && (g1->flags & G1_FLAG_NO_ZOOM_DRAW)) + { return; } @@ -605,7 +652,8 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 int32_t zoom_level = dpi->zoom_level; int32_t zoom_mask = 0xFFFFFFFF << zoom_level; - if (zoom_level && g1->flags & G1_FLAG_RLE_COMPRESSION){ + if (zoom_level && g1->flags & G1_FLAG_RLE_COMPRESSION) + { x -= ~zoom_mask; y -= ~zoom_mask; } @@ -617,21 +665,25 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 // For whatever reason the RLE version does not use // the zoom mask on the y coordinate but does on x. - if (g1->flags & G1_FLAG_RLE_COMPRESSION){ + if (g1->flags & G1_FLAG_RLE_COMPRESSION) + { dest_start_y -= dpi->y; } - else{ - dest_start_y = (dest_start_y&zoom_mask) - dpi->y; + else + { + dest_start_y = (dest_start_y & zoom_mask) - dpi->y; } - //This is the start y coordinate on the source + // This is the start y coordinate on the source int32_t source_start_y = 0; - if (dest_start_y < 0){ + if (dest_start_y < 0) + { // If the destination y is negative reduce the height of the // image as we will cut off the bottom height += dest_start_y; // If the image is no longer visible nothing to draw - if (height <= 0){ + if (height <= 0) + { return; } // The source image will start a further up the image @@ -639,8 +691,10 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 // The destination start is now reset to 0 dest_start_y = 0; } - else{ - if (g1->flags & G1_FLAG_RLE_COMPRESSION && zoom_level){ + else + { + if (g1->flags & G1_FLAG_RLE_COMPRESSION && zoom_level) + { source_start_y -= dest_start_y & ~zoom_mask; height += dest_start_y & ~zoom_mask; } @@ -648,13 +702,15 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 int32_t dest_end_y = dest_start_y + height; - if (dest_end_y > dpi->height){ + if (dest_end_y > dpi->height) + { // If the destination y is outside of the drawing // image reduce the height of the image height -= dest_end_y - dpi->height; } // If the image no longer has anything to draw - if (height <= 0)return; + if (height <= 0) + return; dest_start_y >>= zoom_level; @@ -663,14 +719,16 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 // This is the source start x coordinate int32_t source_start_x = 0; // This is the destination start x coordinate - int16_t dest_start_x = ((x + g1->x_offset + ~zoom_mask)&zoom_mask) - dpi->x; + int16_t dest_start_x = ((x + g1->x_offset + ~zoom_mask) & zoom_mask) - dpi->x; - if (dest_start_x < 0){ + if (dest_start_x < 0) + { // If the destination is negative reduce the width // image will cut off the side width += dest_start_x; // If there is no image to draw - if (width <= 0){ + if (width <= 0) + { return; } // The source start will also need to cut off the side @@ -678,20 +736,24 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 // Reset the destination to 0 dest_start_x = 0; } - else{ - if (g1->flags & G1_FLAG_RLE_COMPRESSION && zoom_level){ + else + { + if (g1->flags & G1_FLAG_RLE_COMPRESSION && zoom_level) + { source_start_x -= dest_start_x & ~zoom_mask; } } int32_t dest_end_x = dest_start_x + width; - if (dest_end_x > dpi->width){ + if (dest_end_x > dpi->width) + { // If the destination x is outside of the drawing area // reduce the image width. width -= dest_end_x - dpi->width; // If there is no image to draw. - if (width <= 0)return; + if (width <= 0) + return; } dest_start_x >>= zoom_level; @@ -700,17 +762,20 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 // Move the pointer to the start point of the destination dest_pointer += ((dpi->width >> zoom_level) + dpi->pitch) * dest_start_y + dest_start_x; - if (g1->flags & G1_FLAG_RLE_COMPRESSION){ + if (g1->flags & G1_FLAG_RLE_COMPRESSION) + { // We have to use a different method to move the source pointer for // rle encoded sprites so that will be handled within this function - gfx_rle_sprite_to_buffer(g1->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width); + gfx_rle_sprite_to_buffer( + g1->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width); return; } uint8_t* source_pointer = g1->offset; // Move the pointer to the start point of the source - source_pointer += g1->width*source_start_y + source_start_x; + source_pointer += g1->width * source_start_y + source_start_x; - if (!(g1->flags & G1_FLAG_1)) { + if (!(g1->flags & G1_FLAG_1)) + { gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1, dpi, height, width, image_type); } } @@ -721,7 +786,8 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32 * * rct2: 0x00681DE2 */ -void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage) +void FASTCALL + gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage) { int32_t left, top, right, bottom, width, height; auto imgMask = gfx_get_g1_element(maskImage & 0x7FFFF); @@ -738,7 +804,8 @@ void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int32_ return; } - if (dpi->zoom_level != 0) { + if (dpi->zoom_level != 0) + { // TODO: Implement other zoom levels (probably not used though) assert(false); return; @@ -763,18 +830,18 @@ void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int32_ int32_t skipX = left - x; int32_t skipY = top - y; - uint8_t const * maskSrc = imgMask->offset + (skipY * imgMask->width) + skipX; - uint8_t const * colourSrc = imgColour->offset + (skipY * imgColour->width) + skipX; - uint8_t * dst = dpi->bits + (left - dpi->x) + ((top - dpi->y) * (dpi->width + dpi->pitch)); + uint8_t const* maskSrc = imgMask->offset + (skipY * imgMask->width) + skipX; + uint8_t const* colourSrc = imgColour->offset + (skipY * imgColour->width) + skipX; + uint8_t* dst = dpi->bits + (left - dpi->x) + ((top - dpi->y) * (dpi->width + dpi->pitch)); - int32_t maskWrap = imgMask->width - width; + int32_t maskWrap = imgMask->width - width; int32_t colourWrap = imgColour->width - width; - int32_t dstWrap = ((dpi->width + dpi->pitch) - width); + int32_t dstWrap = ((dpi->width + dpi->pitch) - width); mask_fn(width, height, maskSrc, colourSrc, dst, maskWrap, colourWrap, dstWrap); } -const rct_g1_element * gfx_get_g1_element(int32_t image_id) +const rct_g1_element* gfx_get_g1_element(int32_t image_id) { openrct2_assert(!gOpenRCT2NoGraphics, "gfx_get_g1_element called on headless instance"); @@ -811,8 +878,7 @@ const rct_g1_element * gfx_get_g1_element(int32_t image_id) const uint32_t idx = image_id - SPR_CSG_BEGIN; if (idx >= _csg.header.num_entries) { - openrct2_assert(idx < _csg.header.num_entries, - "Invalid entry in csg.dat requested, idx = %u.", idx); + openrct2_assert(idx < _csg.header.num_entries, "Invalid entry in csg.dat requested, idx = %u.", idx); return nullptr; } return &_csg.elements[idx]; @@ -820,11 +886,12 @@ const rct_g1_element * gfx_get_g1_element(int32_t image_id) return nullptr; } -void gfx_set_g1_element(int32_t imageId, const rct_g1_element * g1) +void gfx_set_g1_element(int32_t imageId, const rct_g1_element* g1) { openrct2_assert(!gOpenRCT2NoGraphics, "gfx_set_g1_element called on headless instance"); #ifdef DEBUG - openrct2_assert((imageId >= 0 && imageId < SPR_G2_BEGIN) || imageId == SPR_TEMP, "gfx_set_g1_element called with unexpected image id"); + openrct2_assert( + (imageId >= 0 && imageId < SPR_G2_BEGIN) || imageId == SPR_TEMP, "gfx_set_g1_element called with unexpected image id"); openrct2_assert(g1 != nullptr, "g1 was nullptr"); #endif @@ -848,7 +915,7 @@ bool is_csg_loaded() rct_size16 FASTCALL gfx_get_sprite_size(uint32_t image_id) { - const rct_g1_element * g1 = gfx_get_g1_element(image_id & 0X7FFFF); + const rct_g1_element* g1 = gfx_get_g1_element(image_id & 0X7FFFF); rct_size16 size = {}; if (g1 != nullptr) { @@ -858,7 +925,7 @@ rct_size16 FASTCALL gfx_get_sprite_size(uint32_t image_id) return size; } -size_t g1_calculate_data_size(const rct_g1_element * g1) +size_t g1_calculate_data_size(const rct_g1_element* g1) { if (g1->flags & G1_FLAG_PALETTE) { @@ -872,8 +939,8 @@ size_t g1_calculate_data_size(const rct_g1_element * g1) } else { - uint16_t * offsets = (uint16_t *)g1->offset; - uint8_t * ptr = g1->offset + offsets[g1->height - 1]; + uint16_t* offsets = (uint16_t*)g1->offset; + uint8_t* ptr = g1->offset + offsets[g1->height - 1]; bool endOfLine = false; do { diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 8f2c2075e7..18be747ddb 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -7,7 +7,6 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include #include "../common.h" #include "../config/Config.h" #include "../drawing/Drawing.h" @@ -19,6 +18,8 @@ #include "../util/Util.h" #include "TTF.h" +#include + enum : uint32_t { TEXT_DRAW_FLAG_INSET = 1 << 0, @@ -30,23 +31,25 @@ enum : uint32_t TEXT_DRAW_FLAG_NO_DRAW = 1u << 31 }; -static int32_t ttf_get_string_width(const utf8 *text); +static int32_t ttf_get_string_width(const utf8* text); /** * * rct2: 0x006C23B1 */ -int32_t gfx_get_string_width_new_lined(utf8 *text) +int32_t gfx_get_string_width_new_lined(utf8* text) { - utf8 *ch = text; - utf8 *firstCh = text; - utf8 *nextCh; + utf8* ch = text; + utf8* firstCh = text; + utf8* nextCh; utf8 backup; int32_t codepoint; int32_t maxWidth = 0; - while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) { - if (codepoint == FORMAT_NEWLINE || codepoint == FORMAT_NEWLINE_SMALLER) { + while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) + { + if (codepoint == FORMAT_NEWLINE || codepoint == FORMAT_NEWLINE_SMALLER) + { backup = *nextCh; *nextCh = 0; maxWidth = std::max(maxWidth, gfx_get_string_width(firstCh)); @@ -66,7 +69,7 @@ int32_t gfx_get_string_width_new_lined(utf8 *text) * rct2: 0x006C2321 * buffer (esi) */ -int32_t gfx_get_string_width(const utf8 * buffer) +int32_t gfx_get_string_width(const utf8* buffer) { return ttf_get_string_width(buffer); } @@ -78,47 +81,66 @@ int32_t gfx_get_string_width(const utf8 * buffer) * buffer (esi) * width (edi) */ -int32_t gfx_clip_string(utf8 *text, int32_t width) +int32_t gfx_clip_string(utf8* text, int32_t width) { int32_t clippedWidth; - if (width < 6) { + if (width < 6) + { *text = 0; return 0; } clippedWidth = gfx_get_string_width(text); - if (clippedWidth <= width) { + if (clippedWidth <= width) + { return clippedWidth; } utf8 backup[4]; - utf8 *ch = text; - utf8 *nextCh = text; - utf8 *clipCh = text; + utf8* ch = text; + utf8* nextCh = text; + utf8* clipCh = text; int32_t codepoint; - while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) { - if (utf8_is_format_code(codepoint)) { + while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) + { + if (utf8_is_format_code(codepoint)) + { ch = nextCh; ch += utf8_get_format_code_arg_length(codepoint); continue; } - for (int32_t i = 0; i < 4; i++) { backup[i] = nextCh[i]; }; - for (int32_t i = 0; i < 3; i++) { nextCh[i] = '.'; } + for (int32_t i = 0; i < 4; i++) + { + backup[i] = nextCh[i]; + }; + for (int32_t i = 0; i < 3; i++) + { + nextCh[i] = '.'; + } nextCh[3] = 0; int32_t queryWidth = gfx_get_string_width(text); - if (queryWidth < width) { + if (queryWidth < width) + { clipCh = nextCh; clippedWidth = queryWidth; - } else { - for (int32_t i = 0; i < 3; i++) { clipCh[i] = '.'; } + } + else + { + for (int32_t i = 0; i < 3; i++) + { + clipCh[i] = '.'; + } clipCh[3] = 0; return clippedWidth; } - for (int32_t i = 0; i < 4; i++) { nextCh[i] = backup[i]; }; + for (int32_t i = 0; i < 4; i++) + { + nextCh[i] = backup[i]; + }; ch = nextCh; } return gfx_get_string_width(text); @@ -137,29 +159,33 @@ int32_t gfx_clip_string(utf8 *text, int32_t width) * num_lines (edi) - out * font_height (ebx) - out */ -int32_t gfx_wrap_string(utf8 *text, int32_t width, int32_t *outNumLines, int32_t *outFontHeight) +int32_t gfx_wrap_string(utf8* text, int32_t width, int32_t* outNumLines, int32_t* outFontHeight) { int32_t lineWidth = 0; int32_t maxWidth = 0; *outNumLines = 0; // Pointer to the start of the current word - utf8 *currentWord = nullptr; + utf8* currentWord = nullptr; // Width of line up to current word int32_t currentWidth = 0; - utf8 *ch = text; - utf8 *firstCh = text; - utf8 *nextCh; + utf8* ch = text; + utf8* firstCh = text; + utf8* nextCh; int32_t codepoint; int32_t numCharactersOnLine = 0; - while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) { - if (codepoint == ' ') { + while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) + { + if (codepoint == ' ') + { currentWord = ch; currentWidth = lineWidth; numCharactersOnLine++; - } else if (codepoint == FORMAT_NEWLINE) { + } + else if (codepoint == FORMAT_NEWLINE) + { *ch++ = 0; maxWidth = std::max(maxWidth, lineWidth); (*outNumLines)++; @@ -168,7 +194,9 @@ int32_t gfx_wrap_string(utf8 *text, int32_t width, int32_t *outNumLines, int32_t firstCh = ch; numCharactersOnLine = 0; continue; - } else if (utf8_is_format_code(codepoint)) { + } + else if (utf8_is_format_code(codepoint)) + { ch = nextCh; ch += utf8_get_format_code_arg_length(codepoint); continue; @@ -179,10 +207,13 @@ int32_t gfx_wrap_string(utf8 *text, int32_t width, int32_t *outNumLines, int32_t lineWidth = gfx_get_string_width(firstCh); *nextCh = saveCh; - if (lineWidth <= width || numCharactersOnLine == 0) { + if (lineWidth <= width || numCharactersOnLine == 0) + { ch = nextCh; numCharactersOnLine++; - } else if (currentWord == nullptr) { + } + else if (currentWord == nullptr) + { // Single word is longer than line, insert null terminator ch += utf8_insert_codepoint(ch, 0); maxWidth = std::max(maxWidth, lineWidth); @@ -191,7 +222,9 @@ int32_t gfx_wrap_string(utf8 *text, int32_t width, int32_t *outNumLines, int32_t currentWord = nullptr; firstCh = ch; numCharactersOnLine = 0; - } else { + } + else + { ch = currentWord; *ch++ = 0; @@ -211,10 +244,11 @@ int32_t gfx_wrap_string(utf8 *text, int32_t width, int32_t *outNumLines, int32_t /** * Draws text that is left aligned and vertically centred. */ -void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format, void *args, int32_t colour, int32_t x, int32_t y) +void gfx_draw_string_left_centred( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, int32_t colour, int32_t x, int32_t y) { gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - char *buffer = gCommonStringFormatBuffer; + char* buffer = gCommonStringFormatBuffer; format_string(buffer, 256, format, args); int32_t height = string_get_height_raw(buffer); gfx_draw_string(dpi, buffer, colour, x, y - (height / 2)); @@ -223,13 +257,13 @@ void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format, /** * Changes the palette so that the next character changes colour */ -static void colour_char(uint8_t colour, const uint16_t* current_font_flags, uint8_t* palette_pointer) { - +static void colour_char(uint8_t colour, const uint16_t* current_font_flags, uint8_t* palette_pointer) +{ int32_t colour32 = 0; - const rct_g1_element * g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); + const rct_g1_element* g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); if (g1 != nullptr) { - colour32 = ((uint32_t *)g1->offset)[colour & 0xFF]; + colour32 = ((uint32_t*)g1->offset)[colour & 0xFF]; } if (!(*current_font_flags & 2)) @@ -247,16 +281,17 @@ static void colour_char(uint8_t colour, const uint16_t* current_font_flags, uint * Changes the palette so that the next character changes colour * This is specific to changing to a predefined window related colour */ -static void colour_char_window(uint8_t colour, const uint16_t* current_font_flags,uint8_t* palette_pointer) { - +static void colour_char_window(uint8_t colour, const uint16_t* current_font_flags, uint8_t* palette_pointer) +{ int32_t eax; colour = NOT_TRANSLUCENT(colour); eax = ColourMapA[colour].colour_11; - if (*current_font_flags & TEXT_DRAW_FLAG_OUTLINE) { + if (*current_font_flags & TEXT_DRAW_FLAG_OUTLINE) + { eax |= 0x0A0A00; } - //Adjust text palette. Store current colour? + // Adjust text palette. Store current colour? palette_pointer[1] = eax & 0xFF; palette_pointer[2] = (eax >> 8) & 0xFF; palette_pointer[3] = (eax >> 16) & 0xFF; @@ -273,20 +308,22 @@ static void colour_char_window(uint8_t colour, const uint16_t* current_font_flag * text : esi * dpi : edi */ -void draw_string_centred_raw(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t numLines, char *text) +void draw_string_centred_raw(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t numLines, char* text) { gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - gfx_draw_string(dpi, (char *)"", COLOUR_BLACK, dpi->x, dpi->y); + gfx_draw_string(dpi, (char*)"", COLOUR_BLACK, dpi->x, dpi->y); gCurrentFontFlags = 0; - for (int32_t i = 0; i <= numLines; i++) { + for (int32_t i = 0; i <= numLines; i++) + { int32_t width = gfx_get_string_width(text); gfx_draw_string(dpi, text, TEXT_COLOUR_254, x - (width / 2), y); - const utf8 *ch = text; - const utf8 *nextCh = nullptr; + const utf8* ch = text; + const utf8* nextCh = nullptr; - while ((utf8_get_next(ch, &nextCh)) != 0) { + while ((utf8_get_next(ch, &nextCh)) != 0) + { ch = nextCh; } text = (char*)(ch + 1); @@ -295,7 +332,7 @@ void draw_string_centred_raw(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32 } } -int32_t string_get_height_raw(char *buffer) +int32_t string_get_height_raw(char* buffer) { uint16_t fontBase = gCurrentFontSpriteBase; @@ -305,50 +342,62 @@ int32_t string_get_height_raw(char *buffer) else if (fontBase == FONT_SPRITE_BASE_TINY) height += 6; - char *ch = buffer; - while (*ch != 0) { + char* ch = buffer; + while (*ch != 0) + { char c = *ch++; - switch (c) { - case FORMAT_NEWLINE: - if (fontBase == FONT_SPRITE_BASE_SMALL || fontBase == FONT_SPRITE_BASE_MEDIUM) { - height += 10; + switch (c) + { + case FORMAT_NEWLINE: + if (fontBase == FONT_SPRITE_BASE_SMALL || fontBase == FONT_SPRITE_BASE_MEDIUM) + { + height += 10; + break; + } + else if (fontBase == FONT_SPRITE_BASE_TINY) + { + height += 6; + break; + } + height += 18; break; - } else if (fontBase == FONT_SPRITE_BASE_TINY) { - height += 6; + case FORMAT_NEWLINE_SMALLER: + if (fontBase == FONT_SPRITE_BASE_SMALL || fontBase == FONT_SPRITE_BASE_MEDIUM) + { + height += 5; + break; + } + else if (fontBase == FONT_SPRITE_BASE_TINY) + { + height += 3; + break; + } + height += 9; break; - } - height += 18; - break; - case FORMAT_NEWLINE_SMALLER: - if (fontBase == FONT_SPRITE_BASE_SMALL || fontBase == FONT_SPRITE_BASE_MEDIUM) { - height += 5; + case FORMAT_TINYFONT: + fontBase = FONT_SPRITE_BASE_TINY; break; - } else if (fontBase == FONT_SPRITE_BASE_TINY) { - height += 3; + case FORMAT_MEDIUMFONT: + fontBase = FONT_SPRITE_BASE_MEDIUM; + break; + case FORMAT_SMALLFONT: + fontBase = FONT_SPRITE_BASE_SMALL; + break; + default: + if (c >= 32) + continue; + if (c <= 4) + { + ch++; + continue; + } + if (c <= 16) + continue; + ch += 2; + if (c <= 22) + continue; + ch += 2; break; - } - height += 9; - break; - case FORMAT_TINYFONT: - fontBase = FONT_SPRITE_BASE_TINY; - break; - case FORMAT_MEDIUMFONT: - fontBase = FONT_SPRITE_BASE_MEDIUM; - break; - case FORMAT_SMALLFONT: - fontBase = FONT_SPRITE_BASE_SMALL; - break; - default: - if (c >= 32) continue; - if (c <= 4) { - ch++; - continue; - } - if (c <= 16) continue; - ch += 2; - if (c <= 22) continue; - ch += 2; - break; } } @@ -368,16 +417,23 @@ int32_t string_get_height_raw(char *buffer) * width : bp * ticks : ebp >> 16 */ -void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t width, int32_t colour, rct_string_id format, void *args, int32_t ticks) +void gfx_draw_string_centred_wrapped_partial( + rct_drawpixelinfo* dpi, + int32_t x, + int32_t y, + int32_t width, + int32_t colour, + rct_string_id format, + void* args, + int32_t ticks) { int32_t numLines, fontSpriteBase, lineHeight, lineY; - utf8 *buffer = gCommonStringFormatBuffer; + utf8* buffer = gCommonStringFormatBuffer; gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - gfx_draw_string(dpi, (char *)"", colour, dpi->x, dpi->y); + gfx_draw_string(dpi, (char*)"", colour, dpi->x, dpi->y); format_string(buffer, 256, format, args); - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase); lineHeight = font_get_line_height(fontSpriteBase); @@ -387,16 +443,20 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int32_t x, gCurrentFontFlags = 0; lineY = y - ((numLines * lineHeight) / 2); - for (int32_t line = 0; line <= numLines; line++) { + for (int32_t line = 0; line <= numLines; line++) + { int32_t halfWidth = gfx_get_string_width(buffer) / 2; - utf8 *ch = buffer; - utf8 *nextCh; + utf8* ch = buffer; + utf8* nextCh; int32_t codepoint; - while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) { - if (!utf8_is_format_code(codepoint)) { + while ((codepoint = utf8_get_next(ch, (const utf8**)&nextCh)) != 0) + { + if (!utf8_is_format_code(codepoint)) + { numCharactersDrawn++; - if (numCharactersDrawn > numCharactersToDraw) { + if (numCharactersDrawn > numCharactersToDraw) + { *ch = 0; break; } @@ -406,7 +466,8 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int32_t x, gfx_draw_string(dpi, buffer, TEXT_COLOUR_254, x - halfWidth, lineY); - if (numCharactersDrawn > numCharactersToDraw) { + if (numCharactersDrawn > numCharactersToDraw) + { break; } @@ -415,7 +476,8 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int32_t x, } } -struct text_draw_info { +struct text_draw_info +{ int32_t startX; int32_t startY; int32_t x; @@ -425,19 +487,20 @@ struct text_draw_info { int32_t flags; uint8_t palette[8]; uint16_t font_sprite_base; - const int8_t *y_offset; + const int8_t* y_offset; }; -static void ttf_draw_character_sprite(rct_drawpixelinfo *dpi, int32_t codepoint, text_draw_info *info) +static void ttf_draw_character_sprite(rct_drawpixelinfo* dpi, int32_t codepoint, text_draw_info* info) { int32_t characterWidth = font_sprite_get_codepoint_width(info->font_sprite_base, codepoint); int32_t sprite = font_sprite_get_codepoint_sprite(info->font_sprite_base, codepoint); - if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) { - + if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) + { int32_t x = info->x; int32_t y = info->y; - if (info->flags & TEXT_DRAW_FLAG_Y_OFFSET_EFFECT) { + if (info->flags & TEXT_DRAW_FLAG_Y_OFFSET_EFFECT) + { y += *info->y_offset++; } gfx_draw_glpyh(dpi, sprite, x, y, info->palette); @@ -446,35 +509,40 @@ static void ttf_draw_character_sprite(rct_drawpixelinfo *dpi, int32_t codepoint, info->x += characterWidth; } -static void ttf_draw_string_raw_sprite(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info) +static void ttf_draw_string_raw_sprite(rct_drawpixelinfo* dpi, const utf8* text, text_draw_info* info) { - const utf8 *ch = text; + const utf8* ch = text; int32_t codepoint; - while (!utf8_is_format_code(codepoint = utf8_get_next(ch, &ch))) { + while (!utf8_is_format_code(codepoint = utf8_get_next(ch, &ch))) + { ttf_draw_character_sprite(dpi, codepoint, info); }; } #ifndef NO_TTF -static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info) +static void ttf_draw_string_raw_ttf(rct_drawpixelinfo* dpi, const utf8* text, text_draw_info* info) { if (!ttf_initialise()) return; - TTFFontDescriptor *fontDesc = ttf_get_font_from_sprite_base(info->font_sprite_base); - if (fontDesc->font == nullptr) { + TTFFontDescriptor* fontDesc = ttf_get_font_from_sprite_base(info->font_sprite_base); + if (fontDesc->font == nullptr) + { ttf_draw_string_raw_sprite(dpi, text, info); return; } - if (info->flags & TEXT_DRAW_FLAG_NO_DRAW) { + if (info->flags & TEXT_DRAW_FLAG_NO_DRAW) + { info->x += ttf_getwidth_cache_get_or_add(fontDesc->font, text); return; - } else { + } + else + { uint8_t colour = info->palette[1]; - TTFSurface * surface = ttf_surface_cache_get_or_add(fontDesc->font, text); + TTFSurface* surface = ttf_surface_cache_get_or_add(fontDesc->font, text); if (surface == nullptr) return; @@ -485,21 +553,25 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te int32_t overflowX = (dpi->x + dpi->width) - (drawX + width); int32_t overflowY = (dpi->y + dpi->height) - (drawY + height); - if (overflowX < 0) width += overflowX; - if (overflowY < 0) height += overflowY; + if (overflowX < 0) + width += overflowX; + if (overflowY < 0) + height += overflowY; int32_t skipX = drawX - dpi->x; int32_t skipY = drawY - dpi->y; info->x += width; - auto src = (const uint8_t *)surface->pixels; - uint8_t *dst = dpi->bits; + auto src = (const uint8_t*)surface->pixels; + uint8_t* dst = dpi->bits; - if (skipX < 0) { + if (skipX < 0) + { width += skipX; src += -skipX; skipX = 0; } - if (skipY < 0) { + if (skipY < 0) + { height += skipY; src += (-skipY * surface->pitch); skipY = 0; @@ -510,16 +582,20 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te int32_t srcScanSkip = surface->pitch - width; int32_t dstScanSkip = dpi->width + dpi->pitch - width; - uint8_t *dst_orig = dst; - const uint8_t *src_orig = src; + uint8_t* dst_orig = dst; + const uint8_t* src_orig = src; // Draw shadow/outline - if (info->flags & TEXT_DRAW_FLAG_OUTLINE) { - for (int32_t yy = 0; yy < height - 0; yy++) { - for (int32_t xx = 0; xx < width - 0; xx++) { - if (*src != 0) { - *(dst + 1) = info->palette[3]; // right - *(dst - 1) = info->palette[3]; // left + if (info->flags & TEXT_DRAW_FLAG_OUTLINE) + { + for (int32_t yy = 0; yy < height - 0; yy++) + { + for (int32_t xx = 0; xx < width - 0; xx++) + { + if (*src != 0) + { + *(dst + 1) = info->palette[3]; // right + *(dst - 1) = info->palette[3]; // left *(dst - width - dstScanSkip) = info->palette[3]; // top *(dst + width + dstScanSkip) = info->palette[3]; // bottom } @@ -535,10 +611,14 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te dst = dst_orig; src = src_orig; bool use_hinting = gConfigFonts.enable_hinting && fontDesc->hinting_threshold > 0; - for (int32_t yy = 0; yy < height; yy++) { - for (int32_t xx = 0; xx < width; xx++) { - if (*src != 0) { - if (info->flags & TEXT_DRAW_FLAG_INSET) { + for (int32_t yy = 0; yy < height; yy++) + { + for (int32_t xx = 0; xx < width; xx++) + { + if (*src != 0) + { + if (info->flags & TEXT_DRAW_FLAG_INSET) + { *(dst + width + dstScanSkip + 1) = info->palette[3]; } @@ -574,12 +654,15 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te #endif // NO_TTF -static void ttf_draw_string_raw(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info) +static void ttf_draw_string_raw(rct_drawpixelinfo* dpi, const utf8* text, text_draw_info* info) { #ifndef NO_TTF - if (info->flags & TEXT_DRAW_FLAG_TTF) { + if (info->flags & TEXT_DRAW_FLAG_TTF) + { ttf_draw_string_raw_ttf(dpi, text, info); - } else { + } + else + { #endif // NO_TTF ttf_draw_string_raw_sprite(dpi, text, info); #ifndef NO_TTF @@ -587,115 +670,123 @@ static void ttf_draw_string_raw(rct_drawpixelinfo *dpi, const utf8 *text, text_d #endif // NO_TTF } -static const utf8 *ttf_process_format_code(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info) +static const utf8* ttf_process_format_code(rct_drawpixelinfo* dpi, const utf8* text, text_draw_info* info) { - const utf8 *nextCh; + const utf8* nextCh; int32_t codepoint; codepoint = utf8_get_next(text, &nextCh); - switch (codepoint) { - case FORMAT_MOVE_X: - info->x = info->startX + (uint8_t)(*nextCh++); - break; - case FORMAT_ADJUST_PALETTE: + switch (codepoint) { - uint16_t eax = palette_to_g1_offset[(uint8_t)*nextCh++]; - const rct_g1_element * g1 = gfx_get_g1_element(eax); - if (g1 != nullptr) + case FORMAT_MOVE_X: + info->x = info->startX + (uint8_t)(*nextCh++); + break; + case FORMAT_ADJUST_PALETTE: { - uint32_t 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; + uint16_t eax = palette_to_g1_offset[(uint8_t)*nextCh++]; + const rct_g1_element* g1 = gfx_get_g1_element(eax); + if (g1 != nullptr) + { + uint32_t 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, &(g1->offset[247]), 2); - memcpy(info->palette + 5, &(g1->offset[250]), 2); - } - break; - } - case FORMAT_3: - case FORMAT_4: - nextCh++; - break; - case FORMAT_NEWLINE: - info->x = info->startX; - info->y += font_get_line_height(info->font_sprite_base); - break; - case FORMAT_NEWLINE_SMALLER: - info->x = info->startX; - info->y += font_get_line_height_small(info->font_sprite_base); - break; - case FORMAT_TINYFONT: - info->font_sprite_base = FONT_SPRITE_BASE_TINY; - break; - case FORMAT_SMALLFONT: - info->font_sprite_base = FONT_SPRITE_BASE_SMALL; - break; - case FORMAT_MEDIUMFONT: - info->font_sprite_base = FONT_SPRITE_BASE_MEDIUM; - break; - case FORMAT_OUTLINE: - info->flags |= TEXT_DRAW_FLAG_OUTLINE; - break; - case FORMAT_OUTLINE_OFF: - info->flags &= ~TEXT_DRAW_FLAG_OUTLINE; - break; - case FORMAT_WINDOW_COLOUR_1: - { - uint16_t flags = info->flags; - colour_char_window(gCurrentWindowColours[0], &flags, info->palette); - break; - } - case FORMAT_WINDOW_COLOUR_2: - { - uint16_t flags = info->flags; - colour_char_window(gCurrentWindowColours[1], &flags, info->palette); - break; - } - case FORMAT_WINDOW_COLOUR_3: - { - uint16_t flags = info->flags; - colour_char_window(gCurrentWindowColours[2], &flags, info->palette); - break; - } - case FORMAT_16: - break; - case FORMAT_INLINE_SPRITE: - { - uint32_t imageId = *((uint32_t*)(nextCh)); - const rct_g1_element * g1 = gfx_get_g1_element(imageId & 0x7FFFF); - if (g1 != nullptr) - { - if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) { - gfx_draw_sprite(dpi, imageId, info->x, info->y, 0); + // Adjust the text palette + memcpy(info->palette + 3, &(g1->offset[247]), 2); + memcpy(info->palette + 5, &(g1->offset[250]), 2); } - info->x += g1->width; + break; } - nextCh += 4; - break; - } - default: - if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) { + case FORMAT_3: + case FORMAT_4: + nextCh++; + break; + case FORMAT_NEWLINE: + info->x = info->startX; + info->y += font_get_line_height(info->font_sprite_base); + break; + case FORMAT_NEWLINE_SMALLER: + info->x = info->startX; + info->y += font_get_line_height_small(info->font_sprite_base); + break; + case FORMAT_TINYFONT: + info->font_sprite_base = FONT_SPRITE_BASE_TINY; + break; + case FORMAT_SMALLFONT: + info->font_sprite_base = FONT_SPRITE_BASE_SMALL; + break; + case FORMAT_MEDIUMFONT: + info->font_sprite_base = FONT_SPRITE_BASE_MEDIUM; + break; + case FORMAT_OUTLINE: + info->flags |= TEXT_DRAW_FLAG_OUTLINE; + break; + case FORMAT_OUTLINE_OFF: + info->flags &= ~TEXT_DRAW_FLAG_OUTLINE; + break; + case FORMAT_WINDOW_COLOUR_1: + { uint16_t flags = info->flags; - colour_char(codepoint - FORMAT_COLOUR_CODE_START, &flags, info->palette); - } else if (codepoint <= 0x16) { //case 0x11? FORMAT_NEW_LINE_X_Y - nextCh += 2; - } else { - nextCh += 4;//never happens? + colour_char_window(gCurrentWindowColours[0], &flags, info->palette); + break; } - break; + case FORMAT_WINDOW_COLOUR_2: + { + uint16_t flags = info->flags; + colour_char_window(gCurrentWindowColours[1], &flags, info->palette); + break; + } + case FORMAT_WINDOW_COLOUR_3: + { + uint16_t flags = info->flags; + colour_char_window(gCurrentWindowColours[2], &flags, info->palette); + break; + } + case FORMAT_16: + break; + case FORMAT_INLINE_SPRITE: + { + uint32_t imageId = *((uint32_t*)(nextCh)); + const rct_g1_element* g1 = gfx_get_g1_element(imageId & 0x7FFFF); + if (g1 != nullptr) + { + if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) + { + gfx_draw_sprite(dpi, imageId, info->x, info->y, 0); + } + info->x += g1->width; + } + nextCh += 4; + break; + } + default: + if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) + { + uint16_t flags = info->flags; + colour_char(codepoint - FORMAT_COLOUR_CODE_START, &flags, info->palette); + } + else if (codepoint <= 0x16) + { // case 0x11? FORMAT_NEW_LINE_X_Y + nextCh += 2; + } + else + { + nextCh += 4; // never happens? + } + break; } return nextCh; } -static const utf8 *ttf_process_glyph_run(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info) +static const utf8* ttf_process_glyph_run(rct_drawpixelinfo* dpi, const utf8* text, text_draw_info* info) { utf8 buffer[512]; - const utf8 *ch = text; - const utf8 *lastCh; + const utf8* ch = text; + const utf8* lastCh; int32_t codepoint; #ifndef NO_TTF @@ -703,16 +794,21 @@ static const utf8 *ttf_process_glyph_run(rct_drawpixelinfo *dpi, const utf8 *tex #else bool isTTF = false; #endif // NO_TTF - while (!utf8_is_format_code(codepoint = utf8_get_next(ch, &lastCh))) { - if (isTTF && utf8_should_use_sprite_for_codepoint(codepoint)) { + while (!utf8_is_format_code(codepoint = utf8_get_next(ch, &lastCh))) + { + if (isTTF && utf8_should_use_sprite_for_codepoint(codepoint)) + { break; } ch = lastCh; } - if (codepoint == 0) { + if (codepoint == 0) + { ttf_draw_string_raw(dpi, text, info); return ch; - } else { + } + else + { size_t length = (size_t)(ch - text); memcpy(buffer, text, length); buffer[length] = 0; @@ -721,10 +817,10 @@ static const utf8 *ttf_process_glyph_run(rct_drawpixelinfo *dpi, const utf8 *tex } } -static void ttf_process_string(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info) +static void ttf_process_string(rct_drawpixelinfo* dpi, const utf8* text, text_draw_info* info) { - const utf8 *ch = text; - const utf8 *nextCh; + const utf8* ch = text; + const utf8* nextCh; int32_t codepoint; #ifndef NO_TTF @@ -733,13 +829,19 @@ static void ttf_process_string(rct_drawpixelinfo *dpi, const utf8 *text, text_dr bool isTTF = false; #endif // NO_TTF - while ((codepoint = utf8_get_next(ch, &nextCh)) != 0) { - if (utf8_is_format_code(codepoint)) { + while ((codepoint = utf8_get_next(ch, &nextCh)) != 0) + { + if (utf8_is_format_code(codepoint)) + { ch = ttf_process_format_code(dpi, ch, info); - } else if (isTTF && utf8_should_use_sprite_for_codepoint(codepoint)) { + } + else if (isTTF && utf8_should_use_sprite_for_codepoint(codepoint)) + { ttf_draw_character_sprite(dpi, codepoint, info); ch = nextCh; - } else { + } + else + { ch = ttf_process_glyph_run(dpi, ch, info); } info->maxX = std::max(info->maxX, info->x); @@ -747,42 +849,56 @@ static void ttf_process_string(rct_drawpixelinfo *dpi, const utf8 *text, text_dr } } -static void ttf_process_initial_colour(int32_t colour, text_draw_info *info) +static void ttf_process_initial_colour(int32_t colour, text_draw_info* info) { - if (colour != TEXT_COLOUR_254 && colour != TEXT_COLOUR_255) { + if (colour != TEXT_COLOUR_254 && colour != TEXT_COLOUR_255) + { info->flags &= ~(TEXT_DRAW_FLAG_INSET | TEXT_DRAW_FLAG_OUTLINE | TEXT_DRAW_FLAG_DARK | TEXT_DRAW_FLAG_EXTRA_DARK); - if ((int16_t)info->font_sprite_base < 0) { + if ((int16_t)info->font_sprite_base < 0) + { info->flags |= TEXT_DRAW_FLAG_DARK; - if ((int16_t)info->font_sprite_base == FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK) { + if ((int16_t)info->font_sprite_base == FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK) + { info->flags |= TEXT_DRAW_FLAG_EXTRA_DARK; } info->font_sprite_base = FONT_SPRITE_BASE_MEDIUM; } - if (colour & COLOUR_FLAG_OUTLINE) { + if (colour & COLOUR_FLAG_OUTLINE) + { info->flags |= TEXT_DRAW_FLAG_OUTLINE; } colour &= ~COLOUR_FLAG_OUTLINE; - if (!(colour & COLOUR_FLAG_INSET)) { - if (!(info->flags & TEXT_DRAW_FLAG_INSET)) { + if (!(colour & COLOUR_FLAG_INSET)) + { + if (!(info->flags & TEXT_DRAW_FLAG_INSET)) + { uint16_t flags = info->flags; colour_char_window(colour, &flags, (uint8_t*)&info->palette); } - } else { + } + else + { info->flags |= TEXT_DRAW_FLAG_INSET; colour &= ~COLOUR_FLAG_INSET; uint32_t eax; - if (info->flags & TEXT_DRAW_FLAG_DARK) { - if (info->flags & TEXT_DRAW_FLAG_EXTRA_DARK) { + if (info->flags & TEXT_DRAW_FLAG_DARK) + { + if (info->flags & TEXT_DRAW_FLAG_EXTRA_DARK) + { eax = ColourMapA[colour].mid_light; eax = eax << 16; eax = eax | ColourMapA[colour].dark; - } else { + } + else + { eax = ColourMapA[colour].light; eax = eax << 16; eax = eax | ColourMapA[colour].mid_dark; } - } else { + } + else + { eax = ColourMapA[colour].lighter; eax = eax << 16; eax = eax | ColourMapA[colour].mid_light; @@ -798,9 +914,10 @@ static void ttf_process_initial_colour(int32_t colour, text_draw_info *info) } } -void ttf_draw_string(rct_drawpixelinfo *dpi, const_utf8string text, int32_t colour, int32_t x, int32_t y) +void ttf_draw_string(rct_drawpixelinfo* dpi, const_utf8string text, int32_t colour, int32_t x, int32_t y) { - if (text == nullptr) return; + if (text == nullptr) + return; text_draw_info info; info.font_sprite_base = gCurrentFontSpriteBase; @@ -810,7 +927,8 @@ void ttf_draw_string(rct_drawpixelinfo *dpi, const_utf8string text, int32_t colo info.x = x; info.y = y; - if (LocalisationService_UseTrueTypeFont()) { + if (LocalisationService_UseTrueTypeFont()) + { info.flags |= TEXT_DRAW_FLAG_TTF; } @@ -826,7 +944,7 @@ void ttf_draw_string(rct_drawpixelinfo *dpi, const_utf8string text, int32_t colo gLastDrawStringY = info.y; } -static int32_t ttf_get_string_width(const utf8 *text) +static int32_t ttf_get_string_width(const utf8* text) { text_draw_info info; info.font_sprite_base = gCurrentFontSpriteBase; @@ -839,7 +957,8 @@ static int32_t ttf_get_string_width(const utf8 *text) info.maxY = 0; info.flags |= TEXT_DRAW_FLAG_NO_DRAW; - if (LocalisationService_UseTrueTypeFont()) { + if (LocalisationService_UseTrueTypeFont()) + { info.flags |= TEXT_DRAW_FLAG_TTF; } @@ -852,7 +971,14 @@ static int32_t ttf_get_string_width(const utf8 *text) * * rct2: 0x00682F28 */ -void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, int32_t colour, int32_t x, int32_t y, const int8_t *yOffsets, bool forceSpriteFont) +void gfx_draw_string_with_y_offsets( + rct_drawpixelinfo* dpi, + const utf8* text, + int32_t colour, + int32_t x, + int32_t y, + const int8_t* yOffsets, + bool forceSpriteFont) { text_draw_info info; info.font_sprite_base = gCurrentFontSpriteBase; @@ -865,7 +991,8 @@ void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, in info.flags |= TEXT_DRAW_FLAG_Y_OFFSET_EFFECT; - if (!forceSpriteFont && LocalisationService_UseTrueTypeFont()) { + if (!forceSpriteFont && LocalisationService_UseTrueTypeFont()) + { info.flags |= TEXT_DRAW_FLAG_TTF; } @@ -881,20 +1008,23 @@ void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, in gLastDrawStringY = info.y; } -void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int32_t availableWidth) +void shorten_path(utf8* buffer, size_t bufferSize, const utf8* path, int32_t availableWidth) { size_t length = strlen(path); // Return full string if it fits - if (gfx_get_string_width((char*)path) <= availableWidth) { + if (gfx_get_string_width((char*)path) <= availableWidth) + { safe_strcpy(buffer, path, bufferSize); return; } // Count path separators int32_t path_separators = 0; - for (size_t x = 0; x < length; x++) { - if (path[x] == *PATH_SEPARATOR || path[x] == '/') { + for (size_t x = 0; x < length; x++) + { + if (path[x] == *PATH_SEPARATOR || path[x] == '/') + { path_separators++; } } @@ -904,13 +1034,16 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int32_t ava // Abbreviate beginning with xth separator int32_t begin = -1; - for (int32_t x = 0; x < path_separators; x++){ - do { + for (int32_t x = 0; x < path_separators; x++) + { + do + { begin++; } while (path[begin] != *PATH_SEPARATOR && path[begin] != '/'); safe_strcpy(buffer + 3, path + begin, bufferSize - 3); - if (gfx_get_string_width(buffer) <= availableWidth) { + if (gfx_get_string_width(buffer) <= availableWidth) + { return; } } diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 4e4f043d95..6d6919947b 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -7,15 +7,16 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "../common.h" +#include "Drawing.h" + #include "../Context.h" +#include "../OpenRCT2.h" +#include "../common.h" #include "../core/Guard.hpp" #include "../object/Object.h" -#include "../OpenRCT2.h" #include "../platform/platform.h" #include "../util/Util.h" #include "../world/Water.h" -#include "Drawing.h" // HACK These were originally passed back through registers int32_t gLastDrawStringX; @@ -464,8 +465,16 @@ const translucent_window_palette TranslucentWindowPalettes[COLOUR_COUNT] = { }; // clang-format on -void (*mask_fn)(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap) = nullptr; +void (*mask_fn)( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap) + = nullptr; void mask_init() { @@ -486,12 +495,12 @@ void mask_init() } } -void gfx_draw_pixel(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t colour) +void gfx_draw_pixel(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t colour) { gfx_fill_rect(dpi, x, y, x, y, colour); } -void gfx_filter_pixel(rct_drawpixelinfo *dpi, int32_t x, int32_t y, FILTER_PALETTE_ID palette) +void gfx_filter_pixel(rct_drawpixelinfo* dpi, int32_t x, int32_t y, FILTER_PALETTE_ID palette) { gfx_filter_rect(dpi, x, y, x, y, palette); } @@ -504,15 +513,16 @@ void gfx_filter_pixel(rct_drawpixelinfo *dpi, int32_t x, int32_t y, FILTER_PALET */ void gfx_transpose_palette(int32_t pal, uint8_t product) { - const rct_g1_element * g1 = gfx_get_g1_element(pal); + const rct_g1_element* g1 = gfx_get_g1_element(pal); if (g1 != nullptr) { int32_t width = g1->width; int32_t x = g1->x_offset; - uint8_t * dest_pointer = &gGamePalette[x * 4]; - uint8_t * source_pointer = g1->offset; + uint8_t* dest_pointer = &gGamePalette[x * 4]; + uint8_t* source_pointer = g1->offset; - for (; width > 0; width--) { + for (; width > 0; width--) + { dest_pointer[0] = (source_pointer[0] * product) >> 8; dest_pointer[1] = (source_pointer[1] * product) >> 8; dest_pointer[2] = (source_pointer[2] * product) >> 8; @@ -529,26 +539,28 @@ void gfx_transpose_palette(int32_t pal, uint8_t product) */ void load_palette() { - if (gOpenRCT2NoGraphics) { + if (gOpenRCT2NoGraphics) + { return; } - auto water_type = (rct_water_type *)object_entry_get_chunk(OBJECT_TYPE_WATER, 0); + auto water_type = (rct_water_type*)object_entry_get_chunk(OBJECT_TYPE_WATER, 0); uint32_t palette = 0x5FC; - if (water_type != nullptr) { + if (water_type != nullptr) + { openrct2_assert(water_type->image_id != (uint32_t)-1, "Failed to load water palette"); palette = water_type->image_id; } - const rct_g1_element * g1 = gfx_get_g1_element(palette); + const rct_g1_element* g1 = gfx_get_g1_element(palette); if (g1 != nullptr) { int32_t width = g1->width; int32_t x = g1->x_offset; - uint8_t * src = g1->offset; - uint8_t * dst = &gGamePalette[x * 4]; + uint8_t* src = g1->offset; + uint8_t* dst = &gGamePalette[x * 4]; for (; width > 0; width--) { dst[0] = src[0]; @@ -572,15 +584,15 @@ void gfx_invalidate_screen() } /* -* -* rct2: 0x006EE53B -* left (ax) -* width (bx) -* top (cx) -* height (dx) -* drawpixelinfo (edi) -*/ -bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int32_t x, int32_t y, int32_t width, int32_t height) + * + * rct2: 0x006EE53B + * left (ax) + * width (bx) + * top (cx) + * height (dx) + * drawpixelinfo (edi) + */ +bool clip_drawpixelinfo(rct_drawpixelinfo* dst, rct_drawpixelinfo* src, int32_t x, int32_t y, int32_t width, int32_t height) { int32_t right = x + width; int32_t bottom = y + height; @@ -593,7 +605,8 @@ bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int32_t dst->pitch = src->pitch; dst->zoom_level = 0; - if (x > dst->x) { + if (x > dst->x) + { uint16_t clippedFromLeft = x - dst->x; dst->width -= clippedFromLeft; dst->x = x; @@ -602,12 +615,14 @@ bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int32_t } int32_t stickOutWidth = dst->x + dst->width - right; - if (stickOutWidth > 0) { + if (stickOutWidth > 0) + { dst->width -= stickOutWidth; dst->pitch += stickOutWidth; } - if (y > dst->y) { + if (y > dst->y) + { uint16_t clippedFromTop = y - dst->y; dst->height -= clippedFromTop; dst->y = y; @@ -616,11 +631,13 @@ bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int32_t } int32_t bp = dst->y + dst->height - bottom; - if (bp > 0) { + if (bp > 0) + { dst->height -= bp; } - if (dst->width > 0 && dst->height > 0) { + if (dst->width > 0 && dst->height > 0) + { dst->x -= x; dst->y -= y; return true; @@ -634,7 +651,7 @@ void gfx_invalidate_pickedup_peep() uint32_t sprite = gPickupPeepImage; if (sprite != UINT32_MAX) { - const rct_g1_element * g1 = gfx_get_g1_element(sprite & 0x7FFFF); + const rct_g1_element* g1 = gfx_get_g1_element(sprite & 0x7FFFF); if (g1 != nullptr) { int32_t left = gPickupPeepX + g1->x_offset; @@ -646,10 +663,10 @@ void gfx_invalidate_pickedup_peep() } } -void gfx_draw_pickedup_peep(rct_drawpixelinfo *dpi) +void gfx_draw_pickedup_peep(rct_drawpixelinfo* dpi) { - if (gPickupPeepImage != UINT32_MAX) { + if (gPickupPeepImage != UINT32_MAX) + { gfx_draw_sprite(dpi, gPickupPeepImage, gPickupPeepX, gPickupPeepY, 0); } } - diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index ba0df2241d..e56710d128 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -18,45 +18,48 @@ namespace OpenRCT2 interface IPlatformEnvironment; } -struct rct_g1_element { - uint8_t* offset; // 0x00 - int16_t width; // 0x04 - int16_t height; // 0x06 - int16_t x_offset; // 0x08 - int16_t y_offset; // 0x0A - uint16_t flags; // 0x0C - uint16_t zoomed_offset; // 0x0E +struct rct_g1_element +{ + uint8_t* offset; // 0x00 + int16_t width; // 0x04 + int16_t height; // 0x06 + int16_t x_offset; // 0x08 + int16_t y_offset; // 0x0A + uint16_t flags; // 0x0C + uint16_t zoomed_offset; // 0x0E }; -struct rct_drawpixelinfo { - uint8_t* bits; // 0x00 +struct rct_drawpixelinfo +{ + uint8_t* bits; // 0x00 int16_t x; // 0x04 int16_t y; // 0x06 int16_t width; // 0x08 int16_t height; // 0x0A int16_t pitch; // 0x0C note: this is actually (pitch - width) - uint16_t zoom_level; // 0x0E + uint16_t zoom_level; // 0x0E }; -struct rct_g1_element_32bit { - uint32_t offset; // 0x00 note: uint32_t always! - int16_t width; // 0x04 - int16_t height; // 0x06 - int16_t x_offset; // 0x08 - int16_t y_offset; // 0x0A - uint16_t flags; // 0x0C - uint16_t zoomed_offset; // 0x0E +struct rct_g1_element_32bit +{ + uint32_t offset; // 0x00 note: uint32_t always! + int16_t width; // 0x04 + int16_t height; // 0x06 + int16_t x_offset; // 0x08 + int16_t y_offset; // 0x0A + uint16_t flags; // 0x0C + uint16_t zoomed_offset; // 0x0E }; assert_struct_size(rct_g1_element_32bit, 0x10); - -enum { - G1_FLAG_BMP = (1 << 0), // Image data is encoded as raw pixels (no transparency) - G1_FLAG_1 = (1 << 1), +enum +{ + G1_FLAG_BMP = (1 << 0), // Image data is encoded as raw pixels (no transparency) + G1_FLAG_1 = (1 << 1), G1_FLAG_RLE_COMPRESSION = (1 << 2), // Image data is encoded using RCT2's form of run length encoding - G1_FLAG_PALETTE = (1 << 3), // Image data is a sequence of palette entries R8G8B8 + G1_FLAG_PALETTE = (1 << 3), // Image data is a sequence of palette entries R8G8B8 G1_FLAG_HAS_ZOOM_SPRITE = (1 << 4), // Use a different sprite for higher zoom levels - G1_FLAG_NO_ZOOM_DRAW = (1 << 5), // Does not get drawn at higher zoom levels (only zoom 0) + G1_FLAG_NO_ZOOM_DRAW = (1 << 5), // Does not get drawn at higher zoom levels (only zoom 0) }; enum : uint32_t @@ -69,16 +72,18 @@ enum : uint32_t // REMAP_2_PLUS = REMAP 3 }; -enum { - INSET_RECT_FLAG_FILL_GREY = (1 << 2), // 0x04 - INSET_RECT_FLAG_BORDER_NONE = (1 << 3), // 0x08 - INSET_RECT_FLAG_FILL_NONE = (1 << 4), // 0x10 - INSET_RECT_FLAG_BORDER_INSET = (1 << 5), // 0x20 +enum +{ + INSET_RECT_FLAG_FILL_GREY = (1 << 2), // 0x04 + INSET_RECT_FLAG_BORDER_NONE = (1 << 3), // 0x08 + INSET_RECT_FLAG_FILL_NONE = (1 << 4), // 0x10 + INSET_RECT_FLAG_BORDER_INSET = (1 << 5), // 0x20 INSET_RECT_FLAG_FILL_DONT_LIGHTEN = (1 << 6), // 0x40 - INSET_RECT_FLAG_FILL_MID_LIGHT = (1 << 7), // 0x80 + INSET_RECT_FLAG_FILL_MID_LIGHT = (1 << 7), // 0x80 }; -enum FILTER_PALETTE_ID { +enum FILTER_PALETTE_ID +{ PALETTE_NULL = 0, PALETTE_WATER = 32, @@ -153,41 +158,42 @@ enum FILTER_PALETTE_ID { PALETTE_TRANSLUCENT_WHITE = 109, PALETTE_TRANSLUCENT_WHITE_HIGHLIGHT = 110, PALETTE_TRANSLUCENT_WHITE_SHADOW = 111, - PALETTE_GLASS_BLACK = 112 + COLOUR_BLACK, - PALETTE_GLASS_GREY = 112 + COLOUR_GREY, - PALETTE_GLASS_WHITE = 112 + COLOUR_WHITE, - PALETTE_GLASS_DARK_PURPLE = 112 + COLOUR_DARK_PURPLE, - PALETTE_GLASS_LIGHT_PURPLE = 112 + COLOUR_LIGHT_PURPLE, - PALETTE_GLASS_BRIGHT_PURPLE = 112 + COLOUR_BRIGHT_PURPLE, - PALETTE_GLASS_DARK_BLUE = 112 + COLOUR_DARK_BLUE, - PALETTE_GLASS_LIGHT_BLUE = 112 + COLOUR_LIGHT_BLUE, - PALETTE_GLASS_ICY_BLUE = 112 + COLOUR_ICY_BLUE, - PALETTE_GLASS_TEAL = 112 + COLOUR_TEAL, - PALETTE_GLASS_AQUAMARINE = 112 + COLOUR_AQUAMARINE, - PALETTE_GLASS_SATURATED_GREEN = 112 + COLOUR_SATURATED_GREEN, - PALETTE_GLASS_DARK_GREEN = 112 + COLOUR_DARK_GREEN, - PALETTE_GLASS_MOSS_GREEN = 112 + COLOUR_MOSS_GREEN, - PALETTE_GLASS_BRIGHT_GREEN = 112 + COLOUR_BRIGHT_GREEN, - PALETTE_GLASS_OLIVE_GREEN = 112 + COLOUR_OLIVE_GREEN, - PALETTE_GLASS_DARK_OLIVE_GREEN = 112 + COLOUR_DARK_OLIVE_GREEN, - PALETTE_GLASS_BRIGHT_YELLOW = 112 + COLOUR_BRIGHT_YELLOW, - PALETTE_GLASS_YELLOW = 112 + COLOUR_YELLOW, - PALETTE_GLASS_DARK_YELLOW = 112 + COLOUR_DARK_YELLOW, - PALETTE_GLASS_LIGHT_ORANGE = 112 + COLOUR_LIGHT_ORANGE, - PALETTE_GLASS_DARK_ORANGE = 112 + COLOUR_DARK_ORANGE, - PALETTE_GLASS_LIGHT_BROWN = 112 + COLOUR_LIGHT_BROWN, - PALETTE_GLASS_SATURATED_BROWN = 112 + COLOUR_SATURATED_BROWN, - PALETTE_GLASS_DARK_BROWN = 112 + COLOUR_DARK_BROWN, - PALETTE_GLASS_SALMON_PINK = 112 + COLOUR_SALMON_PINK, - PALETTE_GLASS_BORDEAUX_RED = 112 + COLOUR_BORDEAUX_RED, - PALETTE_GLASS_SATURATED_RED = 112 + COLOUR_SATURATED_RED, - PALETTE_GLASS_BRIGHT_RED = 112 + COLOUR_BRIGHT_RED, - PALETTE_GLASS_DARK_PINK = 112 + COLOUR_DARK_PINK, - PALETTE_GLASS_BRIGHT_PINK = 112 + COLOUR_BRIGHT_PINK, - PALETTE_GLASS_LIGHT_PINK = 112 + COLOUR_LIGHT_PINK, + PALETTE_GLASS_BLACK = 112 + COLOUR_BLACK, + PALETTE_GLASS_GREY = 112 + COLOUR_GREY, + PALETTE_GLASS_WHITE = 112 + COLOUR_WHITE, + PALETTE_GLASS_DARK_PURPLE = 112 + COLOUR_DARK_PURPLE, + PALETTE_GLASS_LIGHT_PURPLE = 112 + COLOUR_LIGHT_PURPLE, + PALETTE_GLASS_BRIGHT_PURPLE = 112 + COLOUR_BRIGHT_PURPLE, + PALETTE_GLASS_DARK_BLUE = 112 + COLOUR_DARK_BLUE, + PALETTE_GLASS_LIGHT_BLUE = 112 + COLOUR_LIGHT_BLUE, + PALETTE_GLASS_ICY_BLUE = 112 + COLOUR_ICY_BLUE, + PALETTE_GLASS_TEAL = 112 + COLOUR_TEAL, + PALETTE_GLASS_AQUAMARINE = 112 + COLOUR_AQUAMARINE, + PALETTE_GLASS_SATURATED_GREEN = 112 + COLOUR_SATURATED_GREEN, + PALETTE_GLASS_DARK_GREEN = 112 + COLOUR_DARK_GREEN, + PALETTE_GLASS_MOSS_GREEN = 112 + COLOUR_MOSS_GREEN, + PALETTE_GLASS_BRIGHT_GREEN = 112 + COLOUR_BRIGHT_GREEN, + PALETTE_GLASS_OLIVE_GREEN = 112 + COLOUR_OLIVE_GREEN, + PALETTE_GLASS_DARK_OLIVE_GREEN = 112 + COLOUR_DARK_OLIVE_GREEN, + PALETTE_GLASS_BRIGHT_YELLOW = 112 + COLOUR_BRIGHT_YELLOW, + PALETTE_GLASS_YELLOW = 112 + COLOUR_YELLOW, + PALETTE_GLASS_DARK_YELLOW = 112 + COLOUR_DARK_YELLOW, + PALETTE_GLASS_LIGHT_ORANGE = 112 + COLOUR_LIGHT_ORANGE, + PALETTE_GLASS_DARK_ORANGE = 112 + COLOUR_DARK_ORANGE, + PALETTE_GLASS_LIGHT_BROWN = 112 + COLOUR_LIGHT_BROWN, + PALETTE_GLASS_SATURATED_BROWN = 112 + COLOUR_SATURATED_BROWN, + PALETTE_GLASS_DARK_BROWN = 112 + COLOUR_DARK_BROWN, + PALETTE_GLASS_SALMON_PINK = 112 + COLOUR_SALMON_PINK, + PALETTE_GLASS_BORDEAUX_RED = 112 + COLOUR_BORDEAUX_RED, + PALETTE_GLASS_SATURATED_RED = 112 + COLOUR_SATURATED_RED, + PALETTE_GLASS_BRIGHT_RED = 112 + COLOUR_BRIGHT_RED, + PALETTE_GLASS_DARK_PINK = 112 + COLOUR_DARK_PINK, + PALETTE_GLASS_BRIGHT_PINK = 112 + COLOUR_BRIGHT_PINK, + PALETTE_GLASS_LIGHT_PINK = 112 + COLOUR_LIGHT_PINK, }; -struct translucent_window_palette { +struct translucent_window_palette +{ FILTER_PALETTE_ID base; FILTER_PALETTE_ID highlight; FILTER_PALETTE_ID shadow; @@ -195,7 +201,8 @@ struct translucent_window_palette { #pragma pack(push, 1) -struct rct_palette_entry { +struct rct_palette_entry +{ uint8_t blue; uint8_t green; uint8_t red; @@ -205,7 +212,8 @@ assert_struct_size(rct_palette_entry, 4); #pragma pack(pop) -struct rct_palette { +struct rct_palette +{ rct_palette_entry entries[256]; }; @@ -216,8 +224,10 @@ struct rct_size16 }; #define SPRITE_ID_PALETTE_COLOUR_1(colourId) (IMAGE_TYPE_REMAP | ((colourId) << 19)) -#define SPRITE_ID_PALETTE_COLOUR_2(primaryId, secondaryId) (IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_REMAP | (((primaryId) << 19) | ((secondaryId) << 24))) -#define SPRITE_ID_PALETTE_COLOUR_3(primaryId, secondaryId) (IMAGE_TYPE_REMAP_2_PLUS | (((primaryId) << 19) | ((secondaryId) << 24))) +#define SPRITE_ID_PALETTE_COLOUR_2(primaryId, secondaryId) \ + (IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_REMAP | (((primaryId) << 19) | ((secondaryId) << 24))) +#define SPRITE_ID_PALETTE_COLOUR_3(primaryId, secondaryId) \ + (IMAGE_TYPE_REMAP_2_PLUS | (((primaryId) << 19) | ((secondaryId) << 24))) #define PALETTE_TO_G1_OFFSET_COUNT 144 @@ -253,7 +263,7 @@ extern rct_drawpixelinfo gScreenDPI; extern rct_drawpixelinfo gWindowDPI; // -bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int32_t x, int32_t y, int32_t width, int32_t height); +bool clip_drawpixelinfo(rct_drawpixelinfo* dst, rct_drawpixelinfo* src, int32_t x, int32_t y, int32_t width, int32_t height); void gfx_set_dirty_blocks(int16_t left, int16_t top, int16_t right, int16_t bottom); void gfx_draw_all_dirty_blocks(); void gfx_invalidate_screen(); @@ -263,20 +273,22 @@ void gfx_transpose_palette(int32_t pal, uint8_t product); void load_palette(); // other -void gfx_clear(rct_drawpixelinfo *dpi, uint8_t paletteIndex); -void gfx_draw_pixel(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t colour); -void gfx_filter_pixel(rct_drawpixelinfo *dpi, int32_t x, int32_t y, FILTER_PALETTE_ID palette); +void gfx_clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex); +void gfx_draw_pixel(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t colour); +void gfx_filter_pixel(rct_drawpixelinfo* dpi, int32_t x, int32_t y, FILTER_PALETTE_ID palette); void gfx_invalidate_pickedup_peep(); -void gfx_draw_pickedup_peep(rct_drawpixelinfo *dpi); +void gfx_draw_pickedup_peep(rct_drawpixelinfo* dpi); // line -void gfx_draw_line(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour); -void gfx_draw_line_software(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour); +void gfx_draw_line(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour); +void gfx_draw_line_software(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour); // rect -void gfx_fill_rect(rct_drawpixelinfo *dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t colour); -void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t right, int16_t bottom, int32_t colour, uint8_t flags); -void gfx_filter_rect(rct_drawpixelinfo *dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, FILTER_PALETTE_ID palette); +void gfx_fill_rect(rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t colour); +void gfx_fill_rect_inset( + rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t right, int16_t bottom, int32_t colour, uint8_t flags); +void gfx_filter_rect( + rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, FILTER_PALETTE_ID palette); // sprite bool gfx_load_g1(const OpenRCT2::IPlatformEnvironment& env); @@ -285,72 +297,143 @@ bool gfx_load_csg(); void gfx_unload_g1(); void gfx_unload_g2(); void gfx_unload_csg(); -const rct_g1_element * gfx_get_g1_element(int32_t image_id); -void gfx_set_g1_element(int32_t imageId, const rct_g1_element * g1); +const rct_g1_element* gfx_get_g1_element(int32_t image_id); +void gfx_set_g1_element(int32_t imageId, const rct_g1_element* g1); bool is_csg_loaded(); -uint32_t gfx_object_allocate_images(const rct_g1_element * images, uint32_t count); +uint32_t gfx_object_allocate_images(const rct_g1_element* images, uint32_t count); void gfx_object_free_images(uint32_t baseImageId, uint32_t count); void gfx_object_check_all_images_freed(); -void FASTCALL gfx_bmp_sprite_to_buffer(const uint8_t* palette_pointer, uint8_t* source_pointer, uint8_t* dest_pointer, const rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int32_t height, int32_t width, int32_t image_type); -void FASTCALL gfx_rle_sprite_to_buffer(const uint8_t* RESTRICT source_bits_pointer, uint8_t* RESTRICT dest_bits_pointer, const uint8_t* RESTRICT palette_pointer, const rct_drawpixelinfo * RESTRICT dpi, int32_t image_type, int32_t source_y_start, int32_t height, int32_t source_x_start, int32_t width); -void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour); -void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo *dpi, int32_t image_id, int32_t x, int32_t y, uint8_t * palette); -void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage); -void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int32_t image, int32_t x, int32_t y, uint8_t colour); +void FASTCALL gfx_bmp_sprite_to_buffer( + const uint8_t* palette_pointer, + uint8_t* source_pointer, + uint8_t* dest_pointer, + const rct_g1_element* source_image, + rct_drawpixelinfo* dest_dpi, + int32_t height, + int32_t width, + int32_t image_type); +void FASTCALL gfx_rle_sprite_to_buffer( + const uint8_t* RESTRICT source_bits_pointer, + uint8_t* RESTRICT dest_bits_pointer, + const uint8_t* RESTRICT palette_pointer, + const rct_drawpixelinfo* RESTRICT dpi, + int32_t image_type, + int32_t source_y_start, + int32_t height, + int32_t source_x_start, + int32_t width); +void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour); +void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette); +void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage); +void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint8_t colour); -void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour); +void FASTCALL + gfx_draw_sprite_software(rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint32_t tertiary_colour); uint8_t* FASTCALL gfx_draw_sprite_get_palette(int32_t image_id, uint32_t tertiary_colour); -void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer); -void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage); +void FASTCALL gfx_draw_sprite_palette_set_software( + rct_drawpixelinfo* dpi, int32_t image_id, int32_t x, int32_t y, uint8_t* palette_pointer, uint8_t* unknown_pointer); +void FASTCALL + gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage); // string -void gfx_draw_string(rct_drawpixelinfo *dpi, const_utf8string buffer, uint8_t colour, int32_t x, int32_t y); +void gfx_draw_string(rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t colour, int32_t x, int32_t y); -void gfx_draw_string_left(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y); -void gfx_draw_string_centred(rct_drawpixelinfo *dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, void *args); -void gfx_draw_string_right(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y); +void gfx_draw_string_left(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y); +void gfx_draw_string_centred(rct_drawpixelinfo* dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, void* args); +void gfx_draw_string_right(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y); -void draw_string_left_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y); -void draw_string_centred_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y); -void draw_string_right_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y); +void draw_string_left_underline(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y); +void draw_string_centred_underline( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y); +void draw_string_right_underline( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y); -void gfx_draw_string_left_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y, int32_t width); -void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y, int32_t width); -void gfx_draw_string_right_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8_t colour, int32_t x, int32_t y, int32_t width); +void gfx_draw_string_left_clipped( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y, int32_t width); +void gfx_draw_string_centred_clipped( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y, int32_t width); +void gfx_draw_string_right_clipped( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y, int32_t width); -int32_t gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour); -int32_t gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour); +int32_t gfx_draw_string_left_wrapped( + rct_drawpixelinfo* dpi, void* args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour); +int32_t gfx_draw_string_centred_wrapped( + rct_drawpixelinfo* dpi, void* args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour); -void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format, void *args, int32_t colour, int32_t x, int32_t y); -void draw_string_centred_raw(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t numLines, char *text); -void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int32_t x, int32_t y, int32_t width, int32_t colour, rct_string_id format, void *args, int32_t ticks); -void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, int32_t colour, int32_t x, int32_t y, const int8_t *yOffsets, bool forceSpriteFont); +void gfx_draw_string_left_centred( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, int32_t colour, int32_t x, int32_t y); +void draw_string_centred_raw(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t numLines, char* text); +void gfx_draw_string_centred_wrapped_partial( + rct_drawpixelinfo* dpi, + int32_t x, + int32_t y, + int32_t width, + int32_t colour, + rct_string_id format, + void* args, + int32_t ticks); +void gfx_draw_string_with_y_offsets( + rct_drawpixelinfo* dpi, + const utf8* text, + int32_t colour, + int32_t x, + int32_t y, + const int8_t* yOffsets, + bool forceSpriteFont); int32_t gfx_wrap_string(char* buffer, int32_t width, int32_t* num_lines, int32_t* font_height); -int32_t gfx_get_string_width(const utf8 * buffer); +int32_t gfx_get_string_width(const utf8* buffer); int32_t gfx_get_string_width_new_lined(char* buffer); -int32_t string_get_height_raw(char *buffer); +int32_t string_get_height_raw(char* buffer); int32_t gfx_clip_string(char* buffer, int32_t width); -void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int32_t availableWidth); -void ttf_draw_string(rct_drawpixelinfo *dpi, const_utf8string text, int32_t colour, int32_t x, int32_t y); +void shorten_path(utf8* buffer, size_t bufferSize, const utf8* path, int32_t availableWidth); +void ttf_draw_string(rct_drawpixelinfo* dpi, const_utf8string text, int32_t colour, int32_t x, int32_t y); // scrolling text void scrolling_text_initialise_bitmaps(); -int32_t scrolling_text_setup(struct paint_session * session, rct_string_id stringId, uint16_t scroll, uint16_t scrollingMode); +int32_t scrolling_text_setup(struct paint_session* session, rct_string_id stringId, uint16_t scroll, uint16_t scrollingMode); rct_size16 FASTCALL gfx_get_sprite_size(uint32_t image_id); -size_t g1_calculate_data_size(const rct_g1_element * g1); +size_t g1_calculate_data_size(const rct_g1_element* g1); -void mask_scalar(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap); -void mask_sse4_1(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap); -void mask_avx2(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap); +void mask_scalar( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap); +void mask_sse4_1( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap); +void mask_avx2( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap); void mask_init(); -extern void (*mask_fn)(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap); +extern void (*mask_fn)( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap); #include "NewDrawing.h" diff --git a/src/openrct2/drawing/DrawingFast.cpp b/src/openrct2/drawing/DrawingFast.cpp index 956ced13b1..ebfc1813f7 100644 --- a/src/openrct2/drawing/DrawingFast.cpp +++ b/src/openrct2/drawing/DrawingFast.cpp @@ -9,19 +9,20 @@ #pragma warning(disable : 4127) // conditional expression is constant -#include - #include "Drawing.h" +#include + template -static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, - uint8_t* RESTRICT dest_bits_pointer, - const uint8_t* RESTRICT palette_pointer, - const rct_drawpixelinfo *RESTRICT dpi, - int32_t source_y_start, - int32_t height, - int32_t source_x_start, - int32_t width) +static void FASTCALL DrawRLESprite2( + const uint8_t* RESTRICT source_bits_pointer, + uint8_t* RESTRICT dest_bits_pointer, + const uint8_t* RESTRICT palette_pointer, + const rct_drawpixelinfo* RESTRICT dpi, + int32_t source_y_start, + int32_t height, + int32_t source_x_start, + int32_t width) { // The distance between two samples in the source image. // We draw the image at 1 / (2^zoom_level) scale. @@ -33,19 +34,19 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, // Move up to the first line of the image if source_y_start is negative. Why does this even occur? if (source_y_start < 0) { - source_y_start += zoom_amount; - height -= zoom_amount; + source_y_start += zoom_amount; + height -= zoom_amount; dest_bits_pointer += line_width; } - //For every line in the image + // For every line in the image for (int32_t i = 0; i < height; i += zoom_amount) { int32_t y = source_y_start + i; - //The first part of the source pointer is a list of offsets to different lines - //This will move the pointer to the correct source line. - const uint8_t *lineData = source_bits_pointer + ((uint16_t*)source_bits_pointer)[y]; + // The first part of the source pointer is a list of offsets to different lines + // This will move the pointer to the correct source line. + const uint8_t* lineData = source_bits_pointer + ((uint16_t*)source_bits_pointer)[y]; uint8_t* loop_dest_pointer = dest_bits_pointer + line_width * (i >> zoom_level); uint8_t isEndOfLine = 0; @@ -54,16 +55,16 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, while (!isEndOfLine) { const uint8_t* copySrc = lineData; - //uint8_t* copyDest = loop_dest_pointer; + // uint8_t* copyDest = loop_dest_pointer; // Read chunk metadata - uint8_t dataSize = *copySrc++; + uint8_t dataSize = *copySrc++; uint8_t firstPixelX = *copySrc++; - isEndOfLine = dataSize & 0x80; // If the last bit in dataSize is set, then this is the last line - dataSize &= 0x7F; // The rest of the bits are the actual size + isEndOfLine = dataSize & 0x80; // If the last bit in dataSize is set, then this is the last line + dataSize &= 0x7F; // The rest of the bits are the actual size - //Have our next source pointer point to the next data section + // Have our next source pointer point to the next data section lineData = copySrc + dataSize; int32_t x_start = firstPixelX - source_x_start; @@ -71,14 +72,14 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, if (x_start > 0) { - int mod = x_start & (zoom_amount - 1); // x_start modulo zoom_amount + int mod = x_start & (zoom_amount - 1); // x_start modulo zoom_amount // If x_start is not a multiple of zoom_amount, round it up to a multiple if (mod != 0) { int offset = zoom_amount - mod; - x_start += offset; - copySrc += offset; + x_start += offset; + copySrc += offset; numPixels -= offset; } } @@ -87,20 +88,20 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, // Clamp x_start to zero if negative int offset = 0 - x_start; x_start = 0; - copySrc += offset; + copySrc += offset; numPixels -= offset; } - //If the end position is further out than the whole image - //end position then we need to shorten the line again + // If the end position is further out than the whole image + // end position then we need to shorten the line again if (x_start + numPixels > width) numPixels = width - x_start; - uint8_t *copyDest = loop_dest_pointer + (x_start >> zoom_level); + uint8_t* copyDest = loop_dest_pointer + (x_start >> zoom_level); - //Finally after all those checks, copy the image onto the drawing surface - //If the image type is not a basic one we require to mix the pixels - if (image_type & IMAGE_TYPE_REMAP) // palette controlled images + // Finally after all those checks, copy the image onto the drawing surface + // If the image type is not a basic one we require to mix the pixels + if (image_type & IMAGE_TYPE_REMAP) // palette controlled images { for (int j = 0; j < numPixels; j += zoom_amount, copySrc += zoom_amount, copyDest++) { @@ -115,7 +116,7 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, } } } - else if (image_type & IMAGE_TYPE_TRANSPARENT) // single alpha blended color (used for glass) + else if (image_type & IMAGE_TYPE_TRANSPARENT) // single alpha blended color (used for glass) { for (int j = 0; j < numPixels; j += zoom_amount, copyDest++) { @@ -124,7 +125,7 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, *copyDest = pixel; } } - else // standard opaque image + else // standard opaque image { if (zoom_level == 0) { @@ -142,46 +143,61 @@ static void FASTCALL DrawRLESprite2(const uint8_t* RESTRICT source_bits_pointer, } } -#define DrawRLESpriteHelper2(image_type, zoom_level) \ - DrawRLESprite2(source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width) +#define DrawRLESpriteHelper2(image_type, zoom_level) \ + DrawRLESprite2( \ + source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width) template -static void FASTCALL DrawRLESprite1(const uint8_t* source_bits_pointer, - uint8_t* dest_bits_pointer, - const uint8_t* palette_pointer, - const rct_drawpixelinfo *dpi, - int32_t source_y_start, - int32_t height, - int32_t source_x_start, - int32_t width) +static void FASTCALL DrawRLESprite1( + const uint8_t* source_bits_pointer, + uint8_t* dest_bits_pointer, + const uint8_t* palette_pointer, + const rct_drawpixelinfo* dpi, + int32_t source_y_start, + int32_t height, + int32_t source_x_start, + int32_t width) { int32_t zoom_level = dpi->zoom_level; - switch (zoom_level) { - case 0: DrawRLESpriteHelper2(image_type, 0); break; - case 1: DrawRLESpriteHelper2(image_type, 1); break; - case 2: DrawRLESpriteHelper2(image_type, 2); break; - case 3: DrawRLESpriteHelper2(image_type, 3); break; - default: assert(false); break; + switch (zoom_level) + { + case 0: + DrawRLESpriteHelper2(image_type, 0); + break; + case 1: + DrawRLESpriteHelper2(image_type, 1); + break; + case 2: + DrawRLESpriteHelper2(image_type, 2); + break; + case 3: + DrawRLESpriteHelper2(image_type, 3); + break; + default: + assert(false); + break; } } -#define DrawRLESpriteHelper1(image_type) \ - DrawRLESprite1(source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width) +#define DrawRLESpriteHelper1(image_type) \ + DrawRLESprite1( \ + source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width) /** * Transfers readied images onto buffers * This function copies the sprite data onto the screen * rct2: 0x0067AA18 */ -void FASTCALL gfx_rle_sprite_to_buffer(const uint8_t* RESTRICT source_bits_pointer, - uint8_t* RESTRICT dest_bits_pointer, - const uint8_t* RESTRICT palette_pointer, - const rct_drawpixelinfo * RESTRICT dpi, - int32_t image_type, - int32_t source_y_start, - int32_t height, - int32_t source_x_start, - int32_t width) +void FASTCALL gfx_rle_sprite_to_buffer( + const uint8_t* RESTRICT source_bits_pointer, + uint8_t* RESTRICT dest_bits_pointer, + const uint8_t* RESTRICT palette_pointer, + const rct_drawpixelinfo* RESTRICT dpi, + int32_t image_type, + int32_t source_y_start, + int32_t height, + int32_t source_x_start, + int32_t width) { if (image_type & IMAGE_TYPE_REMAP) { @@ -203,4 +219,3 @@ void FASTCALL gfx_rle_sprite_to_buffer(const uint8_t* RESTRICT source_bits_point DrawRLESpriteHelper1(IMAGE_TYPE_DEFAULT); } } - diff --git a/src/openrct2/drawing/Font.cpp b/src/openrct2/drawing/Font.cpp index b7d206f6ae..3d2d963b25 100644 --- a/src/openrct2/drawing/Font.cpp +++ b/src/openrct2/drawing/Font.cpp @@ -7,13 +7,14 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "Font.h" + #include "../core/Util.hpp" #include "../localisation/FormatCodes.h" #include "../localisation/Language.h" #include "../localisation/LocalisationService.h" #include "../sprites.h" #include "Drawing.h" -#include "Font.h" #include "TTF.h" static constexpr const int32_t SpriteFontLineHeight[FONT_SIZE_COUNT] = { 6, 10, 10 }; @@ -22,7 +23,7 @@ static uint8_t _spriteFontCharacterWidths[FONT_SIZE_COUNT][FONT_SPRITE_GLYPH_COU static uint8_t _additionalSpriteFontCharacterWidth[FONT_SIZE_COUNT][SPR_G2_GLYPH_COUNT] = {}; #ifndef NO_TTF -TTFFontSetDescriptor *gCurrentTTFFontSet; +TTFFontSetDescriptor* gCurrentTTFFontSet; #endif // NO_TTF /** @@ -31,14 +32,17 @@ TTFFontSetDescriptor *gCurrentTTFFontSet; */ void font_sprite_initialise_characters() { - for (int32_t fontSize = 0; fontSize < FONT_SIZE_COUNT; fontSize++) { + for (int32_t fontSize = 0; fontSize < FONT_SIZE_COUNT; fontSize++) + { int32_t glyphOffset = fontSize * FONT_SPRITE_GLYPH_COUNT; - for (uint8_t glyphIndex = 0; glyphIndex < FONT_SPRITE_GLYPH_COUNT; glyphIndex++) { - const rct_g1_element * g1 = gfx_get_g1_element(glyphIndex + SPR_CHAR_START + glyphOffset); + for (uint8_t glyphIndex = 0; glyphIndex < FONT_SPRITE_GLYPH_COUNT; glyphIndex++) + { + const rct_g1_element* g1 = gfx_get_g1_element(glyphIndex + SPR_CHAR_START + glyphOffset); int32_t width = 0; if (g1 != nullptr) { - if (glyphIndex < (FORMAT_ARGUMENT_CODE_START - 32) || glyphIndex >= (FORMAT_COLOUR_CODE_END - 32)) { + if (glyphIndex < (FORMAT_ARGUMENT_CODE_START - 32) || glyphIndex >= (FORMAT_COLOUR_CODE_END - 32)) + { width = (g1->width + 2 * g1->x_offset) - 1; } } @@ -52,7 +56,7 @@ void font_sprite_initialise_characters() int32_t glyphOffset = fontSize * SPR_G2_GLYPH_COUNT; for (int32_t glyphIndex = 0; glyphIndex < SPR_G2_GLYPH_COUNT; glyphIndex++) { - const rct_g1_element * g1 = gfx_get_g1_element(glyphIndex + SPR_G2_CHAR_BEGIN + glyphOffset); + const rct_g1_element* g1 = gfx_get_g1_element(glyphIndex + SPR_G2_CHAR_BEGIN + glyphOffset); int32_t width = 0; if (g1 != nullptr) { @@ -68,84 +72,129 @@ void font_sprite_initialise_characters() int32_t font_sprite_get_codepoint_offset(int32_t codepoint) { - switch (codepoint) { - case FORMAT_ENDQUOTES: return 34 - 32; + switch (codepoint) + { + case FORMAT_ENDQUOTES: + return 34 - 32; - case FORMAT_UP: return 160 - 32; - case FORMAT_INVERTEDEXCLAMATION: return 161 - 32; - case FORMAT_POUND: return 163 - 32; + case FORMAT_UP: + return 160 - 32; + case FORMAT_INVERTEDEXCLAMATION: + return 161 - 32; + case FORMAT_POUND: + return 163 - 32; - case FORMAT_YEN: return 165 - 32; + case FORMAT_YEN: + return 165 - 32; + case FORMAT_COPYRIGHT: + return 169 - 32; + case FORMAT_DOWN: + return 170 - 32; + case FORMAT_LEFTGUILLEMET: + return 171 - 32; + case FORMAT_TICK: + return 172 - 32; + case FORMAT_CROSS: + return 173 - 32; + case FORMAT_RIGHT: + return 175 - 32; + case FORMAT_DEGREE: + return 176 - 32; + case FORMAT_SYMBOL_RAILWAY: + return 177 - 32; + case FORMAT_SQUARED: + return 178 - 32; - case FORMAT_COPYRIGHT: return 169 - 32; - case FORMAT_DOWN: return 170 - 32; - case FORMAT_LEFTGUILLEMET: return 171 - 32; - case FORMAT_TICK: return 172 - 32; - case FORMAT_CROSS: return 173 - 32; + case FORMAT_OPENQUOTES: + return 180 - 32; + case FORMAT_EURO: + return 181 - 32; + case FORMAT_SYMBOL_ROAD: + return 182 - 32; + case FORMAT_SYMBOL_FLAG: + return 183 - 32; + case FORMAT_APPROX: + return 184 - 32; + case FORMAT_POWERNEGATIVEONE: + return 185 - 32; + case FORMAT_BULLET: + return 186 - 32; + case FORMAT_RIGHTGUILLEMET: + return 187 - 32; + case FORMAT_SMALLUP: + return 188 - 32; + case FORMAT_SMALLDOWN: + return 189 - 32; + case FORMAT_LEFT: + return 190 - 32; + case FORMAT_INVERTEDQUESTION: + return 191 - 32; - case FORMAT_RIGHT: return 175 - 32; - case FORMAT_DEGREE: return 176 - 32; - case FORMAT_SYMBOL_RAILWAY: return 177 - 32; - case FORMAT_SQUARED: return 178 - 32; + case UNICODE_A_OGONEK_UC: + return RCT2_A_OGONEK_UC - 32; + case UNICODE_C_ACUTE_UC: + return RCT2_C_ACUTE_UC - 32; + case UNICODE_E_OGONEK_UC: + return RCT2_E_OGONEK_UC - 32; + case UNICODE_N_ACUTE_UC: + return RCT2_N_ACUTE_UC - 32; + case UNICODE_L_STROKE_UC: + return RCT2_L_STROKE_UC - 32; + case UNICODE_S_ACUTE_UC: + return RCT2_S_ACUTE_UC - 32; + case UNICODE_Z_DOT_UC: + return RCT2_Z_DOT_UC - 32; + case UNICODE_Z_ACUTE_UC: + return RCT2_Z_ACUTE_UC - 32; - case FORMAT_OPENQUOTES: return 180 - 32; - case FORMAT_EURO: return 181 - 32; - case FORMAT_SYMBOL_ROAD: return 182 - 32; - case FORMAT_SYMBOL_FLAG: return 183 - 32; - case FORMAT_APPROX: return 184 - 32; - case FORMAT_POWERNEGATIVEONE: return 185 - 32; - case FORMAT_BULLET: return 186 - 32; - case FORMAT_RIGHTGUILLEMET: return 187 - 32; - case FORMAT_SMALLUP: return 188 - 32; - case FORMAT_SMALLDOWN: return 189 - 32; - case FORMAT_LEFT: return 190 - 32; - case FORMAT_INVERTEDQUESTION: return 191 - 32; + case UNICODE_A_OGONEK: + return RCT2_A_OGONEK - 32; + case UNICODE_C_ACUTE: + return RCT2_C_ACUTE - 32; + case UNICODE_E_OGONEK: + return RCT2_E_OGONEK - 32; + case UNICODE_N_ACUTE: + return RCT2_N_ACUTE - 32; + case UNICODE_L_STROKE: + return RCT2_L_STROKE - 32; + case UNICODE_S_ACUTE: + return RCT2_S_ACUTE - 32; + case UNICODE_Z_DOT: + return RCT2_Z_DOT - 32; + case UNICODE_Z_ACUTE: + return RCT2_Z_ACUTE - 32; - case UNICODE_A_OGONEK_UC: return RCT2_A_OGONEK_UC - 32; - case UNICODE_C_ACUTE_UC: return RCT2_C_ACUTE_UC - 32; - case UNICODE_E_OGONEK_UC: return RCT2_E_OGONEK_UC - 32; - case UNICODE_N_ACUTE_UC: return RCT2_N_ACUTE_UC - 32; - case UNICODE_L_STROKE_UC: return RCT2_L_STROKE_UC - 32; - case UNICODE_S_ACUTE_UC: return RCT2_S_ACUTE_UC - 32; - case UNICODE_Z_DOT_UC: return RCT2_Z_DOT_UC - 32; - case UNICODE_Z_ACUTE_UC: return RCT2_Z_ACUTE_UC - 32; + // Render capital sharp-S (ẞ) with lowercase sprite (ß) + case UNICODE_CAPITAL_SHARP_S: + return 223 - 32; - case UNICODE_A_OGONEK: return RCT2_A_OGONEK - 32; - case UNICODE_C_ACUTE: return RCT2_C_ACUTE - 32; - case UNICODE_E_OGONEK: return RCT2_E_OGONEK - 32; - case UNICODE_N_ACUTE: return RCT2_N_ACUTE - 32; - case UNICODE_L_STROKE: return RCT2_L_STROKE - 32; - case UNICODE_S_ACUTE: return RCT2_S_ACUTE - 32; - case UNICODE_Z_DOT: return RCT2_Z_DOT - 32; - case UNICODE_Z_ACUTE: return RCT2_Z_ACUTE - 32; + case UNICODE_AE_UC: + return SPR_G2_AE_UPPER - SPR_CHAR_START; + case UNICODE_O_STROKE_UC: + return SPR_G2_O_STROKE_UPPER - SPR_CHAR_START; + case UNICODE_AE: + return SPR_G2_AE_LOWER - SPR_CHAR_START; + case UNICODE_O_STROKE: + return SPR_G2_O_STROKE_LOWER - SPR_CHAR_START; - // Render capital sharp-S (ẞ) with lowercase sprite (ß) - case UNICODE_CAPITAL_SHARP_S: return 223 - 32; + case UNICODE_DINGBATS_PLUS: + return 11; + case UNICODE_DINGBATS_MINUS: + return 13; - case UNICODE_AE_UC: - return SPR_G2_AE_UPPER - SPR_CHAR_START; - case UNICODE_O_STROKE_UC: - return SPR_G2_O_STROKE_UPPER - SPR_CHAR_START; - case UNICODE_AE: - return SPR_G2_AE_LOWER - SPR_CHAR_START; - case UNICODE_O_STROKE: - return SPR_G2_O_STROKE_LOWER - SPR_CHAR_START; - - case UNICODE_DINGBATS_PLUS: return 11; - case UNICODE_DINGBATS_MINUS: return 13; - - default: - if (codepoint < 32 || codepoint >= 256) codepoint = '?'; - return codepoint - 32; + default: + if (codepoint < 32 || codepoint >= 256) + codepoint = '?'; + return codepoint - 32; } } int32_t font_sprite_get_codepoint_width(uint16_t fontSpriteBase, int32_t codepoint) { - if (fontSpriteBase == (uint16_t)FONT_SPRITE_BASE_MEDIUM_DARK || - fontSpriteBase == (uint16_t)FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK) + if (fontSpriteBase == (uint16_t)FONT_SPRITE_BASE_MEDIUM_DARK + || fontSpriteBase == (uint16_t)FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK) { fontSpriteBase = (uint16_t)FONT_SPRITE_BASE_MEDIUM; } @@ -184,7 +233,8 @@ int32_t font_sprite_get_codepoint_sprite(int32_t fontSpriteBase, int32_t codepoi int32_t font_get_font_index_from_sprite_base(uint16_t spriteBase) { - switch (spriteBase) { + switch (spriteBase) + { case FONT_SPRITE_BASE_TINY: return FONT_SIZE_TINY; case FONT_SPRITE_BASE_SMALL: @@ -197,14 +247,15 @@ int32_t font_get_font_index_from_sprite_base(uint16_t spriteBase) int32_t font_get_size_from_sprite_base(uint16_t spriteBase) { - switch (spriteBase) { - case FONT_SPRITE_BASE_TINY: - return 0; - case FONT_SPRITE_BASE_SMALL: - return 1; - default: - case FONT_SPRITE_BASE_MEDIUM: - return 2; + switch (spriteBase) + { + case FONT_SPRITE_BASE_TINY: + return 0; + case FONT_SPRITE_BASE_SMALL: + return 1; + default: + case FONT_SPRITE_BASE_MEDIUM: + return 2; } } @@ -212,9 +263,12 @@ int32_t font_get_line_height(int32_t fontSpriteBase) { int32_t fontSize = font_get_size_from_sprite_base(fontSpriteBase); #ifndef NO_TTF - if (LocalisationService_UseTrueTypeFont()) { + if (LocalisationService_UseTrueTypeFont()) + { return gCurrentTTFFontSet->size[fontSize].line_height; - } else { + } + else + { #endif // NO_TTF return SpriteFontLineHeight[fontSize]; #ifndef NO_TTF @@ -227,87 +281,94 @@ int32_t font_get_line_height_small(int32_t fontSpriteBase) return font_get_line_height(fontSpriteBase) / 2; } -bool font_supports_string_sprite(const utf8 *text) +bool font_supports_string_sprite(const utf8* text) { - const utf8 *src = text; + const utf8* src = text; uint32_t codepoint; - while ((codepoint = utf8_get_next(src, &src)) != 0) { + while ((codepoint = utf8_get_next(src, &src)) != 0) + { bool supported = false; - switch (codepoint) { - case FORMAT_ENDQUOTES: - case FORMAT_UP: - case FORMAT_INVERTEDEXCLAMATION: - case FORMAT_POUND: - case FORMAT_YEN: - case FORMAT_COPYRIGHT: - case FORMAT_DOWN: - case FORMAT_LEFTGUILLEMET: - case FORMAT_TICK: - case FORMAT_CROSS: - case FORMAT_RIGHT: - case FORMAT_DEGREE: - case FORMAT_SYMBOL_RAILWAY: - case FORMAT_SQUARED: - case FORMAT_OPENQUOTES: - case FORMAT_EURO: - case FORMAT_SYMBOL_ROAD: - case FORMAT_SYMBOL_FLAG: - case FORMAT_APPROX: - case FORMAT_POWERNEGATIVEONE: - case FORMAT_BULLET: - case FORMAT_RIGHTGUILLEMET: - case FORMAT_SMALLUP: - case FORMAT_SMALLDOWN: - case FORMAT_LEFT: - case FORMAT_INVERTEDQUESTION: + switch (codepoint) + { + case FORMAT_ENDQUOTES: + case FORMAT_UP: + case FORMAT_INVERTEDEXCLAMATION: + case FORMAT_POUND: + case FORMAT_YEN: + case FORMAT_COPYRIGHT: + case FORMAT_DOWN: + case FORMAT_LEFTGUILLEMET: + case FORMAT_TICK: + case FORMAT_CROSS: + case FORMAT_RIGHT: + case FORMAT_DEGREE: + case FORMAT_SYMBOL_RAILWAY: + case FORMAT_SQUARED: + case FORMAT_OPENQUOTES: + case FORMAT_EURO: + case FORMAT_SYMBOL_ROAD: + case FORMAT_SYMBOL_FLAG: + case FORMAT_APPROX: + case FORMAT_POWERNEGATIVEONE: + case FORMAT_BULLET: + case FORMAT_RIGHTGUILLEMET: + case FORMAT_SMALLUP: + case FORMAT_SMALLDOWN: + case FORMAT_LEFT: + case FORMAT_INVERTEDQUESTION: - case UNICODE_A_OGONEK_UC: - case UNICODE_C_ACUTE_UC: - case UNICODE_E_OGONEK_UC: - case UNICODE_N_ACUTE_UC: - case UNICODE_L_STROKE_UC: - case UNICODE_S_ACUTE_UC: - case UNICODE_Z_DOT_UC: - case UNICODE_Z_ACUTE_UC: + case UNICODE_A_OGONEK_UC: + case UNICODE_C_ACUTE_UC: + case UNICODE_E_OGONEK_UC: + case UNICODE_N_ACUTE_UC: + case UNICODE_L_STROKE_UC: + case UNICODE_S_ACUTE_UC: + case UNICODE_Z_DOT_UC: + case UNICODE_Z_ACUTE_UC: - case UNICODE_A_OGONEK: - case UNICODE_C_ACUTE: - case UNICODE_E_OGONEK: - case UNICODE_N_ACUTE: - case UNICODE_L_STROKE: - case UNICODE_S_ACUTE: - case UNICODE_Z_DOT: - case UNICODE_Z_ACUTE: + case UNICODE_A_OGONEK: + case UNICODE_C_ACUTE: + case UNICODE_E_OGONEK: + case UNICODE_N_ACUTE: + case UNICODE_L_STROKE: + case UNICODE_S_ACUTE: + case UNICODE_Z_DOT: + case UNICODE_Z_ACUTE: - supported = true; - break; - default: - if (codepoint >= 32 && codepoint < 256) { supported = true; - } - break; + break; + default: + if (codepoint >= 32 && codepoint < 256) + { + supported = true; + } + break; } - if (!supported) { + if (!supported) + { return false; } } return true; } -bool font_supports_string_ttf(const utf8 *text, int32_t fontSize) +bool font_supports_string_ttf(const utf8* text, int32_t fontSize) { #ifndef NO_TTF - const utf8 *src = text; - const TTF_Font *font = gCurrentTTFFontSet->size[fontSize].font; - if (font == nullptr) { + const utf8* src = text; + const TTF_Font* font = gCurrentTTFFontSet->size[fontSize].font; + if (font == nullptr) + { return false; } uint32_t codepoint; - while ((codepoint = utf8_get_next(src, &src)) != 0) { + while ((codepoint = utf8_get_next(src, &src)) != 0) + { bool supported = ttf_provides_glyph(font, codepoint); - if (!supported) { + if (!supported) + { return false; } } @@ -317,11 +378,14 @@ bool font_supports_string_ttf(const utf8 *text, int32_t fontSize) #endif // NO_TTF } -bool font_supports_string(const utf8 *text, int32_t fontSize) +bool font_supports_string(const utf8* text, int32_t fontSize) { - if (LocalisationService_UseTrueTypeFont()) { + if (LocalisationService_UseTrueTypeFont()) + { return font_supports_string_ttf(text, fontSize); - } else { + } + else + { return font_supports_string_sprite(text); } } diff --git a/src/openrct2/drawing/Font.h b/src/openrct2/drawing/Font.h index 6ec21b1689..7604ba9068 100644 --- a/src/openrct2/drawing/Font.h +++ b/src/openrct2/drawing/Font.h @@ -12,14 +12,16 @@ #include "../common.h" -enum { +enum +{ FONT_SIZE_TINY = 2, FONT_SIZE_SMALL = 0, FONT_SIZE_MEDIUM = 1, FONT_SIZE_COUNT = 3 }; -enum { +enum +{ FONT_SPRITE_GLYPH_COUNT = 224, FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK = -2, FONT_SPRITE_BASE_MEDIUM_DARK = -1, @@ -33,22 +35,24 @@ enum { struct _TTF_Font; using TTF_Font = _TTF_Font; -struct TTFFontDescriptor { - const utf8 *filename; - const utf8 *font_name; +struct TTFFontDescriptor +{ + const utf8* filename; + const utf8* font_name; int32_t ptSize; int32_t offset_x; int32_t offset_y; int32_t line_height; int32_t hinting_threshold; - TTF_Font * font; + TTF_Font* font; }; -struct TTFFontSetDescriptor { +struct TTFFontSetDescriptor +{ TTFFontDescriptor size[FONT_SIZE_COUNT]; }; -extern TTFFontSetDescriptor *gCurrentTTFFontSet; +extern TTFFontSetDescriptor* gCurrentTTFFontSet; #endif // NO_TTF @@ -60,8 +64,8 @@ int32_t font_get_font_index_from_sprite_base(uint16_t spriteBase); int32_t font_get_size_from_sprite_base(uint16_t spriteBase); int32_t font_get_line_height(int32_t fontSpriteBase); int32_t font_get_line_height_small(int32_t fontSpriteBase); -bool font_supports_string_sprite(const utf8 *text); -bool font_supports_string_ttf(const utf8 *text, int32_t fontSize); -bool font_supports_string(const utf8 *text, int32_t fontSize); +bool font_supports_string_sprite(const utf8* text); +bool font_supports_string_ttf(const utf8* text, int32_t fontSize); +bool font_supports_string(const utf8* text, int32_t fontSize); #endif diff --git a/src/openrct2/drawing/IDrawingContext.h b/src/openrct2/drawing/IDrawingContext.h index 82857c80ff..eb4521c0a4 100644 --- a/src/openrct2/drawing/IDrawingContext.h +++ b/src/openrct2/drawing/IDrawingContext.h @@ -10,7 +10,6 @@ #pragma once #include "../common.h" - #include "Drawing.h" namespace OpenRCT2::Drawing @@ -19,17 +18,19 @@ namespace OpenRCT2::Drawing interface IDrawingContext { - virtual ~IDrawingContext() { } + virtual ~IDrawingContext() + { + } - virtual OpenRCT2::Drawing::IDrawingEngine * GetEngine() abstract; + virtual OpenRCT2::Drawing::IDrawingEngine* GetEngine() abstract; - virtual void Clear(uint8_t paletteIndex) abstract; - virtual void FillRect(uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract; + virtual void Clear(uint8_t paletteIndex) abstract; + virtual void FillRect(uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract; virtual void FilterRect(FILTER_PALETTE_ID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract; - virtual void DrawLine(uint32_t colour, int32_t x1, int32_t y1, int32_t x2, int32_t y2) abstract; - virtual void DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) abstract; - virtual void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) abstract; - virtual void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) abstract; - virtual void DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t * palette) abstract; + virtual void DrawLine(uint32_t colour, int32_t x1, int32_t y1, int32_t x2, int32_t y2) abstract; + virtual void DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) abstract; + virtual void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) abstract; + virtual void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) abstract; + virtual void DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t * palette) abstract; }; } // namespace OpenRCT2::Drawing diff --git a/src/openrct2/drawing/IDrawingEngine.h b/src/openrct2/drawing/IDrawingEngine.h index 4edc98d48f..c59e320300 100644 --- a/src/openrct2/drawing/IDrawingEngine.h +++ b/src/openrct2/drawing/IDrawingEngine.h @@ -9,9 +9,10 @@ #pragma once -#include #include "../common.h" +#include + enum DRAWING_ENGINE { DRAWING_ENGINE_NONE = -1, @@ -46,24 +47,26 @@ namespace OpenRCT2::Drawing interface IDrawingEngine { - virtual ~IDrawingEngine() { } + virtual ~IDrawingEngine() + { + } - virtual void Initialise() abstract; - virtual void Resize(uint32_t width, uint32_t height) abstract; - virtual void SetPalette(const rct_palette_entry * colours) abstract; + virtual void Initialise() abstract; + virtual void Resize(uint32_t width, uint32_t height) abstract; + virtual void SetPalette(const rct_palette_entry* colours) abstract; virtual void SetVSync(bool vsync) abstract; - virtual void Invalidate(int32_t left, int32_t top, int32_t right, int32_t bottom) abstract; - virtual void BeginDraw() abstract; - virtual void EndDraw() abstract; - virtual void PaintWindows() abstract; - virtual void PaintRain() abstract; - virtual void CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) abstract; - virtual int32_t Screenshot() abstract; + virtual void Invalidate(int32_t left, int32_t top, int32_t right, int32_t bottom) abstract; + virtual void BeginDraw() abstract; + virtual void EndDraw() abstract; + virtual void PaintWindows() abstract; + virtual void PaintRain() abstract; + virtual void CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) abstract; + virtual int32_t Screenshot() abstract; - virtual IDrawingContext * GetDrawingContext(rct_drawpixelinfo * dpi) abstract; - virtual rct_drawpixelinfo * GetDrawingPixelInfo() abstract; + virtual IDrawingContext* GetDrawingContext(rct_drawpixelinfo * dpi) abstract; + virtual rct_drawpixelinfo* GetDrawingPixelInfo() abstract; virtual DRAWING_ENGINE_FLAGS GetFlags() abstract; @@ -72,18 +75,18 @@ namespace OpenRCT2::Drawing interface IDrawingEngineFactory { - virtual ~IDrawingEngineFactory() { } - virtual std::unique_ptr Create(DRAWING_ENGINE_TYPE type, const std::shared_ptr& uiContext) abstract; + virtual ~IDrawingEngineFactory() + { + } + virtual std::unique_ptr Create( + DRAWING_ENGINE_TYPE type, const std::shared_ptr& uiContext) abstract; }; interface IRainDrawer { - virtual ~IRainDrawer() { } - virtual void Draw(int32_t x, - int32_t y, - int32_t width, - int32_t height, - int32_t xStart, - int32_t yStart) abstract; + virtual ~IRainDrawer() + { + } + virtual void Draw(int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart) abstract; }; } // namespace OpenRCT2::Drawing diff --git a/src/openrct2/drawing/Image.cpp b/src/openrct2/drawing/Image.cpp index 5b46d8cd53..eeed5fb085 100644 --- a/src/openrct2/drawing/Image.cpp +++ b/src/openrct2/drawing/Image.cpp @@ -7,14 +7,14 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include -#include +#include "../OpenRCT2.h" #include "../core/Console.hpp" #include "../core/Guard.hpp" -#include "../OpenRCT2.h" - #include "Drawing.h" +#include +#include + constexpr uint32_t BASE_IMAGE_ID = 29294; constexpr uint32_t MAX_IMAGES = 262144; constexpr uint32_t INVALID_IMAGE_ID = UINT32_MAX; @@ -25,9 +25,9 @@ struct ImageList uint32_t Count; }; -static bool _initialised = false; +static bool _initialised = false; static std::list _freeLists; -static uint32_t _allocatedImageCount; +static uint32_t _allocatedImageCount; #ifdef DEBUG static std::list _allocatedLists; @@ -40,13 +40,10 @@ static std::list _allocatedLists; [[maybe_unused]] static bool AllocatedListContains(uint32_t baseImageId, uint32_t count) { - bool contains = std::any_of( - _allocatedLists.begin(), - _allocatedLists.end(), - [baseImageId, count](const ImageList &imageList) -> bool - { - return imageList.BaseId == baseImageId && imageList.Count == count; - }); + bool contains + = std::any_of(_allocatedLists.begin(), _allocatedLists.end(), [baseImageId, count](const ImageList& imageList) -> bool { + return imageList.BaseId == baseImageId && imageList.Count == count; + }); return contains; } @@ -55,10 +52,7 @@ static std::list _allocatedLists; static bool AllocatedListRemove(uint32_t baseImageId, uint32_t count) { auto foundItem = std::find_if( - _allocatedLists.begin(), - _allocatedLists.end(), - [baseImageId, count](const ImageList &imageList) -> bool - { + _allocatedLists.begin(), _allocatedLists.end(), [baseImageId, count](const ImageList& imageList) -> bool { return imageList.BaseId == baseImageId && imageList.Count == count; }); if (foundItem != _allocatedLists.end()) @@ -93,11 +87,7 @@ static void InitialiseImageList() */ static void MergeFreeLists() { - _freeLists.sort( - [](const ImageList &a, const ImageList &b) -> bool - { - return a.BaseId < b.BaseId; - }); + _freeLists.sort([](const ImageList& a, const ImageList& b) -> bool { return a.BaseId < b.BaseId; }); for (auto it = _freeLists.begin(); it != _freeLists.end(); it++) { bool mergeHappened; @@ -129,8 +119,7 @@ static uint32_t TryAllocateImageList(uint32_t count) _freeLists.erase(it); if (imageList.Count > count) { - ImageList remainder = { imageList.BaseId + count, - imageList.Count - count }; + ImageList remainder = { imageList.BaseId + count, imageList.Count - count }; _freeLists.push_back(remainder); } @@ -197,7 +186,7 @@ static void FreeImageList(uint32_t baseImageId, uint32_t count) _freeLists.push_back({ baseImageId, count }); } -uint32_t gfx_object_allocate_images(const rct_g1_element * images, uint32_t count) +uint32_t gfx_object_allocate_images(const rct_g1_element* images, uint32_t count) { if (count == 0 || gOpenRCT2NoGraphics) { @@ -251,4 +240,3 @@ void gfx_object_check_all_images_freed() #endif } } - diff --git a/src/openrct2/drawing/ImageImporter.cpp b/src/openrct2/drawing/ImageImporter.cpp index c780373136..3b0bdb3679 100644 --- a/src/openrct2/drawing/ImageImporter.cpp +++ b/src/openrct2/drawing/ImageImporter.cpp @@ -7,23 +7,21 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "ImageImporter.h" + +#include "../core/Imaging.h" + #include #include #include -#include "../core/Imaging.h" -#include "ImageImporter.h" using namespace OpenRCT2::Drawing; using ImportResult = ImageImporter::ImportResult; constexpr int32_t PALETTE_TRANSPARENT = -1; -ImportResult ImageImporter::Import( - const Image& image, - int32_t offsetX, - int32_t offsetY, - IMPORT_FLAGS flags, - IMPORT_MODE mode) const +ImportResult + ImageImporter::Import(const Image& image, int32_t offsetX, int32_t offsetY, IMPORT_FLAGS flags, IMPORT_MODE mode) const { if (image.Width > 256 || image.Height > 256) { @@ -39,12 +37,11 @@ ImportResult ImageImporter::Import( const auto height = image.Height; auto pixels = GetPixels(image.Pixels.data(), width, height, flags, mode); - auto [buffer, bufferLength] = flags & IMPORT_FLAGS::RLE ? - EncodeRLE(pixels.data(), width, height) : - EncodeRaw(pixels.data(), width, height); + auto [buffer, bufferLength] + = flags & IMPORT_FLAGS::RLE ? EncodeRLE(pixels.data(), width, height) : EncodeRaw(pixels.data(), width, height); rct_g1_element outElement; - outElement.offset = (uint8_t *)buffer; + outElement.offset = (uint8_t*)buffer; outElement.width = width; outElement.height = height; outElement.flags = (flags & IMPORT_FLAGS::RLE ? G1_FLAG_RLE_COMPRESSION : G1_FLAG_BMP); @@ -59,7 +56,8 @@ ImportResult ImageImporter::Import( return result; } -std::vector ImageImporter::GetPixels(const uint8_t * pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode) +std::vector + ImageImporter::GetPixels(const uint8_t* pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode) { std::vector buffer; buffer.reserve(width * height); @@ -110,10 +108,10 @@ std::vector ImageImporter::GetPixels(const uint8_t * pixels, uint32_t w return buffer; } -std::tuple ImageImporter::EncodeRaw(const int32_t * pixels, uint32_t width, uint32_t height) +std::tuple ImageImporter::EncodeRaw(const int32_t* pixels, uint32_t width, uint32_t height) { auto bufferLength = width * height; - auto buffer = (uint8_t *)std::malloc(bufferLength); + auto buffer = (uint8_t*)std::malloc(bufferLength); for (size_t i = 0; i < bufferLength; i++) { auto p = pixels[i]; @@ -122,7 +120,7 @@ std::tuple ImageImporter::EncodeRaw(const int32_t * pixels, uint return std::make_tuple(buffer, bufferLength); } -std::tuple ImageImporter::EncodeRLE(const int32_t * pixels, uint32_t width, uint32_t height) +std::tuple ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t width, uint32_t height) { struct RLECode { @@ -131,21 +129,21 @@ std::tuple ImageImporter::EncodeRLE(const int32_t * pixels, uint }; auto src = pixels; - auto buffer = (uint8_t *)std::malloc((height * 2) + (width * height * 16)); + auto buffer = (uint8_t*)std::malloc((height * 2) + (width * height * 16)); if (buffer == nullptr) { throw std::bad_alloc(); } std::memset(buffer, 0, (height * 2) + (width * height * 16)); - auto yOffsets = (uint16_t *)buffer; + auto yOffsets = (uint16_t*)buffer; auto dst = buffer + (height * 2); for (uint32_t y = 0; y < height; y++) { yOffsets[y] = (uint16_t)(dst - buffer); - auto previousCode = (RLECode *)nullptr; - auto currentCode = (RLECode *)dst; + auto previousCode = (RLECode*)nullptr; + auto currentCode = (RLECode*)dst; dst += 2; auto startX = 0; @@ -191,7 +189,7 @@ std::tuple ImageImporter::EncodeRLE(const int32_t * pixels, uint currentCode->NumPixels |= 0x80; } - currentCode = (RLECode *)dst; + currentCode = (RLECode*)dst; dst += 2; } else @@ -216,7 +214,7 @@ std::tuple ImageImporter::EncodeRLE(const int32_t * pixels, uint } auto bufferLength = (size_t)(dst - buffer); - buffer = (uint8_t * )realloc(buffer, bufferLength); + buffer = (uint8_t*)realloc(buffer, bufferLength); if (buffer == nullptr) { throw std::bad_alloc(); @@ -224,7 +222,8 @@ std::tuple ImageImporter::EncodeRLE(const int32_t * pixels, uint return std::make_tuple(buffer, bufferLength); } -int32_t ImageImporter::CalculatePaletteIndex(IMPORT_MODE mode, int16_t * rgbaSrc, int32_t x, int32_t y, int32_t width, int32_t height) +int32_t ImageImporter::CalculatePaletteIndex( + IMPORT_MODE mode, int16_t* rgbaSrc, int32_t x, int32_t y, int32_t width, int32_t height) { auto palette = StandardPalette; auto paletteIndex = GetPaletteIndex(palette, rgbaSrc); @@ -258,7 +257,8 @@ int32_t ImageImporter::CalculatePaletteIndex(IMPORT_MODE mode, int16_t * rgbaSrc { if (x > 0) { - if (!IsTransparentPixel(rgbaSrc + 4 * (width - 1)) && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * (width - 1)))) + if (!IsTransparentPixel(rgbaSrc + 4 * (width - 1)) + && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * (width - 1)))) { // Bottom left rgbaSrc[4 * (width - 1)] += dr * 3 / 16; @@ -277,7 +277,8 @@ int32_t ImageImporter::CalculatePaletteIndex(IMPORT_MODE mode, int16_t * rgbaSrc if (x + 1 < width) { - if (!IsTransparentPixel(rgbaSrc + 4 * (width + 1)) && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * (width + 1)))) + if (!IsTransparentPixel(rgbaSrc + 4 * (width + 1)) + && IsChangablePixel(GetPaletteIndex(palette, rgbaSrc + 4 * (width + 1)))) { // Bottom right rgbaSrc[4 * (width + 1)] += dr * 1 / 16; @@ -291,15 +292,14 @@ int32_t ImageImporter::CalculatePaletteIndex(IMPORT_MODE mode, int16_t * rgbaSrc return paletteIndex; } -int32_t ImageImporter::GetPaletteIndex(const PaletteBGRA * palette, int16_t * colour) +int32_t ImageImporter::GetPaletteIndex(const PaletteBGRA* palette, int16_t* colour) { if (!IsTransparentPixel(colour)) { for (int32_t i = 0; i < 256; i++) { - if ((int16_t)(palette[i].Red) == colour[0] && - (int16_t)(palette[i].Green) == colour[1] && - (int16_t)(palette[i].Blue) == colour[2]) + if ((int16_t)(palette[i].Red) == colour[0] && (int16_t)(palette[i].Green) == colour[1] + && (int16_t)(palette[i].Blue) == colour[2]) { return i; } @@ -308,7 +308,7 @@ int32_t ImageImporter::GetPaletteIndex(const PaletteBGRA * palette, int16_t * co return PALETTE_TRANSPARENT; } -bool ImageImporter::IsTransparentPixel(const int16_t * colour) +bool ImageImporter::IsTransparentPixel(const int16_t* colour) { return colour[3] < 128; } @@ -333,7 +333,7 @@ bool ImageImporter::IsChangablePixel(int32_t paletteIndex) return true; } -int32_t ImageImporter::GetClosestPaletteIndex(const PaletteBGRA * palette, const int16_t * colour) +int32_t ImageImporter::GetClosestPaletteIndex(const PaletteBGRA* palette, const int16_t* colour) { auto smallestError = (uint32_t)-1; auto bestMatch = PALETTE_TRANSPARENT; @@ -341,10 +341,9 @@ int32_t ImageImporter::GetClosestPaletteIndex(const PaletteBGRA * palette, const { if (IsChangablePixel(x)) { - uint32_t error = - ((int16_t)(palette[x].Red) - colour[0]) * ((int16_t)(palette[x].Red) - colour[0]) + - ((int16_t)(palette[x].Green) - colour[1]) * ((int16_t)(palette[x].Green) - colour[1]) + - ((int16_t)(palette[x].Blue) - colour[2]) * ((int16_t)(palette[x].Blue) - colour[2]); + uint32_t error = ((int16_t)(palette[x].Red) - colour[0]) * ((int16_t)(palette[x].Red) - colour[0]) + + ((int16_t)(palette[x].Green) - colour[1]) * ((int16_t)(palette[x].Green) - colour[1]) + + ((int16_t)(palette[x].Blue) - colour[2]) * ((int16_t)(palette[x].Blue) - colour[2]); if (smallestError == (uint32_t)-1 || smallestError > error) { @@ -356,8 +355,7 @@ int32_t ImageImporter::GetClosestPaletteIndex(const PaletteBGRA * palette, const return bestMatch; } -const PaletteBGRA ImageImporter::StandardPalette[256] = -{ +const PaletteBGRA ImageImporter::StandardPalette[256] = { // 0 (unused) { 0, 0, 0, 255 }, diff --git a/src/openrct2/drawing/ImageImporter.h b/src/openrct2/drawing/ImageImporter.h index 9eb30011d7..070e419acc 100644 --- a/src/openrct2/drawing/ImageImporter.h +++ b/src/openrct2/drawing/ImageImporter.h @@ -7,11 +7,12 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include -#include #include "../core/Imaging.h" #include "Drawing.h" +#include +#include + struct Image; namespace OpenRCT2::Drawing @@ -25,7 +26,7 @@ namespace OpenRCT2::Drawing struct ImportResult { rct_g1_element Element{}; - void * Buffer{}; + void* Buffer{}; size_t BufferLength{}; }; @@ -53,14 +54,16 @@ namespace OpenRCT2::Drawing private: static const PaletteBGRA StandardPalette[256]; - static std::vector GetPixels(const uint8_t * pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode); - static std::tuple EncodeRaw(const int32_t * pixels, uint32_t width, uint32_t height); - static std::tuple EncodeRLE(const int32_t * pixels, uint32_t width, uint32_t height); + static std::vector + GetPixels(const uint8_t* pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode); + static std::tuple EncodeRaw(const int32_t* pixels, uint32_t width, uint32_t height); + static std::tuple EncodeRLE(const int32_t* pixels, uint32_t width, uint32_t height); - static int32_t CalculatePaletteIndex(IMPORT_MODE mode, int16_t * rgbaSrc, int32_t x, int32_t y, int32_t width, int32_t height); - static int32_t GetPaletteIndex(const PaletteBGRA * palette, int16_t * colour); - static bool IsTransparentPixel(const int16_t * colour); + static int32_t + CalculatePaletteIndex(IMPORT_MODE mode, int16_t* rgbaSrc, int32_t x, int32_t y, int32_t width, int32_t height); + static int32_t GetPaletteIndex(const PaletteBGRA* palette, int16_t* colour); + static bool IsTransparentPixel(const int16_t* colour); static bool IsChangablePixel(int32_t paletteIndex); - static int32_t GetClosestPaletteIndex(const PaletteBGRA * palette, const int16_t * colour); + static int32_t GetClosestPaletteIndex(const PaletteBGRA* palette, const int16_t* colour); }; -} +} // namespace OpenRCT2::Drawing diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index de797f951e..90c0b3fe8e 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -9,12 +9,11 @@ #ifdef __ENABLE_LIGHTFX__ -#include -#include -#include +#include "LightFX.h" + +#include "../Game.h" #include "../common.h" #include "../config/Config.h" -#include "../Game.h" #include "../interface/Viewport.h" #include "../interface/Window.h" #include "../ride/Ride.h" @@ -23,57 +22,62 @@ #include "../world/Map.h" #include "../world/Sprite.h" #include "Drawing.h" -#include "LightFX.h" -static uint8_t _bakedLightTexture_lantern_0[32*32]; -static uint8_t _bakedLightTexture_lantern_1[64*64]; -static uint8_t _bakedLightTexture_lantern_2[128*128]; -static uint8_t _bakedLightTexture_lantern_3[256*256]; +#include +#include +#include + +static uint8_t _bakedLightTexture_lantern_0[32 * 32]; +static uint8_t _bakedLightTexture_lantern_1[64 * 64]; +static uint8_t _bakedLightTexture_lantern_2[128 * 128]; +static uint8_t _bakedLightTexture_lantern_3[256 * 256]; static uint8_t _bakedLightTexture_spot_0[32 * 32]; static uint8_t _bakedLightTexture_spot_1[64 * 64]; static uint8_t _bakedLightTexture_spot_2[128 * 128]; static uint8_t _bakedLightTexture_spot_3[256 * 256]; -static rct_drawpixelinfo _pixelInfo; +static rct_drawpixelinfo _pixelInfo; static bool _lightfxAvailable = false; static void* _light_rendered_buffer_back = nullptr; static void* _light_rendered_buffer_front = nullptr; -static uint32_t _lightPolution_back = 0; -static uint32_t _lightPolution_front = 0; +static uint32_t _lightPolution_back = 0; +static uint32_t _lightPolution_front = 0; -struct lightlist_entry { - int16_t x, y, z; - uint8_t lightType; - uint8_t lightIntensity; - uint32_t lightID; - uint16_t lightIDqualifier; - uint8_t lightLinger; - uint8_t pad[1]; +struct lightlist_entry +{ + int16_t x, y, z; + uint8_t lightType; + uint8_t lightIntensity; + uint32_t lightID; + uint16_t lightIDqualifier; + uint8_t lightLinger; + uint8_t pad[1]; }; -static lightlist_entry _LightListA[16000]; -static lightlist_entry _LightListB[16000]; +static lightlist_entry _LightListA[16000]; +static lightlist_entry _LightListB[16000]; -static lightlist_entry *_LightListBack; -static lightlist_entry *_LightListFront; +static lightlist_entry* _LightListBack; +static lightlist_entry* _LightListFront; -static uint32_t LightListCurrentCountBack; -static uint32_t LightListCurrentCountFront; +static uint32_t LightListCurrentCountBack; +static uint32_t LightListCurrentCountFront; -static int16_t _current_view_x_front = 0; -static int16_t _current_view_y_front = 0; -static uint8_t _current_view_rotation_front = 0; -static uint8_t _current_view_zoom_front = 0; -static int16_t _current_view_x_back = 0; -static int16_t _current_view_y_back = 0; -static uint8_t _current_view_rotation_back = 0; -static uint8_t _current_view_zoom_back = 0; -static uint8_t _current_view_zoom_back_delay = 0; +static int16_t _current_view_x_front = 0; +static int16_t _current_view_y_front = 0; +static uint8_t _current_view_rotation_front = 0; +static uint8_t _current_view_zoom_front = 0; +static int16_t _current_view_x_back = 0; +static int16_t _current_view_y_back = 0; +static uint8_t _current_view_rotation_back = 0; +static uint8_t _current_view_zoom_back = 0; +static uint8_t _current_view_zoom_back_delay = 0; static rct_palette gPalette_light; -static uint8_t calc_light_intensity_lantern(int32_t x, int32_t y) { +static uint8_t calc_light_intensity_lantern(int32_t x, int32_t y) +{ double distance = (double)(x * x + y * y); double light = 0.03 + std::pow(10.0 / (1.0 + distance / 100.0), 0.55); @@ -83,7 +87,8 @@ static uint8_t calc_light_intensity_lantern(int32_t x, int32_t y) { return (uint8_t)(std::min(255.0, light * 255.0)); } -static uint8_t calc_light_intensity_spot(int32_t x, int32_t y) { +static uint8_t calc_light_intensity_spot(int32_t x, int32_t y) +{ double distance = (double)(x * x + y * y); double light = 0.3 + std::pow(10.0 / (1.0 + distance / 100.0), 0.75); @@ -93,12 +98,15 @@ static uint8_t calc_light_intensity_spot(int32_t x, int32_t y) { return (uint8_t)(std::min(255.0, light * 255.0)) >> 4; } -static void calc_rescale_light_half( uint8_t *target, uint8_t *source,uint32_t targetWidth, uint32_t targetHeight) { - uint8_t *parcerRead = source; - uint8_t *parcerWrite = target; +static void calc_rescale_light_half(uint8_t* target, uint8_t* source, uint32_t targetWidth, uint32_t targetHeight) +{ + uint8_t* parcerRead = source; + uint8_t* parcerWrite = target; - for (uint32_t y = 0; y < targetHeight; y++) { - for (uint32_t x = 0; x < targetWidth; x++) { + for (uint32_t y = 0; y < targetHeight; y++) + { + for (uint32_t x = 0; x < targetWidth; x++) + { *parcerWrite = (*parcerRead); parcerWrite++; parcerRead += 2; @@ -119,18 +127,20 @@ bool lightfx_is_available() void lightfx_init() { - _LightListBack = _LightListA; - _LightListFront = _LightListB; + _LightListBack = _LightListA; + _LightListFront = _LightListB; memset(_bakedLightTexture_lantern_0, 0xFF, 32 * 32); memset(_bakedLightTexture_lantern_1, 0xFF, 64 * 64); memset(_bakedLightTexture_lantern_2, 0xFF, 128 * 128); memset(_bakedLightTexture_lantern_3, 0xFF, 256 * 256); - uint8_t *parcer = _bakedLightTexture_lantern_3; + uint8_t* parcer = _bakedLightTexture_lantern_3; - for (int32_t y = 0; y < 256; y++) { - for (int32_t x = 0; x < 256; x++) { + for (int32_t y = 0; y < 256; y++) + { + for (int32_t x = 0; x < 256; x++) + { *parcer = calc_light_intensity_lantern(x - 128, y - 128); parcer++; } @@ -138,8 +148,10 @@ void lightfx_init() parcer = _bakedLightTexture_spot_3; - for (int32_t y = 0; y < 256; y++) { - for (int32_t x = 0; x < 256; x++) { + for (int32_t y = 0; y < 256; y++) + { + for (int32_t x = 0; x < 256; x++) + { *parcer = calc_light_intensity_spot(x - 128, y - 128); parcer++; } @@ -154,10 +166,10 @@ void lightfx_init() calc_rescale_light_half(_bakedLightTexture_spot_0, _bakedLightTexture_spot_1, 32, 32); } -void lightfx_update_buffers(rct_drawpixelinfo *info) +void lightfx_update_buffers(rct_drawpixelinfo* info) { - _light_rendered_buffer_front = realloc(_light_rendered_buffer_front, info->width * info->height); - _light_rendered_buffer_back = realloc(_light_rendered_buffer_back, info->width * info->height); + _light_rendered_buffer_front = realloc(_light_rendered_buffer_front, info->width * info->height); + _light_rendered_buffer_back = realloc(_light_rendered_buffer_back, info->width * info->height); memcpy(&_pixelInfo, info, sizeof(rct_drawpixelinfo)); } @@ -166,24 +178,24 @@ extern void viewport_paint_setup(); void lightfx_prepare_light_list() { - for (uint32_t light = 0; light < LightListCurrentCountFront; light++) { - lightlist_entry *entry = &_LightListFront[light]; + for (uint32_t light = 0; light < LightListCurrentCountFront; light++) + { + lightlist_entry* entry = &_LightListFront[light]; - if (entry->z == 0x7FFF) { + if (entry->z == 0x7FFF) + { entry->lightIntensity = 0xFF; continue; } - LocationXYZ16 coord_3d = { - /* .x = */ entry->x, - /* .y = */ entry->y, - /* .z = */ entry->z - }; + LocationXYZ16 coord_3d = { /* .x = */ entry->x, + /* .y = */ entry->y, + /* .z = */ entry->z }; LocationXY16 coord_2d = coordinate_3d_to_2d(&coord_3d, _current_view_rotation_front); - entry->x = coord_2d.x;// - (_current_view_x_front); - entry->y = coord_2d.y;// - (_current_view_y_front); + entry->x = coord_2d.x; // - (_current_view_x_front); + entry->y = coord_2d.y; // - (_current_view_y_front); int32_t posOnScreenX = entry->x - _current_view_x_front; int32_t posOnScreenY = entry->y - _current_view_y_front; @@ -191,94 +203,99 @@ void lightfx_prepare_light_list() posOnScreenX >>= _current_view_zoom_front; posOnScreenY >>= _current_view_zoom_front; - if ((posOnScreenX < -128) || - (posOnScreenY < -128) || - (posOnScreenX > _pixelInfo.width + 128) || - (posOnScreenY > _pixelInfo.height + 128)) { + if ((posOnScreenX < -128) || (posOnScreenY < -128) || (posOnScreenX > _pixelInfo.width + 128) + || (posOnScreenY > _pixelInfo.height + 128)) + { entry->lightType = LIGHTFX_LIGHT_TYPE_NONE; continue; } - - // entry->x >>= _current_view_zoom_front; - // entry->y >>= _current_view_zoom_front; + // entry->x >>= _current_view_zoom_front; + // entry->y >>= _current_view_zoom_front; uint32_t lightIntensityOccluded = 0x0; int32_t dirVecX = 707; int32_t dirVecY = 707; - switch (_current_view_rotation_front) { - case 0: - dirVecX = 707; - dirVecY = 707; - break; - case 1: - dirVecX = -707; - dirVecY = 707; - break; - case 2: - dirVecX = -707; - dirVecY = -707; - break; - case 3: - dirVecX = 707; - dirVecY = -707; - break; - default: - dirVecX = 0; - dirVecY = 0; - break; + switch (_current_view_rotation_front) + { + case 0: + dirVecX = 707; + dirVecY = 707; + break; + case 1: + dirVecX = -707; + dirVecY = 707; + break; + case 2: + dirVecX = -707; + dirVecY = -707; + break; + case 3: + dirVecX = 707; + dirVecY = -707; + break; + default: + dirVecX = 0; + dirVecY = 0; + break; } #ifdef LIGHTFX_UNKNOWN_PART_1 int32_t tileOffsetX = 0; int32_t tileOffsetY = 0; - switch (_current_view_rotation_front) { - case 0: - tileOffsetX = 0; - tileOffsetY = 0; - break; - case 1: - tileOffsetX = 16; - tileOffsetY = 0; - break; - case 2: - tileOffsetX = 32; - tileOffsetY = 32; - break; - case 3: - tileOffsetX = 0; - tileOffsetY = 16; - break; + switch (_current_view_rotation_front) + { + case 0: + tileOffsetX = 0; + tileOffsetY = 0; + break; + case 1: + tileOffsetX = 16; + tileOffsetY = 0; + break; + case 2: + tileOffsetX = 32; + tileOffsetY = 32; + break; + case 3: + tileOffsetX = 0; + tileOffsetY = 16; + break; } int32_t mapFrontDiv = 1 << _current_view_zoom_front; - static int16_t offsetPattern[26] = { 0, 0, -4, 0, 0, -3, 4, 0, 0, 3, - -2, -1, -1, -1, 2, 1, 1, 1, - -3, -2, -3, 2, 3, -2, 3, 2 }; -#endif //LIGHTFX_UNKNOWN_PART_1 + static int16_t offsetPattern[26] + = { 0, 0, -4, 0, 0, -3, 4, 0, 0, 3, -2, -1, -1, -1, 2, 1, 1, 1, -3, -2, -3, 2, 3, -2, 3, 2 }; +#endif // LIGHTFX_UNKNOWN_PART_1 - if (true) { + if (true) + { int32_t totalSamplePoints = 5; int32_t startSamplePoint = 1; // int32_t lastSampleCount = 0; - if ((entry->lightIDqualifier & 0xF) == LIGHTFX_LIGHT_QUALIFIER_MAP) { + if ((entry->lightIDqualifier & 0xF) == LIGHTFX_LIGHT_QUALIFIER_MAP) + { startSamplePoint = 0; totalSamplePoints = 1; } - for (int32_t pat = startSamplePoint; pat < totalSamplePoints; pat++) { + for (int32_t pat = startSamplePoint; pat < totalSamplePoints; pat++) + { LocationXY16 mapCoord = {}; - rct_tile_element *tileElement = nullptr; + rct_tile_element* tileElement = nullptr; int32_t interactionType = 0; - rct_window *w = window_get_main(); - if (w != nullptr) { - // get_map_coordinates_from_pos(entry->x + offsetPattern[pat*2] / mapFrontDiv, entry->y + offsetPattern[pat*2+1] / mapFrontDiv, VIEWPORT_INTERACTION_MASK_NONE, &mapCoord.x, &mapCoord.y, &interactionType, &tileElement, NULL); + rct_window* w = window_get_main(); + if (w != nullptr) + { + // get_map_coordinates_from_pos(entry->x + offsetPattern[pat*2] / mapFrontDiv, entry->y + + // offsetPattern[pat*2+1] / mapFrontDiv, VIEWPORT_INTERACTION_MASK_NONE, &mapCoord.x, &mapCoord.y, + // &interactionType, &tileElement, NULL); #ifdef LIGHTFX_UNKNOWN_PART_1 _unk9AC154 = ~VIEWPORT_INTERACTION_MASK_SPRITE & 0xFFFF; @@ -298,19 +315,20 @@ void lightfx_prepare_light_list() paint_session_arrange(gPaintSession); sub_68862C(); - // log_warning("[%i, %i]", dpi->x, dpi->y); + // log_warning("[%i, %i]", dpi->x, dpi->y); mapCoord.x = _interactionMapX + tileOffsetX; mapCoord.y = _interactionMapY + tileOffsetY; interactionType = _interactionSpriteType; tileElement = RCT2_GLOBAL(0x9AC150, rct_tile_element*); -#endif //LIGHTFX_UNKNOWN_PART_1 +#endif // LIGHTFX_UNKNOWN_PART_1 - //RCT2_GLOBAL(0x9AC154, uint16_t) = VIEWPORT_INTERACTION_MASK_NONE; - //RCT2_GLOBAL(0x9AC148, uint8_t) = 0; - //RCT2_GLOBAL(0x9AC138 + 4, int16_t) = screenX; - //RCT2_GLOBAL(0x9AC138 + 6, int16_t) = screenY; - //if (screenX >= 0 && screenX < (int32_t)myviewport->width && screenY >= 0 && screenY < (int32_t)myviewport->height) + // RCT2_GLOBAL(0x9AC154, uint16_t) = VIEWPORT_INTERACTION_MASK_NONE; + // RCT2_GLOBAL(0x9AC148, uint8_t) = 0; + // RCT2_GLOBAL(0x9AC138 + 4, int16_t) = screenX; + // RCT2_GLOBAL(0x9AC138 + 6, int16_t) = screenY; + // if (screenX >= 0 && screenX < (int32_t)myviewport->width && screenY >= 0 && screenY < + // (int32_t)myviewport->height) //{ // screenX <<= myviewport->zoom; // screenY <<= myviewport->zoom; @@ -339,7 +357,8 @@ void lightfx_prepare_light_list() int32_t minDist = 0; int32_t baseHeight = -999; - if (interactionType != VIEWPORT_INTERACTION_ITEM_SPRITE && tileElement) { + if (interactionType != VIEWPORT_INTERACTION_ITEM_SPRITE && tileElement) + { baseHeight = tileElement->base_height; } @@ -352,33 +371,38 @@ void lightfx_prepare_light_list() projDot = std::max(minDist, projDot); - if (projDot < 5) { - lightIntensityOccluded += 100; + if (projDot < 5) + { + lightIntensityOccluded += 100; } - else { - lightIntensityOccluded += std::max(0, 200 - (projDot * 20)); + else + { + lightIntensityOccluded += std::max(0, 200 - (projDot * 20)); } - // log_warning("light %i [%i, %i, %i], [%i, %i] minDist to %i: %i; projdot: %i", light, coord_3d.x, coord_3d.y, coord_3d.z, mapCoord.x, mapCoord.y, baseHeight, minDist, projDot); + // log_warning("light %i [%i, %i, %i], [%i, %i] minDist to %i: %i; projdot: %i", light, coord_3d.x, coord_3d.y, + // coord_3d.z, mapCoord.x, mapCoord.y, baseHeight, minDist, projDot); - - if (pat == 0) { + if (pat == 0) + { if (lightIntensityOccluded == 100) break; if (_current_view_zoom_front > 2) break; totalSamplePoints += 4; } - else if (pat == 4) { + else if (pat == 4) + { if (_current_view_zoom_front > 1) break; if (lightIntensityOccluded == 0 || lightIntensityOccluded == 500) break; // lastSampleCount = lightIntensityOccluded / 500; - // break; + // break; totalSamplePoints += 4; } - else if (pat == 8) { + else if (pat == 8) + { break; // if (_current_view_zoom_front > 0) // break; @@ -391,23 +415,27 @@ void lightfx_prepare_light_list() totalSamplePoints -= startSamplePoint; - // lightIntensityOccluded = totalSamplePoints * 100; + // lightIntensityOccluded = totalSamplePoints * 100; - // log_warning("sample-count: %i, occlusion: %i", totalSamplePoints, lightIntensityOccluded); + // log_warning("sample-count: %i, occlusion: %i", totalSamplePoints, lightIntensityOccluded); - if (lightIntensityOccluded == 0) { + if (lightIntensityOccluded == 0) + { entry->lightType = LIGHTFX_LIGHT_TYPE_NONE; continue; } - // log_warning("sample-count: %i, occlusion: %i", totalSamplePoints, lightIntensityOccluded / totalSamplePoints); + // log_warning("sample-count: %i, occlusion: %i", totalSamplePoints, lightIntensityOccluded / totalSamplePoints); - entry->lightIntensity = std::min(0xFF, (entry->lightIntensity * lightIntensityOccluded) / (totalSamplePoints * 100)); + entry->lightIntensity + = std::min(0xFF, (entry->lightIntensity * lightIntensityOccluded) / (totalSamplePoints * 100)); entry->lightIntensity = std::max(0x00, entry->lightIntensity - _current_view_zoom_front * 5); } - if (_current_view_zoom_front > 0) { - if ((entry->lightType & 0x3) < _current_view_zoom_front) { + if (_current_view_zoom_front > 0) + { + if ((entry->lightType & 0x3) < _current_view_zoom_front) + { entry->lightType = LIGHTFX_LIGHT_TYPE_NONE; continue; } @@ -419,7 +447,7 @@ void lightfx_prepare_light_list() void lightfx_swap_buffers() { - void *tmp = _light_rendered_buffer_back; + void* tmp = _light_rendered_buffer_back; _light_rendered_buffer_back = _light_rendered_buffer_front; _light_rendered_buffer_front = tmp; @@ -429,7 +457,7 @@ void lightfx_swap_buffers() tmp = _LightListBack; _LightListBack = _LightListFront; - _LightListFront = (lightlist_entry *)tmp; + _LightListFront = (lightlist_entry*)tmp; LightListCurrentCountFront = LightListCurrentCountBack; LightListCurrentCountBack = 0x0; @@ -447,9 +475,10 @@ void lightfx_swap_buffers() void lightfx_update_viewport_settings() { - rct_window *mainWindow = window_get_main(); - if (mainWindow) { - rct_viewport * viewport = window_get_viewport(mainWindow); + rct_window* mainWindow = window_get_main(); + if (mainWindow) + { + rct_viewport* viewport = window_get_viewport(mainWindow); _current_view_x_back = viewport->view_x; _current_view_y_back = viewport->view_y; _current_view_rotation_back = get_current_rotation(); @@ -459,7 +488,8 @@ void lightfx_update_viewport_settings() void lightfx_render_lights_to_frontbuffer() { - if (_light_rendered_buffer_front == nullptr) { + if (_light_rendered_buffer_front == nullptr) + { return; } @@ -467,48 +497,51 @@ void lightfx_render_lights_to_frontbuffer() _lightPolution_back = 0; -// log_warning("%i lights", LightListCurrentCountFront); + // log_warning("%i lights", LightListCurrentCountFront); - for (uint32_t light = 0; light < LightListCurrentCountFront; light++) { - const uint8_t *bufReadBase = nullptr; - uint8_t *bufWriteBase = (uint8_t *)_light_rendered_buffer_front; - uint32_t bufReadWidth, bufReadHeight; - int32_t bufWriteX, bufWriteY; - int32_t bufWriteWidth, bufWriteHeight; - uint32_t bufReadSkip, bufWriteSkip; + for (uint32_t light = 0; light < LightListCurrentCountFront; light++) + { + const uint8_t* bufReadBase = nullptr; + uint8_t* bufWriteBase = (uint8_t*)_light_rendered_buffer_front; + uint32_t bufReadWidth, bufReadHeight; + int32_t bufWriteX, bufWriteY; + int32_t bufWriteWidth, bufWriteHeight; + uint32_t bufReadSkip, bufWriteSkip; - lightlist_entry * entry = &_LightListFront[light]; + lightlist_entry* entry = &_LightListFront[light]; - int32_t inRectCentreX = entry->x; - int32_t inRectCentreY = entry->y; + int32_t inRectCentreX = entry->x; + int32_t inRectCentreY = entry->y; - if (entry->z != 0x7FFF) { + if (entry->z != 0x7FFF) + { inRectCentreX -= _current_view_x_front; inRectCentreY -= _current_view_y_front; inRectCentreX >>= _current_view_zoom_front; inRectCentreY >>= _current_view_zoom_front; } - switch (entry->lightType) { + switch (entry->lightType) + { case LIGHTFX_LIGHT_TYPE_LANTERN_0: - bufReadWidth = 32; - bufReadHeight = 32; - bufReadBase = _bakedLightTexture_lantern_0; + bufReadWidth = 32; + bufReadHeight = 32; + bufReadBase = _bakedLightTexture_lantern_0; break; case LIGHTFX_LIGHT_TYPE_LANTERN_1: - bufReadWidth = 64; - bufReadHeight = 64; - bufReadBase = _bakedLightTexture_lantern_1; + bufReadWidth = 64; + bufReadHeight = 64; + bufReadBase = _bakedLightTexture_lantern_1; break; case LIGHTFX_LIGHT_TYPE_LANTERN_2: - bufReadWidth = 128; - bufReadHeight = 128; - bufReadBase = _bakedLightTexture_lantern_2; + bufReadWidth = 128; + bufReadHeight = 128; + bufReadBase = _bakedLightTexture_lantern_2; break; case LIGHTFX_LIGHT_TYPE_LANTERN_3: - bufReadWidth = 256; - bufReadHeight = 256; - bufReadBase = _bakedLightTexture_lantern_3; + bufReadWidth = 256; + bufReadHeight = 256; + bufReadBase = _bakedLightTexture_lantern_3; break; case LIGHTFX_LIGHT_TYPE_SPOT_0: bufReadWidth = 32; @@ -534,42 +567,47 @@ void lightfx_render_lights_to_frontbuffer() continue; } - bufWriteX = inRectCentreX - bufReadWidth / 2; - bufWriteY = inRectCentreY - bufReadHeight / 2; + bufWriteX = inRectCentreX - bufReadWidth / 2; + bufWriteY = inRectCentreY - bufReadHeight / 2; - bufWriteWidth = bufReadWidth; - bufWriteHeight = bufReadHeight; + bufWriteWidth = bufReadWidth; + bufWriteHeight = bufReadHeight; - if (bufWriteX < 0) { - bufReadBase += -bufWriteX; - bufWriteWidth += bufWriteX; + if (bufWriteX < 0) + { + bufReadBase += -bufWriteX; + bufWriteWidth += bufWriteX; } - else { - bufWriteBase += bufWriteX; + else + { + bufWriteBase += bufWriteX; } if (bufWriteWidth <= 0) continue; - if (bufWriteY < 0) { - bufReadBase += -bufWriteY * bufReadWidth; - bufWriteHeight += bufWriteY; + if (bufWriteY < 0) + { + bufReadBase += -bufWriteY * bufReadWidth; + bufWriteHeight += bufWriteY; } - else { - bufWriteBase += bufWriteY * _pixelInfo.width; + else + { + bufWriteBase += bufWriteY * _pixelInfo.width; } - if (bufWriteHeight <= 0) continue; - int32_t rightEdge = bufWriteX + bufWriteWidth; - int32_t bottomEdge = bufWriteY + bufWriteHeight; + int32_t rightEdge = bufWriteX + bufWriteWidth; + int32_t bottomEdge = bufWriteY + bufWriteHeight; - if (rightEdge > _pixelInfo.width) { + if (rightEdge > _pixelInfo.width) + { bufWriteWidth -= rightEdge - _pixelInfo.width; } - if (bottomEdge > _pixelInfo.height) { + if (bottomEdge > _pixelInfo.height) + { bufWriteHeight -= bottomEdge - _pixelInfo.height; } @@ -580,24 +618,30 @@ void lightfx_render_lights_to_frontbuffer() _lightPolution_back += (bufWriteWidth * bufWriteHeight) / 256; - bufReadSkip = bufReadWidth - bufWriteWidth; - bufWriteSkip = _pixelInfo.width - bufWriteWidth; + bufReadSkip = bufReadWidth - bufWriteWidth; + bufWriteSkip = _pixelInfo.width - bufWriteWidth; - if (entry->lightIntensity == 0xFF) { - for (int32_t y = 0; y < bufWriteHeight; y++) { - for (int32_t x = 0; x < bufWriteWidth; x++) { + if (entry->lightIntensity == 0xFF) + { + for (int32_t y = 0; y < bufWriteHeight; y++) + { + for (int32_t x = 0; x < bufWriteWidth; x++) + { *bufWriteBase = std::min(0xFF, *bufWriteBase + *bufReadBase); bufWriteBase++; bufReadBase++; } - bufWriteBase += bufWriteSkip; - bufReadBase += bufReadSkip; + bufWriteBase += bufWriteSkip; + bufReadBase += bufReadSkip; } } - else { - for (int32_t y = 0; y < bufWriteHeight; y++) { - for (int32_t x = 0; x < bufWriteWidth; x++) { + else + { + for (int32_t y = 0; y < bufWriteHeight; y++) + { + for (int32_t x = 0; x < bufWriteWidth; x++) + { *bufWriteBase = std::min(0xFF, *bufWriteBase + (((*bufReadBase) * (1 + entry->lightIntensity)) >> 8)); bufWriteBase++; bufReadBase++; @@ -615,21 +659,23 @@ void* lightfx_get_front_buffer() return _light_rendered_buffer_front; } -const rct_palette * lightfx_get_palette() +const rct_palette* lightfx_get_palette() { return &gPalette_light; } void lightfx_add_3d_light(uint32_t lightID, uint16_t lightIDqualifier, int16_t x, int16_t y, uint16_t z, uint8_t lightType) { - if (LightListCurrentCountBack == 15999) { + if (LightListCurrentCountBack == 15999) + { return; } -// log_warning("%i lights in back", LightListCurrentCountBack); + // log_warning("%i lights in back", LightListCurrentCountBack); - for (uint32_t i = 0; i < LightListCurrentCountBack; i++) { - lightlist_entry *entry = &_LightListBack[i]; + for (uint32_t i = 0; i < LightListCurrentCountBack; i++) + { + lightlist_entry* entry = &_LightListBack[i]; if (entry->lightID != lightID) continue; if (entry->lightIDqualifier != lightIDqualifier) @@ -647,44 +693,46 @@ void lightfx_add_3d_light(uint32_t lightID, uint16_t lightIDqualifier, int16_t x return; } - lightlist_entry *entry = &_LightListBack[LightListCurrentCountBack++]; + lightlist_entry* entry = &_LightListBack[LightListCurrentCountBack++]; - entry->x = x; - entry->y = y; - entry->z = z; - entry->lightType = lightType; - entry->lightIntensity = 0xFF; - entry->lightID = lightID; + entry->x = x; + entry->y = y; + entry->z = z; + entry->lightType = lightType; + entry->lightIntensity = 0xFF; + entry->lightID = lightID; entry->lightIDqualifier = lightIDqualifier; - entry->lightLinger = 1; + entry->lightLinger = 1; -// log_warning("new 3d light"); + // log_warning("new 3d light"); } -void lightfx_add_3d_light_magic_from_drawing_tile(LocationXY16 mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, uint8_t lightType) +void lightfx_add_3d_light_magic_from_drawing_tile( + LocationXY16 mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, uint8_t lightType) { int16_t x = mapPosition.x + offsetX; int16_t y = mapPosition.y + offsetY; - switch (get_current_rotation()) { - case 0: - x += 16; - y += 16; - break; - case 1: - x += 16; - y += 16; - break; - case 2: - x += 16; - y -= 16; - break; - case 3: - x += 16; - y -= 16; - break; - default: - return; + switch (get_current_rotation()) + { + case 0: + x += 16; + y += 16; + break; + case 1: + x += 16; + y += 16; + break; + case 2: + x += 16; + y -= 16; + break; + case 3: + x += 16; + y -= 16; + break; + default: + return; } lightfx_add_3d_light((x << 16) | y, (offsetZ << 8) | LIGHTFX_LIGHT_QUALIFIER_MAP, x, y, offsetZ, lightType); @@ -698,18 +746,21 @@ uint32_t lightfx_get_light_polution() void lightfx_add_lights_magic_vehicles() { uint16_t spriteIndex = gSpriteListHead[SPRITE_LIST_TRAIN]; - while (spriteIndex != SPRITE_INDEX_NULL) { - rct_vehicle * vehicle = &(get_sprite(spriteIndex)->vehicle); + while (spriteIndex != SPRITE_INDEX_NULL) + { + rct_vehicle* vehicle = &(get_sprite(spriteIndex)->vehicle); uint16_t vehicleID = spriteIndex; spriteIndex = vehicle->next; - rct_vehicle *mother_vehicle = vehicle; + rct_vehicle* mother_vehicle = vehicle; - if (mother_vehicle->ride_subtype == RIDE_ENTRY_INDEX_NULL) { + if (mother_vehicle->ride_subtype == RIDE_ENTRY_INDEX_NULL) + { continue; } - for (uint16_t q = vehicleID; q != SPRITE_INDEX_NULL; ) { + for (uint16_t q = vehicleID; q != SPRITE_INDEX_NULL;) + { vehicle = GET_VEHICLE(q); vehicleID = q; @@ -723,92 +774,197 @@ void lightfx_add_lights_magic_vehicles() place_y = vehicle->y; place_z = vehicle->z; - static constexpr const int16_t offsetLookup[32] = { 10, 10, 9, 8, 7, 6, 4, 2, 0, -2, -4, -6, -7, -8, -9, -10, -10, -10, -9, -8, -7, -6, -4, -2, 0, 2, 4, 6, 7, 8, 9, 10 }; + static constexpr const int16_t offsetLookup[32] + = { 10, 10, 9, 8, 7, 6, 4, 2, 0, -2, -4, -6, -7, -8, -9, -10, + -10, -10, -9, -8, -7, -6, -4, -2, 0, 2, 4, 6, 7, 8, 9, 10 }; - Ride *ride = get_ride(vehicle->ride); - switch (ride->type) { - case RIDE_TYPE_OBSERVATION_TOWER: - lightfx_add_3d_light(vehicleID, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, vehicle->x, vehicle->y + 16, vehicle->z, LIGHTFX_LIGHT_TYPE_SPOT_3); - lightfx_add_3d_light(vehicleID, 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, vehicle->x + 16, vehicle->y, vehicle->z, LIGHTFX_LIGHT_TYPE_SPOT_3); - lightfx_add_3d_light(vehicleID, 0x0200 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, vehicle->x - 16, vehicle->y, vehicle->z, LIGHTFX_LIGHT_TYPE_SPOT_3); - lightfx_add_3d_light(vehicleID, 0x0300 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, vehicle->x, vehicle->y - 16, vehicle->z, LIGHTFX_LIGHT_TYPE_SPOT_3); - break; - case RIDE_TYPE_MINE_TRAIN_COASTER: - case RIDE_TYPE_GHOST_TRAIN: - if (vehicle == vehicle_get_head(vehicle)) { - place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; - place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; - lightfx_add_3d_light(vehicleID, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z, LIGHTFX_LIGHT_TYPE_SPOT_3); + Ride* ride = get_ride(vehicle->ride); + switch (ride->type) + { + case RIDE_TYPE_OBSERVATION_TOWER: + lightfx_add_3d_light( + vehicleID, + 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + vehicle->x, + vehicle->y + 16, + vehicle->z, + LIGHTFX_LIGHT_TYPE_SPOT_3); + lightfx_add_3d_light( + vehicleID, + 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + vehicle->x + 16, + vehicle->y, + vehicle->z, + LIGHTFX_LIGHT_TYPE_SPOT_3); + lightfx_add_3d_light( + vehicleID, + 0x0200 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + vehicle->x - 16, + vehicle->y, + vehicle->z, + LIGHTFX_LIGHT_TYPE_SPOT_3); + lightfx_add_3d_light( + vehicleID, + 0x0300 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + vehicle->x, + vehicle->y - 16, + vehicle->z, + LIGHTFX_LIGHT_TYPE_SPOT_3); + break; + case RIDE_TYPE_MINE_TRAIN_COASTER: + case RIDE_TYPE_GHOST_TRAIN: + if (vehicle == vehicle_get_head(vehicle)) + { + place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; + place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; + lightfx_add_3d_light( + vehicleID, + 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z, + LIGHTFX_LIGHT_TYPE_SPOT_3); + } + break; + case RIDE_TYPE_CHAIRLIFT: + lightfx_add_3d_light( + vehicleID, + 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z - 16, + LIGHTFX_LIGHT_TYPE_LANTERN_2); + break; + case RIDE_TYPE_BOAT_HIRE: + case RIDE_TYPE_CAR_RIDE: + case RIDE_TYPE_GO_KARTS: + case RIDE_TYPE_DODGEMS: + case RIDE_TYPE_MINI_HELICOPTERS: + case RIDE_TYPE_MONORAIL_CYCLES: + case RIDE_TYPE_SUBMARINE_RIDE: + case RIDE_TYPE_SPLASH_BOATS: + case RIDE_TYPE_WATER_COASTER: + { + rct_vehicle* vehicle_draw = vehicle_get_head(vehicle); + if (vehicle_draw->next_vehicle_on_train != SPRITE_INDEX_NULL) + { + vehicle_draw = GET_VEHICLE(vehicle_draw->next_vehicle_on_train); + } + place_x = vehicle_draw->x; + place_y = vehicle_draw->y; + place_z = vehicle_draw->z; + place_x -= offsetLookup[(vehicle_draw->sprite_direction + 0) % 32]; + place_y -= offsetLookup[(vehicle_draw->sprite_direction + 8) % 32]; + lightfx_add_3d_light( + vehicleID, + 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z, + LIGHTFX_LIGHT_TYPE_SPOT_2); + place_x -= offsetLookup[(vehicle_draw->sprite_direction + 0) % 32]; + place_y -= offsetLookup[(vehicle_draw->sprite_direction + 8) % 32]; + lightfx_add_3d_light( + vehicleID, + 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z, + LIGHTFX_LIGHT_TYPE_SPOT_2); + break; } - break; - case RIDE_TYPE_CHAIRLIFT: - lightfx_add_3d_light(vehicleID, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z - 16, LIGHTFX_LIGHT_TYPE_LANTERN_2); - break; - case RIDE_TYPE_BOAT_HIRE: - case RIDE_TYPE_CAR_RIDE: - case RIDE_TYPE_GO_KARTS: - case RIDE_TYPE_DODGEMS: - case RIDE_TYPE_MINI_HELICOPTERS: - case RIDE_TYPE_MONORAIL_CYCLES: - case RIDE_TYPE_SUBMARINE_RIDE: - case RIDE_TYPE_SPLASH_BOATS: - case RIDE_TYPE_WATER_COASTER: { - rct_vehicle *vehicle_draw = vehicle_get_head(vehicle); - if (vehicle_draw->next_vehicle_on_train != SPRITE_INDEX_NULL) { - vehicle_draw = GET_VEHICLE(vehicle_draw->next_vehicle_on_train); - } - place_x = vehicle_draw->x; - place_y = vehicle_draw->y; - place_z = vehicle_draw->z; - place_x -= offsetLookup[(vehicle_draw->sprite_direction + 0) % 32]; - place_y -= offsetLookup[(vehicle_draw->sprite_direction + 8) % 32]; - lightfx_add_3d_light(vehicleID, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z, LIGHTFX_LIGHT_TYPE_SPOT_2); - place_x -= offsetLookup[(vehicle_draw->sprite_direction + 0) % 32]; - place_y -= offsetLookup[(vehicle_draw->sprite_direction + 8) % 32]; - lightfx_add_3d_light(vehicleID, 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z, LIGHTFX_LIGHT_TYPE_SPOT_2); - break; - } - case RIDE_TYPE_MONORAIL: - lightfx_add_3d_light(vehicleID, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, vehicle->x, vehicle->y, vehicle->z + 12, LIGHTFX_LIGHT_TYPE_SPOT_2); - if (vehicle == vehicle_get_head(vehicle)) { - place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; - place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; - lightfx_add_3d_light(vehicleID, 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 10, LIGHTFX_LIGHT_TYPE_LANTERN_3); - place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 3; - place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 3; - lightfx_add_3d_light(vehicleID, 0x0200 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 2, LIGHTFX_LIGHT_TYPE_LANTERN_3); - } - if (vehicle == vehicle_get_tail(vehicle)) { - place_x += offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; - place_y += offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; - lightfx_add_3d_light(vehicleID, 0x0300 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 10, LIGHTFX_LIGHT_TYPE_LANTERN_3); - place_x += offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; - place_y += offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; - lightfx_add_3d_light(vehicleID, 0x0400 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 2, LIGHTFX_LIGHT_TYPE_LANTERN_3); - } - break; - case RIDE_TYPE_MINIATURE_RAILWAY: - if (vehicle == vehicle_get_head(vehicle)) { - place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; - place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; - lightfx_add_3d_light(vehicleID, 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 10, LIGHTFX_LIGHT_TYPE_LANTERN_3); - place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; - place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; - lightfx_add_3d_light(vehicleID, 0x0200 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 2, LIGHTFX_LIGHT_TYPE_LANTERN_3); - - } - else { - lightfx_add_3d_light(vehicleID, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, place_x, place_y, place_z + 10, LIGHTFX_LIGHT_TYPE_LANTERN_3); - } - break; - default: - break; + case RIDE_TYPE_MONORAIL: + lightfx_add_3d_light( + vehicleID, + 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + vehicle->x, + vehicle->y, + vehicle->z + 12, + LIGHTFX_LIGHT_TYPE_SPOT_2); + if (vehicle == vehicle_get_head(vehicle)) + { + place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; + place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; + lightfx_add_3d_light( + vehicleID, + 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 10, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 3; + place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 3; + lightfx_add_3d_light( + vehicleID, + 0x0200 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 2, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + } + if (vehicle == vehicle_get_tail(vehicle)) + { + place_x += offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; + place_y += offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; + lightfx_add_3d_light( + vehicleID, + 0x0300 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 10, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + place_x += offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; + place_y += offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; + lightfx_add_3d_light( + vehicleID, + 0x0400 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 2, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + } + break; + case RIDE_TYPE_MINIATURE_RAILWAY: + if (vehicle == vehicle_get_head(vehicle)) + { + place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; + place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; + lightfx_add_3d_light( + vehicleID, + 0x0100 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 10, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + place_x -= offsetLookup[(vehicle->sprite_direction + 0) % 32] * 2; + place_y -= offsetLookup[(vehicle->sprite_direction + 8) % 32] * 2; + lightfx_add_3d_light( + vehicleID, + 0x0200 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 2, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + } + else + { + lightfx_add_3d_light( + vehicleID, + 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, + place_x, + place_y, + place_z + 10, + LIGHTFX_LIGHT_TYPE_LANTERN_3); + } + break; + default: + break; }; } } } -void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) +void lightfx_apply_palette_filter(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b) { float night = (float)(pow(gDayNightCycle, 1.5)); @@ -828,8 +984,8 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) // Night version natLightR = flerp(natLightR * 4.0f, 0.635f, (float)(std::pow(night, 0.035f + sunLight * 10.50f))); - natLightG = flerp(natLightG * 4.0f, 0.650f, (float)(std::pow(night, 0.100f + sunLight * 5.50f))); - natLightB = flerp(natLightB * 4.0f, 0.850f, (float)(std::pow(night, 0.200f + sunLight * 1.5f))); + natLightG = flerp(natLightG * 4.0f, 0.650f, (float)(std::pow(night, 0.100f + sunLight * 5.50f))); + natLightB = flerp(natLightB * 4.0f, 0.850f, (float)(std::pow(night, 0.200f + sunLight * 1.5f))); float overExpose = 0.0f; float lightAvg = (natLightR + natLightG + natLightB) / 3.0f; @@ -839,7 +995,8 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) // overExpose += ((lightMax - lightAvg) / lightMax) * 0.01f; - if (gClimateCurrent.Temperature > 20) { + if (gClimateCurrent.Temperature > 20) + { float offset = ((float)(gClimateCurrent.Temperature - 20)) * 0.04f; offset *= 1.0f - night; lightAvg /= 1.0f + offset; @@ -850,7 +1007,8 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) lightAvg += (lightMax - lightAvg) * 0.6f; #endif // LIGHTFX_UNKNOWN_PART_2 - if (lightAvg > 1.0f) { + if (lightAvg > 1.0f) + { natLightR /= lightAvg; natLightG /= lightAvg; natLightB /= lightAvg; @@ -864,7 +1022,8 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) float targetFogginess = (float)(gClimateCurrent.RainLevel) / 8.0f; targetFogginess += (night * night) * 0.15f; - if (gClimateCurrent.Temperature < 10) { + if (gClimateCurrent.Temperature < 10) + { targetFogginess += ((float)(10 - gClimateCurrent.Temperature)) * 0.01f; } @@ -887,7 +1046,7 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) reduceColourLit *= night / (float)std::pow(std::max(1.01f, 0.4f + lightAvg), 2.0); - float targetLightPollution = reduceColourLit * std::max(0.0f, 0.0f + 0.000001f * (float)lightfx_get_light_polution()); + float targetLightPollution = reduceColourLit * std::max(0.0f, 0.0f + 0.000001f * (float)lightfx_get_light_polution()); lightPolution -= (lightPolution - targetLightPollution) * 0.001f; // lightPollution /= 1.0f + fogginess * 1.0f; @@ -917,9 +1076,10 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) float fogB = 50.0f * natLightB * 1.3f; lightFog *= 10.0f; - float wetnessBoost = 1.0f;//1.0f + wetness * wetness * 0.1f; + float wetnessBoost = 1.0f; // 1.0f + wetness * wetness * 0.1f; - if (night >= 0 && gClimateLightningFlash != 1) { + if (night >= 0 && gClimateLightningFlash != 1) + { *r = lerp(*r, soft_light(*r, 8), night); *g = lerp(*g, soft_light(*g, 8), night); *b = lerp(*b, soft_light(*b, 128), night); @@ -933,9 +1093,11 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) if (i > 230 && i < 232) boost = ((float)(*b)) / 64.0f; - if (false) { + if (false) + { // This experiment shifts the colour of pixels as-if they are wet, but it is not a pretty solution at all - if ((i % 16)) { + if ((i % 16)) + { float iVal = ((float)((i + 12) % 16)) / 16.0f; float eff = (wetness * ((float)std::pow(iVal, 1.5) * 0.85f)); reduceColourNat *= 1.0f - eff; @@ -949,11 +1111,14 @@ void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b) addLightNatG *= 1.0f - envFog; addLightNatB *= 1.0f - envFog; - *r = (uint8_t)(std::min(255.0f, std::max(0.0f, (-overExpose + (float)(*r) * reduceColourNat * natLightR + envFog * fogR + addLightNatR)))); - *g = (uint8_t)(std::min(255.0f, std::max(0.0f, (-overExpose + (float)(*g) * reduceColourNat * natLightG + envFog * fogG + addLightNatG)))); - *b = (uint8_t)(std::min(255.0f, std::max(0.0f, (-overExpose + (float)(*b) * reduceColourNat * natLightB + envFog * fogB + addLightNatB)))); + *r = (uint8_t)(std::min( + 255.0f, std::max(0.0f, (-overExpose + (float)(*r) * reduceColourNat * natLightR + envFog * fogR + addLightNatR)))); + *g = (uint8_t)(std::min( + 255.0f, std::max(0.0f, (-overExpose + (float)(*g) * reduceColourNat * natLightG + envFog * fogG + addLightNatG)))); + *b = (uint8_t)(std::min( + 255.0f, std::max(0.0f, (-overExpose + (float)(*b) * reduceColourNat * natLightB + envFog * fogB + addLightNatB)))); - rct_palette_entry * dstEntry = &gPalette_light.entries[i]; + rct_palette_entry* dstEntry = &gPalette_light.entries[i]; dstEntry->red = (uint8_t)(std::min(0xFF, ((float)(*r) * reduceColourLit * boost + lightFog) * elecMultR)); dstEntry->green = (uint8_t)(std::min(0xFF, ((float)(*g) * reduceColourLit * boost + lightFog) * elecMultG)); dstEntry->blue = (uint8_t)(std::min(0xFF, ((float)(*b) * reduceColourLit * boost + lightFog) * elecMultB)); @@ -970,37 +1135,43 @@ static uint8_t mix_light(uint32_t a, uint32_t b, uint32_t intensity) } void lightfx_render_to_texture( - void * dstPixels, + void* dstPixels, uint32_t dstPitch, - uint8_t * bits, + uint8_t* bits, uint32_t width, uint32_t height, - const uint32_t * palette, - const uint32_t * lightPalette) + const uint32_t* palette, + const uint32_t* lightPalette) { lightfx_update_viewport_settings(); lightfx_swap_buffers(); lightfx_prepare_light_list(); lightfx_render_lights_to_frontbuffer(); - uint8_t * lightBits = (uint8_t *)lightfx_get_front_buffer(); - if (lightBits == nullptr) { + uint8_t* lightBits = (uint8_t*)lightfx_get_front_buffer(); + if (lightBits == nullptr) + { return; } - for (uint32_t y = 0; y < height; y++) { + for (uint32_t y = 0; y < height; y++) + { uintptr_t dstOffset = (uintptr_t)(y * dstPitch); - uint32_t * dst = (uint32_t *)((uintptr_t)dstPixels + dstOffset); - for (uint32_t x = 0; x < width; x++) { - uint8_t * src = &bits[y * width + x]; + uint32_t* dst = (uint32_t*)((uintptr_t)dstPixels + dstOffset); + for (uint32_t x = 0; x < width; x++) + { + uint8_t* src = &bits[y * width + x]; uint32_t darkColour = palette[*src]; uint32_t lightColour = lightPalette[*src]; uint8_t lightIntensity = lightBits[y * width + x]; uint32_t colour = 0; - if (lightIntensity == 0) { + if (lightIntensity == 0) + { colour = darkColour; - } else { + } + else + { colour |= mix_light((darkColour >> 0) & 0xFF, (lightColour >> 0) & 0xFF, lightIntensity); colour |= mix_light((darkColour >> 8) & 0xFF, (lightColour >> 8) & 0xFF, lightIntensity) << 8; colour |= mix_light((darkColour >> 16) & 0xFF, (lightColour >> 16) & 0xFF, lightIntensity) << 16; diff --git a/src/openrct2/drawing/LightFX.h b/src/openrct2/drawing/LightFX.h index ec46d807bc..2fb5b25829 100644 --- a/src/openrct2/drawing/LightFX.h +++ b/src/openrct2/drawing/LightFX.h @@ -18,26 +18,28 @@ struct LocationXY16; struct rct_drawpixelinfo; struct rct_palette; -enum LIGHTFX_LIGHT_TYPE { - LIGHTFX_LIGHT_TYPE_NONE = 0, - LIGHTFX_LIGHT_TYPE_RESERVED_01 = 1, +enum LIGHTFX_LIGHT_TYPE +{ + LIGHTFX_LIGHT_TYPE_NONE = 0, + LIGHTFX_LIGHT_TYPE_RESERVED_01 = 1, - LIGHTFX_LIGHT_TYPE_LANTERN_0 = 4, - LIGHTFX_LIGHT_TYPE_LANTERN_1 = 5, - LIGHTFX_LIGHT_TYPE_LANTERN_2 = 6, - LIGHTFX_LIGHT_TYPE_LANTERN_3 = 7, + LIGHTFX_LIGHT_TYPE_LANTERN_0 = 4, + LIGHTFX_LIGHT_TYPE_LANTERN_1 = 5, + LIGHTFX_LIGHT_TYPE_LANTERN_2 = 6, + LIGHTFX_LIGHT_TYPE_LANTERN_3 = 7, - LIGHTFX_LIGHT_TYPE_SPOT_0 = 8, - LIGHTFX_LIGHT_TYPE_SPOT_1 = 9, - LIGHTFX_LIGHT_TYPE_SPOT_2 = 10, - LIGHTFX_LIGHT_TYPE_SPOT_3 = 11, + LIGHTFX_LIGHT_TYPE_SPOT_0 = 8, + LIGHTFX_LIGHT_TYPE_SPOT_1 = 9, + LIGHTFX_LIGHT_TYPE_SPOT_2 = 10, + LIGHTFX_LIGHT_TYPE_SPOT_3 = 11, - LIGHTFX_LIGHT_TYPE_RESERVED_FF = 0xFF + LIGHTFX_LIGHT_TYPE_RESERVED_FF = 0xFF }; -enum LIGHTFX_LIGHT_QUALIFIER { - LIGHTFX_LIGHT_QUALIFIER_SPRITE = 0x1, - LIGHTFX_LIGHT_QUALIFIER_MAP = 0x2 +enum LIGHTFX_LIGHT_QUALIFIER +{ + LIGHTFX_LIGHT_QUALIFIER_SPRITE = 0x1, + LIGHTFX_LIGHT_QUALIFIER_MAP = 0x2 }; void lightfx_set_available(bool available); @@ -53,25 +55,26 @@ void lightfx_render_lights_to_frontbuffer(); void lightfx_update_viewport_settings(); void* lightfx_get_front_buffer(); -const rct_palette * lightfx_get_palette(); +const rct_palette* lightfx_get_palette(); void lightfx_add_3d_light(uint32_t lightID, uint16_t lightIDqualifier, int16_t x, int16_t y, uint16_t z, uint8_t lightType); -void lightfx_add_3d_light_magic_from_drawing_tile(LocationXY16 mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, uint8_t lightType); +void lightfx_add_3d_light_magic_from_drawing_tile( + LocationXY16 mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, uint8_t lightType); void lightfx_add_lights_magic_vehicles(); uint32_t lightfx_get_light_polution(); -void lightfx_apply_palette_filter(uint8_t i, uint8_t *r, uint8_t *g, uint8_t *b); +void lightfx_apply_palette_filter(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b); void lightfx_render_to_texture( - void * dstPixels, + void* dstPixels, uint32_t dstPitch, - uint8_t * bits, + uint8_t* bits, uint32_t width, uint32_t height, - const uint32_t * palette, - const uint32_t * lightPalette); + const uint32_t* palette, + const uint32_t* lightPalette); #endif // __ENABLE_LIGHTFX__ diff --git a/src/openrct2/drawing/Line.cpp b/src/openrct2/drawing/Line.cpp index 0e710486d2..43e3d17f2b 100644 --- a/src/openrct2/drawing/Line.cpp +++ b/src/openrct2/drawing/Line.cpp @@ -7,49 +7,57 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "Drawing.h" + #include #include -#include "Drawing.h" - /** * Draws a horizontal line of specified colour to a buffer. * rct2: 0x0068474C */ -static void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int32_t y, int32_t x, int32_t no_pixels) +static void gfx_draw_line_on_buffer(rct_drawpixelinfo* dpi, char colour, int32_t y, int32_t x, int32_t no_pixels) { y -= dpi->y; // Check to make sure point is in the y range - if (y < 0)return; - if (y >= dpi->height)return; + if (y < 0) + return; + if (y >= dpi->height) + return; // Check to make sure we are drawing at least a pixel - if (!no_pixels) no_pixels++; + if (!no_pixels) + no_pixels++; x -= dpi->x; // If x coord outside range leave - if (x < 0){ + if (x < 0) + { // Unless the number of pixels is enough to be in range no_pixels += x; - if (no_pixels <= 0)return; + if (no_pixels <= 0) + return; // Resets starting point to 0 as we don't draw outside the range x = 0; } // Ensure that the end point of the line is within range - if (x + no_pixels - dpi->width > 0){ + if (x + no_pixels - dpi->width > 0) + { // If the end point has any pixels outside range // cut them off. If there are now no pixels return. no_pixels -= x + no_pixels - dpi->width; - if (no_pixels <= 0)return; + if (no_pixels <= 0) + return; } // Get the buffer we are drawing to and move to the first coordinate. - uint8_t* bits_pointer = dpi->bits + y*(dpi->pitch + dpi->width) + x; + uint8_t* bits_pointer = dpi->bits + y * (dpi->pitch + dpi->width) + x; // Draw the line to the specified colour - for (; no_pixels > 0; --no_pixels, ++bits_pointer){ + for (; no_pixels > 0; --no_pixels, ++bits_pointer) + { *bits_pointer = colour; } } @@ -64,22 +72,26 @@ static void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int32_t * y2 (dx) * colour (ebp) */ -void gfx_draw_line_software(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour) +void gfx_draw_line_software(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour) { // Check to make sure the line is within the drawing area - if ((x1 < dpi->x) && (x2 < dpi->x)){ + if ((x1 < dpi->x) && (x2 < dpi->x)) + { return; } - if ((y1 < dpi->y) && (y2 < dpi->y)){ + if ((y1 < dpi->y) && (y2 < dpi->y)) + { return; } - if ((x1 >(dpi->x + dpi->width)) && (x2 >(dpi->x + dpi->width))){ + if ((x1 > (dpi->x + dpi->width)) && (x2 > (dpi->x + dpi->width))) + { return; } - if ((y1 > (dpi->y + dpi->height)) && (y2 > (dpi->y + dpi->height))){ + if ((y1 > (dpi->y + dpi->height)) && (y2 > (dpi->y + dpi->height))) + { return; } @@ -87,7 +99,8 @@ void gfx_draw_line_software(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int3 // If vertical plot points upwards int32_t steep = std::abs(y2 - y1) > std::abs(x2 - x1); - if (steep){ + if (steep) + { int32_t temp_y2 = y2; int32_t temp_x2 = x2; y2 = x1; @@ -97,7 +110,8 @@ void gfx_draw_line_software(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int3 } // If line is right to left swap direction - if (x1 > x2){ + if (x1 > x2) + { int32_t temp_y2 = y2; int32_t temp_x2 = x2; y2 = y1; @@ -113,17 +127,23 @@ void gfx_draw_line_software(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int3 int32_t y = y1; // Direction of step - if (y1 < y2)y_step = 1; - else y_step = -1; + if (y1 < y2) + y_step = 1; + else + y_step = -1; - for (int32_t x = x1, x_start = x1, no_pixels = 1; x < x2; ++x,++no_pixels){ + for (int32_t x = x1, x_start = x1, no_pixels = 1; x < x2; ++x, ++no_pixels) + { // Vertical lines are drawn 1 pixel at a time - if (steep)gfx_draw_line_on_buffer(dpi, colour, x, y, 1); + if (steep) + gfx_draw_line_on_buffer(dpi, colour, x, y, 1); error -= delta_y; - if (error < 0){ + if (error < 0) + { // Non vertical lines are drawn with as many pixels in a horizontal line as possible - if (!steep)gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels); + if (!steep) + gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels); // Reset non vertical line vars x_start = x + 1; @@ -133,7 +153,8 @@ void gfx_draw_line_software(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int3 } // Catch the case of the last line - if (x + 1 == x2 && !steep){ + if (x + 1 == x2 && !steep) + { gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels); } } diff --git a/src/openrct2/drawing/NewDrawing.cpp b/src/openrct2/drawing/NewDrawing.cpp index ea21bbaf11..020ae03531 100644 --- a/src/openrct2/drawing/NewDrawing.cpp +++ b/src/openrct2/drawing/NewDrawing.cpp @@ -7,25 +7,24 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "../Context.h" -#include "../ui/UiContext.h" -#include "../interface/Screenshot.h" -#include "../paint/Painter.h" -#include "IDrawingContext.h" -#include "IDrawingEngine.h" #include "NewDrawing.h" +#include "../Context.h" #include "../config/Config.h" #include "../drawing/Drawing.h" +#include "../interface/Screenshot.h" #include "../localisation/StringIds.h" +#include "../paint/Painter.h" +#include "../ui/UiContext.h" +#include "IDrawingContext.h" +#include "IDrawingEngine.h" using namespace OpenRCT2; using namespace OpenRCT2::Drawing; using namespace OpenRCT2::Paint; using namespace OpenRCT2::Ui; -rct_string_id DrawingEngineStringIds[] = -{ +rct_string_id DrawingEngineStringIds[] = { STR_DRAWING_ENGINE_SOFTWARE, STR_DRAWING_ENGINE_SOFTWARE_WITH_HARDWARE_DISPLAY, STR_DRAWING_ENGINE_OPENGL, @@ -37,9 +36,9 @@ int32_t drawing_engine_get_type() return context->GetDrawingEngineType(); } -static IDrawingEngine * GetDrawingEngine() +static IDrawingEngine* GetDrawingEngine() { - IDrawingEngine * result = nullptr; + IDrawingEngine* result = nullptr; auto context = GetContext(); if (context != nullptr) { @@ -85,7 +84,7 @@ void drawing_engine_resize() } } -void drawing_engine_set_palette(const rct_palette_entry * colours) +void drawing_engine_set_palette(const rct_palette_entry* colours) { auto context = GetContext(); if (context != nullptr) @@ -120,7 +119,7 @@ void drawing_engine_dispose() } } -rct_drawpixelinfo * drawing_engine_get_dpi() +rct_drawpixelinfo* drawing_engine_get_dpi() { auto context = GetContext(); auto drawingEngine = context->GetDrawingEngine(); @@ -169,82 +168,83 @@ void gfx_draw_all_dirty_blocks() { } -void gfx_clear(rct_drawpixelinfo * dpi, uint8_t paletteIndex) +void gfx_clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->Clear(paletteIndex); } } -void gfx_fill_rect(rct_drawpixelinfo * dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t colour) +void gfx_fill_rect(rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t colour) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->FillRect(colour, left, top, right, bottom); } } -void gfx_filter_rect(rct_drawpixelinfo * dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, FILTER_PALETTE_ID palette) +void gfx_filter_rect( + rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, FILTER_PALETTE_ID palette) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->FilterRect(palette, left, top, right, bottom); } } -void gfx_draw_line(rct_drawpixelinfo *dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour) +void gfx_draw_line(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->DrawLine(colour, x1, y1, x2, y2); } } -void FASTCALL gfx_draw_sprite(rct_drawpixelinfo * dpi, int32_t image, int32_t x, int32_t y, uint32_t tertiary_colour) +void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint32_t tertiary_colour) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->DrawSprite(image, x, y, tertiary_colour); } } -void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo * dpi, int32_t image, int32_t x, int32_t y, uint8_t * palette) +void FASTCALL gfx_draw_glpyh(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint8_t* palette) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->DrawGlyph(image, x, y, palette); } } -void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo * dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage) +void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t maskImage, int32_t colourImage) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->DrawSpriteRawMasked(x, y, maskImage, colourImage); } } -void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int32_t image, int32_t x, int32_t y, uint8_t colour) +void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint8_t colour) { auto drawingEngine = GetDrawingEngine(); if (drawingEngine != nullptr) { - IDrawingContext * dc = drawingEngine->GetDrawingContext(dpi); + IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi); dc->DrawSpriteSolid(image, x, y, colour); } } @@ -258,4 +258,3 @@ int32_t screenshot_dump() } return false; } - diff --git a/src/openrct2/drawing/NewDrawing.h b/src/openrct2/drawing/NewDrawing.h index 59d44458c3..fd5df91045 100644 --- a/src/openrct2/drawing/NewDrawing.h +++ b/src/openrct2/drawing/NewDrawing.h @@ -20,11 +20,11 @@ int32_t drawing_engine_get_type(); bool drawing_engine_requires_new_window(int32_t srcEngine, int32_t dstEngine); void drawing_engine_init(); void drawing_engine_resize(); -void drawing_engine_set_palette(const rct_palette_entry * colours); +void drawing_engine_set_palette(const rct_palette_entry* colours); void drawing_engine_copy_rect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy); void drawing_engine_dispose(); -rct_drawpixelinfo * drawing_engine_get_dpi(); +rct_drawpixelinfo* drawing_engine_get_dpi(); bool drawing_engine_has_dirty_optimisations(); void drawing_engine_invalidate_image(uint32_t image); void drawing_engine_set_vsync(bool vsync); diff --git a/src/openrct2/drawing/Rain.cpp b/src/openrct2/drawing/Rain.cpp index ea40b0fe63..b3ddc67481 100644 --- a/src/openrct2/drawing/Rain.cpp +++ b/src/openrct2/drawing/Rain.cpp @@ -7,6 +7,8 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "Rain.h" + #include "../config/Config.h" #include "../interface/Viewport.h" #include "../ride/TrackDesign.h" @@ -15,36 +17,31 @@ #include "../world/Climate.h" #include "Drawing.h" #include "IDrawingEngine.h" -#include "Rain.h" using namespace OpenRCT2; using namespace OpenRCT2::Drawing; -static void DrawLightRain(IRainDrawer * rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height); -static void DrawHeavyRain(IRainDrawer * rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height); +static void DrawLightRain(IRainDrawer* rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height); +static void DrawHeavyRain(IRainDrawer* rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height); /** * * rct2: 0x009AC058 */ -const DrawRainFunc DrawRainFunctions[] = -{ - nullptr, - &DrawLightRain, - &DrawHeavyRain -}; +const DrawRainFunc DrawRainFunctions[] = { nullptr, &DrawLightRain, &DrawHeavyRain }; /** * * rct2: 0x00684218 */ -void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer) +void DrawRain(rct_drawpixelinfo* dpi, IRainDrawer* rainDrawer) { if (gConfigGeneral.render_weather_effects) { // Get rain draw function and draw rain uint32_t rainType = gClimateCurrent.RainLevel; - if (rainType != RAIN_LEVEL_NONE && !gTrackDesignSaveMode && !(gCurrentViewportFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) + if (rainType != RAIN_LEVEL_NONE && !gTrackDesignSaveMode + && !(gCurrentViewportFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) { auto drawFunc = DrawRainFunctions[rainType]; auto uiContext = GetContext()->GetUiContext(); @@ -57,7 +54,7 @@ void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer) * * rct2: 0x00684114 */ -static void DrawLightRain(IRainDrawer * rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height) +static void DrawLightRain(IRainDrawer* rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height) { int32_t x_start = -(int32_t)gScenarioTicks + 8; int32_t y_start = (gScenarioTicks * 3) + 7; @@ -78,7 +75,7 @@ static void DrawLightRain(IRainDrawer * rainDrawer, int32_t left, int32_t top, i * * rct2: 0x0068416D */ -static void DrawHeavyRain(IRainDrawer * rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height) +static void DrawHeavyRain(IRainDrawer* rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height) { int32_t x_start = -(int32_t)gScenarioTicks; int32_t y_start = gScenarioTicks * 5; diff --git a/src/openrct2/drawing/Rain.h b/src/openrct2/drawing/Rain.h index 5dc7c4c5dc..7c49446384 100644 --- a/src/openrct2/drawing/Rain.h +++ b/src/openrct2/drawing/Rain.h @@ -18,4 +18,4 @@ namespace OpenRCT2::Drawing interface IRainDrawer; } -void DrawRain(rct_drawpixelinfo * dpi, OpenRCT2::Drawing::IRainDrawer * rainDrawer); +void DrawRain(rct_drawpixelinfo* dpi, OpenRCT2::Drawing::IRainDrawer* rainDrawer); diff --git a/src/openrct2/drawing/Rect.cpp b/src/openrct2/drawing/Rect.cpp index 2268cf0158..ff0466c5c4 100644 --- a/src/openrct2/drawing/Rect.cpp +++ b/src/openrct2/drawing/Rect.cpp @@ -23,85 +23,114 @@ * colour (ebp) * flags (si) */ -void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t right, int16_t bottom, int32_t colour, uint8_t flags) +void gfx_fill_rect_inset( + rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t right, int16_t bottom, int32_t colour, uint8_t flags) { - if (colour & (COLOUR_FLAG_TRANSLUCENT | COLOUR_FLAG_8)) { + if (colour & (COLOUR_FLAG_TRANSLUCENT | COLOUR_FLAG_8)) + { translucent_window_palette palette; - if (colour & COLOUR_FLAG_8) { + if (colour & COLOUR_FLAG_8) + { // TODO: This can't be added up // palette = NOT_TRANSLUCENT(colour); assert(false); return; - } else { + } + else + { palette = TranslucentWindowPalettes[BASE_COLOUR(colour)]; } - if (flags & INSET_RECT_FLAG_BORDER_NONE) { + if (flags & INSET_RECT_FLAG_BORDER_NONE) + { gfx_filter_rect(dpi, left, top, right, bottom, palette.base); - } else if (flags & INSET_RECT_FLAG_BORDER_INSET) { + } + else if (flags & INSET_RECT_FLAG_BORDER_INSET) + { // Draw outline of box gfx_filter_rect(dpi, left, top, left, bottom, palette.highlight); gfx_filter_rect(dpi, left, top, right, top, palette.highlight); gfx_filter_rect(dpi, right, top, right, bottom, palette.shadow); gfx_filter_rect(dpi, left, bottom, right, bottom, palette.shadow); - if (!(flags & INSET_RECT_FLAG_FILL_NONE)) { - gfx_filter_rect(dpi, left+1, top+1, right-1, bottom-1, palette.base); + if (!(flags & INSET_RECT_FLAG_FILL_NONE)) + { + gfx_filter_rect(dpi, left + 1, top + 1, right - 1, bottom - 1, palette.base); } - } else { + } + else + { // Draw outline of box gfx_filter_rect(dpi, left, top, left, bottom, palette.shadow); gfx_filter_rect(dpi, left, top, right, top, palette.shadow); gfx_filter_rect(dpi, right, top, right, bottom, palette.highlight); gfx_filter_rect(dpi, left, bottom, right, bottom, palette.highlight); - if (!(flags & INSET_RECT_FLAG_FILL_NONE)) { - gfx_filter_rect(dpi, left+1, top+1, right-1, bottom-1, palette.base); + if (!(flags & INSET_RECT_FLAG_FILL_NONE)) + { + gfx_filter_rect(dpi, left + 1, top + 1, right - 1, bottom - 1, palette.base); } } - } else { + } + else + { uint8_t shadow, fill, hilight; - if (flags & INSET_RECT_FLAG_FILL_MID_LIGHT) { - shadow = ColourMapA[colour].dark; - fill = ColourMapA[colour].mid_light; + if (flags & INSET_RECT_FLAG_FILL_MID_LIGHT) + { + shadow = ColourMapA[colour].dark; + fill = ColourMapA[colour].mid_light; hilight = ColourMapA[colour].lighter; - } else { - shadow = ColourMapA[colour].mid_dark; - fill = ColourMapA[colour].light; + } + else + { + shadow = ColourMapA[colour].mid_dark; + fill = ColourMapA[colour].light; hilight = ColourMapA[colour].lighter; } - if (flags & INSET_RECT_FLAG_BORDER_NONE) { + if (flags & INSET_RECT_FLAG_BORDER_NONE) + { gfx_fill_rect(dpi, left, top, right, bottom, fill); - } else if (flags & INSET_RECT_FLAG_BORDER_INSET) { + } + else if (flags & INSET_RECT_FLAG_BORDER_INSET) + { // Draw outline of box gfx_fill_rect(dpi, left, top, left, bottom, shadow); gfx_fill_rect(dpi, left + 1, top, right, top, shadow); gfx_fill_rect(dpi, right, top + 1, right, bottom - 1, hilight); gfx_fill_rect(dpi, left + 1, bottom, right, bottom, hilight); - if (!(flags & INSET_RECT_FLAG_FILL_NONE)) { - if (!(flags & INSET_RECT_FLAG_FILL_DONT_LIGHTEN)) { - if (flags & INSET_RECT_FLAG_FILL_GREY) { + if (!(flags & INSET_RECT_FLAG_FILL_NONE)) + { + if (!(flags & INSET_RECT_FLAG_FILL_DONT_LIGHTEN)) + { + if (flags & INSET_RECT_FLAG_FILL_GREY) + { fill = ColourMapA[COLOUR_BLACK].light; - } else { + } + else + { fill = ColourMapA[colour].lighter; } } - gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill); + gfx_fill_rect(dpi, left + 1, top + 1, right - 1, bottom - 1, fill); } - } else { + } + else + { // Draw outline of box gfx_fill_rect(dpi, left, top, left, bottom - 1, hilight); gfx_fill_rect(dpi, left + 1, top, right - 1, top, hilight); gfx_fill_rect(dpi, right, top, right, bottom - 1, shadow); gfx_fill_rect(dpi, left, bottom, right, bottom, shadow); - if (!(flags & INSET_RECT_FLAG_FILL_NONE)) { - if (flags & INSET_RECT_FLAG_FILL_GREY) { + if (!(flags & INSET_RECT_FLAG_FILL_NONE)) + { + if (flags & INSET_RECT_FLAG_FILL_GREY) + { fill = ColourMapA[COLOUR_BLACK].light; } - gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill); + gfx_fill_rect(dpi, left + 1, top + 1, right - 1, bottom - 1, fill); } } } diff --git a/src/openrct2/drawing/SSE41Drawing.cpp b/src/openrct2/drawing/SSE41Drawing.cpp index 4ec3146573..69c2c34954 100644 --- a/src/openrct2/drawing/SSE41Drawing.cpp +++ b/src/openrct2/drawing/SSE41Drawing.cpp @@ -15,8 +15,15 @@ #include -void mask_sse4_1(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap) +void mask_sse4_1( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap) { if (width == 32) { @@ -24,29 +31,29 @@ void mask_sse4_1(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc for (int32_t yy = 0; yy < height; yy++) { int32_t colourStep = yy * (colourWrap + 32); - int32_t maskStep = yy * (maskWrap + 32); - int32_t dstStep = yy * (dstWrap + 32); + int32_t maskStep = yy * (maskWrap + 32); + int32_t dstStep = yy * (dstWrap + 32); // first half - const __m128i colour1 = _mm_lddqu_si128((const __m128i *)(colourSrc + colourStep)); - const __m128i mask1 = _mm_lddqu_si128((const __m128i *)(maskSrc + maskStep)); - const __m128i dest1 = _mm_lddqu_si128((const __m128i *)(dst + dstStep)); - const __m128i mc1 = _mm_and_si128(colour1, mask1); + const __m128i colour1 = _mm_lddqu_si128((const __m128i*)(colourSrc + colourStep)); + const __m128i mask1 = _mm_lddqu_si128((const __m128i*)(maskSrc + maskStep)); + const __m128i dest1 = _mm_lddqu_si128((const __m128i*)(dst + dstStep)); + const __m128i mc1 = _mm_and_si128(colour1, mask1); const __m128i saturate1 = _mm_cmpeq_epi8(mc1, zero128); // _mm_blendv_epi8 is SSE4.1 const __m128i blended1 = _mm_blendv_epi8(mc1, dest1, saturate1); // second half - const __m128i colour2 = _mm_lddqu_si128((const __m128i *)(colourSrc + 16 + colourStep)); - const __m128i mask2 = _mm_lddqu_si128((const __m128i *)(maskSrc + 16 + maskStep)); - const __m128i dest2 = _mm_lddqu_si128((const __m128i *)(dst + 16 + dstStep)); - const __m128i mc2 = _mm_and_si128(colour2, mask2); + const __m128i colour2 = _mm_lddqu_si128((const __m128i*)(colourSrc + 16 + colourStep)); + const __m128i mask2 = _mm_lddqu_si128((const __m128i*)(maskSrc + 16 + maskStep)); + const __m128i dest2 = _mm_lddqu_si128((const __m128i*)(dst + 16 + dstStep)); + const __m128i mc2 = _mm_and_si128(colour2, mask2); const __m128i saturate2 = _mm_cmpeq_epi8(mc2, zero128); // _mm_blendv_epi8 is SSE4.1 const __m128i blended2 = _mm_blendv_epi8(mc2, dest2, saturate2); - _mm_storeu_si128((__m128i *)(dst + dstStep), blended1); - _mm_storeu_si128((__m128i *)(dst + 16 + dstStep), blended2); + _mm_storeu_si128((__m128i*)(dst + dstStep), blended1); + _mm_storeu_si128((__m128i*)(dst + 16 + dstStep), blended2); } } else @@ -61,8 +68,15 @@ void mask_sse4_1(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc #error You have to compile this file with SSE4.1 enabled, when targetting x86! #endif -void mask_sse4_1(int32_t width, int32_t height, const uint8_t * RESTRICT maskSrc, const uint8_t * RESTRICT colourSrc, - uint8_t * RESTRICT dst, int32_t maskWrap, int32_t colourWrap, int32_t dstWrap) +void mask_sse4_1( + int32_t width, + int32_t height, + const uint8_t* RESTRICT maskSrc, + const uint8_t* RESTRICT colourSrc, + uint8_t* RESTRICT dst, + int32_t maskWrap, + int32_t colourWrap, + int32_t dstWrap) { openrct2_assert(false, "SSE 4.1 function called on a CPU that doesn't support SSE 4.1"); } diff --git a/src/openrct2/drawing/ScrollingText.cpp b/src/openrct2/drawing/ScrollingText.cpp index b0974ff116..1045eb0b12 100644 --- a/src/openrct2/drawing/ScrollingText.cpp +++ b/src/openrct2/drawing/ScrollingText.cpp @@ -7,7 +7,6 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include #include "../config/Config.h" #include "../interface/Colour.h" #include "../localisation/Localisation.h" @@ -17,16 +16,19 @@ #include "Drawing.h" #include "TTF.h" +#include + #pragma pack(push, 1) /* size: 0xA12 */ -struct rct_draw_scroll_text { - rct_string_id string_id; // 0x00 - uint32_t string_args_0; // 0x02 - uint32_t string_args_1; // 0x06 - uint16_t position; // 0x0A - uint16_t mode; // 0x0C - uint32_t id; // 0x0E - uint8_t bitmap[64 * 40]; // 0x12 +struct rct_draw_scroll_text +{ + rct_string_id string_id; // 0x00 + uint32_t string_args_0; // 0x02 + uint32_t string_args_1; // 0x06 + uint16_t position; // 0x0A + uint16_t mode; // 0x0C + uint32_t id; // 0x0E + uint8_t bitmap[64 * 40]; // 0x12 }; assert_struct_size(rct_draw_scroll_text, 0xA12); #pragma pack(pop) @@ -37,33 +39,36 @@ static rct_draw_scroll_text _drawScrollTextList[MAX_SCROLLING_TEXT_ENTRIES]; static uint8_t _characterBitmaps[FONT_SPRITE_GLYPH_COUNT + SPR_G2_GLYPH_COUNT][8]; static uint32_t _drawSCrollNextIndex = 0; -static void scrolling_text_set_bitmap_for_sprite(utf8 *text, int32_t scroll, uint8_t *bitmap, const int16_t *scrollPositionOffsets); -static void scrolling_text_set_bitmap_for_ttf(utf8 *text, int32_t scroll, uint8_t *bitmap, const int16_t *scrollPositionOffsets); +static void + scrolling_text_set_bitmap_for_sprite(utf8* text, int32_t scroll, uint8_t* bitmap, const int16_t* scrollPositionOffsets); +static void + scrolling_text_set_bitmap_for_ttf(utf8* text, int32_t scroll, uint8_t* bitmap, const int16_t* scrollPositionOffsets); void scrolling_text_initialise_bitmaps() { uint8_t drawingSurface[64]; - rct_drawpixelinfo dpi = { - /* .bits = */ (uint8_t *)&drawingSurface, - /* .x = */ 0, - /* .y = */ 0, - /* .width = */ 8, - /* .height = */ 8, - /* .pitch = */ 0, - /* .zoom_level = */ 0 - }; + rct_drawpixelinfo dpi = { /* .bits = */ (uint8_t*)&drawingSurface, + /* .x = */ 0, + /* .y = */ 0, + /* .width = */ 8, + /* .height = */ 8, + /* .pitch = */ 0, + /* .zoom_level = */ 0 }; - - for (int32_t i = 0; i < FONT_SPRITE_GLYPH_COUNT; i++) { + for (int32_t i = 0; i < FONT_SPRITE_GLYPH_COUNT; i++) + { memset(drawingSurface, 0, sizeof(drawingSurface)); gfx_draw_sprite_software(&dpi, SPR_CHAR_START + FONT_SPRITE_BASE_TINY + i, -1, 0, 0); - for (int32_t x = 0; x < 8; x++) { + for (int32_t x = 0; x < 8; x++) + { uint8_t val = 0; - for (int32_t y = 0; y < 8; y++) { + for (int32_t y = 0; y < 8; y++) + { val >>= 1; uint8_t pixel = dpi.bits[x + y * 8]; - if (pixel == 1 || (gTinyFontAntiAliased && pixel == 2)) { + if (pixel == 1 || (gTinyFontAntiAliased && pixel == 2)) + { val |= 0x80; } } @@ -91,7 +96,7 @@ void scrolling_text_initialise_bitmaps() for (int32_t i = 0; i < MAX_SCROLLING_TEXT_ENTRIES; i++) { int32_t imageId = SPR_SCROLLING_TEXT_START + i; - const rct_g1_element * g1original = gfx_get_g1_element(imageId); + const rct_g1_element* g1original = gfx_get_g1_element(imageId); if (g1original != nullptr) { rct_g1_element g1 = *g1original; @@ -109,7 +114,7 @@ void scrolling_text_initialise_bitmaps() } } -static uint8_t *font_sprite_get_codepoint_bitmap(int32_t codepoint) +static uint8_t* font_sprite_get_codepoint_bitmap(int32_t codepoint) { auto offset = font_sprite_get_codepoint_offset(codepoint); if (offset >= FONT_SPRITE_GLYPH_COUNT) @@ -122,14 +127,15 @@ static uint8_t *font_sprite_get_codepoint_bitmap(int32_t codepoint) } } - static int32_t scrolling_text_get_matching_or_oldest(rct_string_id stringId, uint16_t scroll, uint16_t scrollingMode) { uint32_t oldestId = 0xFFFFFFFF; int32_t scrollIndex = -1; - for (int32_t i = 0; i < MAX_SCROLLING_TEXT_ENTRIES; i++) { - rct_draw_scroll_text *scrollText = &_drawScrollTextList[i]; - if (oldestId >= scrollText->id) { + for (int32_t i = 0; i < MAX_SCROLLING_TEXT_ENTRIES; i++) + { + rct_draw_scroll_text* scrollText = &_drawScrollTextList[i]; + if (oldestId >= scrollText->id) + { oldestId = scrollText->id; scrollIndex = i; } @@ -138,13 +144,9 @@ static int32_t scrolling_text_get_matching_or_oldest(rct_string_id stringId, uin uint32_t stringArgs0, stringArgs1; memcpy(&stringArgs0, gCommonFormatArgs + 0, sizeof(uint32_t)); memcpy(&stringArgs1, gCommonFormatArgs + 4, sizeof(uint32_t)); - if ( - scrollText->string_id == stringId && - scrollText->string_args_0 == stringArgs0 && - scrollText->string_args_1 == stringArgs1 && - scrollText->position == scroll && - scrollText->mode == scrollingMode - ) { + if (scrollText->string_id == stringId && scrollText->string_args_0 == stringArgs0 + && scrollText->string_args_1 == stringArgs1 && scrollText->position == scroll && scrollText->mode == scrollingMode) + { scrollText->id = _drawSCrollNextIndex; return i + SPR_SCROLLING_TEXT_START; } @@ -155,25 +157,31 @@ static int32_t scrolling_text_get_matching_or_oldest(rct_string_id stringId, uin static uint8_t scrolling_text_get_colour(uint32_t character) { int32_t colour = character & 0x7F; - if (character & COLOUR_FLAG_TRANSLUCENT) { + if (character & COLOUR_FLAG_TRANSLUCENT) + { return ColourMapA[colour].light; - } else { + } + else + { return ColourMapA[colour].mid_dark; } } -static void scrolling_text_format(utf8 *dst, size_t size, rct_draw_scroll_text *scrollText) +static void scrolling_text_format(utf8* dst, size_t size, rct_draw_scroll_text* scrollText) { - if (gConfigGeneral.upper_case_banners) { + if (gConfigGeneral.upper_case_banners) + { format_string_to_upper(dst, size, scrollText->string_id, &scrollText->string_args_0); - } else { + } + else + { format_string(dst, size, scrollText->string_id, &scrollText->string_args_0); } } extern bool TempForScrollText; -#define SCROLL_POS(x, y) (((y) * 64) + (x)) +#define SCROLL_POS(x, y) (((y)*64) + (x)) // clang-format off static constexpr const int16_t _scrollpos0[] = { @@ -1445,18 +1453,20 @@ static constexpr const int16_t* _scrollPositions[MAX_SCROLLING_TEXT_MODES] = { * @param scrollingMode (bp) * @returns ebx */ -int32_t scrolling_text_setup(paint_session * session, rct_string_id stringId, uint16_t scroll, uint16_t scrollingMode) +int32_t scrolling_text_setup(paint_session* session, rct_string_id stringId, uint16_t scroll, uint16_t scrollingMode) { assert(scrollingMode < MAX_SCROLLING_TEXT_MODES); rct_drawpixelinfo* dpi = session->DPI; - if (dpi->zoom_level != 0) return SPR_SCROLLING_TEXT_DEFAULT; + if (dpi->zoom_level != 0) + return SPR_SCROLLING_TEXT_DEFAULT; _drawSCrollNextIndex++; int32_t scrollIndex = scrolling_text_get_matching_or_oldest(stringId, scroll, scrollingMode); - if (scrollIndex >= SPR_SCROLLING_TEXT_START) return scrollIndex; + if (scrollIndex >= SPR_SCROLLING_TEXT_START) + return scrollIndex; // Setup scrolling text uint32_t stringArgs0, stringArgs1; @@ -1478,9 +1488,12 @@ int32_t scrolling_text_setup(paint_session * session, rct_string_id stringId, ui const int16_t* scrollingModePositions = _scrollPositions[scrollingMode]; memset(scrollText->bitmap, 0, 320 * 8); - if (LocalisationService_UseTrueTypeFont()) { + if (LocalisationService_UseTrueTypeFont()) + { scrolling_text_set_bitmap_for_ttf(scrollString, scroll, scrollText->bitmap, scrollingModePositions); - } else { + } + else + { scrolling_text_set_bitmap_for_sprite(scrollString, scroll, scrollText->bitmap, scrollingModePositions); } @@ -1489,24 +1502,28 @@ int32_t scrolling_text_setup(paint_session * session, rct_string_id stringId, ui return imageId; } -static void scrolling_text_set_bitmap_for_sprite(utf8 *text, int32_t scroll, uint8_t *bitmap, const int16_t *scrollPositionOffsets) +static void + scrolling_text_set_bitmap_for_sprite(utf8* text, int32_t scroll, uint8_t* bitmap, const int16_t* scrollPositionOffsets) { uint8_t characterColour = scrolling_text_get_colour(gCommonFormatArgs[7]); - utf8 *ch = text; - while (true) { + utf8* ch = text; + while (true) + { uint32_t codepoint = utf8_get_next(ch, (const utf8**)&ch); // If at the end of the string loop back to the start - if (codepoint == 0) { + if (codepoint == 0) + { ch = text; continue; } // Set any change in colour - if (codepoint <= FORMAT_COLOUR_CODE_END && codepoint >= FORMAT_COLOUR_CODE_START){ + if (codepoint <= FORMAT_COLOUR_CODE_END && codepoint >= FORMAT_COLOUR_CODE_START) + { codepoint -= FORMAT_COLOUR_CODE_START; - const rct_g1_element * g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); + const rct_g1_element* g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); if (g1 != nullptr) { characterColour = g1->offset[codepoint * 4]; @@ -1515,23 +1532,30 @@ static void scrolling_text_set_bitmap_for_sprite(utf8 *text, int32_t scroll, uin } // If another type of control character ignore - if (codepoint < 32) continue; + if (codepoint < 32) + continue; int32_t characterWidth = font_sprite_get_codepoint_width(FONT_SPRITE_BASE_TINY, codepoint); - uint8_t *characterBitmap = font_sprite_get_codepoint_bitmap(codepoint); - for (; characterWidth != 0; characterWidth--, characterBitmap++) { + uint8_t* characterBitmap = font_sprite_get_codepoint_bitmap(codepoint); + for (; characterWidth != 0; characterWidth--, characterBitmap++) + { // Skip any non-displayed columns - if (scroll != 0) { + if (scroll != 0) + { scroll--; continue; } int16_t scrollPosition = *scrollPositionOffsets; - if (scrollPosition == -1) return; - if (scrollPosition > -1) { - uint8_t *dst = &bitmap[scrollPosition]; - for (uint8_t char_bitmap = *characterBitmap; char_bitmap != 0; char_bitmap >>= 1){ - if (char_bitmap & 1) *dst = characterColour; + if (scrollPosition == -1) + return; + if (scrollPosition > -1) + { + uint8_t* dst = &bitmap[scrollPosition]; + for (uint8_t char_bitmap = *characterBitmap; char_bitmap != 0; char_bitmap >>= 1) + { + if (char_bitmap & 1) + *dst = characterColour; // Jump to next row dst += 64; @@ -1542,11 +1566,12 @@ static void scrolling_text_set_bitmap_for_sprite(utf8 *text, int32_t scroll, uin } } -static void scrolling_text_set_bitmap_for_ttf(utf8 *text, int32_t scroll, uint8_t *bitmap, const int16_t *scrollPositionOffsets) +static void scrolling_text_set_bitmap_for_ttf(utf8* text, int32_t scroll, uint8_t* bitmap, const int16_t* scrollPositionOffsets) { #ifndef NO_TTF - TTFFontDescriptor *fontDesc = ttf_get_font_from_sprite_base(FONT_SPRITE_BASE_TINY); - if (fontDesc->font == nullptr) { + TTFFontDescriptor* fontDesc = ttf_get_font_from_sprite_base(FONT_SPRITE_BASE_TINY); + if (fontDesc->font == nullptr) + { scrolling_text_set_bitmap_for_sprite(text, scroll, bitmap, scrollPositionOffsets); return; } @@ -1554,38 +1579,47 @@ static void scrolling_text_set_bitmap_for_ttf(utf8 *text, int32_t scroll, uint8_ // Currently only supports one colour uint8_t colour = 0; - utf8 *dstCh = text; - utf8 *ch = text; + utf8* dstCh = text; + utf8* ch = text; int32_t codepoint; - while ((codepoint = utf8_get_next(ch, (const utf8**)&ch)) != 0) { - if (utf8_is_format_code(codepoint)) { - if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) { + while ((codepoint = utf8_get_next(ch, (const utf8**)&ch)) != 0) + { + if (utf8_is_format_code(codepoint)) + { + if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) + { colour = (uint8_t)codepoint; } - } else { + } + else + { dstCh = utf8_write_codepoint(dstCh, codepoint); } } *dstCh = 0; - if (colour == 0) { + if (colour == 0) + { colour = scrolling_text_get_colour(gCommonFormatArgs[7]); - } else { - const rct_g1_element * g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); + } + else + { + const rct_g1_element* g1 = gfx_get_g1_element(SPR_TEXT_PALETTE); if (g1 != nullptr) { colour = g1->offset[(colour - FORMAT_COLOUR_CODE_START) * 4]; } } - TTFSurface * surface = ttf_surface_cache_get_or_add(fontDesc->font, text); - if (surface == nullptr) { + TTFSurface* surface = ttf_surface_cache_get_or_add(fontDesc->font, text); + if (surface == nullptr) + { return; } int32_t pitch = surface->pitch; int32_t width = surface->w; - auto src = (const uint8_t *)surface->pixels; + auto src = (const uint8_t*)surface->pixels; // Pitch offset src += 2 * pitch; @@ -1596,7 +1630,7 @@ static void scrolling_text_set_bitmap_for_ttf(utf8 *text, int32_t scroll, uint8_ bool use_hinting = gConfigFonts.enable_hinting && fontDesc->hinting_threshold > 0; - for (int32_t x = 0; ; x++) + for (int32_t x = 0;; x++) { if (x >= width) x = 0; @@ -1610,7 +1644,7 @@ static void scrolling_text_set_bitmap_for_ttf(utf8 *text, int32_t scroll, uint8_ if (scrollPosition > -1) { - uint8_t *dst = &bitmap[scrollPosition]; + uint8_t* dst = &bitmap[scrollPosition]; for (int32_t y = min_vpos; y < max_vpos; y++) { diff --git a/src/openrct2/drawing/TTF.cpp b/src/openrct2/drawing/TTF.cpp index 95fc9d7cea..79ad45b508 100644 --- a/src/openrct2/drawing/TTF.cpp +++ b/src/openrct2/drawing/TTF.cpp @@ -15,10 +15,10 @@ #include FT_FREETYPE_H #pragma clang diagnostic pop +#include "../OpenRCT2.h" #include "../config/Config.h" #include "../localisation/Localisation.h" #include "../localisation/LocalisationService.h" -#include "../OpenRCT2.h" #include "../platform/platform.h" #include "TTF.h" @@ -29,18 +29,18 @@ static bool _ttfInitialised = false; struct ttf_cache_entry { - TTFSurface * surface; - TTF_Font * font; - utf8 * text; - uint32_t lastUseTick; + TTFSurface* surface; + TTF_Font* font; + utf8* text; + uint32_t lastUseTick; }; struct ttf_getwidth_cache_entry { - uint32_t width; - TTF_Font * font; - utf8 * text; - uint32_t lastUseTick; + uint32_t width; + TTF_Font* font; + utf8* text; + uint32_t lastUseTick; }; static ttf_cache_entry _ttfSurfaceCache[TTF_SURFACE_CACHE_SIZE] = {}; @@ -53,38 +53,42 @@ static int32_t _ttfGetWidthCacheCount = 0; static int32_t _ttfGetWidthCacheHitCount = 0; static int32_t _ttfGetWidthCacheMissCount = 0; -static TTF_Font * ttf_open_font(const utf8 * fontPath, int32_t ptSize); -static void ttf_close_font(TTF_Font * font); -static uint32_t ttf_surface_cache_hash(TTF_Font * font, const utf8 * text); -static void ttf_surface_cache_dispose(ttf_cache_entry * entry); +static TTF_Font* ttf_open_font(const utf8* fontPath, int32_t ptSize); +static void ttf_close_font(TTF_Font* font); +static uint32_t ttf_surface_cache_hash(TTF_Font* font, const utf8* text); +static void ttf_surface_cache_dispose(ttf_cache_entry* entry); static void ttf_surface_cache_dispose_all(); static void ttf_getwidth_cache_dispose_all(); -static bool ttf_get_size(TTF_Font * font, const utf8 * text, int32_t * width, int32_t * height); -static TTFSurface * ttf_render(TTF_Font * font, const utf8 * text); +static bool ttf_get_size(TTF_Font* font, const utf8* text, int32_t* width, int32_t* height); +static TTFSurface* ttf_render(TTF_Font* font, const utf8* text); bool ttf_initialise() { - if (!_ttfInitialised) { - if (TTF_Init() != 0) { + if (!_ttfInitialised) + { + if (TTF_Init() != 0) + { log_error("Couldn't initialise FreeType engine"); return false; } - for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) { - TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]); + for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) + { + TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); utf8 fontPath[MAX_PATH]; - if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) { + if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) + { log_verbose("Unable to load font '%s'", fontDesc->font_name); return false; } fontDesc->font = ttf_open_font(fontPath, fontDesc->ptSize); - if (fontDesc->font == nullptr) { + if (fontDesc->font == nullptr) + { log_verbose("Unable to load '%s'", fontPath); return false; } - } ttf_toggle_hinting(); @@ -100,9 +104,11 @@ void ttf_dispose() ttf_surface_cache_dispose_all(); ttf_getwidth_cache_dispose_all(); - for (int32_t i = 0; i < 4; i++) { - TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]); - if (fontDesc->font != nullptr) { + for (int32_t i = 0; i < 4; i++) + { + TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); + if (fontDesc->font != nullptr) + { ttf_close_font(fontDesc->font); fontDesc->font = nullptr; } @@ -113,28 +119,30 @@ void ttf_dispose() } } -static TTF_Font * ttf_open_font(const utf8 * fontPath, int32_t ptSize) +static TTF_Font* ttf_open_font(const utf8* fontPath, int32_t ptSize) { return TTF_OpenFont(fontPath, ptSize); } -static void ttf_close_font(TTF_Font * font) +static void ttf_close_font(TTF_Font* font) { TTF_CloseFont(font); } -static uint32_t ttf_surface_cache_hash(TTF_Font *font, const utf8 *text) +static uint32_t ttf_surface_cache_hash(TTF_Font* font, const utf8* text) { uint32_t hash = (uint32_t)((((uintptr_t)font * 23) ^ 0xAAAAAAAA) & 0xFFFFFFFF); - for (const utf8 *ch = text; *ch != 0; ch++) { + for (const utf8* ch = text; *ch != 0; ch++) + { hash = ror32(hash, 3) ^ (*ch * 13); } return hash; } -static void ttf_surface_cache_dispose(ttf_cache_entry *entry) +static void ttf_surface_cache_dispose(ttf_cache_entry* entry) { - if (entry->surface != nullptr) { + if (entry->surface != nullptr) + { ttf_free_surface(entry->surface); free(entry->text); @@ -146,7 +154,8 @@ static void ttf_surface_cache_dispose(ttf_cache_entry *entry) static void ttf_surface_cache_dispose_all() { - for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) { + for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) + { ttf_surface_cache_dispose(&_ttfSurfaceCache[i]); _ttfSurfaceCacheCount--; } @@ -161,7 +170,7 @@ void ttf_toggle_hinting() for (int32_t i = 0; i < FONT_SIZE_COUNT; i++) { - TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]); + TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]); bool use_hinting = gConfigFonts.enable_hinting && fontDesc->hinting_threshold; TTF_SetFontHinting(fontDesc->font, use_hinting ? 1 : 0); } @@ -172,38 +181,44 @@ void ttf_toggle_hinting() } } -TTFSurface * ttf_surface_cache_get_or_add(TTF_Font * font, const utf8 * text) +TTFSurface* ttf_surface_cache_get_or_add(TTF_Font* font, const utf8* text) { - ttf_cache_entry *entry; + ttf_cache_entry* entry; uint32_t hash = ttf_surface_cache_hash(font, text); int32_t index = hash % TTF_SURFACE_CACHE_SIZE; - for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) { + for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) + { entry = &_ttfSurfaceCache[index]; // Check if entry is a hit - if (entry->surface == nullptr) break; - if (entry->font == font && strcmp(entry->text, text) == 0) { + if (entry->surface == nullptr) + break; + if (entry->font == font && strcmp(entry->text, text) == 0) + { _ttfSurfaceCacheHitCount++; entry->lastUseTick = gCurrentDrawCount; return entry->surface; } // If entry hasn't been used for a while, replace it - if (entry->lastUseTick < gCurrentDrawCount - 64) { + if (entry->lastUseTick < gCurrentDrawCount - 64) + { break; } // Check if next entry is a hit - if (++index >= TTF_SURFACE_CACHE_SIZE) index = 0; + if (++index >= TTF_SURFACE_CACHE_SIZE) + index = 0; } // Cache miss, replace entry with new surface entry = &_ttfSurfaceCache[index]; ttf_surface_cache_dispose(entry); - TTFSurface * surface = ttf_render(font, text); - if (surface == nullptr) { + TTFSurface* surface = ttf_render(font, text); + if (surface == nullptr) + { return nullptr; } @@ -218,9 +233,10 @@ TTFSurface * ttf_surface_cache_get_or_add(TTF_Font * font, const utf8 * text) return entry->surface; } -static void ttf_getwidth_cache_dispose(ttf_getwidth_cache_entry *entry) +static void ttf_getwidth_cache_dispose(ttf_getwidth_cache_entry* entry) { - if (entry->text != nullptr) { + if (entry->text != nullptr) + { free(entry->text); entry->width = 0; @@ -231,36 +247,42 @@ static void ttf_getwidth_cache_dispose(ttf_getwidth_cache_entry *entry) static void ttf_getwidth_cache_dispose_all() { - for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) { + for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) + { ttf_getwidth_cache_dispose(&_ttfGetWidthCache[i]); _ttfGetWidthCacheCount--; } } -uint32_t ttf_getwidth_cache_get_or_add(TTF_Font * font, const utf8 * text) +uint32_t ttf_getwidth_cache_get_or_add(TTF_Font* font, const utf8* text) { - ttf_getwidth_cache_entry *entry; + ttf_getwidth_cache_entry* entry; uint32_t hash = ttf_surface_cache_hash(font, text); int32_t index = hash % TTF_GETWIDTH_CACHE_SIZE; - for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) { + for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) + { entry = &_ttfGetWidthCache[index]; // Check if entry is a hit - if (entry->text == nullptr) break; - if (entry->font == font && strcmp(entry->text, text) == 0) { + if (entry->text == nullptr) + break; + if (entry->font == font && strcmp(entry->text, text) == 0) + { _ttfGetWidthCacheHitCount++; entry->lastUseTick = gCurrentDrawCount; return entry->width; } // If entry hasn't been used for a while, replace it - if (entry->lastUseTick < gCurrentDrawCount - 64) { + if (entry->lastUseTick < gCurrentDrawCount - 64) + { break; } // Check if next entry is a hit - if (++index >= TTF_GETWIDTH_CACHE_SIZE) index = 0; + if (++index >= TTF_GETWIDTH_CACHE_SIZE) + index = 0; } // Cache miss, replace entry with new width @@ -280,22 +302,22 @@ uint32_t ttf_getwidth_cache_get_or_add(TTF_Font * font, const utf8 * text) return entry->width; } -TTFFontDescriptor * ttf_get_font_from_sprite_base(uint16_t spriteBase) +TTFFontDescriptor* ttf_get_font_from_sprite_base(uint16_t spriteBase) { return &gCurrentTTFFontSet->size[font_get_size_from_sprite_base(spriteBase)]; } -bool ttf_provides_glyph(const TTF_Font * font, codepoint_t codepoint) +bool ttf_provides_glyph(const TTF_Font* font, codepoint_t codepoint) { return TTF_GlyphIsProvided(font, codepoint); } -static bool ttf_get_size(TTF_Font * font, const utf8 * text, int32_t * outWidth, int32_t * outHeight) +static bool ttf_get_size(TTF_Font* font, const utf8* text, int32_t* outWidth, int32_t* outHeight) { return TTF_SizeUTF8(font, text, outWidth, outHeight); } -static TTFSurface * ttf_render(TTF_Font * font, const utf8 * text) +static TTFSurface* ttf_render(TTF_Font* font, const utf8* text) { if (TTF_GetFontHinting(font) != 0) { @@ -307,9 +329,9 @@ static TTFSurface * ttf_render(TTF_Font * font, const utf8 * text) } } -void ttf_free_surface(TTFSurface * surface) +void ttf_free_surface(TTFSurface* surface) { - free((void *)surface->pixels); + free((void*)surface->pixels); free(surface); } diff --git a/src/openrct2/drawing/TTF.h b/src/openrct2/drawing/TTF.h index 8e5d4cc25a..d77164687e 100644 --- a/src/openrct2/drawing/TTF.h +++ b/src/openrct2/drawing/TTF.h @@ -16,28 +16,29 @@ void ttf_dispose(); #ifndef NO_TTF -struct TTFSurface { - const void * pixels; - int32_t w; - int32_t h; - int32_t pitch; +struct TTFSurface +{ + const void* pixels; + int32_t w; + int32_t h; + int32_t pitch; }; -TTFFontDescriptor * ttf_get_font_from_sprite_base(uint16_t spriteBase); +TTFFontDescriptor* ttf_get_font_from_sprite_base(uint16_t spriteBase); void ttf_toggle_hinting(); -TTFSurface * ttf_surface_cache_get_or_add(TTF_Font * font, const utf8 * text); -uint32_t ttf_getwidth_cache_get_or_add(TTF_Font * font, const utf8 * text); -bool ttf_provides_glyph(const TTF_Font * font, codepoint_t codepoint); -void ttf_free_surface(TTFSurface * surface); +TTFSurface* ttf_surface_cache_get_or_add(TTF_Font* font, const utf8* text); +uint32_t ttf_getwidth_cache_get_or_add(TTF_Font* font, const utf8* text); +bool ttf_provides_glyph(const TTF_Font* font, codepoint_t codepoint); +void ttf_free_surface(TTFSurface* surface); // TTF_SDLPORT int TTF_Init(void); -TTF_Font * TTF_OpenFont(const char *file, int ptsize); -int TTF_GlyphIsProvided(const TTF_Font *font, codepoint_t ch); -int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h); -TTFSurface * TTF_RenderUTF8_Solid(TTF_Font *font, const char *text, uint32_t colour); -TTFSurface * TTF_RenderUTF8_Shaded(TTF_Font *font, const char *text, uint32_t fg, uint32_t bg); -void TTF_CloseFont(TTF_Font *font); +TTF_Font* TTF_OpenFont(const char* file, int ptsize); +int TTF_GlyphIsProvided(const TTF_Font* font, codepoint_t ch); +int TTF_SizeUTF8(TTF_Font* font, const char* text, int* w, int* h); +TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, uint32_t colour); +TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, uint32_t fg, uint32_t bg); +void TTF_CloseFont(TTF_Font* font); void TTF_SetFontHinting(TTF_Font* font, int hinting); int TTF_GetFontHinting(const TTF_Font* font); void TTF_Quit(void); diff --git a/src/openrct2/drawing/TTFSDLPort.cpp b/src/openrct2/drawing/TTFSDLPort.cpp index 34b660d270..77a19dc18e 100644 --- a/src/openrct2/drawing/TTFSDLPort.cpp +++ b/src/openrct2/drawing/TTFSDLPort.cpp @@ -47,37 +47,38 @@ misrepresented as being the original software. #pragma warning(disable : 4018) // '<': signed / unsigned mismatch /* ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) */ -#define UNICODE_BOM_NATIVE 0xFEFF +#define UNICODE_BOM_NATIVE 0xFEFF #define UNICODE_BOM_SWAPPED 0xFFFE /* Set and retrieve the font style */ -#define TTF_STYLE_NORMAL 0x00 -#define TTF_STYLE_BOLD 0x01 -#define TTF_STYLE_ITALIC 0x02 -#define TTF_STYLE_UNDERLINE 0x04 +#define TTF_STYLE_NORMAL 0x00 +#define TTF_STYLE_BOLD 0x01 +#define TTF_STYLE_ITALIC 0x02 +#define TTF_STYLE_UNDERLINE 0x04 #define TTF_STYLE_STRIKETHROUGH 0x08 /* Set and retrieve FreeType hinter settings */ -#define TTF_HINTING_NORMAL 0 -#define TTF_HINTING_LIGHT 1 -#define TTF_HINTING_MONO 2 -#define TTF_HINTING_NONE 3 +#define TTF_HINTING_NORMAL 0 +#define TTF_HINTING_LIGHT 1 +#define TTF_HINTING_MONO 2 +#define TTF_HINTING_NONE 3 /* FIXME: Right now we assume the gray-scale renderer Freetype is using supports 256 shades of gray, but we should instead key off of num_grays in the result FT_Bitmap after the FT_Render_Glyph() call. */ -#define NUM_GRAYS 256 +#define NUM_GRAYS 256 /* Handy routines for converting from fixed point */ #define FT_FLOOR(X) (((X) & -64) / 64) -#define FT_CEIL(X) ((((X) + 63) & -64) / 64) +#define FT_CEIL(X) ((((X) + 63) & -64) / 64) -#define CACHED_METRICS 0x10 -#define CACHED_BITMAP 0x01 -#define CACHED_PIXMAP 0x02 +#define CACHED_METRICS 0x10 +#define CACHED_BITMAP 0x01 +#define CACHED_PIXMAP 0x02 /* Cached glyph information */ -struct c_glyph { +struct c_glyph +{ int stored; FT_UInt index; FT_Bitmap bitmap; @@ -92,7 +93,8 @@ struct c_glyph { }; /* The structure used to hold internal font information */ -struct _TTF_Font { +struct _TTF_Font +{ /* Freetype2 maintains all sorts of useful info itself */ FT_Face face; @@ -119,11 +121,11 @@ struct _TTF_Font { int underline_height; /* Cache for style-transformed glyphs */ - c_glyph *current; + c_glyph* current; c_glyph cache[257]; /* 257 is a prime */ - /* We are responsible for closing the font stream */ - FILE *src; + /* We are responsible for closing the font stream */ + FILE* src; int freesrc; FT_Open_Args args; @@ -135,36 +137,36 @@ struct _TTF_Font { }; /* Handle a style only if the font does not already handle it */ -#define TTF_HANDLE_STYLE_BOLD(font) (((font)->style & TTF_STYLE_BOLD) && \ - !((font)->face_style & TTF_STYLE_BOLD)) -#define TTF_HANDLE_STYLE_ITALIC(font) (((font)->style & TTF_STYLE_ITALIC) && \ - !((font)->face_style & TTF_STYLE_ITALIC)) +#define TTF_HANDLE_STYLE_BOLD(font) (((font)->style & TTF_STYLE_BOLD) && !((font)->face_style & TTF_STYLE_BOLD)) +#define TTF_HANDLE_STYLE_ITALIC(font) (((font)->style & TTF_STYLE_ITALIC) && !((font)->face_style & TTF_STYLE_ITALIC)) #define TTF_HANDLE_STYLE_UNDERLINE(font) ((font)->style & TTF_STYLE_UNDERLINE) #define TTF_HANDLE_STYLE_STRIKETHROUGH(font) ((font)->style & TTF_STYLE_STRIKETHROUGH) /* Font styles that does not impact glyph drawing */ -#define TTF_STYLE_NO_GLYPH_CHANGE (TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH) +#define TTF_STYLE_NO_GLYPH_CHANGE (TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH) /* The FreeType font engine/library */ static FT_Library library; static int TTF_initialized = 0; -#define TTF_SetError log_error +#define TTF_SetError log_error -#define TTF_CHECKPOINTER(p, errval) \ - if ( !TTF_initialized ) { \ - TTF_SetError("Library not initialized"); \ - return errval; \ - } \ - if ( !(p) ) { \ - TTF_SetError("Passed a NULL pointer"); \ - return errval; \ +#define TTF_CHECKPOINTER(p, errval) \ + if (!TTF_initialized) \ + { \ + TTF_SetError("Library not initialized"); \ + return errval; \ + } \ + if (!(p)) \ + { \ + TTF_SetError("Passed a NULL pointer"); \ + return errval; \ } /* Gets the top row of the underline. The outline is taken into account. */ -static int TTF_underline_top_row(TTF_Font *font) +static int TTF_underline_top_row(TTF_Font* font) { /* With outline, the underline_offset is underline_offset+outline. */ /* So, we don't have to remove the top part of the outline height. */ @@ -174,10 +176,11 @@ static int TTF_underline_top_row(TTF_Font *font) /* Gets the bottom row of the underline. The outline is taken into account. */ -static int TTF_underline_bottom_row(TTF_Font *font) +static int TTF_underline_bottom_row(TTF_Font* font) { int row = TTF_underline_top_row(font) + font->underline_height; - if (font->outline > 0) { + if (font->outline > 0) + { /* Add underline_offset outline offset and */ /* the bottom part of the outline. */ row += font->outline * 2; @@ -188,26 +191,28 @@ static int TTF_underline_bottom_row(TTF_Font *font) /* Gets the top row of the strikethrough. The outline is taken into account. */ -static int TTF_strikethrough_top_row(TTF_Font *font) +static int TTF_strikethrough_top_row(TTF_Font* font) { /* With outline, the first text row is 'outline'. */ /* So, we don't have to remove the top part of the outline height. */ return font->height / 2; } -static void TTF_initLineMectrics(const TTF_Font *font, const TTFSurface *textbuf, const int row, uint8_t **pdst, int *pheight) +static void TTF_initLineMectrics(const TTF_Font* font, const TTFSurface* textbuf, const int row, uint8_t** pdst, int* pheight) { - uint8_t *dst; + uint8_t* dst; int height; - dst = (uint8_t *)textbuf->pixels; - if (row > 0) { + dst = (uint8_t*)textbuf->pixels; + if (row > 0) + { dst += row * textbuf->pitch; } height = font->underline_height; /* Take outline into account */ - if (font->outline > 0) { + if (font->outline > 0) + { height += font->outline * 2; } *pdst = dst; @@ -218,17 +223,18 @@ static void TTF_initLineMectrics(const TTF_Font *font, const TTFSurface *textbuf at the given row. The row value must take the outline into account. */ -static void TTF_drawLine_Solid(const TTF_Font *font, const TTFSurface *textbuf, const int row) +static void TTF_drawLine_Solid(const TTF_Font* font, const TTFSurface* textbuf, const int row) { int line; - uint8_t *dst_check = (uint8_t*)textbuf->pixels + textbuf->pitch * textbuf->h; - uint8_t *dst; + uint8_t* dst_check = (uint8_t*)textbuf->pixels + textbuf->pitch * textbuf->h; + uint8_t* dst; int height; TTF_initLineMectrics(font, textbuf, row, &dst, &height); /* Draw line */ - for (line = height; line>0 && dst < dst_check; --line) { + for (line = height; line > 0 && dst < dst_check; --line) + { /* 1 because 0 is the bg color */ memset(dst, 1, textbuf->w); dst += textbuf->pitch; @@ -239,17 +245,17 @@ static void TTF_drawLine_Solid(const TTF_Font *font, const TTFSurface *textbuf, at the given row. The row value must take the outline into account. */ -static void TTF_drawLine_Shaded(const TTF_Font *font, const TTFSurface *textbuf, const int row) +static void TTF_drawLine_Shaded(const TTF_Font* font, const TTFSurface* textbuf, const int row) { int line; - uint8_t *dst_check = (uint8_t*) textbuf->pixels + textbuf->pitch * textbuf->h; - uint8_t *dst; + uint8_t* dst_check = (uint8_t*)textbuf->pixels + textbuf->pitch * textbuf->h; + uint8_t* dst; int height; TTF_initLineMectrics(font, textbuf, row, &dst, &height); /* Draw line */ - for (line=height; line>0 && dst < dst_check; --line) + for (line = height; line > 0 && dst < dst_check; --line) { memset(dst, NUM_GRAYS - 1, textbuf->w); dst += textbuf->pitch; @@ -260,26 +266,29 @@ static void TTF_SetFTError(const char* msg, [[maybe_unused]] FT_Error error) { #ifdef USE_FREETYPE_ERRORS #undef FTERRORS_H -#define FT_ERRORDEF( e, v, s ) { e, s }, +#define FT_ERRORDEF(e, v, s) { e, s }, static const struct { - int err_code; - const char* err_msg; + int err_code; + const char* err_msg; } ft_errors[] = { #include }; int i; - const char *err_msg; + const char* err_msg; char buffer[1024]; err_msg = NULL; - for (i = 0; i<((sizeof ft_errors) / (sizeof ft_errors[0])); ++i) { - if (error == ft_errors[i].err_code) { + for (i = 0; i < ((sizeof ft_errors) / (sizeof ft_errors[0])); ++i) + { + if (error == ft_errors[i].err_code) + { err_msg = ft_errors[i].err_msg; break; } } - if (!err_msg) { + if (!err_msg) + { err_msg = "unknown FreeType error"; } TTF_SetError("%s: %s", msg, err_msg); @@ -292,37 +301,36 @@ int TTF_Init(void) { int status = 0; - if (!TTF_initialized) { + if (!TTF_initialized) + { FT_Error error = FT_Init_FreeType(&library); - if (error) { + if (error) + { TTF_SetFTError("Couldn't init FreeType engine", error); status = -1; } } - if (status == 0) { + if (status == 0) + { ++TTF_initialized; } return status; } -static unsigned long RWread( - FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count -) +static unsigned long RWread(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) { - FILE *src; + FILE* src; - src = (FILE *)stream->descriptor.pointer; + src = (FILE*)stream->descriptor.pointer; fseek(src, (int)offset, SEEK_SET); - if (count == 0) { + if (count == 0) + { return 0; } return (unsigned long)fread(buffer, 1, (int)count, src); } -static size_t fsize(FILE * file) +static size_t fsize(FILE* file) { size_t origPos = ftell(file); fseek(file, 0, SEEK_END); @@ -331,7 +339,7 @@ static size_t fsize(FILE * file) return size; } -static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long index) +static TTF_Font* TTF_OpenFontIndexRW(FILE* src, int freesrc, int ptsize, long index) { TTF_Font* font; FT_Error error; @@ -342,33 +350,40 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in int64_t position; int i; - if (!TTF_initialized) { + if (!TTF_initialized) + { TTF_SetError("Library not initialized"); - if (src && freesrc) { + if (src && freesrc) + { fclose(src); } return NULL; } - if (!src) { + if (!src) + { TTF_SetError("Passed a NULL font source"); return NULL; } /* Check to make sure we can seek in this stream */ position = ftell(src); - if (position < 0) { + if (position < 0) + { TTF_SetError("Can't seek in stream"); - if (freesrc) { + if (freesrc) + { fclose(src); } return NULL; } font = (TTF_Font*)malloc(sizeof *font); - if (font == NULL) { + if (font == NULL) + { TTF_SetError("Out of memory"); - if (freesrc) { + if (freesrc) + { fclose(src); } return NULL; @@ -379,7 +394,8 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in font->freesrc = freesrc; stream = (FT_Stream)malloc(sizeof(*stream)); - if (stream == NULL) { + if (stream == NULL) + { TTF_SetError("Out of memory"); TTF_CloseFont(font); return NULL; @@ -395,7 +411,8 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in font->args.stream = stream; error = FT_Open_Face(library, &font->args, index, &font->face); - if (error) { + if (error) + { TTF_SetFTError("Couldn't load font file", error); TTF_CloseFont(font); return NULL; @@ -404,26 +421,31 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in /* Set charmap for loaded font */ found = 0; - for (i = 0; i < face->num_charmaps; i++) { + for (i = 0; i < face->num_charmaps; i++) + { FT_CharMap charmap = face->charmaps[i]; - if ((charmap->platform_id == 3 && charmap->encoding_id == 1) /* Windows Unicode */ + if ((charmap->platform_id == 3 && charmap->encoding_id == 1) /* Windows Unicode */ || (charmap->platform_id == 3 && charmap->encoding_id == 0) /* Windows Symbol */ || (charmap->platform_id == 2 && charmap->encoding_id == 1) /* ISO Unicode */ - || (charmap->platform_id == 0)) { /* Apple Unicode */ + || (charmap->platform_id == 0)) + { /* Apple Unicode */ found = charmap; break; } } - if (found) { + if (found) + { /* If this fails, continue using the default charmap */ FT_Set_Charmap(face, found); } /* Make sure that our font face is scalable (global metrics) */ - if (FT_IS_SCALABLE(face)) { + if (FT_IS_SCALABLE(face)) + { /* Set the character size and use default DPI (72) */ error = FT_Set_Char_Size(font->face, 0, ptsize * 64, 0, 0); - if (error) { + if (error) + { TTF_SetFTError("Couldn't set font size", error); TTF_CloseFont(font); return NULL; @@ -437,25 +459,23 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in font->lineskip = FT_CEIL(FT_MulFix(face->height, scale)); font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale)); font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale)); - } - else { + else + { /* Non-scalable font case. ptsize determines which family - * or series of fonts to grab from the non-scalable format. - * It is not the point size of the font. - * */ + * or series of fonts to grab from the non-scalable format. + * It is not the point size of the font. + * */ if (ptsize >= font->face->num_fixed_sizes) ptsize = font->face->num_fixed_sizes - 1; font->font_size_family = ptsize; - error = FT_Set_Pixel_Sizes(face, - face->available_sizes[ptsize].width, - face->available_sizes[ptsize].height); + error = FT_Set_Pixel_Sizes(face, face->available_sizes[ptsize].width, face->available_sizes[ptsize].height); /* With non-scalale fonts, Freetype2 likes to fill many of the - * font metrics with the value of 0. The size of the - * non-scalable fonts must be determined differently - * or sometimes cannot be determined. - * */ + * font metrics with the value of 0. The size of the + * non-scalable fonts must be determined differently + * or sometimes cannot be determined. + * */ font->ascent = face->available_sizes[ptsize].height; font->descent = 0; font->height = face->available_sizes[ptsize].height; @@ -464,28 +484,28 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in font->underline_height = FT_FLOOR(face->underline_thickness); } - if (font->underline_height < 1) { + if (font->underline_height < 1) + { font->underline_height = 1; } #ifdef DEBUG_FONTS printf("Font metrics:\n"); - printf("\tascent = %d, descent = %d\n", - font->ascent, font->descent); - printf("\theight = %d, lineskip = %d\n", - font->height, font->lineskip); - printf("\tunderline_offset = %d, underline_height = %d\n", - font->underline_offset, font->underline_height); - printf("\tunderline_top_row = %d, strikethrough_top_row = %d\n", - TTF_underline_top_row(font), TTF_strikethrough_top_row(font)); + printf("\tascent = %d, descent = %d\n", font->ascent, font->descent); + printf("\theight = %d, lineskip = %d\n", font->height, font->lineskip); + printf("\tunderline_offset = %d, underline_height = %d\n", font->underline_offset, font->underline_height); + printf( + "\tunderline_top_row = %d, strikethrough_top_row = %d\n", TTF_underline_top_row(font), TTF_strikethrough_top_row(font)); #endif /* Initialize the font face style */ font->face_style = TTF_STYLE_NORMAL; - if (font->face->style_flags & FT_STYLE_FLAG_BOLD) { + if (font->face->style_flags & FT_STYLE_FLAG_BOLD) + { font->face_style |= TTF_STYLE_BOLD; } - if (font->face->style_flags & FT_STYLE_FLAG_ITALIC) { + if (font->face->style_flags & FT_STYLE_FLAG_ITALIC) + { font->face_style |= TTF_STYLE_ITALIC; } @@ -501,16 +521,17 @@ static TTF_Font* TTF_OpenFontIndexRW(FILE *src, int freesrc, int ptsize, long in return font; } -static TTF_Font* TTF_OpenFontIndex(const char *file, int ptsize, long index) +static TTF_Font* TTF_OpenFontIndex(const char* file, int ptsize, long index) { - FILE *rw = fopen(file, "rb"); - if (rw == NULL) { + FILE* rw = fopen(file, "rb"); + if (rw == NULL) + { return NULL; } return TTF_OpenFontIndexRW(rw, 1, ptsize, index); } -TTF_Font* TTF_OpenFont(const char *file, int ptsize) +TTF_Font* TTF_OpenFont(const char* file, int ptsize) { return TTF_OpenFontIndex(file, ptsize, 0); } @@ -519,11 +540,13 @@ static void Flush_Glyph(c_glyph* glyph) { glyph->stored = 0; glyph->index = 0; - if (glyph->bitmap.buffer) { + if (glyph->bitmap.buffer) + { free(glyph->bitmap.buffer); glyph->bitmap.buffer = 0; } - if (glyph->pixmap.buffer) { + if (glyph->pixmap.buffer) + { free(glyph->pixmap.buffer); glyph->pixmap.buffer = 0; } @@ -535,11 +558,12 @@ static void Flush_Cache(TTF_Font* font) int i; int size = sizeof(font->cache) / sizeof(font->cache[0]); - for (i = 0; i < size; ++i) { - if (font->cache[i].cached) { + for (i = 0; i < size; ++i) + { + if (font->cache[i].cached) + { Flush_Glyph(&font->cache[i]); } - } } @@ -551,18 +575,21 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan FT_Glyph_Metrics* metrics; FT_Outline* outline; - if (!font || !font->face) { + if (!font || !font->face) + { return FT_Err_Invalid_Handle; } face = font->face; /* Load the glyph */ - if (!cached->index) { + if (!cached->index) + { cached->index = FT_Get_Char_Index(face, ch); } error = FT_Load_Glyph(face, cached->index, FT_LOAD_DEFAULT | font->hinting); - if (error) { + if (error) + { return error; } @@ -572,8 +599,10 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan outline = &glyph->outline; /* Get the glyph metrics if desired */ - if ((want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS)) { - if (FT_IS_SCALABLE(face)) { + if ((want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS)) + { + if (FT_IS_SCALABLE(face)) + { /* Get the bounding box */ cached->minx = FT_FLOOR(metrics->horiBearingX); cached->maxx = FT_CEIL(metrics->horiBearingX + metrics->width); @@ -582,13 +611,14 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan cached->yoffset = font->ascent - cached->maxy; cached->advance = FT_CEIL(metrics->horiAdvance); } - else { + else + { /* Get the bounding box for non-scalable format. - * Again, freetype2 fills in many of the font metrics - * with the value of 0, so some of the values we - * need must be calculated differently with certain - * assumptions about non-scalable formats. - * */ + * Again, freetype2 fills in many of the font metrics + * with the value of 0, so some of the values we + * need must be calculated differently with certain + * assumptions about non-scalable formats. + * */ cached->minx = FT_FLOOR(metrics->horiBearingX); cached->maxx = FT_CEIL(metrics->horiBearingX + metrics->width); cached->maxy = FT_FLOOR(metrics->horiBearingY); @@ -598,17 +628,20 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan } /* Adjust for bold and italic text */ - if (TTF_HANDLE_STYLE_BOLD(font)) { + if (TTF_HANDLE_STYLE_BOLD(font)) + { cached->maxx += font->glyph_overhang; } - if (TTF_HANDLE_STYLE_ITALIC(font)) { + if (TTF_HANDLE_STYLE_ITALIC(font)) + { cached->maxx += (int)ceil(font->glyph_italics); } cached->stored |= CACHED_METRICS; } - if (((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) || - ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP))) { + if (((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) + || ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP))) + { int mono = (want & CACHED_BITMAP); unsigned int i; FT_Bitmap* src; @@ -616,7 +649,8 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan FT_Glyph bitmap_glyph = NULL; /* Handle the italic style */ - if (TTF_HANDLE_STYLE_ITALIC(font)) { + if (TTF_HANDLE_STYLE_ITALIC(font)) + { FT_Matrix shear; shear.xx = 1 << 16; @@ -628,11 +662,13 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan } /* Render as outline */ - if ((font->outline > 0) && glyph->format != FT_GLYPH_FORMAT_BITMAP) { + if ((font->outline > 0) && glyph->format != FT_GLYPH_FORMAT_BITMAP) + { FT_Stroker stroker; FT_Get_Glyph(glyph, &bitmap_glyph); error = FT_Stroker_New(library, &stroker); - if (error) { + if (error) + { return error; } FT_Stroker_Set(stroker, font->outline * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); @@ -640,77 +676,93 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan FT_Stroker_Done(stroker); /* Render the glyph */ error = FT_Glyph_To_Bitmap(&bitmap_glyph, mono ? ft_render_mode_mono : ft_render_mode_normal, 0, 1); - if (error) { + if (error) + { FT_Done_Glyph(bitmap_glyph); return error; } src = &((FT_BitmapGlyph)bitmap_glyph)->bitmap; } - else { + else + { /* Render the glyph */ error = FT_Render_Glyph(glyph, mono ? ft_render_mode_mono : ft_render_mode_normal); - if (error) { + if (error) + { return error; } src = &glyph->bitmap; } /* Copy over information to cache */ - if (mono) { + if (mono) + { dst = &cached->bitmap; } - else { + else + { dst = &cached->pixmap; } memcpy(dst, src, sizeof(*dst)); /* FT_Render_Glyph() and .fon fonts always generate a - * two-color (black and white) glyphslot surface, even - * when rendered in ft_render_mode_normal. */ + * two-color (black and white) glyphslot surface, even + * when rendered in ft_render_mode_normal. */ /* FT_IS_SCALABLE() means that the font is in outline format, - * but does not imply that outline is rendered as 8-bit - * grayscale, because embedded bitmap/graymap is preferred - * (see FT_LOAD_DEFAULT section of FreeType2 API Reference). - * FT_Render_Glyph() canreturn two-color bitmap or 4/16/256- - * color graymap according to the format of embedded bitmap/ - * graymap. */ - if (src->pixel_mode == FT_PIXEL_MODE_MONO) { + * but does not imply that outline is rendered as 8-bit + * grayscale, because embedded bitmap/graymap is preferred + * (see FT_LOAD_DEFAULT section of FreeType2 API Reference). + * FT_Render_Glyph() canreturn two-color bitmap or 4/16/256- + * color graymap according to the format of embedded bitmap/ + * graymap. */ + if (src->pixel_mode == FT_PIXEL_MODE_MONO) + { dst->pitch *= 8; } - else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) { + else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) + { dst->pitch *= 4; } - else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) { + else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) + { dst->pitch *= 2; } /* Adjust for bold and italic text */ - if (TTF_HANDLE_STYLE_BOLD(font)) { + if (TTF_HANDLE_STYLE_BOLD(font)) + { int bump = font->glyph_overhang; dst->pitch += bump; dst->width += bump; } - if (TTF_HANDLE_STYLE_ITALIC(font)) { + if (TTF_HANDLE_STYLE_ITALIC(font)) + { int bump = (int)ceil(font->glyph_italics); dst->pitch += bump; dst->width += bump; } - if (dst->rows != 0) { - dst->buffer = (unsigned char *)malloc(dst->pitch * dst->rows); - if (!dst->buffer) { + if (dst->rows != 0) + { + dst->buffer = (unsigned char*)malloc(dst->pitch * dst->rows); + if (!dst->buffer) + { return FT_Err_Out_Of_Memory; } memset(dst->buffer, 0, dst->pitch * dst->rows); - for (i = 0; i < src->rows; i++) { + for (i = 0; i < src->rows; i++) + { int soffset = i * src->pitch; int doffset = i * dst->pitch; - if (mono) { - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; + if (mono) + { + unsigned char* srcp = src->buffer + soffset; + unsigned char* dstp = dst->buffer + doffset; unsigned int j; - if (src->pixel_mode == FT_PIXEL_MODE_MONO) { - for (j = 0; j < src->width; j += 8) { + if (src->pixel_mode == FT_PIXEL_MODE_MONO) + { + for (j = 0; j < src->width; j += 8) + { unsigned char c = *srcp++; *dstp++ = (c & 0x80) >> 7; c <<= 1; @@ -729,8 +781,10 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan *dstp++ = (c & 0x80) >> 7; } } - else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) { - for (j = 0; j < src->width; j += 4) { + else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) + { + for (j = 0; j < src->width; j += 4) + { unsigned char c = *srcp++; *dstp++ = (((c & 0xA0) >> 6) >= 0x2) ? 1 : 0; c <<= 2; @@ -741,93 +795,113 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan *dstp++ = (((c & 0xA0) >> 6) >= 0x2) ? 1 : 0; } } - else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) { - for (j = 0; j < src->width; j += 2) { + else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) + { + for (j = 0; j < src->width; j += 2) + { unsigned char c = *srcp++; *dstp++ = (((c & 0xF0) >> 4) >= 0x8) ? 1 : 0; c <<= 4; *dstp++ = (((c & 0xF0) >> 4) >= 0x8) ? 1 : 0; } } - else { - for (j = 0; j < src->width; j++) { + else + { + for (j = 0; j < src->width; j++) + { unsigned char c = *srcp++; *dstp++ = (c >= 0x80) ? 1 : 0; } } } - else if (src->pixel_mode == FT_PIXEL_MODE_MONO) { + else if (src->pixel_mode == FT_PIXEL_MODE_MONO) + { /* This special case wouldn't - * be here if the FT_Render_Glyph() - * function wasn't buggy when it tried - * to render a .fon font with 256 - * shades of gray. Instead, it - * returns a black and white surface - * and we have to translate it back - * to a 256 gray shaded surface. - * */ - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; + * be here if the FT_Render_Glyph() + * function wasn't buggy when it tried + * to render a .fon font with 256 + * shades of gray. Instead, it + * returns a black and white surface + * and we have to translate it back + * to a 256 gray shaded surface. + * */ + unsigned char* srcp = src->buffer + soffset; + unsigned char* dstp = dst->buffer + doffset; unsigned char c; unsigned int j, k; - for (j = 0; j < src->width; j += 8) { + for (j = 0; j < src->width; j += 8) + { c = *srcp++; - for (k = 0; k < 8; ++k) { - if ((c & 0x80) >> 7) { + for (k = 0; k < 8; ++k) + { + if ((c & 0x80) >> 7) + { *dstp++ = NUM_GRAYS - 1; } - else { + else + { *dstp++ = 0x00; } c <<= 1; } } } - else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) { - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; + else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) + { + unsigned char* srcp = src->buffer + soffset; + unsigned char* dstp = dst->buffer + doffset; unsigned char c; unsigned int j, k; - for (j = 0; j < src->width; j += 4) { + for (j = 0; j < src->width; j += 4) + { c = *srcp++; - for (k = 0; k < 4; ++k) { - if ((c & 0xA0) >> 6) { + for (k = 0; k < 4; ++k) + { + if ((c & 0xA0) >> 6) + { *dstp++ = NUM_GRAYS * ((c & 0xA0) >> 6) / 3 - 1; } - else { + else + { *dstp++ = 0x00; } c <<= 2; } } } - else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) { - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; + else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) + { + unsigned char* srcp = src->buffer + soffset; + unsigned char* dstp = dst->buffer + doffset; unsigned char c; unsigned int j, k; - for (j = 0; j < src->width; j += 2) { + for (j = 0; j < src->width; j += 2) + { c = *srcp++; - for (k = 0; k < 2; ++k) { - if ((c & 0xF0) >> 4) { + for (k = 0; k < 2; ++k) + { + if ((c & 0xF0) >> 4) + { *dstp++ = NUM_GRAYS * ((c & 0xF0) >> 4) / 15 - 1; } - else { + else + { *dstp++ = 0x00; } c <<= 4; } } } - else { - memcpy(dst->buffer + doffset, - src->buffer + soffset, src->pitch); + else + { + memcpy(dst->buffer + doffset, src->buffer + soffset, src->pitch); } } } /* Handle the bold style */ - if (TTF_HANDLE_STYLE_BOLD(font)) { + if (TTF_HANDLE_STYLE_BOLD(font)) + { int row; int col; int offset; @@ -835,16 +909,22 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan uint8_t* pixmap; /* The pixmap is a little hard, we have to add and clamp */ - for (row = dst->rows - 1; row >= 0; --row) { + for (row = dst->rows - 1; row >= 0; --row) + { pixmap = dst->buffer + row * dst->pitch; - for (offset = 1; offset <= font->glyph_overhang; ++offset) { - for (col = dst->width - 1; col > 0; --col) { - if (mono) { + for (offset = 1; offset <= font->glyph_overhang; ++offset) + { + for (col = dst->width - 1; col > 0; --col) + { + if (mono) + { pixmap[col] |= pixmap[col - 1]; } - else { + else + { pixel = (pixmap[col] + pixmap[col - 1]); - if (pixel > NUM_GRAYS - 1) { + if (pixel > NUM_GRAYS - 1) + { pixel = NUM_GRAYS - 1; } pixmap[col] = (uint8_t)pixel; @@ -855,15 +935,18 @@ static FT_Error Load_Glyph(TTF_Font* font, uint16_t ch, c_glyph* cached, int wan } /* Mark that we rendered this format */ - if (mono) { + if (mono) + { cached->stored |= CACHED_BITMAP; } - else { + else + { cached->stored |= CACHED_PIXMAP; } /* Free outlined glyph */ - if (bitmap_glyph) { + if (bitmap_glyph) + { FT_Done_Glyph(bitmap_glyph); } } @@ -885,7 +968,8 @@ static FT_Error Find_Glyph(TTF_Font* font, uint16_t ch, int want) if (font->current->cached != ch) Flush_Glyph(font->current); - if ((font->current->stored & want) != want) { + if ((font->current->stored & want) != want) + { retval = Load_Glyph(font, ch, font->current, want); } return retval; @@ -893,15 +977,19 @@ static FT_Error Find_Glyph(TTF_Font* font, uint16_t ch, int want) void TTF_CloseFont(TTF_Font* font) { - if (font) { + if (font) + { Flush_Cache(font); - if (font->face) { + if (font->face) + { FT_Done_Face(font->face); } - if (font->args.stream) { + if (font->args.stream) + { free(font->args.stream); } - if (font->freesrc) { + if (font->freesrc) + { fclose(font->src); } free(font); @@ -910,72 +998,92 @@ void TTF_CloseFont(TTF_Font* font) /* Gets a unicode value from a UTF-8 encoded string and advance the string */ #define UNKNOWN_UNICODE 0xFFFD -static uint32_t UTF8_getch(const char **src, size_t *srclen) +static uint32_t UTF8_getch(const char** src, size_t* srclen) { - const uint8_t *p = *(const uint8_t**)src; + const uint8_t* p = *(const uint8_t**)src; size_t left = 0; [[maybe_unused]] bool overlong = false; bool underflow = false; uint32_t ch = UNKNOWN_UNICODE; - if (*srclen == 0) { + if (*srclen == 0) + { return UNKNOWN_UNICODE; } - if (p[0] >= 0xFC) { - if ((p[0] & 0xFE) == 0xFC) { - if (p[0] == 0xFC && (p[1] & 0xFC) == 0x80) { + if (p[0] >= 0xFC) + { + if ((p[0] & 0xFE) == 0xFC) + { + if (p[0] == 0xFC && (p[1] & 0xFC) == 0x80) + { overlong = true; } ch = (uint32_t)(p[0] & 0x01); left = 5; } } - else if (p[0] >= 0xF8) { - if ((p[0] & 0xFC) == 0xF8) { - if (p[0] == 0xF8 && (p[1] & 0xF8) == 0x80) { + else if (p[0] >= 0xF8) + { + if ((p[0] & 0xFC) == 0xF8) + { + if (p[0] == 0xF8 && (p[1] & 0xF8) == 0x80) + { overlong = true; } ch = (uint32_t)(p[0] & 0x03); left = 4; } } - else if (p[0] >= 0xF0) { - if ((p[0] & 0xF8) == 0xF0) { - if (p[0] == 0xF0 && (p[1] & 0xF0) == 0x80) { + else if (p[0] >= 0xF0) + { + if ((p[0] & 0xF8) == 0xF0) + { + if (p[0] == 0xF0 && (p[1] & 0xF0) == 0x80) + { overlong = true; } ch = (uint32_t)(p[0] & 0x07); left = 3; } } - else if (p[0] >= 0xE0) { - if ((p[0] & 0xF0) == 0xE0) { - if (p[0] == 0xE0 && (p[1] & 0xE0) == 0x80) { + else if (p[0] >= 0xE0) + { + if ((p[0] & 0xF0) == 0xE0) + { + if (p[0] == 0xE0 && (p[1] & 0xE0) == 0x80) + { overlong = true; } ch = (uint32_t)(p[0] & 0x0F); left = 2; } } - else if (p[0] >= 0xC0) { - if ((p[0] & 0xE0) == 0xC0) { - if ((p[0] & 0xDE) == 0xC0) { + else if (p[0] >= 0xC0) + { + if ((p[0] & 0xE0) == 0xC0) + { + if ((p[0] & 0xDE) == 0xC0) + { overlong = true; } ch = (uint32_t)(p[0] & 0x1F); left = 1; } } - else { - if ((p[0] & 0x80) == 0x00) { + else + { + if ((p[0] & 0x80) == 0x00) + { ch = (uint32_t)p[0]; } } ++*src; --*srclen; - while (left > 0 && *srclen > 0) { + while (left > 0 && *srclen > 0) + { ++p; - if ((p[0] & 0xC0) != 0x80) { + if ((p[0] & 0xC0) != 0x80) + { ch = UNKNOWN_UNICODE; break; } @@ -985,7 +1093,8 @@ static uint32_t UTF8_getch(const char **src, size_t *srclen) --*srclen; --left; } - if (left > 0) { + if (left > 0) + { underflow = true; } /* Technically overlong sequences are invalid and should not be interpreted. @@ -995,26 +1104,25 @@ static uint32_t UTF8_getch(const char **src, size_t *srclen) See bug 1931 for sample input that triggers this. */ /*if (overlong) return UNKNOWN_UNICODE;*/ - if (underflow || - (ch >= 0xD800 && ch <= 0xDFFF) || - (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) { + if (underflow || (ch >= 0xD800 && ch <= 0xDFFF) || (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) + { ch = UNKNOWN_UNICODE; } return ch; } -int TTF_GlyphIsProvided(const TTF_Font *font, codepoint_t ch) +int TTF_GlyphIsProvided(const TTF_Font* font, codepoint_t ch) { - return(FT_Get_Char_Index(font->face, ch)); + return (FT_Get_Char_Index(font->face, ch)); } -int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h) +int TTF_SizeUTF8(TTF_Font* font, const char* text, int* w, int* h) { int status; int x, z; int minx, maxx; int miny, maxy; - c_glyph *glyph; + c_glyph* glyph; FT_Error error; FT_Long use_kerning; FT_UInt prev_index = 0; @@ -1032,28 +1140,33 @@ int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h) use_kerning = FT_HAS_KERNING(font->face) && font->kerning; /* Init outline handling */ - if (font->outline > 0) { + if (font->outline > 0) + { outline_delta = font->outline * 2; } /* Load each character and sum it's bounding box */ textlen = strlen(text); x = 0; - while (textlen > 0) { + while (textlen > 0) + { uint16_t c = UTF8_getch(&text, &textlen); - if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) { + if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) + { continue; } error = Find_Glyph(font, c, CACHED_METRICS); - if (error) { + if (error) + { TTF_SetFTError("Couldn't find glyph", error); return -1; } glyph = font->current; /* handle kerning */ - if (use_kerning && prev_index && glyph->index) { + if (use_kerning && prev_index && glyph->index) + { FT_Vector delta; FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta); x += delta.x >> 6; @@ -1079,48 +1192,60 @@ int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h) #endif z = x + glyph->minx; - if (minx > z) { + if (minx > z) + { minx = z; } - if (TTF_HANDLE_STYLE_BOLD(font)) { + if (TTF_HANDLE_STYLE_BOLD(font)) + { x += font->glyph_overhang; } - if (glyph->advance > glyph->maxx) { + if (glyph->advance > glyph->maxx) + { z = x + glyph->advance; } - else { + else + { z = x + glyph->maxx; } - if (maxx < z) { + if (maxx < z) + { maxx = z; } x += glyph->advance; - if (glyph->miny < miny) { + if (glyph->miny < miny) + { miny = glyph->miny; } - if (glyph->maxy > maxy) { + if (glyph->maxy > maxy) + { maxy = glyph->maxy; } prev_index = glyph->index; } /* Fill the bounds rectangle */ - if (w) { + if (w) + { /* Add outline extra width */ *w = (maxx - minx) + outline_delta; } - if (h) { + if (h) + { /* Some fonts descend below font height (FletcherGothicFLF) */ /* Add outline extra height */ *h = (font->ascent - miny) + outline_delta; - if (*h < font->height) { + if (*h < font->height) + { *h = font->height; } /* Update height according to the needs of the underline style */ - if (TTF_HANDLE_STYLE_UNDERLINE(font)) { + if (TTF_HANDLE_STYLE_UNDERLINE(font)) + { int bottom_row = TTF_underline_bottom_row(font); - if (*h < bottom_row) { + if (*h < bottom_row) + { *h = bottom_row; } } @@ -1137,11 +1262,11 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse TTFSurface* textbuf; uint8_t* src; uint8_t* dst; - uint8_t *dst_check; + uint8_t* dst_check; unsigned int row, col; - c_glyph *glyph; + c_glyph* glyph; - FT_Bitmap *current; + FT_Bitmap* current; FT_Error error; FT_Long use_kerning; FT_UInt prev_index = 0; @@ -1150,14 +1275,16 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse TTF_CHECKPOINTER(text, NULL); /* Get the dimensions of the text surface */ - if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) { + if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) + { TTF_SetError("Text has zero width"); return NULL; } /* Create the target surface */ - textbuf = (TTFSurface *)calloc(1, sizeof(TTFSurface)); - if (textbuf == NULL) { + textbuf = (TTFSurface*)calloc(1, sizeof(TTFSurface)); + if (textbuf == NULL) + { return NULL; } textbuf->w = width; @@ -1176,14 +1303,17 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse textlen = strlen(text); first = true; xstart = 0; - while (textlen > 0) { + while (textlen > 0) + { uint16_t c = UTF8_getch(&text, &textlen); - if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) { + if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) + { continue; } error = Find_Glyph(font, c, CACHED_METRICS | CACHED_BITMAP); - if (error) { + if (error) + { TTF_SetFTError("Couldn't find glyph", error); ttf_free_surface(textbuf); return NULL; @@ -1191,57 +1321,65 @@ TTFSurface* TTF_RenderUTF8_Solid(TTF_Font* font, const char* text, [[maybe_unuse glyph = font->current; current = &glyph->bitmap; /* Ensure the width of the pixmap is correct. On some cases, - * freetype may report a larger pixmap than possible.*/ + * freetype may report a larger pixmap than possible.*/ width = current->width; - if (font->outline <= 0 && width > glyph->maxx - glyph->minx) { + if (font->outline <= 0 && width > glyph->maxx - glyph->minx) + { width = glyph->maxx - glyph->minx; } /* do kerning, if possible AC-Patch */ - if (use_kerning && prev_index && glyph->index) { + if (use_kerning && prev_index && glyph->index) + { FT_Vector delta; FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta); xstart += delta.x >> 6; } /* Compensate for wrap around bug with negative minx's */ - if (first && (glyph->minx < 0)) { + if (first && (glyph->minx < 0)) + { xstart -= glyph->minx; } first = false; - for (row = 0; row < current->rows; ++row) { + for (row = 0; row < current->rows; ++row) + { /* Make sure we don't go either over, or under the - * limit */ - if ((signed)row + glyph->yoffset < 0) { + * limit */ + if ((signed)row + glyph->yoffset < 0) + { continue; } - if ((signed)row + glyph->yoffset >= textbuf->h) { + if ((signed)row + glyph->yoffset >= textbuf->h) + { continue; } - dst = (uint8_t*)textbuf->pixels + - (row + glyph->yoffset) * textbuf->pitch + - xstart + glyph->minx; + dst = (uint8_t*)textbuf->pixels + (row + glyph->yoffset) * textbuf->pitch + xstart + glyph->minx; src = current->buffer + row * current->pitch; - for (col = width; col>0 && dst < dst_check; --col) { + for (col = width; col > 0 && dst < dst_check; --col) + { *dst++ |= *src++; } } xstart += glyph->advance; - if (TTF_HANDLE_STYLE_BOLD(font)) { + if (TTF_HANDLE_STYLE_BOLD(font)) + { xstart += font->glyph_overhang; } prev_index = glyph->index; } /* Handle the underline style */ - if (TTF_HANDLE_STYLE_UNDERLINE(font)) { + if (TTF_HANDLE_STYLE_UNDERLINE(font)) + { row = TTF_underline_top_row(font); TTF_drawLine_Solid(font, textbuf, row); } /* Handle the strikethrough style */ - if (TTF_HANDLE_STYLE_STRIKETHROUGH(font)) { + if (TTF_HANDLE_STYLE_STRIKETHROUGH(font)) + { row = TTF_strikethrough_top_row(font); TTF_drawLine_Solid(font, textbuf, row); } @@ -1260,7 +1398,7 @@ TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, [[maybe_unus uint8_t* dst_check; unsigned int row, col; FT_Bitmap* current; - c_glyph *glyph; + c_glyph* glyph; FT_Error error; FT_Long use_kerning; FT_UInt prev_index = 0; @@ -1269,14 +1407,14 @@ TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, [[maybe_unus TTF_CHECKPOINTER(text, NULL); /* Get the dimensions of the text surface */ - if ((TTF_SizeUTF8(font, text, &width, &height) < 0 ) || !width) + if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) { TTF_SetError("Text has zero width"); return NULL; } /* Create the target surface */ - textbuf = (TTFSurface *)calloc(1, sizeof(TTFSurface)); + textbuf = (TTFSurface*)calloc(1, sizeof(TTFSurface)); if (textbuf == NULL) { return NULL; @@ -1288,7 +1426,7 @@ TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, [[maybe_unus /* Adding bound checking to avoid all kinds of memory corruption errors that may occur. */ - dst_check = (uint8_t*) textbuf->pixels + textbuf->pitch * textbuf->h; + dst_check = (uint8_t*)textbuf->pixels + textbuf->pitch * textbuf->h; /* check kerning */ use_kerning = FT_HAS_KERNING(font->face) && font->kerning; @@ -1305,7 +1443,7 @@ TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, [[maybe_unus continue; } - error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP); + error = Find_Glyph(font, c, CACHED_METRICS | CACHED_PIXMAP); if (error) { TTF_SetFTError("Couldn't find glyph", error); @@ -1352,12 +1490,10 @@ TTFSurface* TTF_RenderUTF8_Shaded(TTF_Font* font, const char* text, [[maybe_unus continue; } - dst = (uint8_t*) textbuf->pixels + - (row+glyph->yoffset) * textbuf->pitch + - xstart + glyph->minx; + dst = (uint8_t*)textbuf->pixels + (row + glyph->yoffset) * textbuf->pitch + xstart + glyph->minx; src = current->buffer + row * current->pitch; - for (col=width; col>0 && dst < dst_check; --col) + for (col = width; col > 0 && dst < dst_check; --col) { *dst++ |= *src++; } @@ -1414,8 +1550,10 @@ int TTF_GetFontHinting(const TTF_Font* font) void TTF_Quit(void) { - if (TTF_initialized) { - if (--TTF_initialized == 0) { + if (TTF_initialized) + { + if (--TTF_initialized == 0) + { FT_Done_FreeType(library); } } diff --git a/src/openrct2/drawing/Text.cpp b/src/openrct2/drawing/Text.cpp index dcb41a4427..655a5fceac 100644 --- a/src/openrct2/drawing/Text.cpp +++ b/src/openrct2/drawing/Text.cpp @@ -7,15 +7,15 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "Drawing.h" #include "Text.h" #include "../localisation/Localisation.h" +#include "Drawing.h" static TextPaint _legacyPaint; -static void DrawText(rct_drawpixelinfo * dpi, int32_t x, int32_t y, TextPaint * paint, const_utf8string text); -static void DrawText(rct_drawpixelinfo * dpi, int32_t x, int32_t y, TextPaint * paint, rct_string_id format, void * args); +static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, const_utf8string text); +static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, rct_string_id format, void* args); StaticLayout::StaticLayout(utf8string source, TextPaint paint, int32_t width) { @@ -30,7 +30,7 @@ StaticLayout::StaticLayout(utf8string source, TextPaint paint, int32_t width) _lineHeight = font_get_line_height(fontSpriteBase); } -void StaticLayout::Draw(rct_drawpixelinfo * dpi, int32_t x, int32_t y) +void StaticLayout::Draw(rct_drawpixelinfo* dpi, int32_t x, int32_t y) { gCurrentFontFlags = 0; gCurrentFontSpriteBase = _paint.SpriteBase; @@ -40,18 +40,19 @@ void StaticLayout::Draw(rct_drawpixelinfo * dpi, int32_t x, int32_t y) gCurrentFontFlags = 0; int32_t lineY = y; int32_t lineX = x; - switch (_paint.Alignment) { - case TextAlignment::LEFT: - lineX = x; - break; - case TextAlignment::CENTRE: - lineX = x + _maxWidth / 2; - break; - case TextAlignment::RIGHT: - lineX = x + _maxWidth; - break; + switch (_paint.Alignment) + { + case TextAlignment::LEFT: + lineX = x; + break; + case TextAlignment::CENTRE: + lineX = x + _maxWidth / 2; + break; + case TextAlignment::RIGHT: + lineX = x + _maxWidth; + break; } - utf8 * buffer = _buffer; + utf8* buffer = _buffer; for (int32_t line = 0; line < _lineCount; ++line) { DrawText(dpi, lineX, lineY, &tempPaint, buffer); @@ -76,19 +77,20 @@ int32_t StaticLayout::GetLineCount() return _lineCount; } -static void DrawText(rct_drawpixelinfo * dpi, int32_t x, int32_t y, TextPaint * paint, const_utf8string text) +static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, const_utf8string text) { int32_t width = gfx_get_string_width(text); - switch (paint->Alignment) { - case TextAlignment::LEFT: - break; - case TextAlignment::CENTRE: - x -= (width - 1) / 2; - break; - case TextAlignment::RIGHT: - x -= width; - break; + switch (paint->Alignment) + { + case TextAlignment::LEFT: + break; + case TextAlignment::CENTRE: + x -= (width - 1) / 2; + break; + case TextAlignment::RIGHT: + x -= width; + break; } ttf_draw_string(dpi, text, paint->Colour, x, y); @@ -103,15 +105,22 @@ static void DrawText(rct_drawpixelinfo * dpi, int32_t x, int32_t y, TextPaint * } } -static void DrawText(rct_drawpixelinfo * dpi, int32_t x, int32_t y, TextPaint * paint, rct_string_id format, void * args) +static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, rct_string_id format, void* args) { utf8 buffer[256]; format_string(buffer, sizeof(buffer), format, args); DrawText(dpi, x, y, paint, buffer); } -static void DrawTextCompat(rct_drawpixelinfo * dpi, int32_t x, int32_t y, rct_string_id format, void * args, uint8_t colour, - TextAlignment alignment, bool underline = false) +static void DrawTextCompat( + rct_drawpixelinfo* dpi, + int32_t x, + int32_t y, + rct_string_id format, + void* args, + uint8_t colour, + TextAlignment alignment, + bool underline = false) { _legacyPaint.UnderlineText = underline; _legacyPaint.Colour = colour; @@ -121,9 +130,16 @@ static void DrawTextCompat(rct_drawpixelinfo * dpi, int32_t x, int32_t y, rct_st DrawText(dpi, x, y, &_legacyPaint, format, args); } -static void DrawTextEllipsisedCompat(rct_drawpixelinfo * dpi, int32_t x, int32_t y, int32_t width, rct_string_id format, void * args, - uint8_t colour, - TextAlignment alignment, bool underline = false) +static void DrawTextEllipsisedCompat( + rct_drawpixelinfo* dpi, + int32_t x, + int32_t y, + int32_t width, + rct_string_id format, + void* args, + uint8_t colour, + TextAlignment alignment, + bool underline = false) { _legacyPaint.UnderlineText = underline; _legacyPaint.Colour = colour; @@ -138,7 +154,7 @@ static void DrawTextEllipsisedCompat(rct_drawpixelinfo * dpi, int32_t x, int32_t DrawText(dpi, x, y, &_legacyPaint, buffer); } -void gfx_draw_string(rct_drawpixelinfo *dpi, const_utf8string buffer, uint8_t colour, int32_t x, int32_t y) +void gfx_draw_string(rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t colour, int32_t x, int32_t y) { _legacyPaint.UnderlineText = false; _legacyPaint.Colour = colour; @@ -148,55 +164,60 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, const_utf8string buffer, uint8_t co } // Basic -void gfx_draw_string_left(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y) +void gfx_draw_string_left(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y) { DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::LEFT); } -void gfx_draw_string_centred(rct_drawpixelinfo * dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, void * args) +void gfx_draw_string_centred(rct_drawpixelinfo* dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, void* args) { DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::CENTRE); } -void gfx_draw_string_right(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y) +void gfx_draw_string_right(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y) { DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::RIGHT); } // Underline -void draw_string_left_underline(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y) +void draw_string_left_underline(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y) { DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::LEFT, true); } -void draw_string_centred_underline(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y) +void draw_string_centred_underline( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y) { DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::CENTRE, true); } -void draw_string_right_underline(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y) +void draw_string_right_underline(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y) { DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::RIGHT, true); } // Ellipsised -void gfx_draw_string_left_clipped(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y, int32_t width) +void gfx_draw_string_left_clipped( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y, int32_t width) { DrawTextEllipsisedCompat(dpi, x, y, width, format, args, colour, TextAlignment::LEFT); } -void gfx_draw_string_centred_clipped(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y, int32_t width) +void gfx_draw_string_centred_clipped( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y, int32_t width) { DrawTextEllipsisedCompat(dpi, x, y, width, format, args, colour, TextAlignment::CENTRE); } -void gfx_draw_string_right_clipped(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8_t colour, int32_t x, int32_t y, int32_t width) +void gfx_draw_string_right_clipped( + rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y, int32_t width) { DrawTextEllipsisedCompat(dpi, x, y, width, format, args, colour, TextAlignment::RIGHT); } // Wrapping -int32_t gfx_draw_string_left_wrapped(rct_drawpixelinfo * dpi, void * args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour) +int32_t gfx_draw_string_left_wrapped( + rct_drawpixelinfo* dpi, void* args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour) { utf8 buffer[256]; format_string(buffer, sizeof(buffer), format, args); @@ -214,7 +235,8 @@ int32_t gfx_draw_string_left_wrapped(rct_drawpixelinfo * dpi, void * args, int32 return layout.GetHeight(); } -int32_t gfx_draw_string_centred_wrapped(rct_drawpixelinfo * dpi, void * args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour) +int32_t gfx_draw_string_centred_wrapped( + rct_drawpixelinfo* dpi, void* args, int32_t x, int32_t y, int32_t width, rct_string_id format, uint8_t colour) { utf8 buffer[256]; format_string(buffer, sizeof(buffer), format, args); @@ -237,4 +259,3 @@ int32_t gfx_draw_string_centred_wrapped(rct_drawpixelinfo * dpi, void * args, in return layout.GetHeight(); } - diff --git a/src/openrct2/drawing/Text.h b/src/openrct2/drawing/Text.h index 219e66a041..f459878480 100644 --- a/src/openrct2/drawing/Text.h +++ b/src/openrct2/drawing/Text.h @@ -22,27 +22,27 @@ enum class TextAlignment struct TextPaint { - uint8_t Colour = 0; - int16_t SpriteBase = 0; - bool UnderlineText = false; - TextAlignment Alignment = TextAlignment::LEFT; + uint8_t Colour = 0; + int16_t SpriteBase = 0; + bool UnderlineText = false; + TextAlignment Alignment = TextAlignment::LEFT; }; class StaticLayout { private: - utf8string _buffer; - TextPaint _paint; - int32_t _lineCount = 0; - int32_t _lineHeight; - int32_t _maxWidth; + utf8string _buffer; + TextPaint _paint; + int32_t _lineCount = 0; + int32_t _lineHeight; + int32_t _maxWidth; StaticLayout(); - StaticLayout(const StaticLayout &); + StaticLayout(const StaticLayout&); public: StaticLayout(utf8string source, TextPaint paint, int32_t width); - void Draw(rct_drawpixelinfo * dpi, int32_t x, int32_t y); + void Draw(rct_drawpixelinfo* dpi, int32_t x, int32_t y); int32_t GetHeight(); int32_t GetWidth(); int32_t GetLineCount(); diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index f9d58b7c05..af11e869fb 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -7,24 +7,25 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include -#include -#include "../config/Config.h" -#include "../Context.h" -#include "../ui/UiContext.h" -#include "../core/Math.hpp" -#include "../interface/Screenshot.h" -#include "IDrawingContext.h" -#include "IDrawingEngine.h" -#include "Rain.h" #include "X8DrawingEngine.h" +#include "../Context.h" #include "../Game.h" +#include "../Intro.h" +#include "../config/Config.h" +#include "../core/Math.hpp" +#include "../interface/Screenshot.h" #include "../interface/Viewport.h" #include "../interface/Window.h" -#include "../Intro.h" +#include "../ui/UiContext.h" #include "Drawing.h" +#include "IDrawingContext.h" +#include "IDrawingEngine.h" #include "LightFX.h" +#include "Rain.h" + +#include +#include using namespace OpenRCT2; using namespace OpenRCT2::Drawing; @@ -37,10 +38,10 @@ X8RainDrawer::X8RainDrawer() X8RainDrawer::~X8RainDrawer() { - delete [] _rainPixels; + delete[] _rainPixels; } -void X8RainDrawer::SetDPI(rct_drawpixelinfo * dpi) +void X8RainDrawer::SetDPI(rct_drawpixelinfo* dpi) { _screenDPI = dpi; } @@ -57,7 +58,7 @@ void X8RainDrawer::Draw(int32_t x, int32_t y, int32_t width, int32_t height, int }; // clang-format on - const uint8_t * pattern = RainPattern; + const uint8_t* pattern = RainPattern; uint8_t patternXSpace = *pattern++; uint8_t patternYSpace = *pattern++; @@ -67,10 +68,10 @@ void X8RainDrawer::Draw(int32_t x, int32_t y, int32_t width, int32_t height, int uint32_t pixelOffset = (_screenDPI->pitch + _screenDPI->width) * y + x; uint8_t patternYPos = patternStartYOffset % patternYSpace; - uint8_t * screenBits = _screenDPI->bits; + uint8_t* screenBits = _screenDPI->bits; - //Stores the colours of changed pixels - RainPixel * newPixels = &_rainPixels[_rainPixelsCount]; + // Stores the colours of changed pixels + RainPixel* newPixels = &_rainPixels[_rainPixelsCount]; for (; height != 0; height--) { uint8_t patternX = pattern[patternYPos * 2]; @@ -106,8 +107,8 @@ void X8RainDrawer::Restore() { if (_rainPixelsCount > 0) { - uint32_t numPixels = (_screenDPI->width + _screenDPI->pitch) * _screenDPI->height; - uint8_t * bits = _screenDPI->bits; + uint32_t numPixels = (_screenDPI->width + _screenDPI->pitch) * _screenDPI->height; + uint8_t* bits = _screenDPI->bits; for (uint32_t i = 0; i < _rainPixelsCount; i++) { RainPixel rainPixel = _rainPixels[i]; @@ -140,8 +141,8 @@ X8DrawingEngine::X8DrawingEngine([[maybe_unused]] const std::shared_ptr= right) return; - if (top >= bottom) return; + if (left >= right) + return; + if (top >= bottom) + return; right--; bottom--; @@ -182,7 +185,7 @@ void X8DrawingEngine::Invalidate(int32_t left, int32_t top, int32_t right, int32 bottom >>= _dirtyGrid.BlockShiftY; uint32_t dirtyBlockColumns = _dirtyGrid.BlockColumns; - uint8_t * screenDirtyBlocks = _dirtyGrid.Blocks; + uint8_t* screenDirtyBlocks = _dirtyGrid.Blocks; for (int16_t y = top; y <= bottom; y++) { uint32_t yOffset = y * dirtyBlockColumns; @@ -234,7 +237,8 @@ void X8DrawingEngine::PaintRain() void X8DrawingEngine::CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) { - if (dx == 0 && dy == 0) return; + if (dx == 0 && dy == 0) + return; // Originally 0x00683359 // Adjust for move off screen @@ -250,9 +254,9 @@ void X8DrawingEngine::CopyRect(int32_t x, int32_t y, int32_t width, int32_t heig width += lmargin + rmargin; height += tmargin + bmargin; - int32_t stride = _bitsDPI.width + _bitsDPI.pitch; - uint8_t * to = _bitsDPI.bits + y * stride + x; - uint8_t * from = _bitsDPI.bits + (y - dy) * stride + x - dx; + int32_t stride = _bitsDPI.width + _bitsDPI.pitch; + uint8_t* to = _bitsDPI.bits + y * stride + x; + uint8_t* from = _bitsDPI.bits + (y - dy) * stride + x - dx; if (dy > 0) { @@ -276,13 +280,13 @@ int32_t X8DrawingEngine::Screenshot() return screenshot_dump_png(&_bitsDPI); } -IDrawingContext * X8DrawingEngine::GetDrawingContext(rct_drawpixelinfo * dpi) +IDrawingContext* X8DrawingEngine::GetDrawingContext(rct_drawpixelinfo* dpi) { _drawingContext->SetDPI(dpi); return _drawingContext; } -rct_drawpixelinfo * X8DrawingEngine::GetDrawingPixelInfo() +rct_drawpixelinfo* X8DrawingEngine::GetDrawingPixelInfo() { return &_bitsDPI; } @@ -297,15 +301,15 @@ void X8DrawingEngine::InvalidateImage([[maybe_unused]] uint32_t image) // Not applicable for this engine } -rct_drawpixelinfo * X8DrawingEngine::GetDPI() +rct_drawpixelinfo* X8DrawingEngine::GetDPI() { return &_bitsDPI; } void X8DrawingEngine::ConfigureBits(uint32_t width, uint32_t height, uint32_t pitch) { - size_t newBitsSize = pitch * height; - uint8_t * newBits = new uint8_t[newBitsSize]; + size_t newBitsSize = pitch * height; + uint8_t* newBits = new uint8_t[newBitsSize]; if (_bits == nullptr) { std::fill_n(newBits, newBitsSize, 0); @@ -318,8 +322,8 @@ void X8DrawingEngine::ConfigureBits(uint32_t width, uint32_t height, uint32_t pi } else { - uint8_t * src = _bits; - uint8_t * dst = newBits; + uint8_t* src = _bits; + uint8_t* dst = newBits; uint32_t minWidth = std::min(_width, width); uint32_t minHeight = std::min(_height, height); @@ -334,7 +338,7 @@ void X8DrawingEngine::ConfigureBits(uint32_t width, uint32_t height, uint32_t pi dst += pitch; } } - delete [] _bits; + delete[] _bits; } _bits = newBits; @@ -343,7 +347,7 @@ void X8DrawingEngine::ConfigureBits(uint32_t width, uint32_t height, uint32_t pi _height = height; _pitch = pitch; - rct_drawpixelinfo * dpi = &_bitsDPI; + rct_drawpixelinfo* dpi = &_bitsDPI; dpi->bits = _bits; dpi->x = 0; dpi->y = 0; @@ -354,10 +358,10 @@ void X8DrawingEngine::ConfigureBits(uint32_t width, uint32_t height, uint32_t pi ConfigureDirtyGrid(); #ifdef __ENABLE_LIGHTFX__ - if (lightfx_is_available()) - { - lightfx_update_buffers(dpi); - } + if (lightfx_is_available()) + { + lightfx_update_buffers(dpi); + } #endif } @@ -375,15 +379,15 @@ void X8DrawingEngine::ConfigureDirtyGrid() _dirtyGrid.BlockColumns = (_width >> _dirtyGrid.BlockShiftX) + 1; _dirtyGrid.BlockRows = (_height >> _dirtyGrid.BlockShiftY) + 1; - delete [] _dirtyGrid.Blocks; + delete[] _dirtyGrid.Blocks; _dirtyGrid.Blocks = new uint8_t[_dirtyGrid.BlockColumns * _dirtyGrid.BlockRows]; } void X8DrawingEngine::DrawAllDirtyBlocks() { - uint32_t dirtyBlockColumns = _dirtyGrid.BlockColumns; - uint32_t dirtyBlockRows = _dirtyGrid.BlockRows; - uint8_t * dirtyBlocks = _dirtyGrid.Blocks; + uint32_t dirtyBlockColumns = _dirtyGrid.BlockColumns; + uint32_t dirtyBlockRows = _dirtyGrid.BlockRows; + uint8_t* dirtyBlocks = _dirtyGrid.Blocks; for (uint32_t x = 0; x < dirtyBlockColumns; x++) { @@ -429,8 +433,8 @@ void X8DrawingEngine::DrawAllDirtyBlocks() void X8DrawingEngine::DrawDirtyBlocks(uint32_t x, uint32_t y, uint32_t columns, uint32_t rows) { - uint32_t dirtyBlockColumns = _dirtyGrid.BlockColumns; - uint8_t * screenDirtyBlocks = _dirtyGrid.Blocks; + uint32_t dirtyBlockColumns = _dirtyGrid.BlockColumns; + uint8_t* screenDirtyBlocks = _dirtyGrid.Blocks; // Unset dirty blocks for (uint32_t top = y; top < y + rows; top++) @@ -461,23 +465,23 @@ void X8DrawingEngine::DrawDirtyBlocks(uint32_t x, uint32_t y, uint32_t columns, #pragma GCC diagnostic pop #endif -X8DrawingContext::X8DrawingContext(X8DrawingEngine * engine) +X8DrawingContext::X8DrawingContext(X8DrawingEngine* engine) { _engine = engine; } -IDrawingEngine * X8DrawingContext::GetEngine() +IDrawingEngine* X8DrawingContext::GetEngine() { return _engine; } void X8DrawingContext::Clear(uint8_t paletteIndex) { - rct_drawpixelinfo * dpi = _dpi; + rct_drawpixelinfo* dpi = _dpi; int32_t w = dpi->width >> dpi->zoom_level; int32_t h = dpi->height >> dpi->zoom_level; - uint8_t * ptr = dpi->bits; + uint8_t* ptr = dpi->bits; for (int32_t y = 0; y < h; y++) { @@ -536,14 +540,20 @@ static constexpr const uint16_t * Patterns[] = { void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom) { - rct_drawpixelinfo * dpi = _dpi; + rct_drawpixelinfo* dpi = _dpi; - if (left > right) return; - if (top > bottom) return; - if (dpi->x > right) return; - if (left >= dpi->x + dpi->width) return; - if (bottom < dpi->y) return; - if (top >= dpi->y + dpi->height) return; + if (left > right) + return; + if (top > bottom) + return; + if (dpi->x > right) + return; + if (left >= dpi->x + dpi->width) + return; + if (bottom < dpi->y) + return; + if (top >= dpi->y + dpi->height) + return; uint16_t crossPattern = 0; @@ -579,11 +589,11 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3 if (colour & 0x1000000) { // Cross hatching - uint8_t * dst = (startY * (dpi->width + dpi->pitch)) + startX + dpi->bits; + uint8_t* dst = (startY * (dpi->width + dpi->pitch)) + startX + dpi->bits; for (int32_t i = 0; i < height; i++) { - uint8_t * nextdst = dst + dpi->width + dpi->pitch; - uint32_t p = ror32(crossPattern, 1); + uint8_t* nextdst = dst + dpi->width + dpi->pitch; + uint32_t p = ror32(crossPattern, 1); p = (p & 0xFFFF0000) | width; // Fill every other pixel with the colour @@ -606,7 +616,7 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3 } else if (colour & 0x4000000) { - uint8_t * dst = startY * (dpi->width + dpi->pitch) + startX + dpi->bits; + uint8_t* dst = startY * (dpi->width + dpi->pitch) + startX + dpi->bits; // The pattern loops every 15 lines this is which // part the pattern is on. @@ -617,12 +627,12 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3 int32_t startPatternX = (startX + dpi->x) % 16; int32_t patternX = startPatternX; - const uint16_t * patternsrc = Patterns[colour >> 28]; // or possibly uint8_t)[esi*4] ? + const uint16_t* patternsrc = Patterns[colour >> 28]; // or possibly uint8_t)[esi*4] ? for (int32_t numLines = height; numLines > 0; numLines--) { - uint8_t * nextdst = dst + dpi->width + dpi->pitch; - uint16_t pattern = patternsrc[patternY]; + uint8_t* nextdst = dst + dpi->width + dpi->pitch; + uint16_t pattern = patternsrc[patternY]; for (int32_t numPixels = width; numPixels > 0; numPixels--) { @@ -640,7 +650,7 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3 } else { - uint8_t * dst = startY * (dpi->width + dpi->pitch) + startX + dpi->bits; + uint8_t* dst = startY * (dpi->width + dpi->pitch) + startX + dpi->bits; for (int32_t i = 0; i < height; i++) { std::fill_n(dst, width, colour & 0xFF); @@ -651,14 +661,20 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3 void X8DrawingContext::FilterRect(FILTER_PALETTE_ID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) { - rct_drawpixelinfo * dpi = _dpi; + rct_drawpixelinfo* dpi = _dpi; - if (left > right) return; - if (top > bottom) return; - if (dpi->x > right) return; - if (left >= dpi->x + dpi->width) return; - if (bottom < dpi->y) return; - if (top >= dpi->y + dpi->height) return; + if (left > right) + return; + if (top > bottom) + return; + if (dpi->x > right) + return; + if (left >= dpi->x + dpi->width) + return; + if (bottom < dpi->y) + return; + if (top >= dpi->y + dpi->height) + return; int32_t startX = left - dpi->x; if (startX < 0) @@ -687,11 +703,12 @@ void X8DrawingContext::FilterRect(FILTER_PALETTE_ID palette, int32_t left, int32 int32_t width = endX - startX; int32_t height = endY - startY; - - //0x2000000 + // 0x2000000 // 00678B7E 00678C83 // Location in screen buffer? - uint8_t * dst = dpi->bits + (uint32_t)((startY >> (dpi->zoom_level)) * ((dpi->width >> dpi->zoom_level) + dpi->pitch) + (startX >> dpi->zoom_level)); + uint8_t* dst = dpi->bits + + (uint32_t)((startY >> (dpi->zoom_level)) * ((dpi->width >> dpi->zoom_level) + dpi->pitch) + + (startX >> dpi->zoom_level)); // Find colour in colour table? uint16_t g1Index = palette_to_g1_offset[palette]; @@ -703,9 +720,9 @@ void X8DrawingContext::FilterRect(FILTER_PALETTE_ID palette, int32_t left, int32 const int32_t step = ((dpi->width >> dpi->zoom_level) + dpi->pitch); // Fill the rectangle with the colours from the colour table - for (int32_t i = 0; i < height >> dpi->zoom_level; i++) + for (int32_t i = 0; i> dpi->zoom_level; i++) { - uint8_t * nextdst = dst + step * i; + uint8_t* nextdst = dst + step * i; for (int32_t j = 0; j < scaled_width; j++) { *(nextdst + j) = g1Bits[*(nextdst + j)]; @@ -739,12 +756,12 @@ void X8DrawingContext::DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uin gfx_draw_sprite_palette_set_software(_dpi, image | IMAGE_TYPE_REMAP, x, y, palette, nullptr); } -void X8DrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t * palette) +void X8DrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t* palette) { gfx_draw_sprite_palette_set_software(_dpi, image, x, y, palette, nullptr); } -void X8DrawingContext::SetDPI(rct_drawpixelinfo * dpi) +void X8DrawingContext::SetDPI(rct_drawpixelinfo* dpi) { _dpi = dpi; } diff --git a/src/openrct2/drawing/X8DrawingEngine.h b/src/openrct2/drawing/X8DrawingEngine.h index ee0c744b26..3c962f68d6 100644 --- a/src/openrct2/drawing/X8DrawingEngine.h +++ b/src/openrct2/drawing/X8DrawingEngine.h @@ -26,13 +26,13 @@ namespace OpenRCT2 struct DirtyGrid { - uint32_t BlockShiftX; - uint32_t BlockShiftY; - uint32_t BlockWidth; - uint32_t BlockHeight; - uint32_t BlockColumns; - uint32_t BlockRows; - uint8_t * Blocks; + uint32_t BlockShiftX; + uint32_t BlockShiftY; + uint32_t BlockWidth; + uint32_t BlockHeight; + uint32_t BlockColumns; + uint32_t BlockRows; + uint8_t* Blocks; }; class X8RainDrawer final : public IRainDrawer @@ -41,47 +41,47 @@ namespace OpenRCT2 struct RainPixel { uint32_t Position; - uint8_t Colour; + uint8_t Colour; }; static constexpr uint32_t MaxRainPixels = 0xFFFE; - size_t _rainPixelsCapacity = MaxRainPixels; - uint32_t _rainPixelsCount = 0; - RainPixel * _rainPixels = nullptr; - rct_drawpixelinfo * _screenDPI = nullptr; + size_t _rainPixelsCapacity = MaxRainPixels; + uint32_t _rainPixelsCount = 0; + RainPixel* _rainPixels = nullptr; + rct_drawpixelinfo* _screenDPI = nullptr; public: X8RainDrawer(); ~X8RainDrawer(); - void SetDPI(rct_drawpixelinfo * dpi); + void SetDPI(rct_drawpixelinfo* dpi); void Draw(int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart) override; void Restore(); }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wsuggest-final-types" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif class X8DrawingEngine : public IDrawingEngine { protected: - uint32_t _width = 0; - uint32_t _height = 0; - uint32_t _pitch = 0; - size_t _bitsSize = 0; - uint8_t * _bits = nullptr; + uint32_t _width = 0; + uint32_t _height = 0; + uint32_t _pitch = 0; + size_t _bitsSize = 0; + uint8_t* _bits = nullptr; - DirtyGrid _dirtyGrid = {}; + DirtyGrid _dirtyGrid = {}; - rct_drawpixelinfo _bitsDPI = {}; + rct_drawpixelinfo _bitsDPI = {}; - #ifdef __ENABLE_LIGHTFX__ +#ifdef __ENABLE_LIGHTFX__ bool _lastLightFXenabled = false; - #endif +#endif - X8RainDrawer _rainDrawer; - X8DrawingContext * _drawingContext; + X8RainDrawer _rainDrawer; + X8DrawingContext* _drawingContext; public: explicit X8DrawingEngine(const std::shared_ptr& uiContext); @@ -89,7 +89,7 @@ namespace OpenRCT2 void Initialise() override; void Resize(uint32_t width, uint32_t height) override; - void SetPalette(const rct_palette_entry * palette) override; + void SetPalette(const rct_palette_entry* palette) override; void SetVSync(bool vsync) override; void Invalidate(int32_t left, int32_t top, int32_t right, int32_t bottom) override; void BeginDraw() override; @@ -98,12 +98,12 @@ namespace OpenRCT2 void PaintRain() override; void CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) override; int32_t Screenshot() override; - IDrawingContext * GetDrawingContext(rct_drawpixelinfo * dpi) override; - rct_drawpixelinfo * GetDrawingPixelInfo() override; + IDrawingContext* GetDrawingContext(rct_drawpixelinfo* dpi) override; + rct_drawpixelinfo* GetDrawingPixelInfo() override; DRAWING_ENGINE_FLAGS GetFlags() override; void InvalidateImage(uint32_t image) override; - rct_drawpixelinfo * GetDPI(); + rct_drawpixelinfo* GetDPI(); protected: void ConfigureBits(uint32_t width, uint32_t height, uint32_t pitch); @@ -116,19 +116,19 @@ namespace OpenRCT2 void DrawDirtyBlocks(uint32_t x, uint32_t y, uint32_t columns, uint32_t rows); }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ - #pragma GCC diagnostic pop +#pragma GCC diagnostic pop #endif class X8DrawingContext final : public IDrawingContext { private: - X8DrawingEngine * _engine = nullptr; - rct_drawpixelinfo * _dpi = nullptr; + X8DrawingEngine* _engine = nullptr; + rct_drawpixelinfo* _dpi = nullptr; public: - explicit X8DrawingContext(X8DrawingEngine * engine); + explicit X8DrawingContext(X8DrawingEngine* engine); - IDrawingEngine * GetEngine() override; + IDrawingEngine* GetEngine() override; void Clear(uint8_t paletteIndex) override; void FillRect(uint32_t colour, int32_t x, int32_t y, int32_t w, int32_t h) override; @@ -137,9 +137,9 @@ namespace OpenRCT2 void DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override; void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override; void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) override; - void DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t * palette) override; + void DrawGlyph(uint32_t image, int32_t x, int32_t y, uint8_t* palette) override; - void SetDPI(rct_drawpixelinfo * dpi); + void SetDPI(rct_drawpixelinfo* dpi); }; } // namespace Drawing } // namespace OpenRCT2