1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 19:13:07 +01:00

clang-format drawing

This commit is contained in:
clang-format
2018-06-22 22:59:03 +02:00
committed by Hielke Morsink
parent 3a4a11f738
commit 602aac47ba
30 changed files with 2841 additions and 1983 deletions

View File

@@ -15,8 +15,15 @@
#include <immintrin.h>
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");
}

View File

@@ -7,21 +7,22 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include <memory>
#include <stdexcept>
#include <vector>
#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 <memory>
#include <stdexcept>
#include <vector>
using namespace OpenRCT2;
using namespace OpenRCT2::Ui;
@@ -38,7 +39,7 @@ struct rct_gx
{
rct_g1_header header;
std::vector<rct_g1_element> 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<rct_g1_element_32bit[]>(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
{

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
}

View File

@@ -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"

View File

@@ -9,19 +9,20 @@
#pragma warning(disable : 4127) // conditional expression is constant
#include <cstring>
#include "Drawing.h"
#include <cstring>
template<int32_t image_type, int32_t zoom_level>
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<image_type, zoom_level>(source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width)
#define DrawRLESpriteHelper2(image_type, zoom_level) \
DrawRLESprite2<image_type, zoom_level>( \
source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width)
template<int32_t image_type>
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<image_type>(source_bits_pointer, dest_bits_pointer, palette_pointer, dpi, source_y_start, height, source_x_start, width)
#define DrawRLESpriteHelper1(image_type) \
DrawRLESprite1<image_type>( \
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);
}
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -9,9 +9,10 @@
#pragma once
#include <memory>
#include "../common.h"
#include <memory>
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<IDrawingEngine> Create(DRAWING_ENGINE_TYPE type, const std::shared_ptr<OpenRCT2::Ui::IUiContext>& uiContext) abstract;
virtual ~IDrawingEngineFactory()
{
}
virtual std::unique_ptr<IDrawingEngine> Create(
DRAWING_ENGINE_TYPE type, const std::shared_ptr<OpenRCT2::Ui::IUiContext>& 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

View File

@@ -7,14 +7,14 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include <algorithm>
#include <list>
#include "../OpenRCT2.h"
#include "../core/Console.hpp"
#include "../core/Guard.hpp"
#include "../OpenRCT2.h"
#include "Drawing.h"
#include <algorithm>
#include <list>
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<ImageList> _freeLists;
static uint32_t _allocatedImageCount;
static uint32_t _allocatedImageCount;
#ifdef DEBUG
static std::list<ImageList> _allocatedLists;
@@ -40,13 +40,10 @@ static std::list<ImageList> _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<ImageList> _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
}
}

View File

@@ -7,23 +7,21 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "ImageImporter.h"
#include "../core/Imaging.h"
#include <cstring>
#include <stdexcept>
#include <string>
#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<int32_t> ImageImporter::GetPixels(const uint8_t * pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode)
std::vector<int32_t>
ImageImporter::GetPixels(const uint8_t* pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode)
{
std::vector<int32_t> buffer;
buffer.reserve(width * height);
@@ -110,10 +108,10 @@ std::vector<int32_t> ImageImporter::GetPixels(const uint8_t * pixels, uint32_t w
return buffer;
}
std::tuple<void *, size_t> ImageImporter::EncodeRaw(const int32_t * pixels, uint32_t width, uint32_t height)
std::tuple<void*, size_t> 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<void *, size_t> ImageImporter::EncodeRaw(const int32_t * pixels, uint
return std::make_tuple(buffer, bufferLength);
}
std::tuple<void *, size_t> ImageImporter::EncodeRLE(const int32_t * pixels, uint32_t width, uint32_t height)
std::tuple<void*, size_t> ImageImporter::EncodeRLE(const int32_t* pixels, uint32_t width, uint32_t height)
{
struct RLECode
{
@@ -131,21 +129,21 @@ std::tuple<void *, size_t> 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<void *, size_t> 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<void *, size_t> 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<void *, size_t> 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 },

View File

@@ -7,11 +7,12 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include <string_view>
#include <tuple>
#include "../core/Imaging.h"
#include "Drawing.h"
#include <string_view>
#include <tuple>
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<int32_t> GetPixels(const uint8_t * pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode);
static std::tuple<void *, size_t> EncodeRaw(const int32_t * pixels, uint32_t width, uint32_t height);
static std::tuple<void *, size_t> EncodeRLE(const int32_t * pixels, uint32_t width, uint32_t height);
static std::vector<int32_t>
GetPixels(const uint8_t* pixels, uint32_t width, uint32_t height, IMPORT_FLAGS flags, IMPORT_MODE mode);
static std::tuple<void*, size_t> EncodeRaw(const int32_t* pixels, uint32_t width, uint32_t height);
static std::tuple<void*, size_t> 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

File diff suppressed because it is too large Load Diff

View File

@@ -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__

View File

@@ -7,49 +7,57 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "Drawing.h"
#include <cmath>
#include <cstdlib>
#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);
}
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -15,8 +15,15 @@
#include <immintrin.h>
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");
}

View File

@@ -7,7 +7,6 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include <algorithm>
#include "../config/Config.h"
#include "../interface/Colour.h"
#include "../localisation/Localisation.h"
@@ -17,16 +16,19 @@
#include "Drawing.h"
#include "TTF.h"
#include <algorithm>
#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++)
{

View File

@@ -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);
}

View File

@@ -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);

File diff suppressed because it is too large Load Diff

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -7,24 +7,25 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include <algorithm>
#include <cstring>
#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 <algorithm>
#include <cstring>
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<Ui::IUiC
X8DrawingEngine::~X8DrawingEngine()
{
delete _drawingContext;
delete [] _dirtyGrid.Blocks;
delete [] _bits;
delete[] _dirtyGrid.Blocks;
delete[] _bits;
}
void X8DrawingEngine::Initialise()
@@ -170,8 +171,10 @@ void X8DrawingEngine::Invalidate(int32_t left, int32_t top, int32_t right, int32
right = std::min(right, (int32_t)_width);
bottom = std::min(bottom, (int32_t)_height);
if (left >= 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<height>> 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;
}

View File

@@ -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<Ui::IUiContext>& 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