1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

implement utf8, part 15

This commit is contained in:
IntelOrca
2015-07-29 16:34:13 +01:00
parent fa87d8e999
commit 31eb758ba1
8 changed files with 111 additions and 25 deletions

View File

@@ -3821,3 +3821,4 @@ STR_5481 :Themes
STR_5482 :{WINDOW_COLOUR_2}Time since last inspection: {BLACK}1 minute
STR_5483 :{BLACK}({COMMA16} weeks remaining)
STR_5484 :{BLACK}({COMMA16} week remaining)
STR_5485 :{SMALLFONT}{STRING}

View File

@@ -132,7 +132,7 @@ void draw_string_centred_raw(rct_drawpixelinfo *dpi, int x, int y, int numLines,
void gfx_draw_string_right(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
void draw_string_right_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
int string_get_height_raw(char *buffer);
void sub_6C1F57(rct_drawpixelinfo *dpi, int x, int y, int width, int colour, rct_string_id format, void *args, int ticks);
void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int y, int width, int colour, rct_string_id format, void *args, int ticks);
bool ttf_initialise();
void ttf_dispose();

View File

@@ -107,6 +107,10 @@ static void scrolling_text_format(utf8 *dst, rct_draw_scroll_text *scrollText)
/**
*
* rct2: 0x006C42D9
* @param stringId (ax)
* @param scroll (cx)
* @param scrollingMode (bp)
* @returns ebx
*/
int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode)
{

View File

@@ -707,18 +707,63 @@ int string_get_height_raw(char *buffer)
* width : bp
* ticks : ebp >> 16
*/
void sub_6C1F57(rct_drawpixelinfo *dpi, int x, int y, int width, int colour, rct_string_id format, void *args, int ticks)
void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int y, int width, int colour, rct_string_id format, void *args, int ticks)
{
RCT2_CALLPROC_X(
0x006C1F57,
colour,
format,
x,
y,
(int)args,
(int)dpi,
(width & 0xFFFF) | (ticks << 16)
);
int numLines, fontSpriteBase, lineHeight, lineY;
utf8 *buffer = (utf8*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM;
gfx_draw_string(dpi, (char*)0x009C383D, colour, dpi->x, dpi->y);
format_string(buffer, format, args);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM;
gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase);
switch (fontSpriteBase) {
case FONT_SPRITE_BASE_TINY:
lineHeight = 6;
break;
default:
case FONT_SPRITE_BASE_SMALL:
case FONT_SPRITE_BASE_MEDIUM:
lineHeight = 10;
break;
case FONT_SPRITE_BASE_BIG:
lineHeight = 18;
break;
}
int numCharactersDrawn = 0;
int numCharactersToDraw = ticks;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0;
lineY = y;
for (int line = 0; line <= numLines; line++) {
int halfWidth = gfx_get_string_width(buffer) / 2;
utf8 *ch = buffer;
utf8 *nextCh;
int codepoint;
while ((codepoint = utf8_get_next(ch, &nextCh)) != 0) {
if (!utf8_is_format_code(codepoint)) {
numCharactersDrawn++;
if (numCharactersDrawn > numCharactersToDraw) {
*ch = 0;
break;
}
}
ch = nextCh;
}
gfx_draw_string(dpi, buffer, 0xFE, x - halfWidth, lineY);
if (numCharactersDrawn > numCharactersToDraw) {
break;
}
buffer = get_string_end(buffer) + 1;
lineY += lineHeight;
}
}
static uint32 _ttf_surface_cache_hash(TTF_Font *font, const utf8 *text)

View File

