1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-27 16:54:52 +01:00

implement utf8, part 14

This commit is contained in:
IntelOrca
2015-07-29 14:36:21 +01:00
parent 617880e8d2
commit fa87d8e999
14 changed files with 346 additions and 173 deletions

View File

@@ -33,6 +33,7 @@
<ClCompile Include="..\src\cursors.c" />
<ClCompile Include="..\src\diagnostic.c" />
<ClCompile Include="..\src\drawing\drawing.c" />
<ClCompile Include="..\src\drawing\font.c" />
<ClCompile Include="..\src\drawing\line.c" />
<ClCompile Include="..\src\drawing\rain.c" />
<ClCompile Include="..\src\drawing\rect.c" />
@@ -195,6 +196,7 @@
<ClInclude Include="..\src\cursors.h" />
<ClInclude Include="..\src\diagnostic.h" />
<ClInclude Include="..\src\drawing\drawing.h" />
<ClInclude Include="..\src\drawing\font.h" />
<ClInclude Include="..\src\editor.h" />
<ClInclude Include="..\src\game.h" />
<ClInclude Include="..\src\hook.h" />

View File

@@ -501,6 +501,9 @@
<ClCompile Include="..\src\drawing\scrolling_text.c">
<Filter>Source\Drawing</Filter>
</ClCompile>
<ClCompile Include="..\src\drawing\font.c">
<Filter>Source\Drawing</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\management\award.h">
@@ -731,5 +734,8 @@
<ClInclude Include="..\src\cheats.h">
<Filter>Source</Filter>
</ClInclude>
<ClInclude Include="..\src\drawing\font.h">
<Filter>Source\Drawing</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -22,6 +22,7 @@
#define _DRAWING_H_
#include "../common.h"
#include "font.h"
// Size: 0x10
typedef struct {
@@ -113,7 +114,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32
void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer);
// string
void gfx_load_character_widths();
int clip_text(char *buffer, int width);
int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height);
int gfx_get_string_width(char *buffer);

94
src/drawing/font.c Normal file
View File

@@ -0,0 +1,94 @@
#include "../addresses.h"
#include "../localisation/localisation.h"
#include "../sprites.h"
#include "drawing.h"
#include "font.h"
static uint8 *_spriteFontCharacterWidths = (uint8*)RCT2_ADDRESS_FONT_CHAR_WIDTH;
/**
*
* rct2: 0x006C19AC
*/
void font_sprite_initialise_characters()
{
uint8* pCharacterWidth = _spriteFontCharacterWidths;
for (int fontSize = 0; fontSize < FONT_SIZE_COUNT; fontSize++) {
int glyphOffset = fontSize * FONT_SPRITE_GLYPH_COUNT;
for (uint8 glyphIndex = 0; glyphIndex < FONT_SPRITE_GLYPH_COUNT; glyphIndex++) {
rct_g1_element g1 = g1Elements[glyphIndex + SPR_CHAR_START + glyphOffset];
int width = fontSize == FONT_SIZE_BIG ? g1.width + 1 : g1.width - 1;
if (glyphIndex >= (FORMAT_ARGUMENT_CODE_START - 32) && glyphIndex < (FORMAT_COLOUR_CODE_END - 32)) {
width = 0;
}
*pCharacterWidth++ = (uint8)width;
}
}
scrolling_text_initialise_bitmaps();
for (int i = 0; i < 32; i++) {
rct_g1_element* g1 = &g1Elements[0x606 + i];
uint8* unknown_pointer = RCT2_ADDRESS(0x009C3852, uint8) + 0xA12 * i;
g1->offset = unknown_pointer;
g1->width = 64;
g1->height = 40;
*((uint16*)unknown_pointer) = 0xFFFF;
*((uint32*)(unknown_pointer + 0x0E)) = 0;
}
}
int font_sprite_get_codepoint_offset(int codepoint)
{
switch (codepoint) {
case FORMAT_ENDQUOTES: return 34 - 32;
case FORMAT_AMINUSCULE: return 159 - 32;
case FORMAT_UP: return 160 - 32;
case FORMAT_SYMBOL_i: return 160 - 32;
case FORMAT_CENT: return 162 - 32;
case FORMAT_POUND: return 163 - 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_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;
default:
if (codepoint < 32 || codepoint >= 256) codepoint = '?';
return codepoint - 32;
}
}
int font_sprite_get_codepoint_width(int fontSpriteBase, int codepoint)
{
return _spriteFontCharacterWidths[fontSpriteBase + font_sprite_get_codepoint_offset(codepoint)];
}
int font_sprite_get_codepoint_sprite(int fontSpriteBase, int codepoint)
{
return SPR_CHAR_START + ((IMAGE_TYPE_USE_PALETTE << 28) | (fontSpriteBase + font_sprite_get_codepoint_offset(codepoint)));
}

