From 0e3702f4636be8e5e38824b80748aec33e3c97f9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 12 Jun 2014 21:49:59 +0100 Subject: [PATCH 1/6] Started decompiling character width loading function --- src/gfx.c | 248 ++++++++++++++++++++++++++++++----------------------- src/gfx.h | 1 + src/rct2.c | 3 +- 3 files changed, 145 insertions(+), 107 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 5ee2b7a336..92b17bb50d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -113,6 +113,46 @@ int gfx_load_g1() return 0; } +/* +* 0x6C19AC +*/ +void gfx_load_character_widths(){ + uint8* char_width_pointer = RCT2_ADDRESS(0x141E9E8, uint8); + for (int char_set_offset = 0; char_set_offset < 4*0xE0; char_set_offset+=0xE0){ + for (char c = 0; c < 0xE0; c++, char_width_pointer++){ + rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[c + 0xF15 + char_set_offset]; + int width = g1.width - 1; + if (c >= 0x5B && c < 0x7F){ + width = 0; + } + *char_width_pointer = (uint8)width; + } + } + uint8 drawing_surface[0x40]; + rct_drawpixelinfo dpi; + dpi.bits = &drawing_surface; + dpi.width = 8; + dpi.height = 8; + dpi.x = 0; + dpi.y = 0; + dpi.pitch = 0; + dpi.zoom_level = 0; + + for (int i = 0; i < 0xE0; ++i){ + memset(drawing_surface, 0, 0x10); + gfx_draw_sprite(&dpi, i + 0x10D5, -1, 0); + + uint8* bits_pointer = dpi.bits; + bits_pointer += 0; + for (int y = 0; y < 8; ++y){ + for (int x = 0; x < 8; ++x){ + + } + } + + } +} + /** * Clears the screen with the specified colour. * rct2: 0x00678A9F @@ -1891,9 +1931,45 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { if (al < 0x20) { // Control codes - al -= 0x20; switch (al) { - case 0x0E5://Start New Line at set y lower + case 1://Start New Line at start+buffer x, same y. (Overwrite?) + al = *(buffer+1); + buffer++; + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); + max_x += al; + break; + case 2: + al = *(buffer + 1); + buffer++; + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + break; + } + } + + eax = RCT2_ADDRESS(0x097FCBC, uint32)[al * 4]; + g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + ebx = g1_element->offset[0xF9] + (1 << 8); + + if (!(*current_font_flags & 2)) { + ebx = ebx & 0xFF; + } + //Adjust the text palette + RCT2_GLOBAL(0x09ABE05, uint16) = ebx; + memcpy((uint8*)0x09ABE07, &(g1_element->offset[0xF7]), 2); + //ebx = g1_element->offset[0xF7]; + //RCT2_GLOBAL(0x09ABE07, uint16) = ebx; + memcpy((uint8*)0x09ABE09, &(g1_element->offset[0xFA]), 2); + //ebx = g1_element->offset[0xFA]; + //RCT2_GLOBAL(0x09ABE09, uint16) = ebx; + //Set the palette pointer + RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04; + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + break; + case 5://Start New Line at set y lower max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_y += 0x0A; if (*current_font_sprite_base <= 0x0E) { @@ -1905,7 +1981,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } max_y -= 0xFFF4; break; - case 0x0E6://Start New Line at set y lower + case 6://Start New Line at set y lower max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_y += 5; if (*current_font_sprite_base <= 0x0E) { @@ -1917,13 +1993,64 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } max_y -= 0xFFFA;//This does not look correct probably should be an add break; - case 0x0E1://Start New Line at start+buffer x, same y. (Overwrite?) - al = *(buffer+1); - buffer++; - max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); - max_x += al; + case 7: + *current_font_sprite_base = 0x1C0; break; - case 0x0F1: //Start new line at specified x,y + case 8: + *current_font_sprite_base = 0x2A0; + break; + case 9: + *current_font_sprite_base = 0xE0; + break; + case 0xA: + *current_font_sprite_base = 0; + break; + case 0xB: + *current_font_flags |= 2; + break; + case 0xC: + *current_font_flags &= 0x0FFFD; + break; + case 0xD: + ebp = RCT2_GLOBAL(0x0141F740, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + break; + } + sub_682AC7(ebp, current_font_flags); + break; + case 0xE: + ebp = RCT2_GLOBAL(0x0141F741, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + break; + } + sub_682AC7(ebp, current_font_flags); + break; + case 0xF: + ebp = RCT2_GLOBAL(0x0141F742, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + break; + } + sub_682AC7(ebp, current_font_flags); + break; + case 0x11: //Start new line at specified x,y eax = *((uint16*)(buffer+1)); buffer += 2; max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); @@ -1931,92 +2058,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in max_y = y;//RCT2_GLOBAL(0x0EDF842, uint16); max_y += (eax & 0xFF00) >> 8; break; - case 0x0E7: - *current_font_sprite_base = 0x1C0; - break; - case 0x0E8: - *current_font_sprite_base = 0x2A0; - break; - case 0x0E9: - *current_font_sprite_base = 0xE0; - break; - case 0x0EA: - *current_font_sprite_base = 0; - break; - case 0x0EB: - *current_font_flags |= 2; - break; - case 0x0EC: - *current_font_flags &= 0x0FFFD; - break; - case 0x0ED: - ebp = RCT2_GLOBAL(0x0141F740, uint8); - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } else { - skip_char = 0; - } - break; - } - sub_682AC7(ebp, current_font_flags); - break; - case 0x0EE: - ebp = RCT2_GLOBAL(0x0141F741, uint8); - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } else { - skip_char = 0; - } - break; - } - sub_682AC7(ebp, current_font_flags); - break; - case 0x0EF: - ebp = RCT2_GLOBAL(0x0141F742, uint8); - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } else { - skip_char = 0; - } - break; - } - sub_682AC7(ebp, current_font_flags); - break; - case 0x0E2: - al = *(buffer+1); - buffer++; - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - break; - } - } - - eax = RCT2_ADDRESS(0x097FCBC, uint32)[al*4]; - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - ebx = g1_element->offset[0xF9] + (1 << 8); - - if (!(*current_font_flags & 2)) { - ebx = ebx & 0xFF; - } - //Adjust the text palette - RCT2_GLOBAL(0x09ABE05, uint16) = ebx; - memcpy((uint8*)0x09ABE07,&(g1_element->offset[0xF7]),2); - //ebx = g1_element->offset[0xF7]; - //RCT2_GLOBAL(0x09ABE07, uint16) = ebx; - memcpy((uint8*)0x09ABE09,&(g1_element->offset[0xFA]),2); - //ebx = g1_element->offset[0xFA]; - //RCT2_GLOBAL(0x09ABE09, uint16) = ebx; - //Set the palette pointer - RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04; - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } - break; - case 0x0F7: + case 0x17: buffer += 4; if (max_x >= dpi->x + dpi->width) { skip_char = 1; @@ -2033,33 +2075,27 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } } else { - al -= 0x20; + if (max_x >= dpi->x + dpi->width) { skip_char = 1; } if (max_x + 0x1A < dpi->x) { - ebx = al; + ebx = al-0x20; ebx += *current_font_sprite_base; max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); continue; } - ebx = al + *current_font_sprite_base; + ebx = al-0x20 + *current_font_sprite_base; ecx = max_x; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - eax = (int)al; ebx += 0xF15; - edx = max_y; - esi = (int)buffer; - edi = (int)dpi; - ebp = 0; - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); + gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, max_y, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); continue; } diff --git a/src/gfx.h b/src/gfx.h index a627bffb72..6e484b74e7 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -62,6 +62,7 @@ extern int gLastDrawStringX; extern int gLastDrawStringY; int gfx_load_g1(); +void gfx_load_character_widths(); void gfx_clear(rct_drawpixelinfo *dpi, int colour); void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour); diff --git a/src/rct2.c b/src/rct2.c index 7ab6254c34..5b54c1e5ca 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -157,7 +157,8 @@ void rct2_init() scenario_load_list(); track_load_list(253); gfx_load_g1(); - RCT2_CALLPROC_EBPSAFE(0x006C19AC); + gfx_load_character_widths(); + //RCT2_CALLPROC_EBPSAFE(0x006C19AC); //Load character widths osinterface_init(); RCT2_CALLPROC_EBPSAFE(0x006BA8E0); // init_audio(); viewport_init_all(); From 583d769ad162956c0746ae17965a90199762f285 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 13 Jun 2014 00:02:52 +0100 Subject: [PATCH 2/6] Fixed bug in create window due to uninitialised data. Finished load_character_width function --- src/gfx.c | 32 +++++++++++++++++++++++++------- src/osinterface.c | 1 + src/rct2.c | 3 ++- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 92b17bb50d..e6c2e76c2d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -117,9 +117,12 @@ int gfx_load_g1() * 0x6C19AC */ void gfx_load_character_widths(){ + //RCT2_CALLPROC_EBPSAFE(0x006C19AC); + //return; + uint8* char_width_pointer = RCT2_ADDRESS(0x141E9E8, uint8); for (int char_set_offset = 0; char_set_offset < 4*0xE0; char_set_offset+=0xE0){ - for (char c = 0; c < 0xE0; c++, char_width_pointer++){ + for (uint8 c = 0; c < 0xE0; c++, char_width_pointer++){ rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[c + 0xF15 + char_set_offset]; int width = g1.width - 1; if (c >= 0x5B && c < 0x7F){ @@ -127,7 +130,9 @@ void gfx_load_character_widths(){ } *char_width_pointer = (uint8)width; } + } + uint8 drawing_surface[0x40]; rct_drawpixelinfo dpi; dpi.bits = &drawing_surface; @@ -139,18 +144,31 @@ void gfx_load_character_widths(){ dpi.zoom_level = 0; for (int i = 0; i < 0xE0; ++i){ - memset(drawing_surface, 0, 0x10); + memset(drawing_surface, 0, 0x40); gfx_draw_sprite(&dpi, i + 0x10D5, -1, 0); - uint8* bits_pointer = dpi.bits; - bits_pointer += 0; - for (int y = 0; y < 8; ++y){ - for (int x = 0; x < 8; ++x){ - + for (int x = 0; x < 8; ++x){ + uint8 val = 0; + for (int y = 0; y < 8; ++y){ + val >>= 1; + if (dpi.bits[x + y * 8]==1){ + val |= 0x80; + } } + RCT2_ADDRESS(0xF4393C, uint8)[i * 8 + x] = val; } } + + for (int i = 0; i < 0x20; ++i){ + rct_g1_element* g1 = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x606 + i]); + uint8* unknown_pointer = RCT2_ADDRESS(0x9C3852, uint8) + 0xa12 * i; + g1->offset = unknown_pointer; + g1->width = 0x40; + g1->height = 0x28; + *((uint16*)unknown_pointer) = 0xFFFF; + *((uint32*)(unknown_pointer + 0x0E)) = 0; + } } /** diff --git a/src/osinterface.c b/src/osinterface.c index 0843f127c5..a9f7700b46 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -91,6 +91,7 @@ static void osinterface_create_window() exit(-1); } + SDL_VERSION(&wmInfo.version); // Get the HWND context if (SDL_GetWindowWMInfo(_window, &wmInfo) != SDL_TRUE) { RCT2_ERROR("SDL_GetWindowWMInfo failed %s", SDL_GetError()); diff --git a/src/rct2.c b/src/rct2.c index 5b54c1e5ca..1d1473c073 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -157,8 +157,9 @@ void rct2_init() scenario_load_list(); track_load_list(253); gfx_load_g1(); - gfx_load_character_widths(); //RCT2_CALLPROC_EBPSAFE(0x006C19AC); //Load character widths + gfx_load_character_widths(); + osinterface_init(); RCT2_CALLPROC_EBPSAFE(0x006BA8E0); // init_audio(); viewport_init_all(); From 04facd2fcd8478439765b055d4ca8f3b04487b39 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 12:49:35 +0100 Subject: [PATCH 3/6] Small bug fix in char width. Switched to C99 inits 4th character type has to have the width increased from the g1 elements width rather than decreased. --- src/gfx.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index e6c2e76c2d..99425d792a 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -124,7 +124,11 @@ void gfx_load_character_widths(){ for (int char_set_offset = 0; char_set_offset < 4*0xE0; char_set_offset+=0xE0){ for (uint8 c = 0; c < 0xE0; c++, char_width_pointer++){ rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[c + 0xF15 + char_set_offset]; - int width = g1.width - 1; + int width; + + if (char_set_offset == 0xE0*3) width = g1.width + 1; + else width = g1.width - 1; + if (c >= 0x5B && c < 0x7F){ width = 0; } @@ -134,17 +138,18 @@ void gfx_load_character_widths(){ } uint8 drawing_surface[0x40]; - rct_drawpixelinfo dpi; - dpi.bits = &drawing_surface; - dpi.width = 8; - dpi.height = 8; - dpi.x = 0; - dpi.y = 0; - dpi.pitch = 0; - dpi.zoom_level = 0; + rct_drawpixelinfo dpi = { + .bits = &drawing_surface, + .width = 8, + .height = 8, + .x = 0, + .y = 0, + .pitch = 0, + .zoom_level = 0}; + for (int i = 0; i < 0xE0; ++i){ - memset(drawing_surface, 0, 0x40); + memset(drawing_surface, 0, size_of(drawing_surface)); gfx_draw_sprite(&dpi, i + 0x10D5, -1, 0); for (int x = 0; x < 8; ++x){ From a73ed7ce94f82ff145c7cf13c89f47cc8d915813 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 12:57:05 +0100 Subject: [PATCH 4/6] Cleaned up clip_string and string_width Both functions are very similar. They now have the same bugs fixed. --- src/gfx.c | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 99425d792a..cec9e82267 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1350,7 +1350,7 @@ int gfx_get_string_width(char* buffer) uint16* current_font_sprite_base; // Width of string int width; - rct_g1_element* g1_element; + rct_g1_element g1_element; current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; @@ -1358,20 +1358,22 @@ int gfx_get_string_width(char* buffer) for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char >= 0x20) { - //Maybe global not address?? width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; continue; } switch(*curr_char) { case 1: - width = *curr_char; curr_char++; + width = *curr_char; break; case 2: case 3: case 4: curr_char++; break; + case 5: + case 6: + continue; case 7: *current_font_sprite_base = 0x1C0; break; @@ -1384,20 +1386,24 @@ int gfx_get_string_width(char* buffer) case 0x0A: *current_font_sprite_base = 0; break; + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + continue; case 0x17: - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*curr_char&0x7FFFF]); - width += g1_element->width; //RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF]; + width += g1_element.width; curr_char += 4; break; default: - if (*curr_char <= 0x10) { + if (*curr_char <= 0x16) { //case 0x11? + curr_char += 2; continue; } - curr_char += 2; - if (*curr_char <= 0x16) { - continue; - } - curr_char += 2; + curr_char += 4;//never happens? break; } } @@ -1421,6 +1427,7 @@ int gfx_clip_string(char* buffer, int width) char* last_char; // Width of the string, including ellipsis int clipped_width; + rct_g1_element g1_element; if (width < 6) { *buffer = 0; @@ -1445,6 +1452,9 @@ int gfx_clip_string(char* buffer, int width) case 4: curr_char++; continue; + case 5: + case 6: + continue; case 7: current_font_sprite_base = 0x1C0; break; @@ -1457,20 +1467,24 @@ int gfx_clip_string(char* buffer, int width) case 0x0A: current_font_sprite_base = 0; break; + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + continue; case 0x17: - clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*(curr_char+1) & 0x7FFFF) << 4]; + g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF]; + clipped_width += g1_element.width; curr_char += 4; continue; default: - if (*curr_char <= 0x10) { - continue; - } - - if (*curr_char <= 0x16) { + if (*curr_char <= 0x16) { //case 0x11? curr_char += 2; continue; } - curr_char += 4; + curr_char += 4;//never happens? continue; } max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); @@ -1490,7 +1504,6 @@ int gfx_clip_string(char* buffer, int width) return clipped_width; } - /** * Draws i formatted text string left aligned at i specified position but clips * the text with an elipsis if the text width exceeds the specified width. From 92d8e0cf34991102e2215ba91c5ed27e49cce046 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 13:04:09 +0100 Subject: [PATCH 5/6] Added notes for what unknown functions do. --- src/rct2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rct2.c b/src/rct2.c index 1d1473c073..a7b41aedab 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -167,10 +167,10 @@ void rct2_init() get_local_time(); reset_park_entrances(); reset_saved_strings(); - RCT2_CALLPROC_EBPSAFE(0x0069EB13); + RCT2_CALLPROC_EBPSAFE(0x0069EB13); //Sprite list reset/load ride_init_all(); window_guest_list_init_vars_a(); - RCT2_CALLPROC_EBPSAFE(0x006BD3A4); + RCT2_CALLPROC_EBPSAFE(0x006BD3A4); //Peep? map_init(); park_init(); RCT2_CALLPROC_EBPSAFE(0x0066B5C0); // 0x0066B5C0 (part of 0x0066B3E8) screen_game_create_windows() From 2e0f34222cb60d6768fa28d8ca664ffa23b2cbe4 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 15:02:34 +0100 Subject: [PATCH 6/6] Added Char_control_code enum. Refactor of draw string --- src/gfx.c | 431 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 227 insertions(+), 204 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index cec9e82267..31f6d36f37 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -43,6 +43,39 @@ int gLastDrawStringY; uint8 _screenDirtyBlocks[5120]; +enum{ + //The next byte specifies the X coordinate + CHAR_CONTROL_CODE_MOVE_X = 1, + + //The next byte specifies the palette + CHAR_CONTROL_CODE_ADJUST_PALETTE_1 = 2, + + //Jumps a fixed amount of pixels down and + //starts a new line + CHAR_CONTROL_CODE_NEW_LINE_FIXED = 5, + //Jumps less than the above + CHAR_CONTROL_CODE_NEW_LINE_FIXED_SMALLER = 6, + + CHAR_CONTROL_CODE_FONT_2 = 7, + CHAR_CONTROL_CODE_FONT_3 = 8, + CHAR_CONTROL_CODE_FONT_1 = 9, + CHAR_CONTROL_CODE_FONT_0 = 0xA, + + CHAR_CONTROL_CODE_FONT_FLAG_SET_BIT_1 = 0xB, + CHAR_CONTROL_CODE_FONT_FLAG_CLEAR_BIT_1 = 0xC, + + //Adjusts the palette depending on a global var + CHAR_CONTROL_CODE_ADJUST_PALETTE_2 = 0xD, + CHAR_CONTROL_CODE_ADJUST_PALETTE_3 = 0xE, + CHAR_CONTROL_CODE_ADJUST_PALETTE_4 = 0xF, + + //The next 2 bytes specify the X and Y coordinates + CHAR_CONTROL_CODE_NEW_LINE_X_Y = 0x11, + + //The next 4 bytes specify the sprite + CHAR_CONTROL_CODE_SPRITE = 0x17 +}; + //Originally 0x9ABE0C, 12 elements from 0xF3 are the peep top colour, 12 elements from 0xCA are peep trouser colour uint8 peep_palette[0x100] = { 0x00, 0xF3, 0xF4, 0xF5, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, @@ -1362,44 +1395,44 @@ int gfx_get_string_width(char* buffer) continue; } switch(*curr_char) { - case 1: + case CHAR_CONTROL_CODE_MOVE_X: curr_char++; width = *curr_char; break; - case 2: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_1: case 3: case 4: curr_char++; break; - case 5: - case 6: + case CHAR_CONTROL_CODE_NEW_LINE_FIXED: + case CHAR_CONTROL_CODE_NEW_LINE_FIXED_SMALLER: continue; - case 7: + case CHAR_CONTROL_CODE_FONT_2: *current_font_sprite_base = 0x1C0; break; - case 8: + case CHAR_CONTROL_CODE_FONT_3: *current_font_sprite_base = 0x2A0; break; - case 9: + case CHAR_CONTROL_CODE_FONT_1: *current_font_sprite_base = 0x0E0; break; - case 0x0A: + case CHAR_CONTROL_CODE_FONT_0: *current_font_sprite_base = 0; break; - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: + case CHAR_CONTROL_CODE_FONT_FLAG_SET_BIT_1: + case CHAR_CONTROL_CODE_FONT_FLAG_CLEAR_BIT_1: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_2: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_3: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_4: case 0x10: continue; - case 0x17: + case CHAR_CONTROL_CODE_SPRITE: g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF]; width += g1_element.width; curr_char += 4; break; default: - if (*curr_char <= 0x16) { //case 0x11? + if (*curr_char <= 0x16) { //case 0x11? CHAR_CONTROL_CODE_NEW_LINE_X_Y curr_char += 2; continue; } @@ -1443,44 +1476,44 @@ int gfx_clip_string(char* buffer, int width) for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { switch (*curr_char) { - case 1: + case CHAR_CONTROL_CODE_MOVE_X: curr_char++; clipped_width = *curr_char; continue; - case 2: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_1: case 3: case 4: curr_char++; continue; - case 5: - case 6: + case CHAR_CONTROL_CODE_NEW_LINE_FIXED: + case CHAR_CONTROL_CODE_NEW_LINE_FIXED_SMALLER: continue; - case 7: + case CHAR_CONTROL_CODE_FONT_2: current_font_sprite_base = 0x1C0; break; - case 8: + case CHAR_CONTROL_CODE_FONT_3: current_font_sprite_base = 0x2A0; break; - case 9: + case CHAR_CONTROL_CODE_FONT_1: current_font_sprite_base = 0x0E0; break; - case 0x0A: + case CHAR_CONTROL_CODE_FONT_0: current_font_sprite_base = 0; break; - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: + case CHAR_CONTROL_CODE_FONT_FLAG_SET_BIT_1: + case CHAR_CONTROL_CODE_FONT_FLAG_CLEAR_BIT_1: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_2: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_3: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_4: case 0x10: continue; - case 0x17: + case CHAR_CONTROL_CODE_SPRITE: g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF]; clipped_width += g1_element.width; curr_char += 4; continue; default: - if (*curr_char <= 0x16) { //case 0x11? + if (*curr_char <= 0x16) { //case 0x11? CHAR_CONTROL_CODE_NEW_LINE_X_Y curr_char += 2; continue; } @@ -1779,8 +1812,8 @@ void colour_char(int al, uint16* current_font_flags) { int eax; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332]); - eax = ((uint32*)g1_element->offset)[al & 0xFF]; + rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332]; + eax = ((uint32*)g1_element.offset)[al & 0xFF]; if (!(*current_font_flags & 2)) { eax = eax & 0x0FF0000FF; @@ -1821,7 +1854,6 @@ void sub_682AC7(int ebp, uint16* current_font_flags) { void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y) { //int eax, ebx, ecx, edx, esi, edi, ebp; - //char* find = "FINDMEDRAWSTRING"; //eax = colour; //ebx = 0; //ecx = x; @@ -1951,190 +1983,181 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } } - if ((al >= 0x8E) && (al < 0x9C)){ - // Colour codes - al -= 0x8E; - if (*current_font_flags == 1) { + // Control codes + switch (al) { + case CHAR_CONTROL_CODE_MOVE_X://Start New Line at start+buffer x, same y. (Overwrite?) + al = *(buffer+1); + buffer++; + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); + max_x += al; + break; + case CHAR_CONTROL_CODE_ADJUST_PALETTE_1: + al = *(buffer + 1); + buffer++; + if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; - } else { - skip_char = 0; + break; } - continue; } - colour_char(al, current_font_flags); - continue; - } else { - if (al < 0x20) { - // Control codes - switch (al) { - case 1://Start New Line at start+buffer x, same y. (Overwrite?) - al = *(buffer+1); - buffer++; - max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); - max_x += al; - break; - case 2: - al = *(buffer + 1); - buffer++; - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - break; - } - } - eax = RCT2_ADDRESS(0x097FCBC, uint32)[al * 4]; - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - ebx = g1_element->offset[0xF9] + (1 << 8); + eax = RCT2_ADDRESS(0x097FCBC, uint32)[al * 4]; + g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + ebx = g1_element->offset[0xF9] + (1 << 8); + if (!(*current_font_flags & 2)) { + ebx = ebx & 0xFF; + } - if (!(*current_font_flags & 2)) { - ebx = ebx & 0xFF; - } - //Adjust the text palette - RCT2_GLOBAL(0x09ABE05, uint16) = ebx; - memcpy((uint8*)0x09ABE07, &(g1_element->offset[0xF7]), 2); - //ebx = g1_element->offset[0xF7]; - //RCT2_GLOBAL(0x09ABE07, uint16) = ebx; - memcpy((uint8*)0x09ABE09, &(g1_element->offset[0xFA]), 2); - //ebx = g1_element->offset[0xFA]; - //RCT2_GLOBAL(0x09ABE09, uint16) = ebx; - //Set the palette pointer - RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04; - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } - break; - case 5://Start New Line at set y lower - max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); - max_y += 0x0A; - if (*current_font_sprite_base <= 0x0E) { - break; - } - max_y -= 4; - if (*current_font_sprite_base == 0x1C0) { - break; - } - max_y -= 0xFFF4; - break; - case 6://Start New Line at set y lower - max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); - max_y += 5; - if (*current_font_sprite_base <= 0x0E) { - break; - } - max_y -= 2; - if (*current_font_sprite_base == 0x1C0) { - break; - } - max_y -= 0xFFFA;//This does not look correct probably should be an add - break; - case 7: - *current_font_sprite_base = 0x1C0; - break; - case 8: - *current_font_sprite_base = 0x2A0; - break; - case 9: - *current_font_sprite_base = 0xE0; - break; - case 0xA: - *current_font_sprite_base = 0; - break; - case 0xB: - *current_font_flags |= 2; - break; - case 0xC: - *current_font_flags &= 0x0FFFD; - break; - case 0xD: - ebp = RCT2_GLOBAL(0x0141F740, uint8); - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } - else { - skip_char = 0; - } - break; - } - sub_682AC7(ebp, current_font_flags); - break; - case 0xE: - ebp = RCT2_GLOBAL(0x0141F741, uint8); - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } - else { - skip_char = 0; - } - break; - } - sub_682AC7(ebp, current_font_flags); - break; - case 0xF: - ebp = RCT2_GLOBAL(0x0141F742, uint8); - if (*current_font_flags & 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { - skip_char = 1; - } - else { - skip_char = 0; - } - break; - } - sub_682AC7(ebp, current_font_flags); - break; - case 0x11: //Start new line at specified x,y - eax = *((uint16*)(buffer+1)); - buffer += 2; - max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); - max_x += (eax & 0xFF); - max_y = y;//RCT2_GLOBAL(0x0EDF842, uint16); - max_y += (eax & 0xFF00) >> 8; - break; - case 0x17: - buffer += 4; - if (max_x >= dpi->x + dpi->width) { - skip_char = 1; - break; - } - ebx = *(buffer - 3); - eax = ebx & 0x7FFFF; - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - - gfx_draw_sprite(dpi, ebx, max_x, max_y); + //Adjust the text palette + memcpy((uint8*)0x09ABE07, &(g1_element->offset[0xF7]), 2); + memcpy((uint8*)0x09ABE09, &(g1_element->offset[0xFA]), 2); + //Set the palette pointer + RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04; - max_x = max_x + g1_element->width; - break; - } - - } else { - - if (max_x >= dpi->x + dpi->width) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + break; + case CHAR_CONTROL_CODE_NEW_LINE_FIXED://Start New Line at set y lower + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); + max_y += 0x0A; + if (*current_font_sprite_base <= 0x0E) { + break; + } + max_y -= 4; + if (*current_font_sprite_base == 0x1C0) { + break; + } + max_y -= 0xFFF4; + break; + case CHAR_CONTROL_CODE_NEW_LINE_FIXED_SMALLER://Start New Line at set y lower + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); + max_y += 5; + if (*current_font_sprite_base <= 0x0E) { + break; + } + max_y -= 2; + if (*current_font_sprite_base == 0x1C0) { + break; + } + max_y -= 0xFFFA;//This does not look correct probably should be an add + break; + case CHAR_CONTROL_CODE_FONT_2: + *current_font_sprite_base = 0x1C0; + break; + case CHAR_CONTROL_CODE_FONT_3: + *current_font_sprite_base = 0x2A0; + break; + case CHAR_CONTROL_CODE_FONT_1: + *current_font_sprite_base = 0xE0; + break; + case CHAR_CONTROL_CODE_FONT_0: + *current_font_sprite_base = 0; + break; + case CHAR_CONTROL_CODE_FONT_FLAG_SET_BIT_1: + *current_font_flags |= 2; + break; + case CHAR_CONTROL_CODE_FONT_FLAG_CLEAR_BIT_1: + *current_font_flags &= 0x0FFFD; + break; + case CHAR_CONTROL_CODE_ADJUST_PALETTE_2: + ebp = RCT2_GLOBAL(0x0141F740, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; } - if (max_x + 0x1A < dpi->x) { - ebx = al-0x20; - ebx += *current_font_sprite_base; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + else { + skip_char = 0; + } + break; + } + sub_682AC7(ebp, current_font_flags); + break; + case CHAR_CONTROL_CODE_ADJUST_PALETTE_3: + ebp = RCT2_GLOBAL(0x0141F741, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + break; + } + sub_682AC7(ebp, current_font_flags); + break; + case CHAR_CONTROL_CODE_ADJUST_PALETTE_4: + ebp = RCT2_GLOBAL(0x0141F742, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + break; + } + sub_682AC7(ebp, current_font_flags); + break; + case CHAR_CONTROL_CODE_NEW_LINE_X_Y: //Start new line at specified x,y + eax = *((uint16*)(buffer+1)); + buffer += 2; + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); + max_x += (eax & 0xFF); + max_y = y;//RCT2_GLOBAL(0x0EDF842, uint16); + max_y += (eax & 0xFF00) >> 8; + break; + case CHAR_CONTROL_CODE_SPRITE: + buffer += 4; + if (max_x >= dpi->x + dpi->width) { + skip_char = 1; + break; + } + ebx = *(buffer - 3); + eax = ebx & 0x7FFFF; + g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + + gfx_draw_sprite(dpi, ebx, max_x, max_y); + + max_x = max_x + g1_element->width; + break; + default: + // Colour codes + if ((al >= 0x8E) && (al < 0x9C)){ + + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } continue; } - ebx = al-0x20 + *current_font_sprite_base; - - ecx = max_x; - - max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - - ebx += 0xF15; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - - gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, max_y, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); - + colour_char(al-0x8E, current_font_flags); continue; } + + // Normal Characters + if (max_x >= dpi->x + dpi->width) { + skip_char = 1; + } + if (max_x + 0x1A < dpi->x) { + ebx = al-0x20; + ebx += *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + continue; + } + ebx = al-0x20 + *current_font_sprite_base; + + ecx = max_x; + max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + ebx += 0xF15; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + + gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, max_y, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); + + continue; } }