@@ -25,11 +25,13 @@ void* g_hooktableaddress = 0;
int g_hooktableoffset = 0;
int g_maxhooks = 1000;
void hookfunc(int address, int newaddress, int stacksize, int registerargs[], int registersreturned)
void hookfunc(int address, int newaddress, int stacksize, int registerargs[], int registersreturned, int eaxDestinationRegister)
{
int i = 0;
char data[100];
registersreturned |= eaxDestinationRegister;
int registerssaved = 7;
int n = registersreturned;
for (; n; registerssaved--) {
@@ -146,6 +148,39 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in
// returnlocation:
switch (eaxDestinationRegister) {
case EBX:
// mov ebx, eax
data[i++] = 0x8B;
data[i++] = 0xD8;
break;
case ECX:
// mov ecx, eax
data[i++] = 0x8B;
data[i++] = 0xC8;
break;
case EDX:
// mov ecx, eax
data[i++] = 0x8B;
data[i++] = 0xD0;
break;
case ESI:
// mov ecx, eax
data[i++] = 0x8B;
data[i++] = 0xF0;
break;
case EDI:
// mov ecx, eax
data[i++] = 0x8B;
data[i++] = 0xF8;
break;
case EBP:
// mov ecx, eax
data[i++] = 0x8B;
data[i++] = 0xE8;
break;
}
data[i++] = 0x83; // sub esp, x
data[i++] = 0xEC;
data[i++] = (signed char)(stacksize * -4) - rargssize;
@@ -177,7 +212,7 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in
WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0);
}
void addhook(int address, int newaddress, int stacksize, int registerargs[], int registersreturned)
void addhook(int address, int newaddress, int stacksize, int registerargs[], int registersreturned, int eaxDestinationRegister)
{
if (!g_hooktableaddress) {
g_hooktableaddress = VirtualAllocEx(GetCurrentProcess(), NULL, g_maxhooks * 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
@@ -192,6 +227,6 @@ void addhook(int address, int newaddress, int stacksize, int registerargs[], int
*((int *)&data[i]) = hookaddress - address - i - 4; i += 4;
data[i++] = 0xC3; // retn
WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0);
hookfunc(hookaddress, newaddress, stacksize, registerargs, registersreturned);
hookfunc(hookaddress, newaddress, stacksize, registerargs, registersreturned, eaxDestinationRegister);
g_hooktableoffset++;
}

View File

@@ -32,6 +32,6 @@ enum REGISTER_ARGS {
END = 0
};
void addhook(int address, int newaddress, int stacksize, int registerargs[], int registersreturned);
void addhook(int address, int newaddress, int stacksize, int registerargs[], int registersreturned, int eaxDestinationRegister);
#endif

View File

@@ -188,11 +188,13 @@ bool openrct2_initialise()
title_sequences_load_presets();
// Hooks to allow RCT2 to call OpenRCT2 functions instead
addhook(0x006E732D, (int)gfx_set_dirty_blocks, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0); // remove when all callers are decompiled
addhook(0x006E7499, (int)gfx_redraw_screen_rect, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0); // remove when 0x6E7FF3 is decompiled
addhook(0x006B752C, (int)ride_crash, 0, (int[]){ EDX, EBX, END }, 0); // remove when all callers are decompiled
addhook(0x0069A42F, (int)peep_window_state_update, 0, (int[]){ ESI, END }, 0); // remove when all callers are decompiled
addhook(0x006BB76E, (int)sound_play_panned, 0, (int[]){EAX, EBX, ECX, EDX, EBP, END}, EAX); // remove when all callers are decompiled
addhook(0x006E732D, (int)gfx_set_dirty_blocks, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0, 0); // remove when all callers are decompiled
addhook(0x006E7499, (int)gfx_redraw_screen_rect, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0, 0); // remove when 0x6E7FF3 is decompiled
addhook(0x006B752C, (int)ride_crash, 0, (int[]){ EDX, EBX, END }, 0, 0); // remove when all callers are decompiled
addhook(0x0069A42F, (int)peep_window_state_update, 0, (int[]){ ESI, END }, 0, 0); // remove when all callers are decompiled
addhook(0x006BB76E, (int)sound_play_panned, 0, (int[]){EAX, EBX, ECX, EDX, EBP, END}, EAX, 0); // remove when all callers are decompiled
addhook(0x006C42D9, (int)scrolling_text_setup, 0, (int[]){EAX, ECX, EBP, END}, 0, EBX); // remove when all callers are decompiled
addhook(0x006C2321, (int)gfx_get_string_width, 0, (int[]){ESI, END}, 0, ECX); // remove when all callers are decompiled
if (!rct2_init())
return false;

View File

@@ -523,13 +523,12 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo *dpi, rc
);
// Text
stringId = 1926;
utf8 *buffer = (utf8*)0x009B5F2C;
memcpy(buffer, &newsItem->text, 256);
stringId = 5485;
utf8 *newsItemText = newsItem->text;
x = w->x + (middleOutsetWidget->left + middleOutsetWidget->right) / 2;
y = w->y + middleOutsetWidget->top + 11;
width = middleOutsetWidget->right - middleOutsetWidget->left - 62;
sub_6C1F57(dpi, x, y, width, 14, stringId, NULL, newsItem->ticks);
gfx_draw_string_centred_wrapped_partial(dpi, x, y, width, 14, stringId, &newsItemText, newsItem->ticks);
x = w->x + window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].left;
y = w->y + window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].top;