28
src/drawing/font.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef _DRAWING_FONT_H_
#define _DRAWING_FONT_H_
#include "../common.h"
enum {
FONT_SIZE_TINY = 2,
FONT_SIZE_SMALL = 0,
FONT_SIZE_MEDIUM = 1,
FONT_SIZE_BIG = 3,
FONT_SIZE_COUNT = 4
};
enum {
FONT_SPRITE_GLYPH_COUNT = 224,
FONT_SPRITE_BASE_TINY = 448,
FONT_SPRITE_BASE_SMALL = 0,
FONT_SPRITE_BASE_MEDIUM = 224,
FONT_SPRITE_BASE_BIG = 672
};
void font_sprite_initialise_characters();
int font_sprite_get_codepoint_offset(int codepoint);
int font_sprite_get_codepoint_width(int fontSpriteBase, int codepoint);
int font_sprite_get_codepoint_sprite(int fontSpriteBase, int codepoint);
#endif

View File

@@ -1,3 +1,4 @@
#include <SDL_ttf.h>
#include "../addresses.h"
#include "../config.h"
#include "../localisation/localisation.h"
@@ -15,6 +16,10 @@ typedef struct {
} rct_draw_scroll_text;
rct_draw_scroll_text *gDrawScrollTextList = RCT2_ADDRESS(RCT2_ADDRESS_DRAW_SCROLL_LIST, rct_draw_scroll_text);
uint8 *gCharacterBitmaps = RCT2_ADDRESS(RCT2_ADDRESS_CHARACTER_BITMAP, uint8);
void scrolling_text_set_bitmap_for_sprite(utf8 *text, int scroll, uint8 *bitmap, sint16 *scrollPositionOffsets);
void scrolling_text_set_bitmap_for_ttf(utf8 *text, int scroll, uint8 *bitmap, sint16 *scrollPositionOffsets);
void scrolling_text_initialise_bitmaps()
{
@@ -42,27 +47,22 @@ void scrolling_text_initialise_bitmaps()
val |= 0x80;
}
}
RCT2_ADDRESS(RCT2_ADDRESS_CHARACTER_BITMAP, uint8)[i * 8 + x] = val;
gCharacterBitmaps[i * 8 + x] = val;
}
}
}
/**
*
* rct2: 0x006C42D9
*/
int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode)
static uint8 *font_sprite_get_codepoint_bitmap(int codepoint)
{
rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
return &gCharacterBitmaps[font_sprite_get_codepoint_offset(codepoint) * 8];
}
if (dpi->zoom_level != 0) return 0x626;
RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32)++;
// Find the oldest scroll for use as the newest
static int scrolling_text_get_matching_or_oldest(rct_string_id stringId, uint16 scroll, uint16 scrollingMode)
{
uint32 oldestId = 0xFFFFFFFF;
uint8 scrollIndex = 0xFF;
int scrollIndex = -1;
rct_draw_scroll_text* oldestScroll = NULL;
for (int i = 0; i < 32; i++) {
rct_draw_scroll_text *scrollText = &gDrawScrollTextList[i];
@@ -84,70 +84,103 @@ int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrolling
return i + 0x606;
}
}
return scrollIndex;
}
static uint8 scrolling_text_get_colour(uint32 character)
{
int edi = character & 0x7F;
int offset = 0;
if (character >= 0x80) offset = 2;
return RCT2_ADDRESS(0x0141FC47, uint8)[offset + (edi * 8)];
}
static void scrolling_text_format(utf8 *dst, rct_draw_scroll_text *scrollText)
{
if (gConfigGeneral.upper_case_banners) {
format_string_to_upper(dst, scrollText->string_id, &scrollText->string_args_0);
} else {
format_string(dst, scrollText->string_id, &scrollText->string_args_0);
}
}
/**
*
* rct2: 0x006C42D9
*/
int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode)
{
rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
if (dpi->zoom_level != 0) return 0x626;
RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32)++;
int scrollIndex = scrolling_text_get_matching_or_oldest(stringId, scroll, scrollingMode);
if (scrollIndex >= 0x606) return scrollIndex;
// Setup scrolling text
rct_draw_scroll_text* scrollText = oldestScroll;
rct_draw_scroll_text* scrollText = &gDrawScrollTextList[scrollIndex];
scrollText->string_id = stringId;
scrollText->string_args_0 = RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32);
scrollText->string_args_1 = RCT2_GLOBAL(0x13CE956, uint32);
scrollText->string_args_0 = RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32);
scrollText->string_args_1 = RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32);
scrollText->position = scroll;
scrollText->mode = scrollingMode;
scrollText->id = RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32_t);
scrollText->id = RCT2_GLOBAL(RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID, uint32);
uint8* scrollPixelPointer = scrollText->bitmap;
memset(scrollPixelPointer, 0, 320 * 8);
// Create the string to draw
utf8 scrollString[256];
scrolling_text_format(scrollString, scrollText);
// Convert string id back into a string for processing
utf8 scrollString[MAX_PATH];
if (gConfigGeneral.upper_case_banners)
format_string_to_upper(scrollString, stringId, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS);
else
format_string(scrollString, stringId, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS);
sint16* scrollingModePositions = RCT2_ADDRESS(RCT2_ADDRESS_SCROLLING_MODE_POSITIONS, uint16*)[scrollingMode];
memset(scrollText->bitmap, 0, 320 * 8);
if (gUseTrueTypeFont) {
scrolling_text_set_bitmap_for_ttf(scrollString, scroll, scrollText->bitmap, scrollingModePositions);
} else {
scrolling_text_set_bitmap_for_sprite(scrollString, scroll, scrollText->bitmap, scrollingModePositions);
}
// Setup character colour from ???
uint32 character = RCT2_GLOBAL(0x13CE959, uint8);
int edi = character & 0x7F;
int offs = 0;
if (character >= 0x80) offs = 2;
uint8 characterColour = RCT2_ADDRESS(0x0141FC47, uint8)[offs + edi * 8];
return scrollIndex + 0x606;
}
sint16* scrollingModePositions = RCT2_ADDRESS(RCT2_ADDRESS_SCROLLING_MODE_POSITIONS, uint16_t*)[scrollingMode];
uint8* formatResult = scrollString;
void scrolling_text_set_bitmap_for_sprite(utf8 *text, int scroll, uint8 *bitmap, sint16 *scrollPositionOffsets)
{
uint8 characterColour = scrolling_text_get_colour(RCT2_GLOBAL(0x013CE959, uint8));
utf8 *ch = text;
while (true) {
character = utf8_get_next(formatResult, &formatResult);
uint32 codepoint = utf8_get_next(ch, &ch);
// If at the end of the string loop back to the start
if (character == 0) {
formatResult = scrollString;
if (codepoint == 0) {
ch = text;
continue;
}
// Set any change in colour
if (character <= FORMAT_COLOUR_CODE_END && character >= FORMAT_COLOUR_CODE_START){
character -= FORMAT_COLOUR_CODE_START;
characterColour = RCT2_GLOBAL(0x009FF048, uint8*)[character * 4];
if (codepoint <= FORMAT_COLOUR_CODE_END && codepoint >= FORMAT_COLOUR_CODE_START){
codepoint -= FORMAT_COLOUR_CODE_START;
characterColour = RCT2_GLOBAL(0x009FF048, uint8*)[codepoint * 4];
continue;
}
// If another type of control character ignore
if (character < 32) continue;
if (codepoint < 32) continue;
// Convert to an indexable character
character = utf8_get_sprite_offset_for_codepoint(character);
uint8 characterWidth = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH + 448, uint8)[character];
uint8* characterBitmap = &(RCT2_ADDRESS(RCT2_ADDRESS_CHARACTER_BITMAP, uint8)[character * 8]);
int characterWidth = font_sprite_get_codepoint_width(FONT_SPRITE_BASE_TINY, codepoint);
uint8 *characterBitmap = font_sprite_get_codepoint_bitmap(codepoint);
for (; characterWidth != 0; characterWidth--, characterBitmap++) {
// Skip any none displayed columns
if (scroll != 0){
if (scroll != 0) {
scroll--;
continue;
}
sint16 scrollPosition = *scrollingModePositions;
if (scrollPosition == -1) return scrollIndex + 0x606;
sint16 scrollPosition = *scrollPositionOffsets;
if (scrollPosition == -1) return;
if (scrollPosition > -1) {
uint8* dst = &scrollPixelPointer[scrollPosition];
uint8 *dst = &bitmap[scrollPosition];
for (uint8 char_bitmap = *characterBitmap; char_bitmap != 0; char_bitmap >>= 1){
if (char_bitmap & 1) *dst = characterColour;
@@ -155,7 +188,83 @@ int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrolling
dst += 64;
}
}
scrollingModePositions++;
scrollPositionOffsets++;
}
}
}
}
TTF_Font *ttf_get_font_from_sprite_base(uint16 spriteBase);
SDL_Surface *_ttf_surface_cache_get_or_add(TTF_Font *font, const utf8 *text);
void scrolling_text_set_bitmap_for_ttf(utf8 *text, int scroll, uint8 *bitmap, sint16 *scrollPositionOffsets)
{
// Currently only supports one colour
uint8 colour = 0;
utf8 *dstCh = text;
utf8 *ch = text;
int codepoint;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) {
if (utf8_is_format_code(codepoint)) {
if (colour == 0 && codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) {
colour = (uint8)codepoint;
}
} else {
dstCh = utf8_write_codepoint(dstCh, codepoint);
}
}
*dstCh = 0;
if (colour == 0) {
colour = scrolling_text_get_colour(RCT2_GLOBAL(0x013CE959, uint8));
} else {
colour = RCT2_GLOBAL(0x009FF048, uint8*)[(colour - FORMAT_COLOUR_CODE_START) * 4];
}
TTF_Font *font = ttf_get_font_from_sprite_base(FONT_SPRITE_BASE_TINY);
SDL_Surface *surface = _ttf_surface_cache_get_or_add(font, text);
if (surface == NULL) {
return;
}
if (SDL_MUSTLOCK(surface) && SDL_LockSurface(surface) == -1) {
return;
}
int pitch = surface->pitch;
int width = surface->w;
int height = surface->h;
uint8 *src = surface->pixels;
// Offset
height -= 3;
src += 3 * pitch;
height = min(height, 8);
int x = 0;
while (true) {
// Skip any none displayed columns
if (scroll == 0) {
sint16 scrollPosition = *scrollPositionOffsets;
if (scrollPosition == -1) return;
if (scrollPosition > -1) {
uint8 *dst = &bitmap[scrollPosition];
for (int y = 0; y < height; y++) {
if (src[y * pitch + x] != 0) *dst = colour;
// Jump to next row
dst += 64;
}
}
scrollPositionOffsets++;
} else {
scroll--;
}
x++;
if (x >= width) x = 0;
}
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
}

View File

@@ -29,10 +29,10 @@ static void ttf_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, in
static bool _ttfInitialised = false;
static TTF_Font *_ttfFont[4] = { NULL };
static int _ttfFontOffsetX = 0;
static int _ttfFontOffsetY = 0;
int _ttfFontOffsetX = 0;
int _ttfFontOffsetY = 0;
static const int TTFFontSizes[] = { 7, 9, 11, 13 };
static const int TTFFontSizes[] = { 9, 9, 11, 13 };
#define TTF_SURFACE_CACHE_SIZE 256
#define TTF_GETWIDTH_CACHE_SIZE 1024
@@ -61,58 +61,6 @@ static int _ttfGetWidthCacheCount = 0;
static int _ttfGetWidthCacheHitCount = 0;
static int _ttfGetWidthCacheMissCount = 0;
enum {
FONT_SIZE_TINY = 2,
FONT_SIZE_SMALL = 0,
FONT_SIZE_MEDIUM = 1,
FONT_SIZE_BIG = 3,
FONT_SIZE_COUNT = 4
};
enum {
FONT_SPRITE_GLYPH_COUNT = 224,
FONT_SPRITE_BASE_TINY = 448,
FONT_SPRITE_BASE_SMALL = 0,
FONT_SPRITE_BASE_MEDIUM = 224,
FONT_SPRITE_BASE_BIG = 672
};
static uint8 *_spriteFontCharacterWidths = (uint8*)RCT2_ADDRESS_FONT_CHAR_WIDTH;
/**
*
* rct2: 0x006C19AC
*/
void gfx_load_character_widths()
{
uint8* pCharacterWidth = _spriteFontCharacterWidths;
for (int fontSize = 0; fontSize < FONT_SIZE_COUNT; fontSize++) {
int glyphOffset = fontSize * FONT_SPRITE_GLYPH_COUNT;
for (uint8 glyphIndex = 0; glyphIndex < FONT_SPRITE_GLYPH_COUNT; glyphIndex++) {
rct_g1_element g1 = g1Elements[glyphIndex + SPR_CHAR_START + glyphOffset];
int width = fontSize == FONT_SIZE_BIG ? g1.width + 1 : g1.width - 1;
if (glyphIndex >= (FORMAT_ARGUMENT_CODE_START - 32) && glyphIndex < (FORMAT_COLOUR_CODE_END - 32)) {
width = 0;
}
*pCharacterWidth++ = (uint8)width;
}
}
scrolling_text_initialise_bitmaps();
for (int i = 0; i < 32; i++) {
rct_g1_element* g1 = &g1Elements[0x606 + i];
uint8* unknown_pointer = RCT2_ADDRESS(0x009C3852, uint8) + 0xA12 * i;
g1->offset = unknown_pointer;
g1->width = 64;
g1->height = 40;
*((uint16*)unknown_pointer) = 0xFFFF;
*((uint32*)(unknown_pointer + 0x0E)) = 0;
}
}
/**
*
* rct2: 0x006C23B1
@@ -802,7 +750,7 @@ static void _ttf_surface_cache_dispose_all()
}
}
static SDL_Surface *_ttf_surface_cache_get_or_add(TTF_Font *font, const utf8 *text)
SDL_Surface *_ttf_surface_cache_get_or_add(TTF_Font *font, const utf8 *text)
{
ttf_cache_entry *entry;
@@ -987,16 +935,16 @@ typedef struct {
static void ttf_draw_character_sprite(rct_drawpixelinfo *dpi, int codepoint, text_draw_info *info)
{
uint32 charOffset = info->font_sprite_base + utf8_get_sprite_offset_for_codepoint(codepoint);
int charWidth = _spriteFontCharacterWidths[charOffset] & 0xFF;
int characterWidth = font_sprite_get_codepoint_width(info->font_sprite_base, codepoint);
int sprite = font_sprite_get_codepoint_sprite(info->font_sprite_base, codepoint);
if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) {
RCT2_GLOBAL(0x009ABDA4, uint8*) = (uint8*)&info->palette;
RCT2_GLOBAL(0x00EDF81C, uint32) = (IMAGE_TYPE_USE_PALETTE << 28);
gfx_draw_sprite_palette_set(dpi, SPR_CHAR_START + ((IMAGE_TYPE_USE_PALETTE << 28) | charOffset), info->x, info->y, info->palette, NULL);
gfx_draw_sprite_palette_set(dpi, sprite, info->x, info->y, info->palette, NULL);
}
info->x += charWidth;
info->x += characterWidth;
}
static void ttf_draw_string_raw_sprite(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info)

View File

@@ -144,6 +144,32 @@ bool utf8_is_codepoint_start(utf8 *text)
return false;
}
void utf8_remove_format_codes(utf8 *text)
{
utf8 *dstCh = text;
utf8 *ch = text;
int codepoint;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) {
if (!utf8_is_format_code(codepoint)) {
dstCh = utf8_write_codepoint(dstCh, codepoint);
}
}
*dstCh = 0;
}
int utf8_get_codepoint_length(int codepoint)
{
if (codepoint <= 0x7F) {
return 1;
} else if (codepoint <= 0x7FF) {
return 2;
} else if (codepoint <= 0xFFFF) {
return 3;
} else {
return 4;
}
}
const char *language_get_string(rct_string_id id)
{
const char *openrctString = NULL;

View File

@@ -73,5 +73,7 @@ rct_string_id object_get_localised_text(uint8_t** pStringTable/*ebp*/, int type/
uint32 utf8_get_next(const utf8 *char_ptr, const utf8 **nextchar_ptr);
utf8 *utf8_write_codepoint(utf8 *dst, uint32 codepoint);
bool utf8_is_codepoint_start(utf8 *text);
void utf8_remove_format_codes(utf8 *text);
int utf8_get_codepoint_length(int codepoint);
#endif

View File

@@ -154,50 +154,6 @@ bool utf8_should_use_sprite_for_codepoint(int codepoint)
}
}
int utf8_get_sprite_offset_for_codepoint(int codepoint)
{
switch (codepoint) {
case FORMAT_ENDQUOTES: return 34 - 32;
case FORMAT_AMINUSCULE: return 159 - 32;
case FORMAT_UP: return 160 - 32;
case FORMAT_SYMBOL_i: return 160 - 32;
case FORMAT_CENT: return 162 - 32;
case FORMAT_POUND: return 163 - 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_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;
default:
if (codepoint < 32 || codepoint >= 256) codepoint = '?';
return codepoint - 32;
}
}
int utf8_get_format_code_arg_length(int codepoint)
{
switch (codepoint) {

View File

@@ -28,7 +28,7 @@
bool utf8_is_format_code(int codepoint);
bool utf8_should_use_sprite_for_codepoint(int codepoint);
int utf8_get_sprite_offset_for_codepoint(int codepoint);
int font_sprite_get_codepoint_offset(int codepoint);
int utf8_get_format_code_arg_length(int codepoint);
void format_string(char *dest, rct_string_id format, void *args);

View File

@@ -99,7 +99,7 @@ int rct2_init()
gfx_load_g1();
gfx_load_g2();
gfx_load_character_widths();
font_sprite_initialise_characters();
if (!gOpenRCT2Headless) {
platform_init();
audio_init1();

View File

@@ -263,21 +263,21 @@ static void window_banner_dropdown(rct_window *w, int widgetIndex, int dropdownI
banner->text_colour = dropdownIndex + 1;
int colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour;
// Can be replaced with a buffer 34 chars wide ( 32 character + 1 colour_format + 1 '\0')
uint8* text_buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8);
uint8* buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8);
format_string(buffer, banner->string_idx, 0);
format_string(text_buffer, banner->string_idx, 0);
if (text_buffer[0] < FORMAT_COLOUR_CODE_START
|| text_buffer[0] > FORMAT_COLOUR_CODE_END){
int end_point = strlen(text_buffer) + 1;
strncpy(text_buffer + 1, text_buffer, 32);
text_buffer[end_point] = '\0';
int firstCodepoint = utf8_get_next(buffer, NULL);
if (!(firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END)) {
utf8 *endPoint = get_string_end(buffer) + utf8_get_codepoint_length(colourCodepoint);
memmove(buffer + utf8_get_codepoint_length(colourCodepoint), buffer, endPoint - buffer);
*endPoint = 0;
}
utf8_write_codepoint(buffer, colourCodepoint);
text_buffer[0] = banner->text_colour + FORMAT_COLOUR_CODE_START;
rct_string_id stringId = user_string_allocate(128, text_buffer);
rct_string_id stringId = user_string_allocate(128, buffer);
if (stringId != 0) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = stringId;
@@ -296,12 +296,12 @@ static void window_banner_textinput(rct_window *w, int widgetIndex, char *text)
if (widgetIndex == WIDX_BANNER_TEXT && text != NULL) {
rct_banner* banner = &gBanners[w->number];
uint8* text_buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8);
utf8 *buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, uint8);
utf8 *dst = buffer;
dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour);
strncpy(dst, text, 32);
text_buffer[0] = banner->text_colour + FORMAT_COLOUR_CODE_START;
strncpy(text_buffer + 1, text, 32);
rct_string_id stringId = user_string_allocate(128, text_buffer);
rct_string_id stringId = user_string_allocate(128, buffer);
if (stringId) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = stringId;

View File

@@ -118,6 +118,8 @@ void window_text_input_open(rct_window* call_w, int call_widget, rct_string_id t
// from crashing the game.
text_input[maxLength - 1] = '\0';
utf8_remove_format_codes(text_input);
// This is the text displayed above the input box
input_text_description = description;