From f448929f739eca2ef30a9188088d5baf5bf3c252 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 8 May 2014 20:13:58 +0100 Subject: [PATCH 001/209] First couple lines decoded --- src/gfx.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/gfx.c b/src/gfx.c index 022b35e1a2..1e8dc86f84 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -154,6 +154,33 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + + int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; + eax = image_id; + eax >>= 26; + RCT2_GLOBAL(0x00EDF81C, uint32) = ebx; + eax &= 0x7; + eax = RCT2_GLOBAL(0x009E3CE4 + 4 * eax, uint32); + RCT2_GLOBAL(0x009E3CDC, uint32) = eax; + if (!(RCT2_GLOBAL(0x00EDF81C, uint32) & 0xE0000000)){ + if (!(ebx & 0x80000000)) + { + if (!(ebx & 0x20000000)){ + eax = ebx; + RCT2_GLOBAL(0x9E3CDC, uint32) = 0; + eax >>= 13; + eax &= 0x1f; + eax = RCT2_GLOBAL(eax * 4 + 0x91FCBC, uint32); + eax <<= 4; + eax = RCT2_GLOBAL(eax + 0x9EBD28, uint32); + ebp = *((uint32*)eax + 0xF3); + esi = *((uint32*)eax + 0xF7); + RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; + RCT2_GLOBAL(0x9ABF03, uint32) = esi; + ebp = *((uint32*)eax + 0xFB); + }//0x67a361 + }//0x67a445 + }//0x67a46e } /** From 2276c198fdf26533e5514d3d3ba711121e56a4b2 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 8 May 2014 20:43:10 +0100 Subject: [PATCH 002/209] Removed a pointless call in palette tried to make draw sprite more understandable --- src/gfx.c | 20 +++++++++++--------- src/osinterface.c | 4 ++-- src/osinterface.h | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 1e8dc86f84..3c6c2ce010 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -26,6 +26,7 @@ #include "rct2.h" #include "strings.h" #include "window.h" +#include "osinterface.h" // HACK These were originally passed back through registers int gLastDrawStringX; @@ -154,30 +155,32 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + return; int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; eax = image_id; eax >>= 26; - RCT2_GLOBAL(0x00EDF81C, uint32) = ebx; + RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax &= 0x7; eax = RCT2_GLOBAL(0x009E3CE4 + 4 * eax, uint32); RCT2_GLOBAL(0x009E3CDC, uint32) = eax; - if (!(RCT2_GLOBAL(0x00EDF81C, uint32) & 0xE0000000)){ - if (!(ebx & 0x80000000)) + if (!(image_id & 0xE0000000)){ + if (!(image_id & (1<<31))) { - if (!(ebx & 0x20000000)){ - eax = ebx; + if (!(image_id & (1<<29))){ + eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 13; eax &= 0x1f; eax = RCT2_GLOBAL(eax * 4 + 0x91FCBC, uint32); eax <<= 4; - eax = RCT2_GLOBAL(eax + 0x9EBD28, uint32); + eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); ebp = *((uint32*)eax + 0xF3); esi = *((uint32*)eax + 0xF7); RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; RCT2_GLOBAL(0x9ABF03, uint32) = esi; ebp = *((uint32*)eax + 0xFB); + eax = ebx;//0x67a310 }//0x67a361 }//0x67a445 }//0x67a46e @@ -195,7 +198,7 @@ void gfx_transpose_palette(int pal, unsigned char product) uint8* esi, *edi; ebx = pal * 16; - esi = (uint8*)(*((int*)(0x009EBD28 + ebx))); + esi = (uint8*)(*((int*)(RCT2_ADDRESS_G1_ELEMENTS + ebx))); ebp = *((short*)(0x009EBD2C + ebx)); eax = *((short*)(0x009EBD30 + ebx)) * 4; edi = (uint8*)0x01424680 + eax; @@ -207,8 +210,7 @@ void gfx_transpose_palette(int pal, unsigned char product) esi += 3; edi += 4; } - - RCT2_CALLPROC_3(0x00405595, int, int, int, 0x01424680, 10, 236); + osinterface_update_palette((char*)0x01424680, 10, 236); } /** diff --git a/src/osinterface.c b/src/osinterface.c index 3e97491e5b..ad3d2c66aa 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -38,7 +38,7 @@ unsigned int gLastKeyPressed; static void osinterface_create_window(); static void osinterface_close_window(); static void osinterface_resize(int width, int height); -static void osinterface_update_palette(char* colours, int start_index, int num_colours); + static SDL_Window *_window; static SDL_Surface *_surface; @@ -150,7 +150,7 @@ static void osinterface_resize(int width, int height) gfx_invalidate_screen(); } -static void osinterface_update_palette(char* colours, int start_index, int num_colours) +void osinterface_update_palette(char* colours, int start_index, int num_colours) { SDL_Color base[256]; SDL_Surface *surface; diff --git a/src/osinterface.h b/src/osinterface.h index 9ec682fea2..6ddcc3d84e 100644 --- a/src/osinterface.h +++ b/src/osinterface.h @@ -45,6 +45,7 @@ void osinterface_init(); void osinterface_process_messages(); void osinterface_draw(); void osinterface_free(); +void osinterface_update_palette(char* colours, int start_index, int num_colours); int osinterface_open_common_file_dialog(int type, char *title, char *filename, char *filterPattern, char *filterName); From f3e7c6c23c8a49aac4f41176a6ca881bba9f56a5 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 9 May 2014 09:18:49 +0100 Subject: [PATCH 003/209] Added more of draw_sprite still needs work. Function call does not work --- src/gfx.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 216 insertions(+), 21 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 3c6c2ce010..bcfce787f5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -145,6 +145,69 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri RCT2_CALLPROC_X(0x006E6F81, left, right, top, bottom, _si, dpi, colour); } +/* +* rct2: 0x67A934 +*/ +void sub_0x67A934(int eax, int ebp, int ebx, int esi, rct_drawpixelinfo *dpi, int x, int y){ + int ecx = x, edx = y, edi = dpi; + ebp = dpi; + esi = RCT2_GLOBAL(0x9E3D08, uint32); + edi = *((uint32*)dpi); + edx += RCT2_GLOBAL(0x9E3D12, uint16); + eax = RCT2_GLOBAL(0x9E3D0E, uint16); + RCT2_GLOBAL(0xEDF808, uint32) = 0; + RCT2_GLOBAL(0x9ABDAC, uint16) = eax; + if (edx > dpi->y) + { + edx -= dpi->y; + RCT2_GLOBAL(0x9ABDAC, uint16) += edx; + if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0)return; + RCT2_GLOBAL(0xEDF808, uint16) -= edx; + edx = 0; + } + else{ + edx -= dpi->y; + eax = dpi->width; + ebx = edx; + eax += dpi->pitch; + eax *= edx; + edx = ebx; + edi += eax; + } + edx += RCT2_GLOBAL(0x9ABDAC, uint16); + edx -= dpi->height; + if (edx > 0){ + RCT2_GLOBAL(0x9ABDAC, uint16) -= edx; + if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0)return; + } + eax = RCT2_GLOBAL(0x9E3D0C, uint16); + RCT2_GLOBAL(0xEDF80C, uint32) = 0; + ecx += RCT2_GLOBAL(0x9E3D10, uint16); + + RCT2_GLOBAL(0x9ABDA8, uint16) = eax; + ecx -= dpi->x; + if (ecx < 0){ + RCT2_GLOBAL(0x9ABDA8, uint16) += ecx; + if (RCT2_GLOBAL(0x9ABDA8, uint16) <= 0)return; + RCT2_GLOBAL(0xEDF80C, uint16) -= ecx; + ecx = 0; + } + else{ + edi += ecx; + } + ecx += RCT2_GLOBAL(0x9ABDA8, uint16); + ecx -= dpi->width; + if (ecx > 0){ + RCT2_GLOBAL(0x9ABDA8, uint16) -= ecx; + if (RCT2_GLOBAL(0x9ABDA8, uint16) <= 0)return; + } + eax = dpi->width; + eax += dpi->pitch; + RCT2_GLOBAL(0x9ABDB0, uint16) = eax; + //ebx esi edi + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); +} + /** * * rct2: 0x0067A28E @@ -154,8 +217,8 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - return; + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + //return; int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; eax = image_id; @@ -164,26 +227,158 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax &= 0x7; eax = RCT2_GLOBAL(0x009E3CE4 + 4 * eax, uint32); RCT2_GLOBAL(0x009E3CDC, uint32) = eax; - if (!(image_id & 0xE0000000)){ - if (!(image_id & (1<<31))) + + if ((image_id & (1 << 31)) && (image_id & (1 << 29))){ + eax = image_id; + RCT2_GLOBAL(0x9E3CDC, uint32) = 0; + eax >>= 19; + eax &= 0x1f; + eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); + eax <<= 4; + eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + ebp = *((uint32*)eax + 0xF3); + esi = *((uint32*)eax + 0xF7); + RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; + RCT2_GLOBAL(0x9ABF03, uint32) = esi; + ebp = *((uint32*)eax + 0xFB); + eax = ebx;//0x67a310 + + RCT2_GLOBAL(0x9ABF07, uint32) = ebp; + eax >>= 24; + eax &= 0x1f; + eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); + eax <<= 4; + eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + ebp = *((uint32*)eax + 0xF3); + esi = *((uint32*)eax + 0xF7); + RCT2_GLOBAL(0x9ABED6, uint32) = ebp; + RCT2_GLOBAL(0x9ABEDA, uint32) = esi; + ebp = *((uint32*)eax + 0xFB); + + RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; + RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; + } else if ((image_id & (1 << 31))){ + //0x67a361 + } else if ((image_id & (1 << 30))){ + //0x67a445 + } + //0x67A46E + ebx &= 0x7FFFF; + ebx <<= 4; + ebx += RCT2_ADDRESS_G1_ELEMENTS; + if (dpi->pad_0E >= 1){ + if (dpi->pad_0E == 1){ + //long jump into 0x67bd81 + } + if (dpi->pad_0E >= 3){ + //long jump into 0x67DADA + } + //long jump into 0x67FAAE + return; + } + eax = *((uint32*)ebx + 8); + ebp = *((uint32*)ebx + 12); + RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); + RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 4); + RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 8); + RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 12); + if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ + sub_0x67A934(eax, ebp, ebx, esi, dpi, x, y); + //long jump into 0x67A934 + return; + } + ebp = dpi; + esi = RCT2_GLOBAL(0x9E3D08, uint32); + RCT2_GLOBAL(0x9E3CE0, uint32) = 0; + edi = *((uint32*)dpi); + edx = edx & 0xFFFF + RCT2_GLOBAL(0x9E3D12, uint16); + eax = eax & 0xFFFF + RCT2_GLOBAL(0x9E3D0E, uint16); + RCT2_GLOBAL(0x9ABDAC, uint16) = eax; + edx -= dpi->y; + if (edx < 0){ + RCT2_GLOBAL(0x9ABDAC, uint16)+= edx; + if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0){ + //jump 0x67A607 + return; + } + edx = -edx; + eax = RCT2_GLOBAL(0x9E3D0C, uint16); + eax *= edx; + edx = 0; + esi += eax; + RCT2_GLOBAL(0x9E3CE0, uint32) += eax; + } else { + ebx = edx; + eax = dpi->width; + + eax += dpi->pitch; + eax *= edx; + edx = ebx; + edi += eax; + } + edx += RCT2_GLOBAL(0x9ABDAC, uint16); + if (edx > dpi->height){ + edx -= dpi->height; + if (RCT2_GLOBAL(0x9ABDAC, uint32) > edx) { - if (!(image_id & (1<<29))){ - eax = image_id; - RCT2_GLOBAL(0x9E3CDC, uint32) = 0; - eax >>= 13; - eax &= 0x1f; - eax = RCT2_GLOBAL(eax * 4 + 0x91FCBC, uint32); - eax <<= 4; - eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - ebp = *((uint32*)eax + 0xF3); - esi = *((uint32*)eax + 0xF7); - RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; - RCT2_GLOBAL(0x9ABF03, uint32) = esi; - ebp = *((uint32*)eax + 0xFB); - eax = ebx;//0x67a310 - }//0x67a361 - }//0x67a445 - }//0x67a46e + RCT2_GLOBAL(0x9ABDAC, uint32) -= edx; + return;//jump to 0x67A607 + } + RCT2_GLOBAL(0x9ABDAC, uint32) -= edx; + } + else{ + edx -= dpi->height; + } + eax = RCT2_GLOBAL(0x9E3D0C, uint16); + RCT2_GLOBAL(0x9ABDA8, uint16) = eax; + ebx = dpi->width; + eax = -eax; + eax += ebx; + eax += dpi->pitch; + RCT2_GLOBAL(0x9ABDAE, uint16) = 0; + RCT2_GLOBAL(0x9ABDB0, uint16) = eax; + ecx += RCT2_GLOBAL(0x9E3D10, uint16); + if (ecx > dpi->x){ + ecx -= dpi->x; + if (RCT2_GLOBAL(0x9ABDA8, uint16) > ecx ){//missing jz 0x67a596 + RCT2_GLOBAL(0x9ABDA8, uint16) += ecx; + return; + } + RCT2_GLOBAL(0x9ABDA8, uint16) += ecx; + ecx -= RCT2_GLOBAL(0x9ABDAE, uint16); + esi -= ecx; + RCT2_GLOBAL(0x9E3CE0, uint32) -= ecx; + RCT2_GLOBAL(0x9ABDB0, uint16) -= ecx; + ecx = 0; + } + else{ + ecx -= dpi->x; + } + edi += ecx; + ecx += RCT2_GLOBAL(0x9ABDA8, uint16); + if (ecx > dpi->width){ + ecx -= dpi->width; + if (RCT2_GLOBAL(0x9ABDA8, uint16) > ecx){ + RCT2_GLOBAL(0x9ABDA8, uint16) -= ecx; + return; + } + RCT2_GLOBAL(0x9ABDA8, uint16) -= ecx; + RCT2_GLOBAL(0x9ABDAE, uint16) += ecx; + RCT2_GLOBAL(0x9ABDB0, uint16) += ecx; + } + else{ + ecx -= dpi->width; + } + if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ + eax = RCT2_GLOBAL(0x9ABDAC, uint8); + edx = RCT2_GLOBAL(0x9ABDAE, uint16); + ebp = RCT2_GLOBAL(0x9ABDB0, uint16); + ebx = RCT2_GLOBAL(0xEDF81C, uint32); + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + return; + } + //0x67A60A + } /** From 1086c4e5247a376ee8b9f10cad816c2e58f9ac80 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 10 May 2014 07:14:12 +0100 Subject: [PATCH 004/209] added notes to help find bug --- src/gfx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gfx.c b/src/gfx.c index bcfce787f5..de6bd2f664 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -149,6 +149,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * rct2: 0x67A934 */ void sub_0x67A934(int eax, int ebp, int ebx, int esi, rct_drawpixelinfo *dpi, int x, int y){ + //eax = 3000A, ecx = 9C, edx = 152, ebx = A46798, esp = CFCC8, ebp = DC10005, esi = 0, edi = 9DEA74 int ecx = x, edx = y, edi = dpi; ebp = dpi; esi = RCT2_GLOBAL(0x9E3D08, uint32); @@ -205,6 +206,8 @@ void sub_0x67A934(int eax, int ebp, int ebx, int esi, rct_drawpixelinfo *dpi, in eax += dpi->pitch; RCT2_GLOBAL(0x9ABDB0, uint16) = eax; //ebx esi edi + char* FindThis = "FINDTHISSTRING"; + //eax 280,ecx FEFC,edx FFFF,ebx A40003,esp CFCC4,ebp 9DEA74,esi 3E1DF13,edi 322076 RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); } @@ -217,6 +220,7 @@ void sub_0x67A934(int eax, int ebp, int ebx, int esi, rct_drawpixelinfo *dpi, in */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { + char* FindMe = "FINDTHISOTHERSTRING"; //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); //return; From 601305a4e3651d84b78620daefe6c87be9ee0dda Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 10 May 2014 10:12:48 +0100 Subject: [PATCH 005/209] Still searching for bug. Must be some external memory not set --- src/gfx.c | 141 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 90 insertions(+), 51 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index de6bd2f664..2199fb6fe1 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -148,67 +148,105 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri /* * rct2: 0x67A934 */ -void sub_0x67A934(int eax, int ebp, int ebx, int esi, rct_drawpixelinfo *dpi, int x, int y){ - //eax = 3000A, ecx = 9C, edx = 152, ebx = A46798, esp = CFCC8, ebp = DC10005, esi = 0, edi = 9DEA74 - int ecx = x, edx = y, edi = dpi; - ebp = dpi; - esi = RCT2_GLOBAL(0x9E3D08, uint32); - edi = *((uint32*)dpi); - edx += RCT2_GLOBAL(0x9E3D12, uint16); - eax = RCT2_GLOBAL(0x9E3D0E, uint16); +void sub_0x67A934(int _eax, int _ebp, int _ebx, int _esi, rct_drawpixelinfo *dpi, int x, int y){ + //_eax = 3000A, _ecx = 9C, _edx = 152, _ebx = A46798, esp = CFCC8, ebp = DC10005, _esi = 0, _edi = 9DEA74 + int _ecx = x, _edx = y, _edi = dpi; + sint16 dx = y, ax = 0, bx = 0, cx = x; + _ebp = dpi; + _esi = RCT2_GLOBAL(0x9E3D08, uint32); + _edi = *((uint32*)dpi);//2A18EC + dx += RCT2_GLOBAL(0x9E3D12, uint16); + ax = RCT2_GLOBAL(0x9E3D0E, uint16); RCT2_GLOBAL(0xEDF808, uint32) = 0; - RCT2_GLOBAL(0x9ABDAC, uint16) = eax; - if (edx > dpi->y) + RCT2_GLOBAL(0x9ABDAC, uint16) = ax; + dx -= dpi->y; + if (dx < 0) { - edx -= dpi->y; - RCT2_GLOBAL(0x9ABDAC, uint16) += edx; + RCT2_GLOBAL(0x9ABDAC, uint16) += dx; if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0)return; - RCT2_GLOBAL(0xEDF808, uint16) -= edx; - edx = 0; + RCT2_GLOBAL(0xEDF808, uint16) -= dx; + _edx = 0; + dx = 0; } else{ - edx -= dpi->y; - eax = dpi->width; - ebx = edx; - eax += dpi->pitch; - eax *= edx; - edx = ebx; - edi += eax; + ax = dpi->width; + bx = dx; + ax += dpi->pitch; + _edx = dx; + _eax = ax; + _eax *= _edx; + _edx = 0; + ax = _eax; + dx = bx; + _edi += _eax; } - edx += RCT2_GLOBAL(0x9ABDAC, uint16); - edx -= dpi->height; - if (edx > 0){ - RCT2_GLOBAL(0x9ABDAC, uint16) -= edx; + dx += RCT2_GLOBAL(0x9ABDAC, uint16); + dx -= dpi->height; + if (dx > 0){ + RCT2_GLOBAL(0x9ABDAC, uint16) -= dx; if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0)return; } - eax = RCT2_GLOBAL(0x9E3D0C, uint16); + ax = RCT2_GLOBAL(0x9E3D0C, uint16); RCT2_GLOBAL(0xEDF80C, uint32) = 0; - ecx += RCT2_GLOBAL(0x9E3D10, uint16); + cx += RCT2_GLOBAL(0x9E3D10, uint16); - RCT2_GLOBAL(0x9ABDA8, uint16) = eax; - ecx -= dpi->x; - if (ecx < 0){ - RCT2_GLOBAL(0x9ABDA8, uint16) += ecx; + RCT2_GLOBAL(0x9ABDA8, uint16) = ax; + cx -= dpi->x; + if (cx < 0){ + RCT2_GLOBAL(0x9ABDA8, uint16) += cx; if (RCT2_GLOBAL(0x9ABDA8, uint16) <= 0)return; - RCT2_GLOBAL(0xEDF80C, uint16) -= ecx; - ecx = 0; + RCT2_GLOBAL(0xEDF80C, uint16) -= cx; + _ecx = 0; + cx = 0; } else{ - edi += ecx; + _ecx = cx; + _edi += _ecx; } - ecx += RCT2_GLOBAL(0x9ABDA8, uint16); - ecx -= dpi->width; - if (ecx > 0){ - RCT2_GLOBAL(0x9ABDA8, uint16) -= ecx; + cx += RCT2_GLOBAL(0x9ABDA8, uint16); + cx -= dpi->width; + if (cx > 0){ + RCT2_GLOBAL(0x9ABDA8, uint16) -= cx; if (RCT2_GLOBAL(0x9ABDA8, uint16) <= 0)return; } - eax = dpi->width; - eax += dpi->pitch; - RCT2_GLOBAL(0x9ABDB0, uint16) = eax; - //ebx esi edi + ax = dpi->width; + ax += dpi->pitch; + RCT2_GLOBAL(0x9ABDB0, uint16) = ax; + _eax = (_eax & 0xFFFF0000) + ax; + _ebx = (_ebx & 0xFFFF0000) + bx; + _ecx = (_ecx & 0xFFFF0000) + cx; + _edx = (_edx & 0xFFFF0000) + dx; + + //_ebx _esi _edi char* FindThis = "FINDTHISSTRING"; - //eax 280,ecx FEFC,edx FFFF,ebx A40003,esp CFCC4,ebp 9DEA74,esi 3E1DF13,edi 322076 - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + //_eax 280,_ecx FEFC,_edx FFFF,_ebx A40003,esp CFCC4,ebp 9DEA74,_esi 3E1DF13,_edi 322076 + _asm{ + push eax + push ebx + push ecx + push edx + push edi + push esi + push ebp + push 0x67AA18 + push dpi + mov eax, _eax + mov ebx, _ebx + mov ecx, _ecx + mov edx, _edx + mov esi, _esi + mov edi, _edi + mov ebp, _ebp + call [esp+4] + add esp,8 + pop ebp + pop esi + pop edi + pop edx + pop ecx + pop ebx + pop eax + } } /** @@ -229,7 +267,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax >>= 26; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax &= 0x7; - eax = RCT2_GLOBAL(0x009E3CE4 + 4 * eax, uint32); + + eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32);//3D91F13 3F71F13 * 2 RCT2_GLOBAL(0x009E3CDC, uint32) = eax; if ((image_id & (1 << 31)) && (image_id & (1 << 29))){ @@ -280,12 +319,12 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //long jump into 0x67FAAE return; } - eax = *((uint32*)ebx + 8); - ebp = *((uint32*)ebx + 12); - RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); - RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 4); - RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 8); - RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 12); + eax = *((uint32*)ebx + 2); + ebp = *((uint32*)ebx + 3); + RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx);//3F8DF13 3D8DF13 + RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1);//4E003A 4E003A + RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2);//3000A * 2 + RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3);//DC10005 *2 if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ sub_0x67A934(eax, ebp, ebx, esi, dpi, x, y); //long jump into 0x67A934 From 16ed98348a1ee20c7e0728b9e2f158b9ba5cbe90 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 10 May 2014 10:16:23 +0100 Subject: [PATCH 006/209] Found bug due to signness on global var --- src/gfx.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 2199fb6fe1..994536e0a5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -162,9 +162,9 @@ void sub_0x67A934(int _eax, int _ebp, int _ebx, int _esi, rct_drawpixelinfo *dpi dx -= dpi->y; if (dx < 0) { - RCT2_GLOBAL(0x9ABDAC, uint16) += dx; - if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0)return; - RCT2_GLOBAL(0xEDF808, uint16) -= dx; + RCT2_GLOBAL(0x9ABDAC, sint16) += dx; + if (RCT2_GLOBAL(0x9ABDAC, sint16) <= 0)return; + RCT2_GLOBAL(0xEDF808, sint16) -= dx; _edx = 0; dx = 0; } @@ -180,22 +180,22 @@ void sub_0x67A934(int _eax, int _ebp, int _ebx, int _esi, rct_drawpixelinfo *dpi dx = bx; _edi += _eax; } - dx += RCT2_GLOBAL(0x9ABDAC, uint16); + dx += RCT2_GLOBAL(0x9ABDAC, sint16); dx -= dpi->height; if (dx > 0){ - RCT2_GLOBAL(0x9ABDAC, uint16) -= dx; - if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0)return; + RCT2_GLOBAL(0x9ABDAC, sint16) -= dx; + if (RCT2_GLOBAL(0x9ABDAC, sint16) <= 0)return; } ax = RCT2_GLOBAL(0x9E3D0C, uint16); RCT2_GLOBAL(0xEDF80C, uint32) = 0; cx += RCT2_GLOBAL(0x9E3D10, uint16); - RCT2_GLOBAL(0x9ABDA8, uint16) = ax; + RCT2_GLOBAL(0x9ABDA8, sint16) = ax; cx -= dpi->x; if (cx < 0){ - RCT2_GLOBAL(0x9ABDA8, uint16) += cx; - if (RCT2_GLOBAL(0x9ABDA8, uint16) <= 0)return; - RCT2_GLOBAL(0xEDF80C, uint16) -= cx; + RCT2_GLOBAL(0x9ABDA8, sint16) += cx; + if (RCT2_GLOBAL(0x9ABDA8, sint16) <= 0)return; + RCT2_GLOBAL(0xEDF80C, sint16) -= cx; _ecx = 0; cx = 0; } @@ -203,11 +203,11 @@ void sub_0x67A934(int _eax, int _ebp, int _ebx, int _esi, rct_drawpixelinfo *dpi _ecx = cx; _edi += _ecx; } - cx += RCT2_GLOBAL(0x9ABDA8, uint16); + cx += RCT2_GLOBAL(0x9ABDA8, sint16); cx -= dpi->width; if (cx > 0){ - RCT2_GLOBAL(0x9ABDA8, uint16) -= cx; - if (RCT2_GLOBAL(0x9ABDA8, uint16) <= 0)return; + RCT2_GLOBAL(0x9ABDA8, sint16) -= cx; + if (RCT2_GLOBAL(0x9ABDA8, sint16) <= 0)return; } ax = dpi->width; ax += dpi->pitch; From 26f4b35e613d8fb2f211a0165a9b4208088e29a9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 10 May 2014 12:26:19 +0100 Subject: [PATCH 007/209] Cleaned up code so that it makes more sense. --- src/addresses.h | 18 ++++++ src/gfx.c | 164 +++++++++++++++++++----------------------------- 2 files changed, 81 insertions(+), 101 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 2ec02b5edd..961bb4e1a1 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -277,6 +277,24 @@ static void RCT2_CALLPROC_X(int address, int _eax, int _ebx, int _ecx, int _edx, } } +static void RCT2_CALLPROC_X_EBPSAFE(int address, int _eax, int _ebx, int _ecx, int _edx, int _esi, int _edi, int _ebp) +{ + __asm { + push ebp + push address + mov eax, _eax + mov ebx, _ebx + mov ecx, _ecx + mov edx, _edx + mov esi, _esi + mov edi, _edi + mov ebp, _ebp + call[esp] + add esp, 4 + pop ebp + } +} + static void RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_edx, int *_esi, int *_edi, int *_ebp) { __asm { diff --git a/src/gfx.c b/src/gfx.c index 994536e0a5..c114018af6 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -145,108 +145,69 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri RCT2_CALLPROC_X(0x006E6F81, left, right, top, bottom, _si, dpi, colour); } +#define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 +#define RCT2_Y_RELATED_GLOBAL_2 0x9ABDAC //sint16 + /* -* rct2: 0x67A934 +* rct2: 0x67A934 title screen bitmaps on buttons +* This function readies all the global vars for copying the sprite data onto the screen +* I think its only used for bitmaps onto buttons but i am not sure. */ -void sub_0x67A934(int _eax, int _ebp, int _ebx, int _esi, rct_drawpixelinfo *dpi, int x, int y){ +void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ //_eax = 3000A, _ecx = 9C, _edx = 152, _ebx = A46798, esp = CFCC8, ebp = DC10005, _esi = 0, _edi = 9DEA74 - int _ecx = x, _edx = y, _edi = dpi; - sint16 dx = y, ax = 0, bx = 0, cx = x; - _ebp = dpi; - _esi = RCT2_GLOBAL(0x9E3D08, uint32); - _edi = *((uint32*)dpi);//2A18EC - dx += RCT2_GLOBAL(0x9E3D12, uint16); - ax = RCT2_GLOBAL(0x9E3D0E, uint16); + int _edi = dpi, _esi; + sint16 translated_x = x, translated_y = y; + char* bits_pointer; + bits_pointer = dpi->bits; + + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); RCT2_GLOBAL(0xEDF808, uint32) = 0; - RCT2_GLOBAL(0x9ABDAC, uint16) = ax; - dx -= dpi->y; - if (dx < 0) + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint16) = RCT2_GLOBAL(0x9E3D0E, uint16); + translated_y -= dpi->y; + if (translated_y < 0) { - RCT2_GLOBAL(0x9ABDAC, sint16) += dx; - if (RCT2_GLOBAL(0x9ABDAC, sint16) <= 0)return; - RCT2_GLOBAL(0xEDF808, sint16) -= dx; - _edx = 0; - dx = 0; + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; + RCT2_GLOBAL(0xEDF808, sint16) -= translated_y; + translated_y = 0; } else{ - ax = dpi->width; - bx = dx; - ax += dpi->pitch; - _edx = dx; - _eax = ax; - _eax *= _edx; - _edx = 0; - ax = _eax; - dx = bx; - _edi += _eax; + bits_pointer += (dpi->width + dpi->pitch)*translated_y; } - dx += RCT2_GLOBAL(0x9ABDAC, sint16); - dx -= dpi->height; - if (dx > 0){ - RCT2_GLOBAL(0x9ABDAC, sint16) -= dx; - if (RCT2_GLOBAL(0x9ABDAC, sint16) <= 0)return; + + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16); + translated_y -= dpi->height; + if (translated_y > 0){ + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; } - ax = RCT2_GLOBAL(0x9E3D0C, uint16); + RCT2_GLOBAL(0xEDF80C, uint32) = 0; - cx += RCT2_GLOBAL(0x9E3D10, uint16); + translated_x += RCT2_GLOBAL(0x9E3D10, uint16); - RCT2_GLOBAL(0x9ABDA8, sint16) = ax; - cx -= dpi->x; - if (cx < 0){ - RCT2_GLOBAL(0x9ABDA8, sint16) += cx; + RCT2_GLOBAL(0x9ABDA8, sint16) = RCT2_GLOBAL(0x9E3D0C, uint16); + translated_x -= dpi->x; + if (translated_x < 0){ + RCT2_GLOBAL(0x9ABDA8, sint16) += translated_x; if (RCT2_GLOBAL(0x9ABDA8, sint16) <= 0)return; - RCT2_GLOBAL(0xEDF80C, sint16) -= cx; - _ecx = 0; - cx = 0; + RCT2_GLOBAL(0xEDF80C, sint16) -= translated_x; + translated_x = 0; } else{ - _ecx = cx; - _edi += _ecx; + bits_pointer += translated_x; } - cx += RCT2_GLOBAL(0x9ABDA8, sint16); - cx -= dpi->width; - if (cx > 0){ - RCT2_GLOBAL(0x9ABDA8, sint16) -= cx; + translated_x += RCT2_GLOBAL(0x9ABDA8, sint16); + translated_x -= dpi->width; + if (translated_x > 0){ + RCT2_GLOBAL(0x9ABDA8, sint16) -= translated_x; if (RCT2_GLOBAL(0x9ABDA8, sint16) <= 0)return; } - ax = dpi->width; - ax += dpi->pitch; - RCT2_GLOBAL(0x9ABDB0, uint16) = ax; - _eax = (_eax & 0xFFFF0000) + ax; - _ebx = (_ebx & 0xFFFF0000) + bx; - _ecx = (_ecx & 0xFFFF0000) + cx; - _edx = (_edx & 0xFFFF0000) + dx; - //_ebx _esi _edi - char* FindThis = "FINDTHISSTRING"; - //_eax 280,_ecx FEFC,_edx FFFF,_ebx A40003,esp CFCC4,ebp 9DEA74,_esi 3E1DF13,_edi 322076 - _asm{ - push eax - push ebx - push ecx - push edx - push edi - push esi - push ebp - push 0x67AA18 - push dpi - mov eax, _eax - mov ebx, _ebx - mov ecx, _ecx - mov edx, _edx - mov esi, _esi - mov edi, _edi - mov ebp, _ebp - call [esp+4] - add esp,8 - pop ebp - pop esi - pop edi - pop edx - pop ecx - pop ebx - pop eax - } + RCT2_GLOBAL(0x9ABDB0, uint16) = dpi->width + dpi->pitch; + + // I dont think it uses ecx, edx but just in case + //This is a G1 Loaded sprite address 0x9E3D08 + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); } /** @@ -258,7 +219,6 @@ void sub_0x67A934(int _eax, int _ebp, int _ebx, int _esi, rct_drawpixelinfo *dpi */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { - char* FindMe = "FINDTHISOTHERSTRING"; //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); //return; @@ -284,7 +244,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; RCT2_GLOBAL(0x9ABF03, uint32) = esi; ebp = *((uint32*)eax + 0xFB); - eax = ebx;//0x67a310 + eax = ebx; RCT2_GLOBAL(0x9ABF07, uint32) = ebp; eax >>= 24; @@ -321,26 +281,26 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } eax = *((uint32*)ebx + 2); ebp = *((uint32*)ebx + 3); - RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx);//3F8DF13 3D8DF13 - RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1);//4E003A 4E003A - RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2);//3000A * 2 - RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3);//DC10005 *2 + RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); + RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); + RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //Y related + RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ - sub_0x67A934(eax, ebp, ebx, esi, dpi, x, y); - //long jump into 0x67A934 + //Title screen bitmaps + sub_0x67A934(dpi, x, y); return; } ebp = dpi; esi = RCT2_GLOBAL(0x9E3D08, uint32); RCT2_GLOBAL(0x9E3CE0, uint32) = 0; edi = *((uint32*)dpi); - edx = edx & 0xFFFF + RCT2_GLOBAL(0x9E3D12, uint16); + edx = edx & 0xFFFF + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); eax = eax & 0xFFFF + RCT2_GLOBAL(0x9E3D0E, uint16); - RCT2_GLOBAL(0x9ABDAC, uint16) = eax; + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = eax; edx -= dpi->y; if (edx < 0){ - RCT2_GLOBAL(0x9ABDAC, uint16)+= edx; - if (RCT2_GLOBAL(0x9ABDAC, uint16) <= 0){ + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += edx; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0){ //jump 0x67A607 return; } @@ -359,15 +319,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) edx = ebx; edi += eax; } - edx += RCT2_GLOBAL(0x9ABDAC, uint16); + edx += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16); if (edx > dpi->height){ edx -= dpi->height; - if (RCT2_GLOBAL(0x9ABDAC, uint32) > edx) + //RCT2_Y_RELATED_GLOBAL_2 is normaly 16 bit signed??? + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint32) > edx) { - RCT2_GLOBAL(0x9ABDAC, uint32) -= edx; + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint32) -= edx; return;//jump to 0x67A607 } - RCT2_GLOBAL(0x9ABDAC, uint32) -= edx; + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint32) -= edx; } else{ edx -= dpi->height; @@ -413,7 +374,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ecx -= dpi->width; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - eax = RCT2_GLOBAL(0x9ABDAC, uint8); + //RCT2_Y_RELATED_GLOBAL_2 is normally 16 bit signed??? + eax = RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint8); edx = RCT2_GLOBAL(0x9ABDAE, uint16); ebp = RCT2_GLOBAL(0x9ABDB0, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); From 6d97593093f0e8a2ee6f32a5db0506ba8046052e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 11 May 2014 10:14:38 +0100 Subject: [PATCH 008/209] Bug in main draw_sprite func for now skipping code --- src/gfx.c | 196 +++++++++++++++++++++++++++--------------------------- src/gfx.h | 2 +- 2 files changed, 100 insertions(+), 98 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c114018af6..8f663827f5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -147,23 +147,24 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri #define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 #define RCT2_Y_RELATED_GLOBAL_2 0x9ABDAC //sint16 - +#define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 +#define RCT2_X_RELATED_GLOBAL_2 0x9ABDA8 //sint16 /* * rct2: 0x67A934 title screen bitmaps on buttons * This function readies all the global vars for copying the sprite data onto the screen * I think its only used for bitmaps onto buttons but i am not sure. */ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ - //_eax = 3000A, _ecx = 9C, _edx = 152, _ebx = A46798, esp = CFCC8, ebp = DC10005, _esi = 0, _edi = 9DEA74 + int _edi = dpi, _esi; sint16 translated_x = x, translated_y = y; char* bits_pointer; bits_pointer = dpi->bits; - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; RCT2_GLOBAL(0xEDF808, uint32) = 0; - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint16) = RCT2_GLOBAL(0x9E3D0E, uint16); - translated_y -= dpi->y; + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + if (translated_y < 0) { RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; @@ -175,38 +176,35 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ bits_pointer += (dpi->width + dpi->pitch)*translated_y; } - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16); - translated_y -= dpi->height; + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height; if (translated_y > 0){ RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; } RCT2_GLOBAL(0xEDF80C, uint32) = 0; - translated_x += RCT2_GLOBAL(0x9E3D10, uint16); + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; - RCT2_GLOBAL(0x9ABDA8, sint16) = RCT2_GLOBAL(0x9E3D0C, uint16); - translated_x -= dpi->x; + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); if (translated_x < 0){ - RCT2_GLOBAL(0x9ABDA8, sint16) += translated_x; - if (RCT2_GLOBAL(0x9ABDA8, sint16) <= 0)return; + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; RCT2_GLOBAL(0xEDF80C, sint16) -= translated_x; translated_x = 0; } else{ bits_pointer += translated_x; } - translated_x += RCT2_GLOBAL(0x9ABDA8, sint16); + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16); translated_x -= dpi->width; if (translated_x > 0){ - RCT2_GLOBAL(0x9ABDA8, sint16) -= translated_x; - if (RCT2_GLOBAL(0x9ABDA8, sint16) <= 0)return; + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; } RCT2_GLOBAL(0x9ABDB0, uint16) = dpi->width + dpi->pitch; // I dont think it uses ecx, edx but just in case - //This is a G1 Loaded sprite address 0x9E3D08 RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); } @@ -227,11 +225,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax >>= 26; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax &= 0x7; - - eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32);//3D91F13 3F71F13 * 2 + eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32); RCT2_GLOBAL(0x009E3CDC, uint32) = eax; if ((image_id & (1 << 31)) && (image_id & (1 << 29))){ + /* eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -259,130 +257,134 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = *((uint32*)eax + 0xFB); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; - RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; + RCT2_GLOBAL(0x9ABEDE, uint32) = ebp;*/ + return; } else if ((image_id & (1 << 31))){ - //0x67a361 + return; + //jump into 0x67a361 } else if ((image_id & (1 << 30))){ - //0x67a445 + return; + //jump into 0x67a445 } - //0x67A46E + ebx &= 0x7FFFF; ebx <<= 4; ebx += RCT2_ADDRESS_G1_ELEMENTS; if (dpi->pad_0E >= 1){ if (dpi->pad_0E == 1){ - //long jump into 0x67bd81 + return; + //jump into 0x67bd81 } if (dpi->pad_0E >= 3){ - //long jump into 0x67DADA + return;//jump into 0x67FAAE } - //long jump into 0x67FAAE + //jump into 0x67DADA return; } eax = *((uint32*)ebx + 2); ebp = *((uint32*)ebx + 3); - RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); + RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); //offset to g1 bits? RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); - RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //Y related + RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps sub_0x67A934(dpi, x, y); return; } + + + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + return; + //There is a mistake in the code below this point calling the above to skip it. + + //dpi on stack + int translated_x, translated_y; + char* bits_pointer; + ebp = dpi; esi = RCT2_GLOBAL(0x9E3D08, uint32); RCT2_GLOBAL(0x9E3CE0, uint32) = 0; - edi = *((uint32*)dpi); - edx = edx & 0xFFFF + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); - eax = eax & 0xFFFF + RCT2_GLOBAL(0x9E3D0E, uint16); - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = eax; - edx -= dpi->y; - if (edx < 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += edx; + bits_pointer = dpi->bits; + + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + + translated_y = y + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; + + + if (translated_y < 0){ + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0){ - //jump 0x67A607 return; } - edx = -edx; - eax = RCT2_GLOBAL(0x9E3D0C, uint16); - eax *= edx; - edx = 0; - esi += eax; - RCT2_GLOBAL(0x9E3CE0, uint32) += eax; + translated_y = -translated_y; + esi += translated_y * RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(0x9E3CE0, sint32) += translated_y * RCT2_GLOBAL(0x9E3D0C, sint16); + translated_y = 0; } else { - ebx = edx; - eax = dpi->width; - - eax += dpi->pitch; - eax *= edx; - edx = ebx; - edi += eax; + eax = (dpi->width + dpi->pitch) * translated_y; + bits_pointer += eax; } - edx += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16); - if (edx > dpi->height){ - edx -= dpi->height; - //RCT2_Y_RELATED_GLOBAL_2 is normaly 16 bit signed??? - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint32) > edx) + + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height;; + + if (translated_y > 0){ + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <=0) { - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint32) -= edx; - return;//jump to 0x67A607 + return; } - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint32) -= edx; } - else{ - edx -= dpi->height; - } - eax = RCT2_GLOBAL(0x9E3D0C, uint16); - RCT2_GLOBAL(0x9ABDA8, uint16) = eax; - ebx = dpi->width; - eax = -eax; - eax += ebx; - eax += dpi->pitch; + + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); + eax = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(0x9ABDAE, uint16) = 0; - RCT2_GLOBAL(0x9ABDB0, uint16) = eax; - ecx += RCT2_GLOBAL(0x9E3D10, uint16); - if (ecx > dpi->x){ - ecx -= dpi->x; - if (RCT2_GLOBAL(0x9ABDA8, uint16) > ecx ){//missing jz 0x67a596 - RCT2_GLOBAL(0x9ABDA8, uint16) += ecx; + RCT2_GLOBAL(0x9ABDB0, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); + translated_x = x + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; + + if (translated_x < 0){ + + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ return; } - RCT2_GLOBAL(0x9ABDA8, uint16) += ecx; - ecx -= RCT2_GLOBAL(0x9ABDAE, uint16); - esi -= ecx; - RCT2_GLOBAL(0x9E3CE0, uint32) -= ecx; - RCT2_GLOBAL(0x9ABDB0, uint16) -= ecx; - ecx = 0; + + translated_x -= RCT2_GLOBAL(0x9ABDAE, sint16); + esi -= translated_x; + RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; + RCT2_GLOBAL(0x9ABDB0, sint16) -= translated_x; + translated_x = 0; } - else{ - ecx -= dpi->x; - } - edi += ecx; - ecx += RCT2_GLOBAL(0x9ABDA8, uint16); - if (ecx > dpi->width){ - ecx -= dpi->width; - if (RCT2_GLOBAL(0x9ABDA8, uint16) > ecx){ - RCT2_GLOBAL(0x9ABDA8, uint16) -= ecx; + + bits_pointer += translated_x; + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) - dpi->width; + + if (translated_x > 0){ + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ return; } - RCT2_GLOBAL(0x9ABDA8, uint16) -= ecx; - RCT2_GLOBAL(0x9ABDAE, uint16) += ecx; - RCT2_GLOBAL(0x9ABDB0, uint16) += ecx; - } - else{ - ecx -= dpi->width; + RCT2_GLOBAL(0x9ABDAE, sint16) += translated_x; + RCT2_GLOBAL(0x9ABDB0, sint16) += translated_x; } + if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - //RCT2_Y_RELATED_GLOBAL_2 is normally 16 bit signed??? - eax = RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint8); - edx = RCT2_GLOBAL(0x9ABDAE, uint16); - ebp = RCT2_GLOBAL(0x9ABDB0, uint16); + eax = (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) & 0xFF) << 8; + edx = RCT2_GLOBAL(0x9ABDAE, sint16); + ebp = RCT2_GLOBAL(0x9ABDB0, sint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + ecx = 0xFFFF&translated_x; + //ebx, esi, edi, ah used in 0x67a690 + //Calling is wrong + //esi or bits is most likely wrong + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, bits_pointer, ebp); return; } //0x67A60A + esi -= RCT2_GLOBAL(0x9E3D08, sint32); + return; + } diff --git a/src/gfx.h b/src/gfx.h index 9af771d4f8..de0411b258 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -31,7 +31,7 @@ typedef struct { short width; // 0x08 short height; // 0x0A short pitch; // 0x0C note: this is actually (pitch - width) - char pad_0E; // 0x0E + uint16 pad_0E; // 0x0E char var_0F; // 0x0F } rct_drawpixelinfo; From 81f2bfed359cb87f0eeeec2eda109b21331c9c69 Mon Sep 17 00:00:00 2001 From: ddevrien Date: Sun, 11 May 2014 10:51:05 +0200 Subject: [PATCH 009/209] Implemented checkbox widget draw function --- src/widget.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/widget.c b/src/widget.c index c476beed44..c2d386e705 100644 --- a/src/widget.c +++ b/src/widget.c @@ -37,6 +37,7 @@ static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetI static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); +static void widget_checkbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_hscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, int l, int t, int r, int b, int colour); @@ -154,6 +155,8 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) widget_scroll_draw(dpi, w, widgetIndex); break; case WWT_CHECKBOX: + widget_checkbox_draw(dpi, w, widgetIndex); + break; case WWT_24: break; case WWT_25: @@ -711,6 +714,46 @@ static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widg gfx_draw_string_centred_clipped(dpi, widget->image, (void*)0x013CE952, colour, l, t, widget->right - widget->left - 2); } +/** +* +* rct2: 0x006EBAD9 +*/ +static void widget_checkbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) +{ + rct_widget* widget; + int l, t, b; + uint8 colour; + + // Get the widget + widget = &w->widgets[widgetIndex]; + + // Resolve the absolute ltb + l = w->x + widget->left; + t = w->y + widget->top; + b = w->y + widget->bottom; + + // Get the colour + colour = w->colours[widget->colour]; + + // checkbox + gfx_fill_rect_inset(dpi, l, t, l + 9, b - 1, colour, 0x60); + + // fill it when checkbox is pressed + if (widget_is_pressed(w, widgetIndex)) { + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224; + gfx_draw_string(dpi, (char*)0x009DED72, colour & 0x7F, l, t); + } + + // draw the text + if (widget->image == -1) + return; + + if (widget_is_disabled(w, widgetIndex)) { + colour |= 0x40; + } + gfx_draw_string_left(dpi, widget->image, (char*)0x013CE952, colour, l + 14, t); +} + /** * * rct2: 0x006EBD96 From 705af9377b19c234c2405f0d4d897647919c716e Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 13:06:28 +0200 Subject: [PATCH 010/209] Start decompiling gfx_fill_rect Section starting 0x00678C83 complete and works, but needs better comments/names --- src/gfx.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 3 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 8f663827f5..cf534af2f7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -119,14 +119,177 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c * rct2: 0x00678AD4 * dpi (edi) * left (ax) - * top (cx) + * top (cx) ? * right (bx) - * bottom (dx) + * bottom (dx) ? * colour (ebp) */ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour) { - RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour); + + int left_, right_, top_, bottom_; + rct_drawpixelinfo* dpi_; + left_ = left; + right_ = right; + top_ = top; + bottom_ = bottom; + dpi_ = dpi; + + if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) || + (bottom < dpi->y) || (top >= (dpi->y + dpi->height))) + return; + + colour |= RCT2_GLOBAL(0x009ABD9C, uint32); + + if (!(colour & 0x1000000)) { + if (!(colour & 0x8000000)) { + left_ = left - dpi->x; + if (left_ < 0) + left_ = 0; + + right_ = right - dpi->x; + right_++; + if (right_ > dpi->width) + right_ = dpi->width; + + right_ -= left_; + + top_ = top - dpi->y; + if (top_ < 0) + top_ = 0; + + bottom_ = bottom - dpi->y; + bottom_++; + + if (bottom_ > dpi->height) + bottom_ = dpi->height; + + bottom_ -= top_; + + if (!(colour & 0x2000000)) { + if (!(colour & 0x4000000)) { + char* edi; + edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; + + // Take the last byte of colour and repeat it 4 times? + uint32 ax; + ax = colour & 0xffff; + ax = (ax & 0xff) << 8; + ax = ax << 8; + ax = (ax & 0xff00) >> 8; + ax = ax << 8; + ax = (ax & 0xff00) >> 8; + + int length; + length = dpi->width + dpi->pitch - right_; + + for (int dx = bottom_; dx > 0; --dx) { + uint32 ecx; + ecx = right_; + ecx = ecx/2; + if (ecx % 2 != 0) { + *edi = ax & 0xff; + edi++; + } + ecx = ecx/2; + if (ecx % 2 != 0) { + *edi = ax & 0xffff; + edi += 2; + } + memset(edi, ax, ecx); + + edi += length; + + } + return; + + } else { + // 00678B8A 00678E38 + char* esi; + esi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;; + + int eax, ebp; + eax = colour; + ebp = dpi->width + dpi->pitch - right_; + + RCT2_GLOBAL(0x00EDF810, uint32) = ebp; + RCT2_GLOBAL(0x009ABDB2, uint16) = bottom_; + RCT2_GLOBAL(0x00EDF814, uint32) = right_; + + top_ = (top + dpi_->y) & 0xf; + right_ = (right + dpi_->x) &0xf; + + dpi_ = esi; + + esi = eax >> 0x1C; + esi = RCT2_GLOBAL(0x0097FEFC,uint32)[esi]; // or possibly uint8)[esi*4] ? + + for (; RCT2_GLOBAL(0x009ABDB2, uint16) > 0; RCT2_GLOBAL(0x009ABDB2, uint16)--) { + // push ebx + // push ecx + ebp = *(esi + top_*2); + + // mov bp, [esi+top_*2]; + int ecx; + ecx = RCT2_GLOBAL(0x00EDF814, uint32); + + for (int i = ecx; i >=0; --i) { + if (!(ebp & (1 << right_))) + dpi_->bits = left_ & 0xFF; + + right_++; + right_ = right_ & 0xF; + dpi_++; + } + // pop ecx + // pop ebx + top_++; + top_ = top_ &0xf; + dpi_ += RCT2_GLOBAL(0x00EDF810, uint32); + } + return; + } + + } else { + // 00678B7E 00678C83 + if (dpi_->pad_0E < 1) { + // Location in screen buffer? + uint8* edi = top_ * (dpi_->width + dpi_->pitch) + left_ + dpi_->bits; + + // Find colour in colour table? + uint32 eax = RCT2_ADDRESS(0x0097FCBC, uint32)[(colour & 0xFF)]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + + int length = (dpi_->width + dpi_->pitch) - right_; + + // Fill the rectangle with the colours from the colour table + for (int i = 0; i < bottom_; ++i) { + uint8 al; + al = 0; + for (int j = 0; j < right_; ++j) { + al = *edi; + *edi = *((uint8*)(&g1_element->offset[al])); + edi++; + } + edi += length; + } + } else if (dpi_->pad_0E > 1) { + // 00678C8A 00678D57 + } else if (dpi_->pad_0E == 1) { + // 00678C88 00678CEE + + } + + } + } else { + // 00678B3A 00678EC9 + + } + } else { + // 00678B2E 00678BE5 + } + + // RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour); } /** From 6f1421117be088eb7571b9044297aca0b10cc50c Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 15:56:59 +0200 Subject: [PATCH 011/209] Some tidying up. Scrollbars don't work --- src/gfx.c | 56 +++++++++++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index cf534af2f7..3354d45c07 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -168,41 +168,34 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot if (!(colour & 0x2000000)) { if (!(colour & 0x4000000)) { - char* edi; + uint8* edi; edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; - // Take the last byte of colour and repeat it 4 times? - uint32 ax; - ax = colour & 0xffff; - ax = (ax & 0xff) << 8; - ax = ax << 8; - ax = (ax & 0xff00) >> 8; - ax = ax << 8; - ax = (ax & 0xff00) >> 8; + uint8 col = colour & 0xFF; int length; length = dpi->width + dpi->pitch - right_; - for (int dx = bottom_; dx > 0; --dx) { - uint32 ecx; - ecx = right_; - ecx = ecx/2; - if (ecx % 2 != 0) { - *edi = ax & 0xff; - edi++; - } - ecx = ecx/2; - if (ecx % 2 != 0) { - *edi = ax & 0xffff; - edi += 2; - } - memset(edi, ax, ecx); - - edi += length; - - } - return; - + for (int i = 0; i < bottom_; ++i) { + uint32 ecx; + ecx = right_; + ecx = ecx / 2; + if (ecx % 2 != 0) { + *edi = col; + edi++; + } + ecx = ecx / 2; + if (ecx % 2 != 0) { + *edi = col; + edi++; + *edi = col; + edi++; + // *((uint16*)edi) = ax & 0xffff; + // edi += 2; + } + memset(edi, col, ecx*4); + edi += length; + } } else { // 00678B8A 00678E38 char* esi; @@ -264,11 +257,8 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot // Fill the rectangle with the colours from the colour table for (int i = 0; i < bottom_; ++i) { - uint8 al; - al = 0; for (int j = 0; j < right_; ++j) { - al = *edi; - *edi = *((uint8*)(&g1_element->offset[al])); + *edi = *((uint8*)(&g1_element->offset[*edi])); edi++; } edi += length; From ce0df832988354cbf00365f4d702374c22646aa8 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 17:48:33 +0200 Subject: [PATCH 012/209] Formatting --- src/gfx.c | 243 +++++++++++++++++++++++++++--------------------------- 1 file changed, 122 insertions(+), 121 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 3354d45c07..b5bd3c67ad 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -127,157 +127,158 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour) { - int left_, right_, top_, bottom_; - rct_drawpixelinfo* dpi_; - left_ = left; - right_ = right; - top_ = top; - bottom_ = bottom; - dpi_ = dpi; + int left_, right_, top_, bottom_; + rct_drawpixelinfo* dpi_; + left_ = left; + right_ = right; + top_ = top; + bottom_ = bottom; + dpi_ = dpi; - if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) || - (bottom < dpi->y) || (top >= (dpi->y + dpi->height))) - return; + if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) || + (bottom < dpi->y) || (top >= (dpi->y + dpi->height))) + return; - colour |= RCT2_GLOBAL(0x009ABD9C, uint32); + colour |= RCT2_GLOBAL(0x009ABD9C, uint32); - if (!(colour & 0x1000000)) { - if (!(colour & 0x8000000)) { - left_ = left - dpi->x; - if (left_ < 0) - left_ = 0; + if (!(colour & 0x1000000)) { + if (!(colour & 0x8000000)) { + left_ = left - dpi->x; + if (left_ < 0) + left_ = 0; - right_ = right - dpi->x; - right_++; - if (right_ > dpi->width) - right_ = dpi->width; + right_ = right - dpi->x; + right_++; + if (right_ > dpi->width) + right_ = dpi->width; - right_ -= left_; + right_ -= left_; - top_ = top - dpi->y; - if (top_ < 0) - top_ = 0; + top_ = top - dpi->y; + if (top_ < 0) + top_ = 0; - bottom_ = bottom - dpi->y; - bottom_++; + bottom_ = bottom - dpi->y; + bottom_++; - if (bottom_ > dpi->height) - bottom_ = dpi->height; + if (bottom_ > dpi->height) + bottom_ = dpi->height; - bottom_ -= top_; + bottom_ -= top_; - if (!(colour & 0x2000000)) { - if (!(colour & 0x4000000)) { - uint8* edi; - edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; + if (!(colour & 0x2000000)) { + if (!(colour & 0x4000000)) { + uint8* edi; + edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; - uint8 col = colour & 0xFF; + uint8 col = colour & 0xFF; - int length; - length = dpi->width + dpi->pitch - right_; + int length; + length = dpi->width + dpi->pitch - right_; - for (int i = 0; i < bottom_; ++i) { - uint32 ecx; - ecx = right_; - ecx = ecx / 2; - if (ecx % 2 != 0) { - *edi = col; - edi++; - } - ecx = ecx / 2; - if (ecx % 2 != 0) { - *edi = col; - edi++; - *edi = col; - edi++; - // *((uint16*)edi) = ax & 0xffff; - // edi += 2; - } - memset(edi, col, ecx*4); - edi += length; - } - } else { - // 00678B8A 00678E38 - char* esi; - esi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;; + for (int i = 0; i < bottom_; ++i) { + uint32 ecx; + ecx = right_; + ecx = ecx / 2; + if (ecx % 2 != 0) { + *edi = col; + edi++; + } + ecx = ecx / 2; + if (ecx % 2 != 0) { + *edi = col; + edi++; + *edi = col; + edi++; + // *((uint16*)edi) = ax & 0xffff; + // edi += 2; + } + memset(edi, col, ecx*4); + edi += length; + } + } else { + // 00678B8A 00678E38 + char* esi; + esi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;; - int eax, ebp; - eax = colour; - ebp = dpi->width + dpi->pitch - right_; + int eax, ebp; + eax = colour; + ebp = dpi->width + dpi->pitch - right_; - RCT2_GLOBAL(0x00EDF810, uint32) = ebp; - RCT2_GLOBAL(0x009ABDB2, uint16) = bottom_; - RCT2_GLOBAL(0x00EDF814, uint32) = right_; + RCT2_GLOBAL(0x00EDF810, uint32) = ebp; + RCT2_GLOBAL(0x009ABDB2, uint16) = bottom_; + RCT2_GLOBAL(0x00EDF814, uint32) = right_; - top_ = (top + dpi_->y) & 0xf; - right_ = (right + dpi_->x) &0xf; + top_ = (top + dpi_->y) & 0xf; + right_ = (right + dpi_->x) &0xf; - dpi_ = esi; + dpi_ = esi; - esi = eax >> 0x1C; - esi = RCT2_GLOBAL(0x0097FEFC,uint32)[esi]; // or possibly uint8)[esi*4] ? + esi = eax >> 0x1C; + esi = RCT2_GLOBAL(0x0097FEFC,uint32)[esi]; // or possibly uint8)[esi*4] ? - for (; RCT2_GLOBAL(0x009ABDB2, uint16) > 0; RCT2_GLOBAL(0x009ABDB2, uint16)--) { - // push ebx - // push ecx - ebp = *(esi + top_*2); + for (; RCT2_GLOBAL(0x009ABDB2, uint16) > 0; RCT2_GLOBAL(0x009ABDB2, uint16)--) { + // push ebx + // push ecx + ebp = *(esi + top_*2); - // mov bp, [esi+top_*2]; - int ecx; - ecx = RCT2_GLOBAL(0x00EDF814, uint32); + // mov bp, [esi+top_*2]; + int ecx; + ecx = RCT2_GLOBAL(0x00EDF814, uint32); - for (int i = ecx; i >=0; --i) { - if (!(ebp & (1 << right_))) - dpi_->bits = left_ & 0xFF; + for (int i = ecx; i >=0; --i) { + if (!(ebp & (1 << right_))) + dpi_->bits = left_ & 0xFF; - right_++; - right_ = right_ & 0xF; - dpi_++; - } - // pop ecx - // pop ebx - top_++; - top_ = top_ &0xf; - dpi_ += RCT2_GLOBAL(0x00EDF810, uint32); - } - return; - } + right_++; + right_ = right_ & 0xF; + dpi_++; + } + // pop ecx + // pop ebx + top_++; + top_ = top_ &0xf; + dpi_ += RCT2_GLOBAL(0x00EDF810, uint32); + } + return; + } - } else { - // 00678B7E 00678C83 - if (dpi_->pad_0E < 1) { - // Location in screen buffer? - uint8* edi = top_ * (dpi_->width + dpi_->pitch) + left_ + dpi_->bits; + } else { + // 00678B7E 00678C83 + if (dpi_->pad_0E < 1) { + // Location in screen buffer? + uint8* edi = top_ * (dpi_->width + dpi_->pitch) + left_ + dpi_->bits; - // Find colour in colour table? - uint32 eax = RCT2_ADDRESS(0x0097FCBC, uint32)[(colour & 0xFF)]; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + // Find colour in colour table? + uint32 eax = RCT2_ADDRESS(0x0097FCBC, uint32)[(colour & 0xFF)]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - int length = (dpi_->width + dpi_->pitch) - right_; + int length = (dpi_->width + dpi_->pitch) - right_; - // Fill the rectangle with the colours from the colour table - for (int i = 0; i < bottom_; ++i) { - for (int j = 0; j < right_; ++j) { - *edi = *((uint8*)(&g1_element->offset[*edi])); - edi++; - } - edi += length; - } - } else if (dpi_->pad_0E > 1) { - // 00678C8A 00678D57 - } else if (dpi_->pad_0E == 1) { - // 00678C88 00678CEE - - } + // Fill the rectangle with the colours from the colour table + for (int i = 0; i < bottom_; ++i) { + for (int j = 0; j < right_; ++j) { + *edi = *((uint8*)(&g1_element->offset[*edi])); + edi++; + } + edi += length; + } + } else if (dpi_->pad_0E > 1) { + // 00678C8A 00678D57 + right_ = right; + } else if (dpi_->pad_0E == 1) { + // 00678C88 00678CEE + right = right; + } - } - } else { - // 00678B3A 00678EC9 - + } + } else { + // 00678B3A 00678EC9 + right_ = right; } } else { // 00678B2E 00678BE5 - } + } // RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour); } From ba6263d2bd46dd8a6885190fa5afbb84adb24635 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 17:49:13 +0200 Subject: [PATCH 013/209] Cross-hatching branch --- src/gfx.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/gfx.c b/src/gfx.c index b5bd3c67ad..feec6685af 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -278,6 +278,63 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } } else { // 00678B2E 00678BE5 + // Cross hatching + uint16 si; + si = 0; + + left_ = left_ - dpi->x; + if (left_ < 0) { + si = si ^ left_; + left_ = 0; + } + + right_ = right_ - dpi->x; + right_++; + + if (right_ > dpi->width) + right_ = dpi-> width; + + right_ = right_ - left_; + + top_ = top - dpi->y; + if (top_ < 0) { + si = si ^ top_; + top_ = 0; + } + + bottom_ = bottom - dpi->y; + bottom_++; + + if (bottom_ > dpi->height) + bottom_ = dpi->height; + + bottom_ -= top_; + + uint8* edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; + + uint8 col = colour & 0xFF; + + int length = dpi->width + dpi->pitch - right_; + + for (int i = 0; i < bottom_; ++i) { + uint32 ecx; + ecx = si; + // Rotate right + ecx = (ecx >> 1) | (ecx << (sizeof(ecx) * CHAR_BIT - 1)); + ecx = (ecx & 0xFFFF0000) | right_; + + while (ecx > 0 && ecx != 0xFFFFFFFF) { + ecx = ecx ^ 0x80000000; + if ((int)ecx < 0) { + *edi = col; + } + edi++; + ecx--; + } + si = si ^ 1; + edi += length; + + } } // RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour); From 1e8f80fa5c439a3a0c8f44cf88e59b346007645a Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 18:41:18 +0200 Subject: [PATCH 014/209] Bug fix - memset doesn't increase pointer --- src/gfx.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index feec6685af..57b91881c9 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -177,24 +177,8 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot length = dpi->width + dpi->pitch - right_; for (int i = 0; i < bottom_; ++i) { - uint32 ecx; - ecx = right_; - ecx = ecx / 2; - if (ecx % 2 != 0) { - *edi = col; - edi++; - } - ecx = ecx / 2; - if (ecx % 2 != 0) { - *edi = col; - edi++; - *edi = col; - edi++; - // *((uint16*)edi) = ax & 0xffff; - // edi += 2; - } - memset(edi, col, ecx*4); - edi += length; + memset(edi, col, right_); + edi += length + right_; } } else { // 00678B8A 00678E38 From 7f4e21f334c467c55a947856c94963e6c7b8109f Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 21:31:31 +0200 Subject: [PATCH 015/209] Bug fix: cross-hatch loop was wrong Also rename and tidy up a bunch of variables --- src/gfx.c | 57 +++++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 57b91881c9..ce6aaac213 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -168,17 +168,13 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot if (!(colour & 0x2000000)) { if (!(colour & 0x4000000)) { - uint8* edi; - edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; + uint8* pixel = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; - uint8 col = colour & 0xFF; - - int length; - length = dpi->width + dpi->pitch - right_; + int length = dpi->width + dpi->pitch - right_; for (int i = 0; i < bottom_; ++i) { - memset(edi, col, right_); - edi += length + right_; + memset(pixel, (colour & 0xFF), right_); + pixel += length + right_; } } else { // 00678B8A 00678E38 @@ -193,7 +189,7 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot RCT2_GLOBAL(0x009ABDB2, uint16) = bottom_; RCT2_GLOBAL(0x00EDF814, uint32) = right_; - top_ = (top + dpi_->y) & 0xf; + top_ = (top + dpi->y) & 0xf; right_ = (right + dpi_->x) &0xf; dpi_ = esi; @@ -229,28 +225,28 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } else { // 00678B7E 00678C83 - if (dpi_->pad_0E < 1) { + if (dpi->pad_0E < 1) { // Location in screen buffer? - uint8* edi = top_ * (dpi_->width + dpi_->pitch) + left_ + dpi_->bits; + uint8* pixel = top_ * (dpi->width + dpi->pitch) + left_ + dpi->bits; // Find colour in colour table? uint32 eax = RCT2_ADDRESS(0x0097FCBC, uint32)[(colour & 0xFF)]; rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - int length = (dpi_->width + dpi_->pitch) - right_; + int length = (dpi->width + dpi->pitch) - right_; // Fill the rectangle with the colours from the colour table for (int i = 0; i < bottom_; ++i) { for (int j = 0; j < right_; ++j) { - *edi = *((uint8*)(&g1_element->offset[*edi])); - edi++; + *pixel = *((uint8*)(&g1_element->offset[*pixel])); + pixel++; } - edi += length; + pixel += length; } - } else if (dpi_->pad_0E > 1) { + } else if (dpi->pad_0E > 1) { // 00678C8A 00678D57 right_ = right; - } else if (dpi_->pad_0E == 1) { + } else if (dpi->pad_0E == 1) { // 00678C88 00678CEE right = right; } @@ -263,12 +259,11 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } else { // 00678B2E 00678BE5 // Cross hatching - uint16 si; - si = 0; + uint16 pattern = 0; left_ = left_ - dpi->x; if (left_ < 0) { - si = si ^ left_; + pattern = pattern ^ left_; left_ = 0; } @@ -282,7 +277,7 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot top_ = top - dpi->y; if (top_ < 0) { - si = si ^ top_; + pattern = pattern ^ top_; top_ = 0; } @@ -294,29 +289,25 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot bottom_ -= top_; - uint8* edi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; - - uint8 col = colour & 0xFF; + uint8* pixel = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; int length = dpi->width + dpi->pitch - right_; for (int i = 0; i < bottom_; ++i) { - uint32 ecx; - ecx = si; + uint32 ecx = pattern; // Rotate right ecx = (ecx >> 1) | (ecx << (sizeof(ecx) * CHAR_BIT - 1)); ecx = (ecx & 0xFFFF0000) | right_; - - while (ecx > 0 && ecx != 0xFFFFFFFF) { + // Fill every other pixel with the colour + for (; (ecx & 0xFFFF) > 0; ecx--) { ecx = ecx ^ 0x80000000; if ((int)ecx < 0) { - *edi = col; + *pixel = colour & 0xFF; } - edi++; - ecx--; + pixel++; } - si = si ^ 1; - edi += length; + pattern = pattern ^ 1; + pixel += length; } } From ea83381e4cfe282a991d74830a289fb7ef231e2d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 11 May 2014 22:19:01 +0200 Subject: [PATCH 016/209] Add author --- src/gfx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ce6aaac213..e4c229c955 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Peter Hill * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. @@ -119,9 +119,9 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c * rct2: 0x00678AD4 * dpi (edi) * left (ax) - * top (cx) ? + * top (cx) * right (bx) - * bottom (dx) ? + * bottom (dx) * colour (ebp) */ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour) @@ -293,8 +293,9 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot int length = dpi->width + dpi->pitch - right_; + uint32 ecx; for (int i = 0; i < bottom_; ++i) { - uint32 ecx = pattern; + ecx = pattern; // Rotate right ecx = (ecx >> 1) | (ecx << (sizeof(ecx) * CHAR_BIT - 1)); ecx = (ecx & 0xFFFF0000) | right_; From 756f21b427790787eea7ca997cd67517e8ea3c29 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 12 May 2014 22:04:07 +0100 Subject: [PATCH 017/209] Trying to understand how the drawing function works --- src/gfx.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 8f663827f5..7e83e998e1 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -149,6 +149,77 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri #define RCT2_Y_RELATED_GLOBAL_2 0x9ABDAC //sint16 #define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 #define RCT2_X_RELATED_GLOBAL_2 0x9ABDA8 //sint16 + +void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixelinfo *dpi){ + if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ + return; //0x67AAB3 + } + + if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x4000000){ + return; //0x67AFD8 + } + + int ebx = RCT2_GLOBAL(0xEDF808, uint32); + ebx = RCT2_GLOBAL(ebx * 2 + source_bits_pointer,uint16); + int ebp = dest_bits_pointer; + ebx += (int)source_bits_pointer; + +StartLoop: + ebx = ebx; + int cx = RCT2_GLOBAL(ebx, uint16); + RCT2_GLOBAL(0x9ABDB4, uint8) = cx & 0xFF; + ebx += 2; + cx &= 0xFF7F; + int esi = ebx; + int edx = (cx & 0xFF00) >> 8; + ebx += cx; + edx -= RCT2_GLOBAL(0xEDF80C, sint32); + int edi = ebp; + if (edx > 0){ + edi += edx; + } + else{ + esi -= edx; + cx += edx & 0xFFFF; + if (cx <= 0){ + goto TestLoop; + //jump to 0x67AA97 + } + edx &= 0xFFFF0000; + } + edx += cx; + edx -= RCT2_GLOBAL(0x9ABDA8, sint16); + if (edx > 0){ + cx -= edx; + if (cx <= 0){ + goto TestLoop; + //jump to 0x67AA97 + } + } + if (cx & 1){ + cx >>= 1; + RCT2_GLOBAL(edi, uint8) = RCT2_GLOBAL(esi, uint8); + } + else cx >>= 1; + + if (cx & 1){ + cx >>= 1; + RCT2_GLOBAL(edi, uint16) = RCT2_GLOBAL(esi, uint16); + } + else cx >>= 1; + + for (int i = cx; i > 0; --i, edi++, esi++){ + RCT2_GLOBAL(edi, uint16) = RCT2_GLOBAL(esi, uint16); + } +TestLoop: + if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; + edx = RCT2_GLOBAL(0x9ABDB0, sint16); + ebp += edx; + RCT2_GLOBAL(0x9ABDAC, sint16)--; + if (RCT2_GLOBAL(0x9ABDAC, sint16))goto StartLoop; + +} + /* * rct2: 0x67A934 title screen bitmaps on buttons * This function readies all the global vars for copying the sprite data onto the screen @@ -205,7 +276,10 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ RCT2_GLOBAL(0x9ABDB0, uint16) = dpi->width + dpi->pitch; // I dont think it uses ecx, edx but just in case - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); + //esi is the source and bits_pointer is the destination + sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dpi); + + //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); } /** From 1d754dc390d7516e734f3d06d75929a2a0a8ba49 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 13 May 2014 18:32:57 +0100 Subject: [PATCH 018/209] Still searching for bug --- src/gfx.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 7e83e998e1..24a30287fb 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -277,9 +277,9 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ // I dont think it uses ecx, edx but just in case //esi is the source and bits_pointer is the destination - sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dpi); + //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dpi); - //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); } /** @@ -303,6 +303,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = eax; if ((image_id & (1 << 31)) && (image_id & (1 << 29))){ + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); /* eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -334,9 +335,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABEDE, uint32) = ebp;*/ return; } else if ((image_id & (1 << 31))){ + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return; //jump into 0x67a361 } else if ((image_id & (1 << 30))){ + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return; //jump into 0x67a445 } @@ -368,8 +371,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - return; + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + //return; //There is a mistake in the code below this point calling the above to skip it. //dpi on stack @@ -444,7 +447,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - eax = (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) & 0xFF) << 8; + eax = (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint8)) << 8; edx = RCT2_GLOBAL(0x9ABDAE, sint16); ebp = RCT2_GLOBAL(0x9ABDB0, sint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); @@ -452,10 +455,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //ebx, esi, edi, ah used in 0x67a690 //Calling is wrong //esi or bits is most likely wrong - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, bits_pointer, ebp); + RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi, bits_pointer, ebp); return; } //0x67A60A + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); esi -= RCT2_GLOBAL(0x9E3D08, sint32); return; From ba16b197e3f1583ed95cd78729dbb7ef5b23bf5c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 13 May 2014 19:01:59 +0100 Subject: [PATCH 019/209] Bug found in the first test doh. --- src/gfx.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 24a30287fb..e69e64a763 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -291,18 +291,19 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - //return; + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + return; int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; eax = image_id; eax >>= 26; - RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; + RCT2_GLOBAL(0x00EDF81C, uint32) = ebx; eax &= 0x7; eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32); + RCT2_GLOBAL(0x00EDF81C, uint32) &= 0xE0000000; RCT2_GLOBAL(0x009E3CDC, uint32) = eax; - if ((image_id & (1 << 31)) && (image_id & (1 << 29))){ + if (ebx&0xE0000000){ RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); /* eax = image_id; @@ -334,11 +335,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; RCT2_GLOBAL(0x9ABEDE, uint32) = ebp;*/ return; - } else if ((image_id & (1 << 31))){ + } else if (ebx & 0x80000000){ RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return; //jump into 0x67a361 - } else if ((image_id & (1 << 30))){ + } else if (ebx & 0x20000000){ RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return; //jump into 0x67a445 @@ -366,12 +367,14 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps + //RCT2_CALLPROC_X(0x0067A934, eax, ebx, x, y, 0, dpi, ebp); sub_0x67A934(dpi, x, y); return; } - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + //RCT2_CALLPROC_X(0x0067A4CA, eax,ebx, x, y, 0, dpi, ebp); + //return; //return; //There is a mistake in the code below this point calling the above to skip it. From 20c7b98c889b037fe3179c903478c4053d6d9029 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 13 May 2014 19:06:15 +0100 Subject: [PATCH 020/209] merge --- src/gfx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 5e6e4019b5..cb4308a338 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -407,7 +407,6 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { -<<<<<<< HEAD RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return; @@ -582,11 +581,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); esi -= RCT2_GLOBAL(0x9E3D08, sint32); return; - - -======= - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); ->>>>>>> master } /** From 92386e5758d2be781b0adda731eb254b0d2ffa7e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 13 May 2014 19:12:18 +0100 Subject: [PATCH 021/209] Fix sketchy line bug that i introduced --- src/gfx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gfx.h b/src/gfx.h index de0411b258..162ccd121f 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -31,7 +31,7 @@ typedef struct { short width; // 0x08 short height; // 0x0A short pitch; // 0x0C note: this is actually (pitch - width) - uint16 pad_0E; // 0x0E + uint8 pad_0E; // 0x0E char var_0F; // 0x0F } rct_drawpixelinfo; From 8ecde8f07a8fb3147988e70c298d61e7bb0b6bf3 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 13 May 2014 20:10:49 +0100 Subject: [PATCH 022/209] Moved around logic so it runs correctly --- src/gfx.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index cb4308a338..d74ce12556 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -407,20 +407,28 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - return; + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + //return; int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; - eax = image_id; - eax >>= 26; - RCT2_GLOBAL(0x00EDF81C, uint32) = ebx; - eax &= 0x7; - eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32); - RCT2_GLOBAL(0x00EDF81C, uint32) &= 0xE0000000; - RCT2_GLOBAL(0x009E3CDC, uint32) = eax; - if (ebx&0xE0000000){ + RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; + eax = (image_id >> 26) & 0x7; + //eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32); + RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); + + if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + // + return;//jump into 0x67a445 + } + else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ + char* find = "FINDMEDUNCAN"; + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + return;//jump into 0x67a361 + } + else if ((image_id)& 0xE0000000){ + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); /* eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -451,14 +459,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; RCT2_GLOBAL(0x9ABEDE, uint32) = ebp;*/ return; - } else if (ebx & 0x80000000){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - return; - //jump into 0x67a361 - } else if (ebx & 0x20000000){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - return; - //jump into 0x67a445 } ebx &= 0x7FFFF; @@ -488,12 +488,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } - - //RCT2_CALLPROC_X(0x0067A4CA, eax,ebx, x, y, 0, dpi, ebp); - //return; - //return; - //There is a mistake in the code below this point calling the above to skip it. - //dpi on stack int translated_x, translated_y; char* bits_pointer; @@ -572,8 +566,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, esi, edi, ah used in 0x67a690 - //Calling is wrong - //esi or bits is most likely wrong RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi, bits_pointer, ebp); return; } From 2c7118c01b55f6791ef6f91f7fc9f850dabae785 Mon Sep 17 00:00:00 2001 From: Duncan Date: Wed, 14 May 2014 17:01:13 +0100 Subject: [PATCH 023/209] Added guess about G1 dpi. Warning not tested. --- src/gfx.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d74ce12556..8c0f84ae27 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -341,16 +341,16 @@ TestLoop: * This function readies all the global vars for copying the sprite data onto the screen * I think its only used for bitmaps onto buttons but i am not sure. */ -void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ +void sub_0x67A934(rct_drawpixelinfo *source_dpi, rct_drawpixelinfo *dest_dpi, int x, int y){ - int _edi = dpi, _esi; + int _edi = dest_dpi, _esi; sint16 translated_x = x, translated_y = y; char* bits_pointer; - bits_pointer = dpi->bits; + bits_pointer = dest_dpi->bits; - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dest_dpi->y; RCT2_GLOBAL(0xEDF808, uint32) = 0; - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = source_dpi->y;//RCT2_GLOBAL(0x9E3D0E, sint16); if (translated_y < 0) { @@ -360,19 +360,19 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ translated_y = 0; } else{ - bits_pointer += (dpi->width + dpi->pitch)*translated_y; + bits_pointer += (dest_dpi->width + dest_dpi->pitch)*translated_y; } - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height; + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dest_dpi->height; if (translated_y > 0){ RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; } RCT2_GLOBAL(0xEDF80C, uint32) = 0; - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dest_dpi->x; - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = source_dpi->x;//RCT2_GLOBAL(0x9E3D0C, sint16); if (translated_x < 0){ RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; @@ -383,19 +383,19 @@ void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ bits_pointer += translated_x; } translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16); - translated_x -= dpi->width; + translated_x -= dest_dpi->width; if (translated_x > 0){ RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; } - RCT2_GLOBAL(0x9ABDB0, uint16) = dpi->width + dpi->pitch; + RCT2_GLOBAL(0x9ABDB0, uint16) = dest_dpi->width + dest_dpi->pitch; // I dont think it uses ecx, edx but just in case //esi is the source and bits_pointer is the destination - //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dpi); + //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dpi); + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dest_dpi); } /** @@ -477,6 +477,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } eax = *((uint32*)ebx + 2); ebp = *((uint32*)ebx + 3); + rct_drawpixelinfo* g1_source_dpi = (rct_drawpixelinfo*)ebx; + //This is a rct2_drawpixelinfo struct RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); //offset to g1 bits? RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y @@ -484,7 +486,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps //RCT2_CALLPROC_X(0x0067A934, eax, ebx, x, y, 0, dpi, ebp); - sub_0x67A934(dpi, x, y); + sub_0x67A934(g1_source_dpi, dpi, x, y); return; } From ff86f7e9e9aea07b0b6791ee8253b09879593f6e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 14 May 2014 21:58:35 +0100 Subject: [PATCH 024/209] sub0x67a934 turned into almost proper C code --- src/gfx.c | 161 +++++++++++++++++++++++++++++------------------------- 1 file changed, 88 insertions(+), 73 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 8c0f84ae27..62435a8bdb 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -262,9 +262,10 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri } #define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 -#define RCT2_Y_RELATED_GLOBAL_2 0x9ABDAC //sint16 +#define RCT2_Y_END_POINT_GLOBAL 0x9ABDAC //sint16 #define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 -#define RCT2_X_RELATED_GLOBAL_2 0x9ABDA8 //sint16 +#define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 +#define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixelinfo *dpi){ if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ @@ -304,7 +305,7 @@ StartLoop: edx &= 0xFFFF0000; } edx += cx; - edx -= RCT2_GLOBAL(0x9ABDA8, sint16); + edx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); if (edx > 0){ cx -= edx; if (cx <= 0){ @@ -329,10 +330,10 @@ StartLoop: } TestLoop: if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; - edx = RCT2_GLOBAL(0x9ABDB0, sint16); + edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); ebp += edx; - RCT2_GLOBAL(0x9ABDAC, sint16)--; - if (RCT2_GLOBAL(0x9ABDAC, sint16))goto StartLoop; + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16)--; + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; } @@ -341,61 +342,75 @@ TestLoop: * This function readies all the global vars for copying the sprite data onto the screen * I think its only used for bitmaps onto buttons but i am not sure. */ -void sub_0x67A934(rct_drawpixelinfo *source_dpi, rct_drawpixelinfo *dest_dpi, int x, int y){ +void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y){ - int _edi = dest_dpi, _esi; - sint16 translated_x = x, translated_y = y; char* bits_pointer; bits_pointer = dest_dpi->bits; - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dest_dpi->y; RCT2_GLOBAL(0xEDF808, uint32) = 0; - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = source_dpi->y;//RCT2_GLOBAL(0x9E3D0E, sint16); - if (translated_y < 0) - { - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; - RCT2_GLOBAL(0xEDF808, sint16) -= translated_y; - translated_y = 0; - } - else{ - bits_pointer += (dest_dpi->width + dest_dpi->pitch)*translated_y; - } - - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dest_dpi->height; - if (translated_y > 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; - } - - RCT2_GLOBAL(0xEDF80C, uint32) = 0; - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dest_dpi->x; - - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = source_dpi->x;//RCT2_GLOBAL(0x9E3D0C, sint16); - if (translated_x < 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; - RCT2_GLOBAL(0xEDF80C, sint16) -= translated_x; - translated_x = 0; - } - else{ - bits_pointer += translated_x; - } - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16); - translated_x -= dest_dpi->width; - if (translated_x > 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; - } - - RCT2_GLOBAL(0x9ABDB0, uint16) = dest_dpi->width + dest_dpi->pitch; + int start_y, end_y; + start_y = y + source_g1->y_offset - dest_dpi->y; - // I dont think it uses ecx, edx but just in case - //esi is the source and bits_pointer is the destination - //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); + //If the start position is negative reset to zero + if (start_y < 0){ + //Create the end point within the drawing area + end_y = source_g1->height + start_y; + //If the end point is now <= 0 no need to draw + if (end_y <= 0)return; - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), bits_pointer, dest_dpi); + RCT2_GLOBAL(0xEDF808, sint16) -= start_y; + start_y = 0; + } + else{ + end_y = source_g1->height; + //Move the pointer to the correct starting y location + bits_pointer += (dest_dpi->width + dest_dpi->pitch)*start_y; + } + + int height = start_y + end_y; + //If the image is taller than the drawing area + if (height > dest_dpi->height){ + //Make the end within the drawing area + end_y -= height - dest_dpi->height; + //If the end is now <=0 then there is nothing to draw + if (end_y <= 0)return; + } + + RCT2_GLOBAL(0xEDF80C, uint32) = 0; + int start_x, end_x; + start_x = x + source_g1->x_offset - dest_dpi->x; + + //If the start position is negative reset to zero + if (start_x < 0){ + //Create the end point within the drawing area + end_x = source_g1->width + start_x; + //If the end point is now <= 0 no need to draw + if (end_x <= 0)return; + + RCT2_GLOBAL(0xEDF80C, sint16) -= start_x; + start_x = 0; + } + else{ + end_x = source_g1->width; + //Increment the pointer to our start location + bits_pointer += start_x; + } + + int width = start_x + end_x; + //If the image is wider than the drawing area + if (width > dest_dpi->width){ + //Make the end within drawing area + end_x -= width - dest_dpi->width; + //If the end is now <=0 then there is nothing to draw + if (end_x <= 0)return; + } + + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; + //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); } /** @@ -423,7 +438,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return;//jump into 0x67a445 } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - char* find = "FINDMEDUNCAN"; RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); return;//jump into 0x67a361 } @@ -477,16 +491,17 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } eax = *((uint32*)ebx + 2); ebp = *((uint32*)ebx + 3); - rct_drawpixelinfo* g1_source_dpi = (rct_drawpixelinfo*)ebx; + rct_g1_element* g1_source = (rct_g1_element*)ebx; //This is a rct2_drawpixelinfo struct RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); //offset to g1 bits? RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); + if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps //RCT2_CALLPROC_X(0x0067A934, eax, ebx, x, y, 0, dpi, ebp); - sub_0x67A934(g1_source_dpi, dpi, x, y); + sub_0x67A934(g1_source, dpi, x, y); return; } @@ -499,14 +514,14 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9E3CE0, uint32) = 0; bits_pointer = dpi->bits; - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); translated_y = y + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; if (translated_y < 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0){ + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) += translated_y; + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0){ return; } translated_y = -translated_y; @@ -518,53 +533,53 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) bits_pointer += eax; } - translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height;; + translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height;; if (translated_y > 0){ - RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <=0) + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) -= translated_y; + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0) { return; } } - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); eax = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); RCT2_GLOBAL(0x9ABDAE, uint16) = 0; - RCT2_GLOBAL(0x9ABDB0, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); translated_x = x + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; if (translated_x < 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) += translated_x; + if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ return; } translated_x -= RCT2_GLOBAL(0x9ABDAE, sint16); esi -= translated_x; RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; - RCT2_GLOBAL(0x9ABDB0, sint16) -= translated_x; + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) -= translated_x; translated_x = 0; } bits_pointer += translated_x; - translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) - dpi->width; + translated_x += RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) - dpi->width; if (translated_x > 0){ - RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) -= translated_x; + if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ return; } RCT2_GLOBAL(0x9ABDAE, sint16) += translated_x; - RCT2_GLOBAL(0x9ABDB0, sint16) += translated_x; + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) += translated_x; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - eax = (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint8)) << 8; + eax = (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8)) << 8; edx = RCT2_GLOBAL(0x9ABDAE, sint16); - ebp = RCT2_GLOBAL(0x9ABDB0, sint16); + ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, esi, edi, ah used in 0x67a690 From 84c7f33ba1c7f87d253ea75b0c4355e5bbb32028 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 14 May 2014 22:07:59 +0100 Subject: [PATCH 025/209] Changed to memset to make code look a bit simpler --- src/gfx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 62435a8bdb..046fcde8c5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -138,9 +138,7 @@ void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, 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){ - *((uint8*)bits_pointer) = colour; - } + memset(bits_pointer, colour, no_pixels); } From 7f20fa9338a3f4d24413da88bf98aae027c43de7 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 14 May 2014 22:14:46 +0100 Subject: [PATCH 026/209] Skipping buggy code for now. Will be looked at some time later --- src/gfx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 046fcde8c5..99c35a463e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -502,7 +502,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) sub_0x67A934(g1_source, dpi, x, y); return; } - + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + return; //dpi on stack int translated_x, translated_y; char* bits_pointer; From 12dfd1e6447ba420818ed83e64955f3809f5f3cc Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 15 May 2014 00:23:50 +0100 Subject: [PATCH 027/209] fix warnings --- src/gfx.c | 357 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 264 insertions(+), 93 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 99c35a463e..941ed5e7f1 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2014 Ted John + * Copyright (c) 2014 Ted John, Peter Hill * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. @@ -138,7 +138,9 @@ void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, bits_pointer = dpi->bits + y*(dpi->pitch + dpi->width) + x; //Draw the line to the specified colour - memset(bits_pointer, colour, no_pixels); + for (; no_pixels > 0; --no_pixels, ++bits_pointer){ + *((uint8*)bits_pointer) = colour; + } } @@ -240,7 +242,194 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c */ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour) { - RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, (int)dpi, colour); + + int left_, right_, top_, bottom_; + rct_drawpixelinfo* dpi_; + left_ = left; + right_ = right; + top_ = top; + bottom_ = bottom; + dpi_ = dpi; + + if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) || + (bottom < dpi->y) || (top >= (dpi->y + dpi->height))) + return; + + colour |= RCT2_GLOBAL(0x009ABD9C, uint32); + + if (!(colour & 0x1000000)) { + if (!(colour & 0x8000000)) { + left_ = left - dpi->x; + if (left_ < 0) + left_ = 0; + + right_ = right - dpi->x; + right_++; + if (right_ > dpi->width) + right_ = dpi->width; + + right_ -= left_; + + top_ = top - dpi->y; + if (top_ < 0) + top_ = 0; + + bottom_ = bottom - dpi->y; + bottom_++; + + if (bottom_ > dpi->height) + bottom_ = dpi->height; + + bottom_ -= top_; + + if (!(colour & 0x2000000)) { + if (!(colour & 0x4000000)) { + uint8* pixel = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; + + int length = dpi->width + dpi->pitch - right_; + + for (int i = 0; i < bottom_; ++i) { + memset(pixel, (colour & 0xFF), right_); + pixel += length + right_; + } + } else { + // 00678B8A 00678E38 + char* esi; + esi = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits;; + + int eax, ebp; + eax = colour; + ebp = dpi->width + dpi->pitch - right_; + + RCT2_GLOBAL(0x00EDF810, uint32) = ebp; + RCT2_GLOBAL(0x009ABDB2, uint16) = bottom_; + RCT2_GLOBAL(0x00EDF814, uint32) = right_; + + top_ = (top + dpi->y) & 0xf; + right_ = (right + dpi_->x) &0xf; + + dpi_ = (rct_drawpixelinfo*)esi; + + esi = (char*)(eax >> 0x1C); + esi = (char*)RCT2_GLOBAL(0x0097FEFC,uint32)[esi]; // or possibly uint8)[esi*4] ? + + for (; RCT2_GLOBAL(0x009ABDB2, uint16) > 0; RCT2_GLOBAL(0x009ABDB2, uint16)--) { + // push ebx + // push ecx + ebp = *(esi + top_*2); + + // mov bp, [esi+top_*2]; + int ecx; + ecx = RCT2_GLOBAL(0x00EDF814, uint32); + + for (int i = ecx; i >=0; --i) { + if (!(ebp & (1 << right_))) + dpi_->bits = (char*)(left_ & 0xFF); + + right_++; + right_ = right_ & 0xF; + dpi_++; + } + // pop ecx + // pop ebx + top_++; + top_ = top_ &0xf; + dpi_ += RCT2_GLOBAL(0x00EDF810, uint32); + } + return; + } + + } else { + // 00678B7E 00678C83 + if (dpi->pad_0E < 1) { + // Location in screen buffer? + uint8* pixel = top_ * (dpi->width + dpi->pitch) + left_ + dpi->bits; + + // Find colour in colour table? + uint32 eax = RCT2_ADDRESS(0x0097FCBC, uint32)[(colour & 0xFF)]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + + int length = (dpi->width + dpi->pitch) - right_; + + // Fill the rectangle with the colours from the colour table + for (int i = 0; i < bottom_; ++i) { + for (int j = 0; j < right_; ++j) { + *pixel = *((uint8*)(&g1_element->offset[*pixel])); + pixel++; + } + pixel += length; + } + } else if (dpi->pad_0E > 1) { + // 00678C8A 00678D57 + right_ = right; + } else if (dpi->pad_0E == 1) { + // 00678C88 00678CEE + right = right; + } + + } + } else { + // 00678B3A 00678EC9 + right_ = right; + } + } else { + // 00678B2E 00678BE5 + // Cross hatching + uint16 pattern = 0; + + left_ = left_ - dpi->x; + if (left_ < 0) { + pattern = pattern ^ left_; + left_ = 0; + } + + right_ = right_ - dpi->x; + right_++; + + if (right_ > dpi->width) + right_ = dpi-> width; + + right_ = right_ - left_; + + top_ = top - dpi->y; + if (top_ < 0) { + pattern = pattern ^ top_; + top_ = 0; + } + + bottom_ = bottom - dpi->y; + bottom_++; + + if (bottom_ > dpi->height) + bottom_ = dpi->height; + + bottom_ -= top_; + + uint8* pixel = (top_ * (dpi->width + dpi->pitch)) + left_ + dpi->bits; + + int length = dpi->width + dpi->pitch - right_; + + uint32 ecx; + for (int i = 0; i < bottom_; ++i) { + ecx = pattern; + // Rotate right + ecx = (ecx >> 1) | (ecx << (sizeof(ecx) * CHAR_BIT - 1)); + ecx = (ecx & 0xFFFF0000) | right_; + // Fill every other pixel with the colour + for (; (ecx & 0xFFFF) > 0; ecx--) { + ecx = ecx ^ 0x80000000; + if ((int)ecx < 0) { + *pixel = colour & 0xFF; + } + pixel++; + } + pattern = pattern ^ 1; + pixel += length; + + } + } + + // RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour); } /** @@ -260,10 +449,9 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri } #define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 -#define RCT2_Y_END_POINT_GLOBAL 0x9ABDAC //sint16 +#define RCT2_Y_RELATED_GLOBAL_2 0x9ABDAC //sint16 #define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 -#define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 -#define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch +#define RCT2_X_RELATED_GLOBAL_2 0x9ABDA8 //sint16 void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixelinfo *dpi){ if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ @@ -276,7 +464,7 @@ void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixe int ebx = RCT2_GLOBAL(0xEDF808, uint32); ebx = RCT2_GLOBAL(ebx * 2 + source_bits_pointer,uint16); - int ebp = dest_bits_pointer; + int ebp = (int)dest_bits_pointer; ebx += (int)source_bits_pointer; StartLoop: @@ -303,7 +491,7 @@ StartLoop: edx &= 0xFFFF0000; } edx += cx; - edx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); + edx -= RCT2_GLOBAL(0x9ABDA8, sint16); if (edx > 0){ cx -= edx; if (cx <= 0){ @@ -328,10 +516,10 @@ StartLoop: } TestLoop: if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; - edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); + edx = RCT2_GLOBAL(0x9ABDB0, sint16); ebp += edx; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16)--; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; + RCT2_GLOBAL(0x9ABDAC, sint16)--; + if (RCT2_GLOBAL(0x9ABDAC, sint16))goto StartLoop; } @@ -340,75 +528,61 @@ TestLoop: * This function readies all the global vars for copying the sprite data onto the screen * I think its only used for bitmaps onto buttons but i am not sure. */ -void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y){ +void sub_0x67A934(rct_drawpixelinfo *dpi, int x, int y){ + int _edi = (int)dpi; + sint16 translated_x = x, translated_y = y; char* bits_pointer; - bits_pointer = dest_dpi->bits; + bits_pointer = dpi->bits; + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; RCT2_GLOBAL(0xEDF808, uint32) = 0; + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); - int start_y, end_y; - start_y = y + source_g1->y_offset - dest_dpi->y; - - //If the start position is negative reset to zero - if (start_y < 0){ - //Create the end point within the drawing area - end_y = source_g1->height + start_y; - //If the end point is now <= 0 no need to draw - if (end_y <= 0)return; - - RCT2_GLOBAL(0xEDF808, sint16) -= start_y; - start_y = 0; + if (translated_y < 0) + { + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; + RCT2_GLOBAL(0xEDF808, sint16) -= translated_y; + translated_y = 0; } else{ - end_y = source_g1->height; - //Move the pointer to the correct starting y location - bits_pointer += (dest_dpi->width + dest_dpi->pitch)*start_y; + bits_pointer += (dpi->width + dpi->pitch)*translated_y; } - int height = start_y + end_y; - //If the image is taller than the drawing area - if (height > dest_dpi->height){ - //Make the end within the drawing area - end_y -= height - dest_dpi->height; - //If the end is now <=0 then there is nothing to draw - if (end_y <= 0)return; + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height; + if (translated_y > 0){ + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; } - + RCT2_GLOBAL(0xEDF80C, uint32) = 0; - int start_x, end_x; - start_x = x + source_g1->x_offset - dest_dpi->x; - - //If the start position is negative reset to zero - if (start_x < 0){ - //Create the end point within the drawing area - end_x = source_g1->width + start_x; - //If the end point is now <= 0 no need to draw - if (end_x <= 0)return; + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; - RCT2_GLOBAL(0xEDF80C, sint16) -= start_x; - start_x = 0; + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); + if (translated_x < 0){ + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; + RCT2_GLOBAL(0xEDF80C, sint16) -= translated_x; + translated_x = 0; } else{ - end_x = source_g1->width; - //Increment the pointer to our start location - bits_pointer += start_x; + bits_pointer += translated_x; + } + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16); + translated_x -= dpi->width; + if (translated_x > 0){ + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0)return; } - int width = start_x + end_x; - //If the image is wider than the drawing area - if (width > dest_dpi->width){ - //Make the end within drawing area - end_x -= width - dest_dpi->width; - //If the end is now <=0 then there is nothing to draw - if (end_x <= 0)return; - } + RCT2_GLOBAL(0x9ABDB0, uint16) = dpi->width + dpi->pitch; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; - //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); + // I dont think it uses ecx, edx but just in case + //esi is the source and bits_pointer is the destination + //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dpi); + + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, translated_x, translated_y, RCT2_GLOBAL(0x9E3D08, uint32), (int)bits_pointer, (int)dpi); } /** @@ -423,7 +597,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); //return; - int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; + int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; @@ -431,16 +605,17 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); // return;//jump into 0x67a445 } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + char* find = "FINDMEDUNCAN"; + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); return;//jump into 0x67a361 } else if ((image_id)& 0xE0000000){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); /* eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -489,38 +664,34 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } eax = *((uint32*)ebx + 2); ebp = *((uint32*)ebx + 3); - rct_g1_element* g1_source = (rct_g1_element*)ebx; - //This is a rct2_drawpixelinfo struct RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); //offset to g1 bits? RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); - if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps //RCT2_CALLPROC_X(0x0067A934, eax, ebx, x, y, 0, dpi, ebp); - sub_0x67A934(g1_source, dpi, x, y); + sub_0x67A934(dpi, x, y); return; } - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - return; + //dpi on stack int translated_x, translated_y; char* bits_pointer; - ebp = dpi; + ebp = (int)dpi; esi = RCT2_GLOBAL(0x9E3D08, uint32); RCT2_GLOBAL(0x9E3CE0, uint32) = 0; bits_pointer = dpi->bits; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); translated_y = y + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; if (translated_y < 0){ - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) += translated_y; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0){ + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) += translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0){ return; } translated_y = -translated_y; @@ -532,61 +703,61 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) bits_pointer += eax; } - translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height;; + translated_y += RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) - dpi->height;; if (translated_y > 0){ - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0) + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) -= translated_y; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <=0) { return; } } - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); eax = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); RCT2_GLOBAL(0x9ABDAE, uint16) = 0; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(0x9ABDB0, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); translated_x = x + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; if (translated_x < 0){ - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) += translated_x; - if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) += translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ return; } translated_x -= RCT2_GLOBAL(0x9ABDAE, sint16); esi -= translated_x; RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) -= translated_x; + RCT2_GLOBAL(0x9ABDB0, sint16) -= translated_x; translated_x = 0; } bits_pointer += translated_x; - translated_x += RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) - dpi->width; + translated_x += RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) - dpi->width; if (translated_x > 0){ - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) -= translated_x; + if (RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_2, sint16) <= 0){ return; } RCT2_GLOBAL(0x9ABDAE, sint16) += translated_x; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) += translated_x; + RCT2_GLOBAL(0x9ABDB0, sint16) += translated_x; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - eax = (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8)) << 8; + eax = (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, uint8)) << 8; edx = RCT2_GLOBAL(0x9ABDAE, sint16); - ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); + ebp = RCT2_GLOBAL(0x9ABDB0, sint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, esi, edi, ah used in 0x67a690 - RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi, bits_pointer, ebp); + RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); return; } //0x67A60A - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); esi -= RCT2_GLOBAL(0x9E3D08, sint32); return; } From 1aa3bc0232017fb241808994dcd054be4807e92f Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 15 May 2014 22:15:29 +0100 Subject: [PATCH 028/209] Started clean up of buffer interaction code.Still a little buggy --- src/gfx.c | 90 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 99c35a463e..11c380dfc7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -274,22 +274,32 @@ void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixe return; //0x67AFD8 } - int ebx = RCT2_GLOBAL(0xEDF808, uint32); - ebx = RCT2_GLOBAL(ebx * 2 + source_bits_pointer,uint16); - int ebp = dest_bits_pointer; - ebx += (int)source_bits_pointer; - + int ebx = RCT2_GLOBAL(0xEDF808, uint32); //G1 y start location + ebx = RCT2_GLOBAL(ebx * 2 + source_bits_pointer, uint16);//? x2?? would have though move to width*ebx + //Possibly more information is stored about each horizontal line + //maybe an x offset with each one? + int ebp = (int)dest_bits_pointer; + ebx += (int)source_bits_pointer; //Move to the correct y location? + int ecx = 0; + int edx = 0; StartLoop: - ebx = ebx; - int cx = RCT2_GLOBAL(ebx, uint16); - RCT2_GLOBAL(0x9ABDB4, uint8) = cx & 0xFF; - ebx += 2; + edx = 0; + int cx = RCT2_GLOBAL(ebx, uint16); //Maybe X start stop offsets + int cl = cx & 0xff; + RCT2_GLOBAL(0x9ABDB4, uint8) = cl; //start offset + + ebx += 2;//skip the extra offset info cx &= 0xFF7F; + cl &= 0x7F; //?? int esi = ebx; - int edx = (cx & 0xFF00) >> 8; - ebx += cx; - edx -= RCT2_GLOBAL(0xEDF80C, sint32); + int dl = (cx & 0xFF00) >> 8; + int ch = 0; + cx = cl; + ebx += cx;//?? + edx = dl; + edx -= RCT2_GLOBAL(0xEDF80C, sint32);//g1 x start location int edi = ebp; + //Looks like checking line is with vision if (edx > 0){ edi += edx; } @@ -302,39 +312,48 @@ StartLoop: } edx &= 0xFFFF0000; } - edx += cx; - edx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); - if (edx > 0){ - cx -= edx; + int dx = edx&0xFFFF; + dx += cx; + dx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); + if (dx > 0){ + cx -= dx; if (cx <= 0){ goto TestLoop; //jump to 0x67AA97 } } - if (cx & 1){ - cx >>= 1; + + for (; cx > 0; cx--, edi++, esi++){ RCT2_GLOBAL(edi, uint8) = RCT2_GLOBAL(esi, uint8); } - else cx >>= 1; + + /*if (cx & 1){ + RCT2_GLOBAL(edi, uint8) = RCT2_GLOBAL(esi, uint8); + edi+=1; + esi+=1; + } + cx >>= 1; if (cx & 1){ - cx >>= 1; RCT2_GLOBAL(edi, uint16) = RCT2_GLOBAL(esi, uint16); + edi+=2; + esi+=2; } - else cx >>= 1; + cx >>= 1; - for (int i = cx; i > 0; --i, edi++, esi++){ - RCT2_GLOBAL(edi, uint16) = RCT2_GLOBAL(esi, uint16); - } + for (int i = cx; i > 0; i-=4, edi+=4, esi+=4){ + RCT2_GLOBAL(edi, uint32) = RCT2_GLOBAL(esi, uint32); + }*/ TestLoop: if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; - edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); + edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebp += edx; RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16)--; if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; } + /* * rct2: 0x67A934 title screen bitmaps on buttons * This function readies all the global vars for copying the sprite data onto the screen @@ -407,8 +426,9 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; - //sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); + char* find = "FINDMEDUNCAN"; + sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); + //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); } /** @@ -423,7 +443,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); //return; - int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = dpi, ebp = 0; + int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; @@ -431,16 +451,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); // return;//jump into 0x67a445 } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); return;//jump into 0x67a361 } else if ((image_id)& 0xE0000000){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); /* eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -502,13 +522,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) sub_0x67A934(g1_source, dpi, x, y); return; } - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); return; //dpi on stack int translated_x, translated_y; char* bits_pointer; - ebp = dpi; + ebp = (int)dpi; esi = RCT2_GLOBAL(0x9E3D08, uint32); RCT2_GLOBAL(0x9E3CE0, uint32) = 0; bits_pointer = dpi->bits; @@ -582,11 +602,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, esi, edi, ah used in 0x67a690 - RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi, bits_pointer, ebp); + RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi,(int) bits_pointer, ebp); return; } //0x67A60A - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); esi -= RCT2_GLOBAL(0x9E3D08, sint32); return; } From 088ac32da35b2d763bf76e111fd284f9dc6969c7 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 15 May 2014 21:29:29 +0200 Subject: [PATCH 029/209] Add gfx_fill_rect Still a little buggy for transparent colours --- src/gfx.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 941ed5e7f1..11b97b6cab 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -445,7 +445,106 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot */ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si) { - RCT2_CALLPROC_X(0x006E6F81, left, right, top, bottom, _si, (int)dpi, colour); + int colour_, colour1, colour2, colour3; + uint16 ax, bx, si2; + uint8 cl; + + if ((colour & 0x180)) { + // jnz loc_6E719A + if (!(colour & 0x100)) { + colour = colour & 0x7F; + } else { + colour = RCT2_ADDRESS(0x009DEDF4,uint8)[colour]; + } + + colour = colour & 0x2000000; + + if (_si, 8) { + gfx_fill_rect(dpi, left, top, bottom, right, colour); + return; + } else if (_si & 0x20) { + gfx_fill_rect(dpi, left, top, left, bottom, colour + 1); + gfx_fill_rect(dpi, left, top, right, top, colour + 1); + gfx_fill_rect(dpi, right, top, right, bottom, colour + 2); + gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 2); + + if (!(_si & 0x10)) { + gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour); + } + } else { + gfx_fill_rect(dpi, left, top, left, bottom, colour + 2); + gfx_fill_rect(dpi, left, top, right, top, colour + 2); + gfx_fill_rect(dpi, right, top, right, bottom, colour + 1); + gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 1); + + if (!(_si & 0x10)) { + gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour); + } + } + } else { + if (_si & 0x80) { + ax = RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8]; + bx = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; + cl = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; + } else { + ax = RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]; + bx = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8]; + cl = RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]; + } + colour_ = ((ax & 0xFF) << 12) | (cl << 8) | bx; + + colour2 = ax & 0xFF; + colour1 = cl; + si2 = (ax & 0xFF00) >> 8; + + if (!(_si & 8)) { + if (!(_si & 0x20)) { + + // Draw outline of box, with top and left in one colour + // and bottom and right in the other + gfx_fill_rect(dpi, left, top, left, bottom - 1, colour1); + gfx_fill_rect(dpi, left + 1, top, right - 1, top, colour1); + gfx_fill_rect(dpi, right, top, right, bottom - 1, colour2); + gfx_fill_rect(dpi, left, bottom, right, bottom, colour2); + + if (!(_si & 0x10)) { + if (_si & 0x04) { + colour3 = RCT2_ADDRESS(0x0141FC49, uint8)[0]; + } else { + colour3 = colour_ & 0xFF; + } + gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour3); + } + + } else { + // jnz loc_6E70AC + // movzx ebp, [esp+10h+var_10] + // movzx ebp, [esp+10h+var_10] + gfx_fill_rect(dpi, left, top, left, bottom, colour2); + gfx_fill_rect(dpi, left + 1, top, right, top, colour2); + + // movzx ebp, byte ptr [esp+10h+var_E+2] + gfx_fill_rect(dpi, right, top + 1, right, bottom - 1, colour1); + gfx_fill_rect(dpi, left + 1, bottom, right, bottom, colour1); + + if (!(_si & 0x10)) { + if (_si & 0x40) { + colour3 = colour_ & 0x00FF; + } else { + if (_si & 0x04) { + colour3 = RCT2_ADDRESS(0x0141FC49, uint8)[0]; + } else { + colour3 = colour_ & 0xFF; + } + colour3 = colour_ & 0xFF00; + } + gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour3); + } + } + } else { + gfx_fill_rect(dpi, left, top, right, bottom, colour); + } + } } #define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 From 67980e2f5f8160e96d8360748106e875086f5533 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 15 May 2014 22:13:27 +0200 Subject: [PATCH 030/209] Fix bug with transparency --- src/gfx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 11b97b6cab..a91b3c8c30 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -451,17 +451,16 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri if ((colour & 0x180)) { // jnz loc_6E719A - if (!(colour & 0x100)) { + if (colour & 0x100) { colour = colour & 0x7F; } else { colour = RCT2_ADDRESS(0x009DEDF4,uint8)[colour]; } - colour = colour & 0x2000000; + colour = colour | 0x2000000; - if (_si, 8) { + if (_si & 8) { gfx_fill_rect(dpi, left, top, bottom, right, colour); - return; } else if (_si & 0x20) { gfx_fill_rect(dpi, left, top, left, bottom, colour + 1); gfx_fill_rect(dpi, left, top, right, top, colour + 1); From 4fae966855841d90214fdb95ac5cbccfd077122f Mon Sep 17 00:00:00 2001 From: ZedThree Date: Fri, 16 May 2014 19:01:25 +0200 Subject: [PATCH 031/209] Bug fix: pressed buttons not the right colour --- src/gfx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a91b3c8c30..fdc4f9318b 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -533,15 +533,14 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri if (_si & 0x04) { colour3 = RCT2_ADDRESS(0x0141FC49, uint8)[0]; } else { - colour3 = colour_ & 0xFF; + colour3 = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; } - colour3 = colour_ & 0xFF00; } gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour3); } } } else { - gfx_fill_rect(dpi, left, top, right, bottom, colour); + gfx_fill_rect(dpi, left, top, right, bottom, colour_); } } } From e209e370be26263a06a7fc3cb99309f0fc685025 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Fri, 16 May 2014 19:49:52 +0200 Subject: [PATCH 032/209] Tidy up gfx_fill_rect_inset Give names to flags and different tones --- src/gfx.c | 117 +++++++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index fdc4f9318b..3dc0eeba5b 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -433,7 +433,8 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } /** - * + * Draw a rectangle, with optional border or fill + * * rct2: 0x006E6F81 * dpi (edi) * left (ax) @@ -441,106 +442,94 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot * right (bx) * bottom (dx) * colour (ebp) - * _si (si) + * flags (si) */ -void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si) +void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short flags) { - int colour_, colour1, colour2, colour3; - uint16 ax, bx, si2; - uint8 cl; + uint8 shadow, fill, hilight; - if ((colour & 0x180)) { - // jnz loc_6E719A + // Flags + int no_border, no_fill, pressed; + + no_border = 8; + no_fill = 0x10; + pressed = 0x20; + + if (colour & 0x180) { if (colour & 0x100) { colour = colour & 0x7F; } else { colour = RCT2_ADDRESS(0x009DEDF4,uint8)[colour]; } - colour = colour | 0x2000000; + colour = colour | 0x2000000; //Transparent - if (_si & 8) { + if (flags & no_border) { gfx_fill_rect(dpi, left, top, bottom, right, colour); - } else if (_si & 0x20) { + } else if (flags & pressed) { + // Draw outline of box gfx_fill_rect(dpi, left, top, left, bottom, colour + 1); gfx_fill_rect(dpi, left, top, right, top, colour + 1); gfx_fill_rect(dpi, right, top, right, bottom, colour + 2); gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 2); - if (!(_si & 0x10)) { + if (!(flags & no_fill)) { gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour); } } else { + // Draw outline of box gfx_fill_rect(dpi, left, top, left, bottom, colour + 2); gfx_fill_rect(dpi, left, top, right, top, colour + 2); gfx_fill_rect(dpi, right, top, right, bottom, colour + 1); gfx_fill_rect(dpi, left, bottom, right, bottom, colour + 1); - if (!(_si & 0x10)) { + if (!(flags & no_fill)) { gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour); } } } else { - if (_si & 0x80) { - ax = RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8]; - bx = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; - cl = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; + if (flags & 0x80) { + shadow = RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8]; + fill = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; + hilight = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; } else { - ax = RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]; - bx = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8]; - cl = RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]; + shadow = RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]; + fill = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8]; + hilight = RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]; } - colour_ = ((ax & 0xFF) << 12) | (cl << 8) | bx; - colour2 = ax & 0xFF; - colour1 = cl; - si2 = (ax & 0xFF00) >> 8; + if (flags & no_border) { + gfx_fill_rect(dpi, left, top, right, bottom, fill); + } else if (flags & pressed) { + // 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 (!(_si & 8)) { - if (!(_si & 0x20)) { - - // Draw outline of box, with top and left in one colour - // and bottom and right in the other - gfx_fill_rect(dpi, left, top, left, bottom - 1, colour1); - gfx_fill_rect(dpi, left + 1, top, right - 1, top, colour1); - gfx_fill_rect(dpi, right, top, right, bottom - 1, colour2); - gfx_fill_rect(dpi, left, bottom, right, bottom, colour2); - - if (!(_si & 0x10)) { - if (_si & 0x04) { - colour3 = RCT2_ADDRESS(0x0141FC49, uint8)[0]; + if (!(flags & no_fill)) { + if (!(flags & 0x40)) { + if (flags & 0x04) { + fill = RCT2_ADDRESS(0x0141FC49, uint8)[0]; } else { - colour3 = colour_ & 0xFF; + fill = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; } - gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour3); - } - - } else { - // jnz loc_6E70AC - // movzx ebp, [esp+10h+var_10] - // movzx ebp, [esp+10h+var_10] - gfx_fill_rect(dpi, left, top, left, bottom, colour2); - gfx_fill_rect(dpi, left + 1, top, right, top, colour2); - - // movzx ebp, byte ptr [esp+10h+var_E+2] - gfx_fill_rect(dpi, right, top + 1, right, bottom - 1, colour1); - gfx_fill_rect(dpi, left + 1, bottom, right, bottom, colour1); - - if (!(_si & 0x10)) { - if (_si & 0x40) { - colour3 = colour_ & 0x00FF; - } else { - if (_si & 0x04) { - colour3 = RCT2_ADDRESS(0x0141FC49, uint8)[0]; - } else { - colour3 = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; - } - } - gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, colour3); } + gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill); } } else { - gfx_fill_rect(dpi, left, top, right, bottom, colour_); + // 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 & no_fill)) { + if (flags & 0x04) { + fill = RCT2_ADDRESS(0x0141FC49, uint8)[0]; + } + gfx_fill_rect(dpi, left+1, top+1, right-1, bottom-1, fill); + } } } } From 001ccc3945aa8f891d5eee6cc0c77eebe7352a3f Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 16 May 2014 19:06:35 +0100 Subject: [PATCH 033/209] Started cleanup of code introduced a bug at some point --- src/gfx.c | 77 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 11c380dfc7..a0aa6ebe8d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -265,7 +265,8 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri #define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 #define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch -void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixelinfo *dpi){ +void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, uint16 g1_y_start, uint16 g1_y_end, uint16 g1_x_start, uint16 g1_x_end){ + //Image_id if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ return; //0x67AAB3 } @@ -273,21 +274,60 @@ void sub_0x67AA18(int* source_bits_pointer, int* dest_bits_pointer, rct_drawpixe if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x4000000){ return; //0x67AFD8 } + + uint16 offset_to_first_line = *(uint16*)(RCT2_GLOBAL(0xEDF808, uint32) * 2 + (uint32)source_bits_pointer); + //This will now point to the first line + char* source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); + char* dest_pointer = dest_bits_pointer; + char* next_dest_pointer = dest_pointer; int ebx = RCT2_GLOBAL(0xEDF808, uint32); //G1 y start location - ebx = RCT2_GLOBAL(ebx * 2 + source_bits_pointer, uint16);//? x2?? would have though move to width*ebx + ebx = RCT2_GLOBAL(ebx * 2 + (uint32)source_bits_pointer, uint16);//? x2?? would have though move to width*ebx //Possibly more information is stored about each horizontal line //maybe an x offset with each one? - int ebp = (int)dest_bits_pointer; - ebx += (int)source_bits_pointer; //Move to the correct y location? + int ebp = (uint32)dest_bits_pointer; + ebx += (uint32)source_bits_pointer; //Move to the correct y location? int ecx = 0; int edx = 0; StartLoop: edx = 0; + uint8 gap_size = *source_pointer++; + uint8 no_pixels = *source_pointer++; + uint8 last_data_line = gap_size & 0x80; + //Clear the last data line bit + gap_size &= 0x7f; + //Move this to the end + char* next_source_pointer = source_pointer + gap_size; + + + int x_start = (int)no_pixels - (int)g1_x_start; + + if (x_start > 0){ + dest_pointer += x_start; + } + else{ + source_pointer -= x_start; + no_pixels += x_start; + if (no_pixels <= 0) goto TestLoop; + x_start = 0; + } + + int x_end = x_start + no_pixels - g1_x_end; + + if (x_end > 0){ + no_pixels -= x_end; + if (no_pixels <= 0) goto TestLoop; + } + + for (; no_pixels > 0; no_pixels--, dest_pointer++, source_pointer++){ + *dest_pointer = *source_pointer; + } + goto TestLoop; + int cx = RCT2_GLOBAL(ebx, uint16); //Maybe X start stop offsets int cl = cx & 0xff; RCT2_GLOBAL(0x9ABDB4, uint8) = cl; //start offset - + ebx += 2;//skip the extra offset info cx &= 0xFF7F; cl &= 0x7F; //?? @@ -345,6 +385,14 @@ StartLoop: RCT2_GLOBAL(edi, uint32) = RCT2_GLOBAL(esi, uint32); }*/ TestLoop: + source_pointer = next_source_pointer; + if (!last_data_line)goto StartLoop; + next_dest_pointer += dpi->width + dpi->pitch; + dest_pointer = next_dest_pointer; + g1_y_end--; + if (g1_y_end)goto StartLoop; + return; + if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebp += edx; @@ -360,11 +408,11 @@ TestLoop: * I think its only used for bitmaps onto buttons but i am not sure. */ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y){ - + uint16 g1_y_start, g1_x_start; char* bits_pointer; - bits_pointer = dest_dpi->bits; - RCT2_GLOBAL(0xEDF808, uint32) = 0; + bits_pointer = dest_dpi->bits; + g1_y_start = 0; int start_y, end_y; start_y = y + source_g1->y_offset - dest_dpi->y; @@ -376,7 +424,7 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, //If the end point is now <= 0 no need to draw if (end_y <= 0)return; - RCT2_GLOBAL(0xEDF808, sint16) -= start_y; + g1_y_start -= start_y; start_y = 0; } else{ @@ -394,8 +442,9 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, if (end_y <= 0)return; } - RCT2_GLOBAL(0xEDF80C, uint32) = 0; + int start_x, end_x; + g1_x_start = 0; start_x = x + source_g1->x_offset - dest_dpi->x; //If the start position is negative reset to zero @@ -405,7 +454,7 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, //If the end point is now <= 0 no need to draw if (end_x <= 0)return; - RCT2_GLOBAL(0xEDF80C, sint16) -= start_x; + g1_x_start -= start_x; start_x = 0; } else{ @@ -426,8 +475,10 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; - char* find = "FINDMEDUNCAN"; - sub_0x67AA18(RCT2_GLOBAL(0x9E3D08, int*), (int*)bits_pointer, dest_dpi); + RCT2_GLOBAL(0xEDF808, uint16) = g1_y_start; + RCT2_GLOBAL(0xEDF80C, uint16) = g1_x_start; + + sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); } From 5eb445857b6fb3f850407bcfe9b026eb04e77c21 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 17 May 2014 17:40:55 +0100 Subject: [PATCH 034/209] Trying to find bug in new version of code --- src/gfx.c | 92 +++++++++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a0aa6ebe8d..65b818b01e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -275,11 +275,11 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi return; //0x67AFD8 } - uint16 offset_to_first_line = *(uint16*)(RCT2_GLOBAL(0xEDF808, uint32) * 2 + (uint32)source_bits_pointer); + uint16 offset_to_first_line = *(uint16*)(g1_y_start*2 + (uint32)source_bits_pointer); //This will now point to the first line char* source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); char* dest_pointer = dest_bits_pointer; - char* next_dest_pointer = dest_pointer; + char* next_dest_pointer = dest_bits_pointer; int ebx = RCT2_GLOBAL(0xEDF808, uint32); //G1 y start location ebx = RCT2_GLOBAL(ebx * 2 + (uint32)source_bits_pointer, uint16);//? x2?? would have though move to width*ebx @@ -291,43 +291,18 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi int edx = 0; StartLoop: edx = 0; - uint8 gap_size = *source_pointer++; uint8 no_pixels = *source_pointer++; - uint8 last_data_line = gap_size & 0x80; + uint8 gap_size = *source_pointer++; + uint8 last_data_line = no_pixels & 0x80; //Clear the last data line bit - gap_size &= 0x7f; + no_pixels &= 0x7f; //Move this to the end - char* next_source_pointer = source_pointer + gap_size; + char* next_source_pointer = source_pointer + no_pixels; - - int x_start = (int)no_pixels - (int)g1_x_start; - - if (x_start > 0){ - dest_pointer += x_start; - } - else{ - source_pointer -= x_start; - no_pixels += x_start; - if (no_pixels <= 0) goto TestLoop; - x_start = 0; - } - - int x_end = x_start + no_pixels - g1_x_end; - - if (x_end > 0){ - no_pixels -= x_end; - if (no_pixels <= 0) goto TestLoop; - } - - for (; no_pixels > 0; no_pixels--, dest_pointer++, source_pointer++){ - *dest_pointer = *source_pointer; - } - goto TestLoop; - int cx = RCT2_GLOBAL(ebx, uint16); //Maybe X start stop offsets int cl = cx & 0xff; RCT2_GLOBAL(0x9ABDB4, uint8) = cl; //start offset - + ebx += 2;//skip the extra offset info cx &= 0xFF7F; cl &= 0x7F; //?? @@ -339,30 +314,41 @@ StartLoop: edx = dl; edx -= RCT2_GLOBAL(0xEDF80C, sint32);//g1 x start location int edi = ebp; - //Looks like checking line is with vision - if (edx > 0){ + + int x_start = (int)gap_size - (int)g1_x_start; + + if (edx > 0){ //edx x_start edi += edx; + dest_pointer += x_start; } else{ + source_pointer -= x_start; + no_pixels += x_start; + esi -= edx; cx += edx & 0xFFFF; - if (cx <= 0){ - goto TestLoop; - //jump to 0x67AA97 - } + + if (cx <= 0) goto TestLoop;//cx + x_start = 0; edx &= 0xFFFF0000; } + + int x_end = x_start + (int)no_pixels - (int)g1_x_end; int dx = edx&0xFFFF; dx += cx; dx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); - if (dx > 0){ + + if (dx > 0){ //dx x_end + no_pixels -= x_end; cx -= dx; - if (cx <= 0){ - goto TestLoop; - //jump to 0x67AA97 - } + if (cx <= 0) goto TestLoop;//cx } + for (; no_pixels > 0; no_pixels--, dest_pointer++, source_pointer++){ + *dest_pointer = *source_pointer; + } + goto TestLoop; + for (; cx > 0; cx--, edi++, esi++){ RCT2_GLOBAL(edi, uint8) = RCT2_GLOBAL(esi, uint8); } @@ -386,18 +372,22 @@ StartLoop: }*/ TestLoop: source_pointer = next_source_pointer; - if (!last_data_line)goto StartLoop; - next_dest_pointer += dpi->width + dpi->pitch; + int test = (RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80); + if (!test) goto StartLoop; + //if (!last_data_line)goto StartLoop; + next_dest_pointer += (int)dpi->width + (int)dpi->pitch; dest_pointer = next_dest_pointer; - g1_y_end--; - if (g1_y_end)goto StartLoop; - return; - if (!(RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80)) goto StartLoop; edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebp += edx; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16)--; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; + + test = --RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16); + g1_y_end--; + if (g1_y_end)goto StartLoop;//test + return; + +// +// if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; } From 0fa9e6ebb9312ef583c84e7a072f1bc99af20bd7 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 18 May 2014 08:14:47 +0100 Subject: [PATCH 035/209] Finished turning the code into C removed all present bugs. Buffer draw code for basic images is done. --- src/gfx.c | 157 ++++++++++++++++++------------------------------------ 1 file changed, 51 insertions(+), 106 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 65b818b01e..a50288073e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -277,118 +277,63 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi uint16 offset_to_first_line = *(uint16*)(g1_y_start*2 + (uint32)source_bits_pointer); //This will now point to the first line - char* source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); - char* dest_pointer = dest_bits_pointer; + char* next_source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); char* next_dest_pointer = dest_bits_pointer; - - int ebx = RCT2_GLOBAL(0xEDF808, uint32); //G1 y start location - ebx = RCT2_GLOBAL(ebx * 2 + (uint32)source_bits_pointer, uint16);//? x2?? would have though move to width*ebx - //Possibly more information is stored about each horizontal line - //maybe an x offset with each one? - int ebp = (uint32)dest_bits_pointer; - ebx += (uint32)source_bits_pointer; //Move to the correct y location? - int ecx = 0; - int edx = 0; -StartLoop: - edx = 0; - uint8 no_pixels = *source_pointer++; - uint8 gap_size = *source_pointer++; - uint8 last_data_line = no_pixels & 0x80; - //Clear the last data line bit - no_pixels &= 0x7f; - //Move this to the end - char* next_source_pointer = source_pointer + no_pixels; - int cx = RCT2_GLOBAL(ebx, uint16); //Maybe X start stop offsets - int cl = cx & 0xff; - RCT2_GLOBAL(0x9ABDB4, uint8) = cl; //start offset + //For every line in the image + for (; g1_y_end; g1_y_end--){ - ebx += 2;//skip the extra offset info - cx &= 0xFF7F; - cl &= 0x7F; //?? - int esi = ebx; - int dl = (cx & 0xFF00) >> 8; - int ch = 0; - cx = cl; - ebx += cx;//?? - edx = dl; - edx -= RCT2_GLOBAL(0xEDF80C, sint32);//g1 x start location - int edi = ebp; + uint8 last_data_line = 0; + //For every data section in the line + while (!last_data_line){ + char* source_pointer = next_source_pointer; + char* dest_pointer = next_dest_pointer; - int x_start = (int)gap_size - (int)g1_x_start; + sint8 no_pixels = *source_pointer++; + uint8 gap_size = *source_pointer++; + //The last bit in no_pixels tells you if you have reached the end of a line + last_data_line = no_pixels & 0x80; + //Clear the last data line bit so we have just the no_pixels + no_pixels &= 0x7f; + //Have our next source pointer point to the next data section + next_source_pointer = source_pointer + (int)no_pixels; - if (edx > 0){ //edx x_start - edi += edx; - dest_pointer += x_start; + //Calculates the start point of the image + int x_start = (int)gap_size - (int)g1_x_start; + + if (x_start > 0){ + //Since the start is positive + //We need to move the drawing surface to the correct position + dest_pointer += x_start; + } + else{ + //If the start is negative we require to remove part of the image. + //This is done by moving the image pointer to the correct position. + source_pointer -= x_start; + //The no_pixels will be reduced in this operation + no_pixels += x_start; + //If there are no pixels there is nothing to draw this line + if (no_pixels <= 0) continue; + //Reset the start position to zero as we have taken into account all moves + x_start = 0; + } + + int x_end = x_start + (int)no_pixels; + //If the end position is further out than the whole image + //end position then we need to shorten the line again + if (x_end > (int)g1_x_end){ + //Shorten the line + no_pixels -= x_end - (int)g1_x_end; + //If there are no pixels there is nothing to draw. + if (no_pixels <= 0) continue; + } + + //Finally after all those checks copy the image onto the drawing surface + memcpy(dest_pointer, source_pointer, no_pixels); + } + //Add a line to the drawing surface pointer + next_dest_pointer += (int)dpi->width + (int)dpi->pitch; } - else{ - source_pointer -= x_start; - no_pixels += x_start; - - esi -= edx; - cx += edx & 0xFFFF; - - if (cx <= 0) goto TestLoop;//cx - x_start = 0; - edx &= 0xFFFF0000; - } - - int x_end = x_start + (int)no_pixels - (int)g1_x_end; - int dx = edx&0xFFFF; - dx += cx; - dx -= RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); - - if (dx > 0){ //dx x_end - no_pixels -= x_end; - cx -= dx; - if (cx <= 0) goto TestLoop;//cx - } - - for (; no_pixels > 0; no_pixels--, dest_pointer++, source_pointer++){ - *dest_pointer = *source_pointer; - } - goto TestLoop; - - for (; cx > 0; cx--, edi++, esi++){ - RCT2_GLOBAL(edi, uint8) = RCT2_GLOBAL(esi, uint8); - } - - /*if (cx & 1){ - RCT2_GLOBAL(edi, uint8) = RCT2_GLOBAL(esi, uint8); - edi+=1; - esi+=1; - } - cx >>= 1; - - if (cx & 1){ - RCT2_GLOBAL(edi, uint16) = RCT2_GLOBAL(esi, uint16); - edi+=2; - esi+=2; - } - cx >>= 1; - - for (int i = cx; i > 0; i-=4, edi+=4, esi+=4){ - RCT2_GLOBAL(edi, uint32) = RCT2_GLOBAL(esi, uint32); - }*/ -TestLoop: - source_pointer = next_source_pointer; - int test = (RCT2_GLOBAL(0x9ABDB4, uint8) & 0x80); - if (!test) goto StartLoop; - //if (!last_data_line)goto StartLoop; - next_dest_pointer += (int)dpi->width + (int)dpi->pitch; - dest_pointer = next_dest_pointer; - - edx = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); - ebp += edx; - - test = --RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16); - g1_y_end--; - if (g1_y_end)goto StartLoop;//test - return; - -// -// if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16))goto StartLoop; - } From 69b9c45a4035751b19052e5641c3a3679c2022e7 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 18 May 2014 09:30:13 +0100 Subject: [PATCH 036/209] Started adding in the rest of draw sprite function added in stub function for 2nd draw to buffer func --- src/gfx.c | 120 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 101 insertions(+), 19 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a50288073e..ed64965863 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -261,17 +261,36 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri #define RCT2_Y_RELATED_GLOBAL_1 0x9E3D12 //uint16 #define RCT2_Y_END_POINT_GLOBAL 0x9ABDAC //sint16 +#define RCT2_Y_START_POINT_GLOBAL 0xEDF808 //sint16 #define RCT2_X_RELATED_GLOBAL_1 0x9E3D10 //uint16 #define RCT2_X_END_POINT_GLOBAL 0x9ABDA8 //sint16 +#define RCT2_X_START_POINT_GLOBAL 0xEDF80C //sint16 #define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch +/* +* rct2: 0x67A690 very similar in function to 0x67AA18 readied images are copied onto +* buffers +*/ +void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp){ + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, eax, ebx, ecx, edx, esi, edi, ebp); + return; +} + +/* +* rct2: 0x67AA18 transfers readied images onto buffers +* This function copies the sprite data onto the screen +* I think its only used for bitmaps onto buttons but i am not sure. +* There is still a small bug with this code when it is in the choose park view. +*/ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, uint16 g1_y_start, uint16 g1_y_end, uint16 g1_x_start, uint16 g1_x_end){ //Image_id if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); return; //0x67AAB3 } if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x4000000){ + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); return; //0x67AFD8 } @@ -296,10 +315,10 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi //Clear the last data line bit so we have just the no_pixels no_pixels &= 0x7f; //Have our next source pointer point to the next data section - next_source_pointer = source_pointer + (int)no_pixels; + next_source_pointer = source_pointer + no_pixels; //Calculates the start point of the image - int x_start = (int)gap_size - (int)g1_x_start; + int x_start = gap_size - g1_x_start; if (x_start > 0){ //Since the start is positive @@ -318,17 +337,17 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi x_start = 0; } - int x_end = x_start + (int)no_pixels; + int x_end = x_start + no_pixels; //If the end position is further out than the whole image //end position then we need to shorten the line again - if (x_end > (int)g1_x_end){ + if (x_end > g1_x_end){ //Shorten the line - no_pixels -= x_end - (int)g1_x_end; + no_pixels -= x_end - g1_x_end; //If there are no pixels there is nothing to draw. if (no_pixels <= 0) continue; } - //Finally after all those checks copy the image onto the drawing surface + //Finally after all those checks, copy the image onto the drawing surface memcpy(dest_pointer, source_pointer, no_pixels); } //Add a line to the drawing surface pointer @@ -407,11 +426,13 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, if (end_x <= 0)return; } + //Can be removed when i work out the bug in the second function and we don't need to + //test the old version. RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; - RCT2_GLOBAL(0xEDF808, uint16) = g1_y_start; - RCT2_GLOBAL(0xEDF80C, uint16) = g1_x_start; + RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; + RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); @@ -437,17 +458,77 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); // - return;//jump into 0x67a445 + //return;//jump into 0x67a445 + if ((image_id)& 0x40000000){ + eax = image_id; + eax >>= 13; + eax &= 0xFF; + RCT2_GLOBAL(0x009E3CDC, uint32) = 0; + } + else{ + eax = image_id; + eax >>= 13; + eax &= 0x7F; + } + eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); + eax <<= 4; + eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + RCT2_GLOBAL(0x9ABDA4, uint32) = eax; + } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - return;//jump into 0x67a361 + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + //return;//jump into 0x67a361 + + eax = image_id; + RCT2_GLOBAL(0x9E3CDC, uint32) = 0; + eax >>= 13; + //push edx/y + eax &= 0x1F; + ebp = RCT2_GLOBAL(ebp * 4 + 0x97FCBC, uint32); + eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); + ebp <<= 4; + eax <<= 4; + ebp = RCT2_GLOBAL(ebp + RCT2_ADDRESS_G1_ELEMENTS, uint32); + eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + edx = *((uint32*)eax + 0xF3); + esi = *((uint32*)eax + 0xF7); + RCT2_GLOBAL(0x9ABFFF, uint32) = edx; + RCT2_GLOBAL(0x9AC003, uint32) = esi; + edx = *((uint32*)ebp + 0xF3); + esi = *((uint32*)ebp + 0xF7); + esi = *((uint32*)eax + 0xF7); + + edx = *((uint32*)eax + 0xFB); + esi = *((uint32*)ebp + 0xFB); + + eax = image_id; + RCT2_GLOBAL(0x9AC007, uint32) = edx; + eax >>= 18; + RCT2_GLOBAL(0x9ABF42, uint32) = esi; + eax &= 0x1F; + + //image_id + RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000; + + eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); + eax <<= 4; + eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + edx = *((uint32*)eax + 0xF3); + esi = *((uint32*)eax + 0xF7); + RCT2_GLOBAL(0x9ABFD6, uint32) = edx; + RCT2_GLOBAL(0x9ABFDA, uint32) = esi; + edx = *((uint32*)eax + 0xFB); + RCT2_GLOBAL(0x9ABDA4, uint32) = 0x9ABF0C; + RCT2_GLOBAL(0x9ABFDE, uint32) = edx; + edx = y; + } else if ((image_id)& 0xE0000000){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - /* + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + //return; eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -455,6 +536,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + ebp = *((uint32*)eax + 0xF3); esi = *((uint32*)eax + 0xF7); RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; @@ -475,8 +557,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = *((uint32*)eax + 0xFB); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; - RCT2_GLOBAL(0x9ABEDE, uint32) = ebp;*/ - return; + RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; + } ebx &= 0x7FFFF; @@ -508,8 +590,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) sub_0x67A934(g1_source, dpi, x, y); return; } - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); - return; + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); + //return; //dpi on stack int translated_x, translated_y; char* bits_pointer; @@ -588,7 +670,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, esi, edi, ah used in 0x67a690 - RCT2_CALLPROC_X_EBPSAFE(0x67A690, eax, ebx, ecx, edx, esi,(int) bits_pointer, ebp); + sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); return; } //0x67A60A From a4645ec806b1ddeb9614d3f386b5c74e486aab91 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 18 May 2014 19:27:00 +0100 Subject: [PATCH 037/209] Trying to locate bug in drawing ready code. --- src/gfx.c | 92 ++++++++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ed64965863..88d9e5cb41 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -434,8 +434,8 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; - sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); - //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, source_g1->offset, bits_pointer, dest_dpi); + //sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); + RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_g1->offset, (int)bits_pointer, (int)dest_dpi); } /** @@ -458,9 +458,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); // - //return;//jump into 0x67a445 + return;//jump into 0x67a445 if ((image_id)& 0x40000000){ eax = image_id; eax >>= 13; @@ -479,8 +479,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - //return;//jump into 0x67a361 + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + return;//jump into 0x67a361 eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -493,16 +493,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax <<= 4; ebp = RCT2_GLOBAL(ebp + RCT2_ADDRESS_G1_ELEMENTS, uint32); eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - edx = *((uint32*)eax + 0xF3); - esi = *((uint32*)eax + 0xF7); + edx = *((uint32*)(eax + 0xF3)); + esi = *((uint32*)(eax + 0xF7)); RCT2_GLOBAL(0x9ABFFF, uint32) = edx; RCT2_GLOBAL(0x9AC003, uint32) = esi; - edx = *((uint32*)ebp + 0xF3); - esi = *((uint32*)ebp + 0xF7); - esi = *((uint32*)eax + 0xF7); + edx = *((uint32*)(ebp + 0xF3)); + esi = *((uint32*)(ebp + 0xF7)); + esi = *((uint32*)(eax + 0xF7)); - edx = *((uint32*)eax + 0xFB); - esi = *((uint32*)ebp + 0xFB); + edx = *((uint32*)(eax + 0xFB)); + esi = *((uint32*)(ebp + 0xFB)); eax = image_id; RCT2_GLOBAL(0x9AC007, uint32) = edx; @@ -516,19 +516,19 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - edx = *((uint32*)eax + 0xF3); - esi = *((uint32*)eax + 0xF7); + edx = *((uint32*)(eax + 0xF3)); + esi = *((uint32*)(eax + 0xF7)); RCT2_GLOBAL(0x9ABFD6, uint32) = edx; RCT2_GLOBAL(0x9ABFDA, uint32) = esi; - edx = *((uint32*)eax + 0xFB); + edx = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x9ABF0C; RCT2_GLOBAL(0x9ABFDE, uint32) = edx; edx = y; } else if ((image_id)& 0xE0000000){ - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - //return; + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + return; eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -537,11 +537,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - ebp = *((uint32*)eax + 0xF3); - esi = *((uint32*)eax + 0xF7); + ebp = *((uint32*)(eax + 0xF3)); + esi = *((uint32*)(eax + 0xF7)); RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; RCT2_GLOBAL(0x9ABF03, uint32) = esi; - ebp = *((uint32*)eax + 0xFB); + ebp = *((uint32*)(eax + 0xFB)); eax = ebx; RCT2_GLOBAL(0x9ABF07, uint32) = ebp; @@ -550,11 +550,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - ebp = *((uint32*)eax + 0xF3); - esi = *((uint32*)eax + 0xF7); + ebp = *((uint32*)(eax + 0xF3)); + esi = *((uint32*)(eax + 0xF7)); RCT2_GLOBAL(0x9ABED6, uint32) = ebp; RCT2_GLOBAL(0x9ABEDA, uint32) = esi; - ebp = *((uint32*)eax + 0xFB); + ebp = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; @@ -597,13 +597,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) char* bits_pointer; ebp = (int)dpi; - esi = RCT2_GLOBAL(0x9E3D08, uint32); + esi = (int)g1_source->offset;//RCT2_GLOBAL(0x9E3D08, uint32); RCT2_GLOBAL(0x9E3CE0, uint32) = 0; bits_pointer = dpi->bits; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0E, sint16); + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_source->height;// RCT2_GLOBAL(0x9E3D0E, sint16); - translated_y = y + RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16) - dpi->y; + translated_y = y - dpi->y + g1_source->y_offset;//RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); if (translated_y < 0){ @@ -612,30 +612,27 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } translated_y = -translated_y; - esi += translated_y * RCT2_GLOBAL(0x9E3D0C, sint16); - RCT2_GLOBAL(0x9E3CE0, sint32) += translated_y * RCT2_GLOBAL(0x9E3D0C, sint16); + esi += translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(0x9E3CE0, sint32) += translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); translated_y = 0; } else { - eax = (dpi->width + dpi->pitch) * translated_y; - bits_pointer += eax; + //eax = ; + bits_pointer += (dpi->width + dpi->pitch) * translated_y;//eax; } - translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height;; + translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height; if (translated_y > 0){ RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0) - { - return; - } + if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0)return; } - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = RCT2_GLOBAL(0x9E3D0C, sint16); - eax = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_source->width;// RCT2_GLOBAL(0x9E3D0C, sint16); + eax = dpi->width + dpi->pitch - g1_source->width; //RCT2_GLOBAL(0x9E3D0C, sint16); RCT2_GLOBAL(0x9ABDAE, uint16) = 0; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - RCT2_GLOBAL(0x9E3D0C, sint16); - translated_x = x + RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - g1_source->width;// RCT2_GLOBAL(0x9E3D0C, sint16); + translated_x = x - dpi->x + g1_source->x_offset;//RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16); if (translated_x < 0){ @@ -644,7 +641,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } - translated_x -= RCT2_GLOBAL(0x9ABDAE, sint16); + RCT2_GLOBAL(0x9ABDAE, sint16) -= translated_x; esi -= translated_x; RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) -= translated_x; @@ -656,21 +653,20 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (translated_x > 0){ RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ - return; - } + if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0)return; + RCT2_GLOBAL(0x9ABDAE, sint16) += translated_x; RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) += translated_x; } - if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ - eax = (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8)) << 8; + if (!(g1_source->flags & 0x02)){ + eax = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) & 0xFF + (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8)) << 8; edx = RCT2_GLOBAL(0x9ABDAE, sint16); ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; - //ebx, esi, edi, ah used in 0x67a690 - sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); + //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 + sub_0x67A690(eax, ebx, 0, edx, esi, (int)bits_pointer, ebp); return; } //0x67A60A From 400351a38cd30f636c53763b275c7f05774ecd42 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 19 May 2014 21:12:00 +0100 Subject: [PATCH 038/209] Finally found bug. It was caused by the wrong offset in the calling sub. --- src/gfx.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 88d9e5cb41..1b6e3fd581 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -272,7 +272,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * buffers */ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp){ - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, eax, ebx, ecx, edx, esi, edi, ebp); + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); return; } @@ -458,9 +458,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); // - return;//jump into 0x67a445 + //return;//jump into 0x67a445 if ((image_id)& 0x40000000){ eax = image_id; eax >>= 13; @@ -479,8 +479,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - return;//jump into 0x67a361 + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + //return;//jump into 0x67a361 eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -527,8 +527,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if ((image_id)& 0xE0000000){ - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - return; + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); + //return; eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -605,6 +605,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) translated_y = y - dpi->y + g1_source->y_offset;//RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); + if (image_id == 5200){ + image_id = image_id; + } if (translated_y < 0){ RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) += translated_y; @@ -612,7 +615,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } translated_y = -translated_y; - esi += translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); + esi += (uint32)translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); RCT2_GLOBAL(0x9E3CE0, sint32) += translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); translated_y = 0; } else { @@ -649,24 +652,28 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } bits_pointer += translated_x; - translated_x += RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) - dpi->width; + translated_x += RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); + + + translated_x -= dpi->width; if (translated_x > 0){ RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) -= translated_x; if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0)return; - RCT2_GLOBAL(0x9ABDAE, sint16) += translated_x; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) += translated_x; + RCT2_GLOBAL(0x9ABDAE, uint16) += translated_x; + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) += translated_x; } - + if (!(g1_source->flags & 0x02)){ - eax = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) & 0xFF + (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8)) << 8; - edx = RCT2_GLOBAL(0x9ABDAE, sint16); - ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16); + eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); + eax <<= 8; + edx = RCT2_GLOBAL(0x9ABDAE, uint16); + ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 - sub_0x67A690(eax, ebx, 0, edx, esi, (int)bits_pointer, ebp); + sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); return; } //0x67A60A From 9270aa6aae3abbc6c1a29fda01bf383e499b7bca Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 19 May 2014 22:06:01 +0100 Subject: [PATCH 039/209] Fixed tab background bug. --- src/gfx.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 1b6e3fd581..4d044d8665 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -458,18 +458,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - // - //return;//jump into 0x67a445 - if ((image_id)& 0x40000000){ + + if (!((image_id)& 0x40000000)){ eax = image_id; - eax >>= 13; + eax >>= 19; eax &= 0xFF; RCT2_GLOBAL(0x009E3CDC, uint32) = 0; } else{ eax = image_id; - eax >>= 13; + eax >>= 19; eax &= 0x7F; } eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); @@ -484,13 +482,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; - eax >>= 13; + eax >>= 19; //push edx/y eax &= 0x1F; ebp = RCT2_GLOBAL(ebp * 4 + 0x97FCBC, uint32); eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); - ebp <<= 4; - eax <<= 4; + ebp <<= 0x4; + eax <<= 0x4; ebp = RCT2_GLOBAL(ebp + RCT2_ADDRESS_G1_ELEMENTS, uint32); eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); edx = *((uint32*)(eax + 0xF3)); @@ -506,7 +504,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = image_id; RCT2_GLOBAL(0x9AC007, uint32) = edx; - eax >>= 18; + eax >>= 24; RCT2_GLOBAL(0x9ABF42, uint32) = esi; eax &= 0x1F; @@ -677,8 +675,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } //0x67A60A + + esi -= (uint32)g1_source->offset; + ebp = esi; + eax = g1_source->width*g1_source->height; + esi = g1_source->offset; + edx = eax; + edi = 0x9E3D28; + eax = 0; + RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); - esi -= RCT2_GLOBAL(0x9E3D08, sint32); return; } From 0a8a56d4b003d5934a5c6668dbf872a7f66418e4 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 20 May 2014 18:32:42 +0100 Subject: [PATCH 040/209] Bug in buffer code changing the colour of peep --- src/gfx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 4d044d8665..3244ad472c 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -340,7 +340,7 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi int x_end = x_start + no_pixels; //If the end position is further out than the whole image //end position then we need to shorten the line again - if (x_end > g1_x_end){ + if (x_end > (int)g1_x_end){ //Shorten the line no_pixels -= x_end - g1_x_end; //If there are no pixels there is nothing to draw. @@ -433,9 +433,9 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; - - //sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_g1->offset, (int)bits_pointer, (int)dest_dpi); + + sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); + //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_g1->offset, (int)bits_pointer, (int)dest_dpi); } /** From 1dc5b6576700b1f2db5c8bba2750b6f78b6a31d3 Mon Sep 17 00:00:00 2001 From: lnz Date: Wed, 21 May 2014 14:04:08 +0200 Subject: [PATCH 041/209] Initial implementation of ride reachability checks --- src/ride.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ride.h | 5 +- src/scenario.c | 2 +- 3 files changed, 209 insertions(+), 2 deletions(-) diff --git a/src/ride.c b/src/ride.c index 42f32287ff..296936e935 100644 --- a/src/ride.c +++ b/src/ride.c @@ -19,6 +19,9 @@ *****************************************************************************/ #include "addresses.h" +#include "map.h" +#include "news_item.h" +#include "sprite.h" #include "ride.h" #include "sprite.h" #include "peep.h" @@ -200,3 +203,204 @@ void ride_update_favourited_stat() window_invalidate_by_id(WC_RIDE_LIST, 0); } + +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & 0x3C; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + + + +/** + * rct2: 0x006B7C59 + * @return 1 if the coordinate is reachable or has no entrance, 0 otw + */ +int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + int tile_idx = ((x << 8) | y) >> 3; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while(1) { + uint8 element_type = tile->type & 0x3C; + if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { + break; + } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { + return 1; + } + tile++; + } + + uint8 face_direction = tile->type & 3; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + return map_coord_is_connected(tile_idx, station_height, face_direction); + /* while (1) { */ + /* rct_map_element_path_properties props; */ + + /* element_type = tile->type & 0x3C; */ + /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ + /* goto end; */ + + /* props = tile->properties.path; */ + /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ + /* if ((props.type & 3) == face_direction) { */ + /* if (station_height == tile->base_height + 2) */ + /* return 1; */ + /* } */ + /* else { */ + /* uint8 madness = (props.type & 3) ^ 2; */ + /* if (madness == face_direction && station_height == tile->base_height) */ + /* return 1; */ + /* } */ + /* } else { // off-road only same height counts as connected */ + /* if (station_height == tile->base_height) */ + /* return 1; */ + /* } */ + + /* end: */ + /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ + /* return 0; */ + /* tile++; */ + /* } */ +} + + +void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) +{ + for (int i = 0; i < 4; ++i) { + uint16 station_start = ride->station_starts[i], + entrance = ride->entrances[i], + exit = ride->exits[i]; + + if (station_start == -1 ) + continue; + if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; + } + + if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb27, ride_idx); + ride->var_1AF = 3; + } + + } +} + + +void blue_reachable(rct_ride* ride, int ride_idx) +{ + uint16 coordinate = ride->station_starts[ride_idx]; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint16 magic = 0; + int tile_idx = ((x << 8) | y) >> 3, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while (1) { + // First find the appropriate track element for our ride + uint8 element_type = tile->type & 0x3C; + if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) + break; + + if(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) + return; + tile++; + } + + uint8 track_type = tile->properties.track.type; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } + + magic = magic << (tile->type & 3); + magic = ((magic >> 12) | magic) & 0xF; + + for (int count = 0; magic != 0; ++count) { + if (!(magic & 1)) { + magic >>= 1; + continue; + } + + uint8 face_direction = count ^ 2; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + if (map_coord_is_connected(tile, tile->base_height, face_direction)) + return; + } + + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; +} + + + +/** + * rct2: 0x006B7A5E + **/ +void ride_check_all_reachable() +{ +/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ + rct_ride *ride; + + for (int i = 0; i < MAX_RIDES; i++) { + ride = GET_RIDE(i); + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->var_1AF != 0) + ride->var_1AF--; + if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + continue; + + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { + //lightblue + blue_reachable(ride, i); + return; + } + else { + //pink + ride_entrance_exit_connected(ride, i); + } + + } +} + diff --git a/src/ride.h b/src/ride.h index 84eb778120..a782f19f64 100644 --- a/src/ride.h +++ b/src/ride.h @@ -79,7 +79,9 @@ typedef struct { uint16 var_196; uint8 pad_198; uint8 var_199; - uint8 pad_19A[0x1A]; + uint8 pad_19A[0x15]; + uint8 var_1AF; + uint32 pad_1B0; sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 uint8 pad_1BC[0x12]; @@ -262,5 +264,6 @@ int ride_get_max_queue_time(rct_ride *ride); void ride_init_all(); void reset_all_ride_build_dates(); void ride_update_favourited_stat(); +void ride_check_all_reachable(); #endif diff --git a/src/scenario.c b/src/scenario.c index 81f97bbd08..c71abc6b55 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -874,7 +874,7 @@ void scenario_update() finance_pay_interest(); scenario_marketing_update(); peep_problem_warnings_update(); - RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability + ride_check_all_reachable(); ride_update_favourited_stat(); if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) { From e11e9d78f9ded6e0ccb9c8e524888e9f87a3a7c7 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 21 May 2014 18:21:49 +0100 Subject: [PATCH 042/209] Fixed small bug due to wrong constant. --- src/gfx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 3244ad472c..f702d70ae9 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -284,12 +284,12 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) */ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, uint16 g1_y_start, uint16 g1_y_end, uint16 g1_x_start, uint16 g1_x_end){ //Image_id - if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x2000000){ + if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x20000000){ RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); return; //0x67AAB3 } - if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x4000000){ + if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x40000000){ RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); return; //0x67AFD8 } @@ -679,7 +679,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) esi -= (uint32)g1_source->offset; ebp = esi; eax = g1_source->width*g1_source->height; - esi = g1_source->offset; + esi = (int)g1_source->offset; edx = eax; edi = 0x9E3D28; eax = 0; From e5a9426203161631735c2ffd4b023d1114153f93 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 21 May 2014 18:57:56 +0100 Subject: [PATCH 043/209] Added final part of main code section. --- src/gfx.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index f702d70ae9..d48159409c 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -683,8 +683,47 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) edx = eax; edi = 0x9E3D28; eax = 0; + while (edx>0){ + eax = *((sint8*)esi); + if (eax >= 0){ + esi++; + ecx = eax; + edx -= eax; + memcpy((char*)edi, (char*)esi, ecx); + edi += ecx; + esi += ecx; + continue; + } + ecx = eax; + ebx = edi; + eax &= 0x7; + ecx >>= 3; + eax <<= 8; + ecx = -ecx; + eax = eax & 0xFF00 + *((sint8*)esi); + edx -= ecx; + esi += 2; + ebx -= eax; + eax = esi; + esi = ebx; + ebx = eax; + eax = 0; + memcpy((char*)edi, (char*)esi, ecx); + edi += ecx; + esi += ecx; + esi = ebx; + } + //edi poped off stack + esi = ebp; + esi += 0x9E3D28; + eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); + eax <<= 8; + edx = RCT2_GLOBAL(0x9ABDAE, uint16); + ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); + ebx = RCT2_GLOBAL(0xEDF81C, uint32); - RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); + sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); + //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); return; } From 5c927eb418c8e35c01109257d6d863855411d7aa Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 22 May 2014 17:51:15 +0100 Subject: [PATCH 044/209] Fixed small graphical glitch caused by too small a variable --- src/gfx.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d48159409c..a1f1b8c700 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -282,7 +282,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) * I think its only used for bitmaps onto buttons but i am not sure. * There is still a small bug with this code when it is in the choose park view. */ -void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, uint16 g1_y_start, uint16 g1_y_end, uint16 g1_x_start, uint16 g1_x_end){ +void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ //Image_id if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x20000000){ RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); @@ -308,7 +308,7 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi char* source_pointer = next_source_pointer; char* dest_pointer = next_dest_pointer; - sint8 no_pixels = *source_pointer++; + int no_pixels = *source_pointer++; uint8 gap_size = *source_pointer++; //The last bit in no_pixels tells you if you have reached the end of a line last_data_line = no_pixels & 0x80; @@ -362,7 +362,7 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi * I think its only used for bitmaps onto buttons but i am not sure. */ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y){ - uint16 g1_y_start, g1_x_start; + int g1_y_start, g1_x_start; char* bits_pointer; bits_pointer = dest_dpi->bits; @@ -426,16 +426,7 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, if (end_x <= 0)return; } - //Can be removed when i work out the bug in the second function and we don't need to - //test the old version. - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dest_dpi->width + dest_dpi->pitch; - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = end_x; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = end_y; - RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; - RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; - - sub_0x67AA18(source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); - //RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_g1->offset, (int)bits_pointer, (int)dest_dpi); + sub_0x67AA18((char*)source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); } /** From 5a5a5409a241876f3d74450ee3f17a0024a41099 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 22 May 2014 19:18:50 +0100 Subject: [PATCH 045/209] Started implementing next set of buffer functions. Cleaned up some comments and code paths --- src/gfx.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a1f1b8c700..a41bad8105 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -272,6 +272,31 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * buffers */ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp){ + if (ebx & 0x20000000){ + //0x67a7f7 + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + return; + } + if (ebx & 0x40000000){ + //0x67a786 + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + return; + } + + if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){ + //0x67a707 + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + return; + } + + int _ebx = RCT2_GLOBAL(0x9ABDA8, uint16); + if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){ + //0x67A722 + RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + return; + } + + int _ecx = ebx; RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); return; } @@ -285,11 +310,22 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ //Image_id if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x20000000){ + + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dpi->width + dpi->pitch; + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_x_end; + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_y_end; + RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; + RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); return; //0x67AAB3 } if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x40000000){ + RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dpi->width + dpi->pitch; + RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_x_end; + RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_y_end; + RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; + RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); return; //0x67AFD8 } @@ -555,13 +591,14 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx += RCT2_ADDRESS_G1_ELEMENTS; if (dpi->pad_0E >= 1){ if (dpi->pad_0E == 1){ + RCT2_CALLPROC_X(0x0067BD81, eax, ebx, x, y, 0, dpi, ebp); return; - //jump into 0x67bd81 } if (dpi->pad_0E >= 3){ - return;//jump into 0x67FAAE + RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, dpi, ebp); + return; } - //jump into 0x67DADA + RCT2_CALLPROC_X(0x0067DADA, eax, ebx, x, y, 0, dpi, ebp); return; } eax = *((uint32*)ebx + 2); @@ -575,12 +612,10 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps - //RCT2_CALLPROC_X(0x0067A934, eax, ebx, x, y, 0, dpi, ebp); sub_0x67A934(g1_source, dpi, x, y); return; } - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); - //return; + //dpi on stack int translated_x, translated_y; char* bits_pointer; From 8bc3ac03c4392463533e8337b4fffbcb5f6f4314 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 09:05:21 +0100 Subject: [PATCH 046/209] Added more buffer of the buffer function --- src/gfx.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a41bad8105..c56ef9e7fe 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -273,8 +273,67 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri */ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp){ if (ebx & 0x20000000){ - //0x67a7f7 - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + int _ecx = eax >> 8; + uint32 _ebx = RCT2_GLOBAL(0x9ABDA4, uint32); + _ecx--; + _ecx <<= 0x10; + + if (RCT2_GLOBAL(0x9E3CDC, uint32)){ + + RCT2_GLOBAL(0x9E3D04, uint32) = ebp; + uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); + _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); + + for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ + for (int _cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); _cx > 0; --_cx){ + uint8 al = *((char*)esi); + esi++; + al = *((char*)_ebx + al); + al &= *((char*)_ebp); + if (al){ + *((char*)edi) = al; + } + edi++; + _ebp++; + } + esi += edx; + edi += RCT2_GLOBAL(0x9E3D04, uint32); + _ebp += edx; + } + return; + } + + if ((RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16)) == 4){ + + ebp += 4; + edx += 4; + for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ + for (int i = 0; i < 4; ++i){ + uint8 al = *((char*)esi+i); + al = *((char*)_ebx + al); + if (al){ + *((char*)edi+i) = al; + } + } + edi += ebp; + esi += edx; + } + return; + } + + for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ + for (int _cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); _cx > 0; --_cx){ + uint8 al = *((char*)esi); + esi++; + al = *((char*)_ebx + al); + if (al){ + *((char*)edi) = al; + } + edi++; + } + esi += edx; + edi += ebp; + } return; } if (ebx & 0x40000000){ @@ -289,15 +348,26 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) return; } - int _ebx = RCT2_GLOBAL(0x9ABDA8, uint16); + int _ebx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){ //0x67A722 RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); return; } - int _ecx = ebx; - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + for (int ah = eax >> 8; ah > 0; --ah){ + int _ecx = _ebx; + for (; _ecx > 0; --_ecx){ + char al = *((char*)esi); + esi++; + if (al){ + *((char*)edi) = al; + } + edi++; + } + esi += edx; + edi += ebp; + } return; } @@ -591,14 +661,14 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx += RCT2_ADDRESS_G1_ELEMENTS; if (dpi->pad_0E >= 1){ if (dpi->pad_0E == 1){ - RCT2_CALLPROC_X(0x0067BD81, eax, ebx, x, y, 0, dpi, ebp); + RCT2_CALLPROC_X(0x0067BD81, eax, ebx, x, y, 0,(int) dpi, ebp); return; } if (dpi->pad_0E >= 3){ - RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, dpi, ebp); + RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, (int)dpi, ebp); return; } - RCT2_CALLPROC_X(0x0067DADA, eax, ebx, x, y, 0, dpi, ebp); + RCT2_CALLPROC_X(0x0067DADA, eax, ebx, x, y, 0, (int)dpi, ebp); return; } eax = *((uint32*)ebx + 2); From b144147400070df8bdb73ca5bfbe943d1ae0d322 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 09:45:18 +0100 Subject: [PATCH 047/209] Added last parts to main buffer function --- src/gfx.c | 85 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 21 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c56ef9e7fe..18c61cca64 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -271,15 +271,17 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * rct2: 0x67A690 very similar in function to 0x67AA18 readied images are copied onto * buffers */ -void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp){ - if (ebx & 0x20000000){ +void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, int image_type){ + + //Has a background image? + if (image_type & 0x2){ int _ecx = eax >> 8; uint32 _ebx = RCT2_GLOBAL(0x9ABDA4, uint32); _ecx--; _ecx <<= 0x10; + //Mix with background image and colour adjusted if (RCT2_GLOBAL(0x9E3CDC, uint32)){ - RCT2_GLOBAL(0x9E3D04, uint32) = ebp; uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); @@ -303,6 +305,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) return; } + //Quicker? if ((RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16)) == 4){ ebp += 4; @@ -321,6 +324,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) return; } + //image colour adjusted? for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ for (int _cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); _cx > 0; --_cx){ uint8 al = *((char*)esi); @@ -336,28 +340,65 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) } return; } - if (ebx & 0x40000000){ - //0x67a786 - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + + //image_type mix with background? + if (image_type & 0x4){ + int _ebx = RCT2_GLOBAL(0x9ABDA4, uint16); + for (int ah = eax >> 8; ah > 0; --ah){ + + for (int cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); cx > 0; --ecx){ + uint8 al = *((char*)esi); + esi++; + if (al){ + al = *((char*)edi); + al = *((char*)_ebx + al); + *((char*)edi) = al; + } + edi++; + } + esi += edx; + edi += ebp; + } return; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){ - //0x67a707 - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); + int bx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); + for (int ax = RCT2_GLOBAL(0x9ABDAC, uint16); ax > 0; --ax){ + memcpy((char*)edi, (char*)esi, bx); + edi += bx; + esi += bx; + edi += ebp; + esi += edx; + } return; } int _ebx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){ - //0x67A722 - RCT2_CALLPROC_X(0x67A690, eax, ebx, ecx, edx, esi, edi, ebp); - return; + RCT2_GLOBAL(0x9E3D04, uint32) = ebp; + uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); + _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); + + for (int ah = eax >> 8; ah > 0; --ah){ + for (int _ecx = _ebx; _ecx > 0; --_ecx){ + char al = *((char*)esi); + esi++; + al &= *((char*)_ebp); + if (al){ + *((char*)edi) = al; + } + edi++; + _ebp++; + } + esi += edx; + edi += RCT2_GLOBAL(0x9E3D04, uint32); + _ebp += edx; + } } for (int ah = eax >> 8; ah > 0; --ah){ - int _ecx = _ebx; - for (; _ecx > 0; --_ecx){ + for (int _ecx = _ebx; _ecx > 0; --_ecx){ char al = *((char*)esi); esi++; if (al){ @@ -377,9 +418,9 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) * I think its only used for bitmaps onto buttons but i am not sure. * There is still a small bug with this code when it is in the choose park view. */ -void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ +void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ //Image_id - if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x20000000){ + if (image_type & 0x2){ RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dpi->width + dpi->pitch; RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_x_end; @@ -390,7 +431,7 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi return; //0x67AAB3 } - if (RCT2_GLOBAL(0xEDF81C, uint32) & 0x40000000){ + if (image_type & 0x4){ RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dpi->width + dpi->pitch; RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_x_end; RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_y_end; @@ -467,7 +508,7 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi * This function readies all the global vars for copying the sprite data onto the screen * I think its only used for bitmaps onto buttons but i am not sure. */ -void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y){ +void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y, int image_type){ int g1_y_start, g1_x_start; char* bits_pointer; @@ -532,7 +573,7 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, if (end_x <= 0)return; } - sub_0x67AA18((char*)source_g1->offset, bits_pointer, dest_dpi, g1_y_start, end_y, g1_x_start, end_x); + sub_0x67AA18((char*)source_g1->offset, bits_pointer, dest_dpi, image_type, g1_y_start, end_y, g1_x_start, end_x); } /** @@ -548,6 +589,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //return; int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; + int image_type = (image_id & 0xE0000000) >> 28; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; @@ -607,6 +649,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //image_id RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000; + image_type |= 0x2; eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; @@ -682,7 +725,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ //Title screen bitmaps - sub_0x67A934(g1_source, dpi, x, y); + sub_0x67A934(g1_source, dpi, x, y, image_type); return; } @@ -767,7 +810,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 - sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); + sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); return; } //0x67A60A @@ -818,7 +861,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp); + sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); return; } From 9f3bdff3c987565fb3d4b57e3c3cfbe2235e87dc Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 10:22:31 +0100 Subject: [PATCH 048/209] Added alternitive image_types to 2nd buffer function --- src/gfx.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 18c61cca64..e9909897f4 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -419,28 +419,6 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, * There is still a small bug with this code when it is in the choose park view. */ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ - //Image_id - if (image_type & 0x2){ - - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dpi->width + dpi->pitch; - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_x_end; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_y_end; - RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; - RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); - return; //0x67AAB3 - } - - if (image_type & 0x4){ - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) = dpi->width + dpi->pitch; - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_x_end; - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_y_end; - RCT2_GLOBAL(RCT2_Y_START_POINT_GLOBAL, uint16) = g1_y_start; - RCT2_GLOBAL(RCT2_X_START_POINT_GLOBAL, uint16) = g1_x_start; - RCT2_CALLPROC_X_EBPSAFE(0x67AA18, 0, 0, 0, 0, (int)source_bits_pointer, (int)dest_bits_pointer, (int)dpi); - return; //0x67AFD8 - } - uint16 offset_to_first_line = *(uint16*)(g1_y_start*2 + (uint32)source_bits_pointer); //This will now point to the first line char* next_source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); @@ -495,7 +473,31 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi } //Finally after all those checks, copy the image onto the drawing surface - memcpy(dest_pointer, source_pointer, no_pixels); + //If the image type is not a basic one we require to mix the pixels + if (image_type & 0x2){ + for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ + uint8 al = *source_pointer; + uint8 ah = *dest_pointer; + if (image_type & 0x4)//Mix with background and image + al = *((uint8*)(((al | ((int)ah)<<8) - 0x100) + RCT2_GLOBAL(0x9ABDA4, uint32))); + else //Adjust colours? + al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); + *dest_pointer = al; + } + } + else if (image_type & 0x4){ + //Doesnt use source pointer ??? mix with background only? + for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ + uint8 al = *dest_pointer; + al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); + *dest_pointer = al; + } + } + else + { + memcpy(dest_pointer, source_pointer, no_pixels); + } + } //Add a line to the drawing surface pointer next_dest_pointer += (int)dpi->width + (int)dpi->pitch; From cd3db82343cc85acf647e74a215d8eac4de1536d Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 10:54:31 +0100 Subject: [PATCH 049/209] Added notes for what has been tested. --- src/gfx.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index e9909897f4..452f5afdfe 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -281,7 +281,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, _ecx <<= 0x10; //Mix with background image and colour adjusted - if (RCT2_GLOBAL(0x9E3CDC, uint32)){ + if (RCT2_GLOBAL(0x9E3CDC, uint32)){ //Not tested RCT2_GLOBAL(0x9E3D04, uint32) = ebp; uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); @@ -342,7 +342,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, } //image_type mix with background? - if (image_type & 0x4){ + if (image_type & 0x4){//Not tested int _ebx = RCT2_GLOBAL(0x9ABDA4, uint16); for (int ah = eax >> 8; ah > 0; --ah){ @@ -362,7 +362,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, return; } - if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){ + if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){//Not tested int bx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); for (int ax = RCT2_GLOBAL(0x9ABDAC, uint16); ax > 0; --ax){ memcpy((char*)edi, (char*)esi, bx); @@ -375,7 +375,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, } int _ebx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); - if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){ + if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested RCT2_GLOBAL(0x9E3D04, uint32) = ebp; uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); @@ -474,19 +474,20 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi //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 & 0x2){ + if (image_type & 0x2){//In the .exe these are all unraveled loops for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ uint8 al = *source_pointer; uint8 ah = *dest_pointer; - if (image_type & 0x4)//Mix with background and image + if (image_type & 0x4)//Mix with background and image Not Tested al = *((uint8*)(((al | ((int)ah)<<8) - 0x100) + RCT2_GLOBAL(0x9ABDA4, uint32))); else //Adjust colours? al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); *dest_pointer = al; } } - else if (image_type & 0x4){ + else if (image_type & 0x4){//In the .exe these are all unraveled loops //Doesnt use source pointer ??? mix with background only? + //Not Tested for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ uint8 al = *dest_pointer; al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); @@ -587,15 +588,13 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, */ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) { - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, dpi, 0); - //return; int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; int image_type = (image_id & 0xE0000000) >> 28; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; - //eax = RCT2_GLOBAL(0x009E3CE4 + eax*4, uint32); + RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { @@ -618,9 +617,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - //return;//jump into 0x67a361 - + //Has not been tested eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -667,8 +664,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if ((image_id)& 0xE0000000){ - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0,(int) dpi, 0); - //return; eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -704,16 +699,17 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx &= 0x7FFFF; ebx <<= 4; ebx += RCT2_ADDRESS_G1_ELEMENTS; - if (dpi->pad_0E >= 1){ + if (dpi->pad_0E >= 1){ //These have not been tested + //something to do with zooming if (dpi->pad_0E == 1){ RCT2_CALLPROC_X(0x0067BD81, eax, ebx, x, y, 0,(int) dpi, ebp); return; } - if (dpi->pad_0E >= 3){ - RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, (int)dpi, ebp); + if (dpi->pad_0E == 2){ + RCT2_CALLPROC_X(0x0067DADA, eax, ebx, x, y, 0, (int)dpi, ebp); return; } - RCT2_CALLPROC_X(0x0067DADA, eax, ebx, x, y, 0, (int)dpi, ebp); + RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, (int)dpi, ebp); return; } eax = *((uint32*)ebx + 2); From 503826e76294f3d6ec64d156bcfcad8aa19bbb50 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 12:08:20 +0100 Subject: [PATCH 050/209] Cleaned up comments added enums to make code easier to read --- src/gfx.c | 49 ++++++++++++++++++++++++------------------------- src/gfx.h | 11 +++++++++++ 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c979021e37..58192ed5bc 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -454,13 +454,14 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri #define RCT2_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 //uint16 width+pitch /* -* rct2: 0x67A690 very similar in function to 0x67AA18 readied images are copied onto -* buffers +* rct2: 0x67A690 +* copies a sprite onto the buffer. There is no compression used on the sprite +* image. */ -void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, int image_type){ +void gfx_bmp_sprite_to_buffer(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, int image_type){ //Has a background image? - if (image_type & 0x2){ + if (image_type & IMAGE_TYPE_USE_PALATE){ int _ecx = eax >> 8; uint32 _ebx = RCT2_GLOBAL(0x9ABDA4, uint32); _ecx--; @@ -528,7 +529,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, } //image_type mix with background? - if (image_type & 0x4){//Not tested + if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested int _ebx = RCT2_GLOBAL(0x9ABDA4, uint16); for (int ah = eax >> 8; ah > 0; --ah){ @@ -604,7 +605,7 @@ void sub_0x67A690(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, * I think its only used for bitmaps onto buttons but i am not sure. * There is still a small bug with this code when it is in the choose park view. */ -void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ +void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ uint16 offset_to_first_line = *(uint16*)(g1_y_start*2 + (uint32)source_bits_pointer); //This will now point to the first line char* next_source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); @@ -660,18 +661,18 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi //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 & 0x2){//In the .exe these are all unraveled loops + if (image_type & IMAGE_TYPE_USE_PALATE){//In the .exe these are all unraveled loops for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ uint8 al = *source_pointer; uint8 ah = *dest_pointer; - if (image_type & 0x4)//Mix with background and image Not Tested + if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested al = *((uint8*)(((al | ((int)ah)<<8) - 0x100) + RCT2_GLOBAL(0x9ABDA4, uint32))); else //Adjust colours? al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); *dest_pointer = al; } } - else if (image_type & 0x4){//In the .exe these are all unraveled loops + else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops //Doesnt use source pointer ??? mix with background only? //Not Tested for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ @@ -693,11 +694,11 @@ void sub_0x67AA18(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpi /* -* rct2: 0x67A934 title screen bitmaps on buttons -* This function readies all the global vars for copying the sprite data onto the screen -* I think its only used for bitmaps onto buttons but i am not sure. +* rct2: 0x67A934 +* Draws a run length encoded sprite +* This function readies all the vars for copying the sprite data onto the screen */ -void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y, int image_type){ +void gfx_draw_rle_sprite(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y, int image_type){ int g1_y_start, g1_x_start; char* bits_pointer; @@ -762,7 +763,7 @@ void sub_0x67A934(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, if (end_x <= 0)return; } - sub_0x67AA18((char*)source_g1->offset, bits_pointer, dest_dpi, image_type, g1_y_start, end_y, g1_x_start, end_x); + gfx_rle_sprite_to_buffer((char*)source_g1->offset, bits_pointer, dest_dpi, image_type, g1_y_start, end_y, g1_x_start, end_x); } /** @@ -783,9 +784,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); - if (((image_id)& 0xE0000000) && !(image_id & (1 << 31))) { + if (image_type && !(image_type & IMAGE_TYPE_UNKNOWN)) { - if (!((image_id)& 0x40000000)){ + if (!(image_type & (1 << 2))){ eax = image_id; eax >>= 19; eax &= 0xFF; @@ -802,7 +803,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABDA4, uint32) = eax; } - else if (((image_id)& 0xE0000000) && !(image_id & (1 << 29))){ + else if (image_type && !(image_type & IMAGE_TYPE_USE_PALATE)){ //Has not been tested eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -834,7 +835,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //image_id RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000; - image_type |= 0x2; + image_type |= IMAGE_TYPE_USE_PALATE; eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; @@ -849,7 +850,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) edx = y; } - else if ((image_id)& 0xE0000000){ + else if (image_type){ eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; eax >>= 19; @@ -907,9 +908,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); - if (RCT2_GLOBAL(0x9E3D14, uint32) & (1 << 2)){ - //Title screen bitmaps - sub_0x67A934(g1_source, dpi, x, y, image_type); + if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){ + gfx_draw_rle_sprite(g1_source, dpi, x, y, image_type); return; } @@ -994,7 +994,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 - sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); + gfx_bmp_sprite_to_buffer(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); return; } //0x67A60A @@ -1045,8 +1045,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - sub_0x67A690(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); - //RCT2_CALLPROC_X(0x0067A28E, 0, image_id, x, y, 0, (int)dpi, 0); + gfx_bmp_sprite_to_buffer(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); return; } diff --git a/src/gfx.h b/src/gfx.h index 162ccd121f..733c94d68a 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -46,6 +46,17 @@ typedef struct { sint16 unused; // 0x0E } rct_g1_element; +enum{ + G1_FLAG_RLE_COMPRESSION = (1<<2), +}; + +enum{ + IMAGE_TYPE_NO_BACKGROUND = (1<<0), + IMAGE_TYPE_USE_PALATE = (1<<1), + IMAGE_TYPE_MIX_BACKGROUND = (1<<2), + IMAGE_TYPE_UNKNOWN = (1<<3) +}; + extern int gLastDrawStringX; extern int gLastDrawStringY; From 296e014ac0d9d4b9a7d180f0547ba575970ca4c9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 13:03:26 +0100 Subject: [PATCH 051/209] Added palette pointer --- src/gfx.c | 40 ++++++++++++++++++++++------------------ src/gfx.h | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 58192ed5bc..33c0093892 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -458,12 +458,12 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * copies a sprite onto the buffer. There is no compression used on the sprite * image. */ -void gfx_bmp_sprite_to_buffer(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, int image_type){ +void gfx_bmp_sprite_to_buffer(char* palette_pointer, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, int image_type){ //Has a background image? - if (image_type & IMAGE_TYPE_USE_PALATE){ + if (image_type & IMAGE_TYPE_USE_PALETTE){ int _ecx = eax >> 8; - uint32 _ebx = RCT2_GLOBAL(0x9ABDA4, uint32); + uint32 _ebx = (uint32)palette_pointer; _ecx--; _ecx <<= 0x10; @@ -530,7 +530,7 @@ void gfx_bmp_sprite_to_buffer(int eax, int ebx, int ecx, int edx, int esi, int e //image_type mix with background? if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested - int _ebx = RCT2_GLOBAL(0x9ABDA4, uint16); + int _ebx = (uint32)palette_pointer; for (int ah = eax >> 8; ah > 0; --ah){ for (int cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); cx > 0; --ecx){ @@ -551,7 +551,7 @@ void gfx_bmp_sprite_to_buffer(int eax, int ebx, int ecx, int edx, int esi, int e if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){//Not tested int bx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); - for (int ax = RCT2_GLOBAL(0x9ABDAC, uint16); ax > 0; --ax){ + for (int ax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint16); ax > 0; --ax){ memcpy((char*)edi, (char*)esi, bx); edi += bx; esi += bx; @@ -605,7 +605,7 @@ void gfx_bmp_sprite_to_buffer(int eax, int ebx, int ecx, int edx, int esi, int e * I think its only used for bitmaps onto buttons but i am not sure. * There is still a small bug with this code when it is in the choose park view. */ -void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ +void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer, char* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ uint16 offset_to_first_line = *(uint16*)(g1_y_start*2 + (uint32)source_bits_pointer); //This will now point to the first line char* next_source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); @@ -661,14 +661,14 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer //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_USE_PALATE){//In the .exe these are all unraveled loops + if (image_type & IMAGE_TYPE_USE_PALETTE){//In the .exe these are all unraveled loops for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ uint8 al = *source_pointer; uint8 ah = *dest_pointer; if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested - al = *((uint8*)(((al | ((int)ah)<<8) - 0x100) + RCT2_GLOBAL(0x9ABDA4, uint32))); + al = palette_pointer[(al | ((int)ah) << 8) - 0x100]; else //Adjust colours? - al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); + al = palette_pointer[al]; *dest_pointer = al; } } @@ -677,7 +677,7 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer //Not Tested for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ uint8 al = *dest_pointer; - al = *((uint8*)(al + RCT2_GLOBAL(0x9ABDA4, uint32))); + al = palette_pointer[al]; *dest_pointer = al; } } @@ -698,7 +698,7 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer * Draws a run length encoded sprite * This function readies all the vars for copying the sprite data onto the screen */ -void gfx_draw_rle_sprite(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y, int image_type){ +void gfx_draw_rle_sprite(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y, int image_type, char* palette_pointer){ int g1_y_start, g1_x_start; char* bits_pointer; @@ -763,7 +763,7 @@ void gfx_draw_rle_sprite(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, if (end_x <= 0)return; } - gfx_rle_sprite_to_buffer((char*)source_g1->offset, bits_pointer, dest_dpi, image_type, g1_y_start, end_y, g1_x_start, end_x); + gfx_rle_sprite_to_buffer((char*)source_g1->offset, bits_pointer, palette_pointer, dest_dpi, image_type, g1_y_start, end_y, g1_x_start, end_x); } /** @@ -779,6 +779,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; int image_type = (image_id & 0xE0000000) >> 28; + char* palette_pointer = NULL; + RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; @@ -801,9 +803,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); RCT2_GLOBAL(0x9ABDA4, uint32) = eax; - + palette_pointer = (char*)eax; } - else if (image_type && !(image_type & IMAGE_TYPE_USE_PALATE)){ + else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ //Has not been tested eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -835,7 +837,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //image_id RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000; - image_type |= IMAGE_TYPE_USE_PALATE; + image_type |= IMAGE_TYPE_USE_PALETTE; eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; @@ -846,6 +848,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABFDA, uint32) = esi; edx = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x9ABF0C; + palette_pointer = (char*)0x9ABF0C; RCT2_GLOBAL(0x9ABFDE, uint32) = edx; edx = y; @@ -879,6 +882,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; + palette_pointer = (char*)0x9ABE0C; RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; } @@ -909,7 +913,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){ - gfx_draw_rle_sprite(g1_source, dpi, x, y, image_type); + gfx_draw_rle_sprite(g1_source, dpi, x, y, image_type, palette_pointer); return; } @@ -994,7 +998,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx = RCT2_GLOBAL(0xEDF81C, uint32); ecx = 0xFFFF&translated_x; //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 - gfx_bmp_sprite_to_buffer(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer,eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); return; } //0x67A60A @@ -1045,7 +1049,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - gfx_bmp_sprite_to_buffer(eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); return; } diff --git a/src/gfx.h b/src/gfx.h index 733c94d68a..51ceee10c8 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -52,7 +52,7 @@ enum{ enum{ IMAGE_TYPE_NO_BACKGROUND = (1<<0), - IMAGE_TYPE_USE_PALATE = (1<<1), + IMAGE_TYPE_USE_PALETTE= (1 << 1), IMAGE_TYPE_MIX_BACKGROUND = (1<<2), IMAGE_TYPE_UNKNOWN = (1<<3) }; From 0b20f94182bfb82361c09fee77b70908dcae8b98 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 23 May 2014 13:57:47 +0100 Subject: [PATCH 052/209] Added more readable variable names --- src/gfx.c | 112 +++++++++++++++++++++++++++--------------------------- src/gfx.h | 2 +- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 33c0093892..b58b433078 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -458,11 +458,11 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * copies a sprite onto the buffer. There is no compression used on the sprite * image. */ -void gfx_bmp_sprite_to_buffer(char* palette_pointer, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp, int image_type){ +void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* dest_pointer, int end_y, int end_x, int edx, int ebp, int image_type){ //Has a background image? if (image_type & IMAGE_TYPE_USE_PALETTE){ - int _ecx = eax >> 8; + int _ecx = end_y; uint32 _ebx = (uint32)palette_pointer; _ecx--; _ecx <<= 0x10; @@ -474,56 +474,56 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, int eax, int ebx, int ecx, _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ - for (int _cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); _cx > 0; --_cx){ - uint8 al = *((char*)esi); - esi++; + for (int _cx = end_x; _cx > 0; --_cx){ + uint8 al = *source_pointer; + source_pointer++; al = *((char*)_ebx + al); al &= *((char*)_ebp); if (al){ - *((char*)edi) = al; + *dest_pointer = al; } - edi++; + dest_pointer++; _ebp++; } - esi += edx; - edi += RCT2_GLOBAL(0x9E3D04, uint32); + source_pointer += edx; + dest_pointer += RCT2_GLOBAL(0x9E3D04, uint32); _ebp += edx; } return; } //Quicker? - if ((RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16)) == 4){ + if (end_x == 4){ ebp += 4; edx += 4; for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ for (int i = 0; i < 4; ++i){ - uint8 al = *((char*)esi+i); + uint8 al = *(source_pointer + i); al = *((char*)_ebx + al); if (al){ - *((char*)edi+i) = al; + *(dest_pointer + i) = al; } } - edi += ebp; - esi += edx; + dest_pointer += ebp; + source_pointer += edx; } return; } //image colour adjusted? for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ - for (int _cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); _cx > 0; --_cx){ - uint8 al = *((char*)esi); - esi++; + for (int _cx = end_x; _cx > 0; --_cx){ + uint8 al = *source_pointer; + source_pointer++; al = *((char*)_ebx + al); if (al){ - *((char*)edi) = al; + *dest_pointer = al; } - edi++; + dest_pointer++; } - esi += edx; - edi += ebp; + source_pointer += edx; + dest_pointer += ebp; } return; } @@ -531,70 +531,70 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, int eax, int ebx, int ecx, //image_type mix with background? if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested int _ebx = (uint32)palette_pointer; - for (int ah = eax >> 8; ah > 0; --ah){ + for (int ah = end_y; ah > 0; --ah){ - for (int cx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); cx > 0; --ecx){ - uint8 al = *((char*)esi); - esi++; + for (int cx = end_x; cx > 0; --cx){ + uint8 al = *source_pointer; + source_pointer++; if (al){ - al = *((char*)edi); + al = *dest_pointer; al = *((char*)_ebx + al); - *((char*)edi) = al; + *dest_pointer = al; } - edi++; + dest_pointer++; } - esi += edx; - edi += ebp; + source_pointer += edx; + dest_pointer += ebp; } return; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){//Not tested - int bx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); - for (int ax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint16); ax > 0; --ax){ - memcpy((char*)edi, (char*)esi, bx); - edi += bx; - esi += bx; - edi += ebp; - esi += edx; + int bx = end_x; + for (int ax = end_y; ax > 0; --ax){ + memcpy(dest_pointer, source_pointer, bx); + dest_pointer += bx; + source_pointer += bx; + dest_pointer += ebp; + source_pointer += edx; } return; } - int _ebx = RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, uint16); + int _ebx = end_x; if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested RCT2_GLOBAL(0x9E3D04, uint32) = ebp; uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); - for (int ah = eax >> 8; ah > 0; --ah){ + for (int ah = end_y; ah > 0; --ah){ for (int _ecx = _ebx; _ecx > 0; --_ecx){ - char al = *((char*)esi); - esi++; + char al = *source_pointer; + source_pointer++; al &= *((char*)_ebp); if (al){ - *((char*)edi) = al; + *dest_pointer = al; } - edi++; + dest_pointer++; _ebp++; } - esi += edx; - edi += RCT2_GLOBAL(0x9E3D04, uint32); + source_pointer += edx; + dest_pointer += RCT2_GLOBAL(0x9E3D04, uint32); _ebp += edx; } } - for (int ah = eax >> 8; ah > 0; --ah){ + for (int no_lines = end_y; no_lines > 0; --no_lines){ for (int _ecx = _ebx; _ecx > 0; --_ecx){ - char al = *((char*)esi); - esi++; + char al = *source_pointer; + source_pointer++; if (al){ - *((char*)edi) = al; + *dest_pointer = al; } - edi++; + dest_pointer++; } - esi += edx; - edi += ebp; + source_pointer += edx; + dest_pointer += ebp; } return; } @@ -992,13 +992,12 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (!(g1_source->flags & 0x02)){ eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); - eax <<= 8; edx = RCT2_GLOBAL(0x9ABDAE, uint16); ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - ecx = 0xFFFF&translated_x; + //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 - gfx_bmp_sprite_to_buffer(palette_pointer,eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), edx, ebp, image_type); return; } //0x67A60A @@ -1044,12 +1043,11 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) esi = ebp; esi += 0x9E3D28; eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); - eax <<= 8; edx = RCT2_GLOBAL(0x9ABDAE, uint16); ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - gfx_bmp_sprite_to_buffer(palette_pointer, eax, ebx, ecx, edx, esi, (int)bits_pointer, ebp, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), edx, ebp, image_type); return; } diff --git a/src/gfx.h b/src/gfx.h index 51ceee10c8..f748c02fc8 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -51,7 +51,7 @@ enum{ }; enum{ - IMAGE_TYPE_NO_BACKGROUND = (1<<0), + IMAGE_TYPE_NO_BACKGROUND = 0, IMAGE_TYPE_USE_PALETTE= (1 << 1), IMAGE_TYPE_MIX_BACKGROUND = (1<<2), IMAGE_TYPE_UNKNOWN = (1<<3) From 20d136bacfe82e51e4a1d54005d3cc74ebd16097 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 24 May 2014 10:53:34 +0100 Subject: [PATCH 053/209] Started to turn the buffer code into legable C --- src/gfx.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index b58b433078..052b09ca3d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -462,22 +462,17 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* //Has a background image? if (image_type & IMAGE_TYPE_USE_PALETTE){ - int _ecx = end_y; - uint32 _ebx = (uint32)palette_pointer; - _ecx--; - _ecx <<= 0x10; - //Mix with background image and colour adjusted if (RCT2_GLOBAL(0x9E3CDC, uint32)){ //Not tested RCT2_GLOBAL(0x9E3D04, uint32) = ebp; uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); - for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ + for (; end_y > 0; --end_y){ for (int _cx = end_x; _cx > 0; --_cx){ uint8 al = *source_pointer; source_pointer++; - al = *((char*)_ebx + al); + al = palette_pointer[al]; al &= *((char*)_ebp); if (al){ *dest_pointer = al; @@ -497,10 +492,10 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* ebp += 4; edx += 4; - for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ + for (; end_y > 0; --end_y){ for (int i = 0; i < 4; ++i){ uint8 al = *(source_pointer + i); - al = *((char*)_ebx + al); + al = palette_pointer[al]; if (al){ *(dest_pointer + i) = al; } @@ -512,11 +507,11 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* } //image colour adjusted? - for (_ecx >>= 0x10; _ecx >= 0; --_ecx){ + for (; end_y > 0; --end_y){ for (int _cx = end_x; _cx > 0; --_cx){ uint8 al = *source_pointer; source_pointer++; - al = *((char*)_ebx + al); + al = palette_pointer[al]; if (al){ *dest_pointer = al; } @@ -788,7 +783,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (image_type && !(image_type & IMAGE_TYPE_UNKNOWN)) { - if (!(image_type & (1 << 2))){ + if (!(image_type & IMAGE_TYPE_MIX_BACKGROUND)){ eax = image_id; eax >>= 19; eax &= 0xFF; @@ -996,7 +991,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); ebx = RCT2_GLOBAL(0xEDF81C, uint32); - //ebx, edx, esi, edi, ah, ebp used in 0x67a690 eax=1966, ecx=ff39, edx=ebx=0, esp = cfca4, ebp = 266, esi =368823e, edi = 16c79b2 gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), edx, ebp, image_type); return; } From b3ced1eedc9b27bdf8480a22416e8c152178d13a Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 24 May 2014 14:41:33 +0100 Subject: [PATCH 054/209] more C cleanup --- src/gfx.c | 127 +++++++++++++++++++++++++----------------------------- 1 file changed, 59 insertions(+), 68 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 052b09ca3d..459fc31379 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -458,67 +458,65 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * copies a sprite onto the buffer. There is no compression used on the sprite * image. */ -void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* dest_pointer, int end_y, int end_x, int edx, int ebp, int image_type){ +void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ //Has a background image? if (image_type & IMAGE_TYPE_USE_PALETTE){ //Mix with background image and colour adjusted if (RCT2_GLOBAL(0x9E3CDC, uint32)){ //Not tested - RCT2_GLOBAL(0x9E3D04, uint32) = ebp; + uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); - for (; end_y > 0; --end_y){ - for (int _cx = end_x; _cx > 0; --_cx){ - uint8 al = *source_pointer; + for (; height > 0; --height){ + for (int no_pixels = width; no_pixels > 0; --no_pixels){ + uint8 pixel = *source_pointer; source_pointer++; - al = palette_pointer[al]; - al &= *((char*)_ebp); - if (al){ - *dest_pointer = al; + pixel = palette_pointer[pixel]; + pixel &= *((char*)_ebp); + if (pixel){ + *dest_pointer = pixel; } dest_pointer++; _ebp++; } - source_pointer += edx; - dest_pointer += RCT2_GLOBAL(0x9E3D04, uint32); - _ebp += edx; + source_pointer += source_image->width - width; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width; + _ebp += source_image->width - width; } return; } //Quicker? - if (end_x == 4){ + if (width == 4){ - ebp += 4; - edx += 4; - for (; end_y > 0; --end_y){ - for (int i = 0; i < 4; ++i){ - uint8 al = *(source_pointer + i); - al = palette_pointer[al]; - if (al){ - *(dest_pointer + i) = al; + for (; height > 0; --height){ + for (int no_pixels = 0; no_pixels < 4; ++no_pixels){ + uint8 pixel = source_pointer[no_pixels]; + pixel = palette_pointer[pixel]; + if (pixel){ + dest_pointer[no_pixels] = pixel; } } - dest_pointer += ebp; - source_pointer += edx; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width + 4; + source_pointer += source_image->width - width + 4; } return; } //image colour adjusted? - for (; end_y > 0; --end_y){ - for (int _cx = end_x; _cx > 0; --_cx){ - uint8 al = *source_pointer; + for (; height > 0; --height){ + for (int no_pixels = width; no_pixels > 0; --no_pixels){ + uint8 pixel = *source_pointer; source_pointer++; - al = palette_pointer[al]; - if (al){ - *dest_pointer = al; + pixel = palette_pointer[pixel]; + if (pixel){ + *dest_pointer = pixel; } dest_pointer++; } - source_pointer += edx; - dest_pointer += ebp; + source_pointer += source_image->width - width; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width; } return; } @@ -526,9 +524,10 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* //image_type mix with background? if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested int _ebx = (uint32)palette_pointer; - for (int ah = end_y; ah > 0; --ah){ + for (int ah = height; ah > 0; --ah){ - for (int cx = end_x; cx > 0; --cx){ + for (int no_pixels = width; no_pixels > 0; --no_pixels){ + //Check this uint8 al = *source_pointer; source_pointer++; if (al){ @@ -538,58 +537,57 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* } dest_pointer++; } - source_pointer += edx; - dest_pointer += ebp; + source_pointer += source_image->width - width; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width; } return; } if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){//Not tested - int bx = end_x; - for (int ax = end_y; ax > 0; --ax){ + int bx = width; + for (int ax = height; ax > 0; --ax){ memcpy(dest_pointer, source_pointer, bx); dest_pointer += bx; source_pointer += bx; - dest_pointer += ebp; - source_pointer += edx; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width; + source_pointer += source_image->width - width; } return; } - int _ebx = end_x; + int _ebx = width; if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested - RCT2_GLOBAL(0x9E3D04, uint32) = ebp; uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); - for (int ah = end_y; ah > 0; --ah){ + for (int ah = height; ah > 0; --ah){ for (int _ecx = _ebx; _ecx > 0; --_ecx){ - char al = *source_pointer; + char pixel = *source_pointer; source_pointer++; - al &= *((char*)_ebp); - if (al){ - *dest_pointer = al; + pixel &= *((char*)_ebp); + if (pixel){ + *dest_pointer = pixel; } dest_pointer++; _ebp++; } - source_pointer += edx; - dest_pointer += RCT2_GLOBAL(0x9E3D04, uint32); - _ebp += edx; + source_pointer += source_image->width - width; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width; + _ebp += source_image->width - width; } } - for (int no_lines = end_y; no_lines > 0; --no_lines){ + for (int no_lines = height; no_lines > 0; --no_lines){ for (int _ecx = _ebx; _ecx > 0; --_ecx){ - char al = *source_pointer; + char pixel = *source_pointer; source_pointer++; - if (al){ - *dest_pointer = al; + if (pixel){ + *dest_pointer = pixel; } dest_pointer++; } - source_pointer += edx; - dest_pointer += ebp; + source_pointer += source_image->width - width; + dest_pointer += dest_dpi->width + dest_dpi->pitch - width; } return; } @@ -671,9 +669,9 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer //Doesnt use source pointer ??? mix with background only? //Not Tested for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ - uint8 al = *dest_pointer; - al = palette_pointer[al]; - *dest_pointer = al; + uint8 pixel = *dest_pointer; + pixel = palette_pointer[pixel]; + *dest_pointer = pixel; } } else @@ -987,11 +985,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (!(g1_source->flags & 0x02)){ eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); - edx = RCT2_GLOBAL(0x9ABDAE, uint16); - ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); - ebx = RCT2_GLOBAL(0xEDF81C, uint32); - - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), edx, ebp, image_type); + + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), image_type); return; } //0x67A60A @@ -1037,11 +1032,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) esi = ebp; esi += 0x9E3D28; eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); - edx = RCT2_GLOBAL(0x9ABDAE, uint16); - ebp = RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16); - ebx = RCT2_GLOBAL(0xEDF81C, uint32); - - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), edx, ebp, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), image_type); return; } From 08dcee5d92aae05701cea8f9c2f2fe2b1f39c58c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 24 May 2014 18:35:33 +0100 Subject: [PATCH 055/209] Translated more into C --- src/gfx.c | 97 ++++++++++++++++++++++++------------------------------- src/gfx.h | 1 + 2 files changed, 43 insertions(+), 55 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 459fc31379..a2de032087 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -459,14 +459,14 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * image. */ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ - - //Has a background image? + //Requires use of palette? if (image_type & IMAGE_TYPE_USE_PALETTE){ - //Mix with background image and colour adjusted - if (RCT2_GLOBAL(0x9E3CDC, uint32)){ //Not tested + + //Mix with another image?? and colour adjusted + if (RCT2_GLOBAL(0x9E3CDC, uint32)){ //Not tested. I can't actually work out when this code runs. uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); - _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); + _ebp += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32); for (; height > 0; --height){ for (int no_pixels = width; no_pixels > 0; --no_pixels){ @@ -521,19 +521,17 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* return; } - //image_type mix with background? + //Mix with background. It only uses source pointer for + //telling if it needs to be drawn not for colour. if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested - int _ebx = (uint32)palette_pointer; - for (int ah = height; ah > 0; --ah){ - + for (; height > 0; --height){ for (int no_pixels = width; no_pixels > 0; --no_pixels){ - //Check this - uint8 al = *source_pointer; + uint8 pixel = *source_pointer; source_pointer++; - if (al){ - al = *dest_pointer; - al = *((char*)_ebx + al); - *dest_pointer = al; + if (pixel){ + pixel = *dest_pointer; + pixel = palette_pointer[pixel]; + *dest_pointer = pixel; } dest_pointer++; } @@ -543,26 +541,23 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* return; } - if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 1)){//Not tested - int bx = width; - for (int ax = height; ax > 0; --ax){ - memcpy(dest_pointer, source_pointer, bx); - dest_pointer += bx; - source_pointer += bx; - dest_pointer += dest_dpi->width + dest_dpi->pitch - width; - source_pointer += source_image->width - width; + //Basic bitmap no fancy stuff + if (!(source_image->flags & G1_FLAG_BMP)){//Not tested + for (; height > 0; --height){ + memcpy(dest_pointer, source_pointer, width); + dest_pointer += dest_dpi->width + dest_dpi->pitch; + source_pointer += source_image->width; } return; } - int _ebx = width; - if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested + if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested. I can't actually work out when this code runs. uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); - _ebp += RCT2_GLOBAL(0x9E3CE0, uint32); + _ebp += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32); - for (int ah = height; ah > 0; --ah){ - for (int _ecx = _ebx; _ecx > 0; --_ecx){ - char pixel = *source_pointer; + for (; height > 0; --height){ + for (int no_pixels = width; no_pixels > 0; --no_pixels){ + uint8 pixel = *source_pointer; source_pointer++; pixel &= *((char*)_ebp); if (pixel){ @@ -577,9 +572,10 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* } } + //Basic bitmap with no draw pixels for (int no_lines = height; no_lines > 0; --no_lines){ - for (int _ecx = _ebx; _ecx > 0; --_ecx){ - char pixel = *source_pointer; + for (int no_pixels = width; no_pixels > 0; --no_pixels){ + uint8 pixel = *source_pointer; source_pointer++; if (pixel){ *dest_pointer = pixel; @@ -918,18 +914,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) esi = (int)g1_source->offset;//RCT2_GLOBAL(0x9E3D08, uint32); RCT2_GLOBAL(0x9E3CE0, uint32) = 0; bits_pointer = dpi->bits; - - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) = g1_source->height;// RCT2_GLOBAL(0x9E3D0E, sint16); + int height = g1_source->height; translated_y = y - dpi->y + g1_source->y_offset;//RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); - if (image_id == 5200){ - image_id = image_id; - } - if (translated_y < 0){ - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) += translated_y; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0){ + height += translated_y; + if (height <= 0){ return; } translated_y = -translated_y; @@ -944,21 +935,20 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height; if (translated_y > 0){ - RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) -= translated_y; - if (RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) <= 0)return; + height -= translated_y; + if (height <= 0)return; } - - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) = g1_source->width;// RCT2_GLOBAL(0x9E3D0C, sint16); + + int width = g1_source->width; eax = dpi->width + dpi->pitch - g1_source->width; //RCT2_GLOBAL(0x9E3D0C, sint16); RCT2_GLOBAL(0x9ABDAE, uint16) = 0; RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - g1_source->width;// RCT2_GLOBAL(0x9E3D0C, sint16); translated_x = x - dpi->x + g1_source->x_offset;//RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16); - + if (translated_x < 0){ - - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) += translated_x; - if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0){ + width += translated_x; + if (width <= 0){ return; } @@ -970,23 +960,21 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } bits_pointer += translated_x; - translated_x += RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16); + translated_x += width; translated_x -= dpi->width; if (translated_x > 0){ - RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) -= translated_x; - if (RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16) <= 0)return; + width -= translated_x; + if (width <= 0)return; RCT2_GLOBAL(0x9ABDAE, uint16) += translated_x; RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) += translated_x; } if (!(g1_source->flags & 0x02)){ - eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); - - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, height, width, image_type); return; } //0x67A60A @@ -1031,8 +1019,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //edi poped off stack esi = ebp; esi += 0x9E3D28; - eax = RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, uint8); - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, eax, RCT2_GLOBAL(RCT2_X_END_POINT_GLOBAL, sint16), image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, height, width, image_type); return; } diff --git a/src/gfx.h b/src/gfx.h index f748c02fc8..054fd31a94 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -47,6 +47,7 @@ typedef struct { } rct_g1_element; enum{ + G1_FLAG_BMP = (1 << 0), //No invisible sections G1_FLAG_RLE_COMPRESSION = (1<<2), }; From fdca2fb275ee4b4c4d762c0e73b953094f03d86f Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 24 May 2014 20:18:48 +0100 Subject: [PATCH 056/209] Even more c clean up --- src/gfx.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a2de032087..dafddd9546 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -906,17 +906,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } - //dpi on stack int translated_x, translated_y; - char* bits_pointer; + char* dest_pointer; + char* source_pointer; - ebp = (int)dpi; - esi = (int)g1_source->offset;//RCT2_GLOBAL(0x9E3D08, uint32); - RCT2_GLOBAL(0x9E3CE0, uint32) = 0; - bits_pointer = dpi->bits; + source_pointer = g1_source->offset; + + dest_pointer = dpi->bits; int height = g1_source->height; - translated_y = y - dpi->y + g1_source->y_offset;//RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_1, uint16); + translated_y = y - dpi->y + g1_source->y_offset; if (translated_y < 0){ height += translated_y; @@ -924,15 +923,14 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } translated_y = -translated_y; - esi += (uint32)translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); - RCT2_GLOBAL(0x9E3CE0, sint32) += translated_y * g1_source->width;//RCT2_GLOBAL(0x9E3D0C, sint16); + source_pointer += (uint32)translated_y * g1_source->width; + translated_y = 0; } else { - //eax = ; - bits_pointer += (dpi->width + dpi->pitch) * translated_y;//eax; + dest_pointer += (dpi->width + dpi->pitch) * translated_y; } - translated_y += RCT2_GLOBAL(RCT2_Y_END_POINT_GLOBAL, sint16) - dpi->height; + translated_y += height - dpi->height; if (translated_y > 0){ height -= translated_y; @@ -940,26 +938,19 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } int width = g1_source->width; - eax = dpi->width + dpi->pitch - g1_source->width; //RCT2_GLOBAL(0x9E3D0C, sint16); - RCT2_GLOBAL(0x9ABDAE, uint16) = 0; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) = dpi->width + dpi->pitch - g1_source->width;// RCT2_GLOBAL(0x9E3D0C, sint16); - translated_x = x - dpi->x + g1_source->x_offset;//RCT2_GLOBAL(RCT2_X_RELATED_GLOBAL_1, uint16); + translated_x = x - dpi->x + g1_source->x_offset; if (translated_x < 0){ width += translated_x; if (width <= 0){ return; } - - RCT2_GLOBAL(0x9ABDAE, sint16) -= translated_x; - esi -= translated_x; - RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, sint16) -= translated_x; + source_pointer -= translated_x; translated_x = 0; } - bits_pointer += translated_x; + dest_pointer += translated_x; translated_x += width; @@ -968,19 +959,16 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) if (translated_x > 0){ width -= translated_x; if (width <= 0)return; - - RCT2_GLOBAL(0x9ABDAE, uint16) += translated_x; - RCT2_GLOBAL(RCT2_DPI_LINE_LENGTH_GLOBAL, uint16) += translated_x; } if (!(g1_source->flags & 0x02)){ - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, height, width, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); return; } //0x67A60A esi -= (uint32)g1_source->offset; - ebp = esi; + ebp = (int)source_pointer; eax = g1_source->width*g1_source->height; esi = (int)g1_source->offset; edx = eax; @@ -1019,7 +1007,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //edi poped off stack esi = ebp; esi += 0x9E3D28; - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, bits_pointer, g1_source, dpi, height, width, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, dest_pointer, g1_source, dpi, height, width, image_type); return; } From af33568f015c9d43fa29e63949ad8eac881c6700 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 25 May 2014 09:30:54 +0100 Subject: [PATCH 057/209] Cleaned up functions brought two identical ones together --- src/gfx.c | 189 +++++++++++++++--------------------------------------- 1 file changed, 52 insertions(+), 137 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index dafddd9546..f64d9299fa 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -458,7 +458,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * copies a sprite onto the buffer. There is no compression used on the sprite * image. */ -void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ +void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ //Requires use of palette? if (image_type & IMAGE_TYPE_USE_PALETTE){ @@ -473,7 +473,7 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* uint8 pixel = *source_pointer; source_pointer++; pixel = palette_pointer[pixel]; - pixel &= *((char*)_ebp); + pixel &= *((uint8*)_ebp); if (pixel){ *dest_pointer = pixel; } @@ -594,22 +594,24 @@ void gfx_bmp_sprite_to_buffer(char* palette_pointer, char* source_pointer, char* * I think its only used for bitmaps onto buttons but i am not sure. * There is still a small bug with this code when it is in the choose park view. */ -void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer, char* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int g1_y_start, int g1_y_end, int g1_x_start, int g1_x_end){ - uint16 offset_to_first_line = *(uint16*)(g1_y_start*2 + (uint32)source_bits_pointer); +void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){ + uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start]; //This will now point to the first line - char* next_source_pointer = (char*)((uint32)source_bits_pointer + offset_to_first_line); - char* next_dest_pointer = dest_bits_pointer; + uint8* next_source_pointer = source_bits_pointer + offset_to_first_line; + uint8* next_dest_pointer = dest_bits_pointer; //For every line in the image - for (; g1_y_end; g1_y_end--){ + for (; height; height--){ uint8 last_data_line = 0; //For every data section in the line while (!last_data_line){ - char* source_pointer = next_source_pointer; - char* dest_pointer = next_dest_pointer; + uint8* source_pointer = next_source_pointer; + uint8* dest_pointer = next_dest_pointer; int no_pixels = *source_pointer++; + //gap_size is the number of non drawn pixels you require to + //jump over on your destination uint8 gap_size = *source_pointer++; //The last bit in no_pixels tells you if you have reached the end of a line last_data_line = no_pixels & 0x80; @@ -619,7 +621,7 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer next_source_pointer = source_pointer + no_pixels; //Calculates the start point of the image - int x_start = gap_size - g1_x_start; + int x_start = gap_size - source_x_start; if (x_start > 0){ //Since the start is positive @@ -641,9 +643,9 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer int x_end = x_start + no_pixels; //If the end position is further out than the whole image //end position then we need to shorten the line again - if (x_end > (int)g1_x_end){ + if (x_end > width){ //Shorten the line - no_pixels -= x_end - g1_x_end; + no_pixels -= x_end - width; //If there are no pixels there is nothing to draw. if (no_pixels <= 0) continue; } @@ -682,79 +684,6 @@ void gfx_rle_sprite_to_buffer(char* source_bits_pointer, char* dest_bits_pointer } -/* -* rct2: 0x67A934 -* Draws a run length encoded sprite -* This function readies all the vars for copying the sprite data onto the screen -*/ -void gfx_draw_rle_sprite(rct_g1_element *source_g1, rct_drawpixelinfo *dest_dpi, int x, int y, int image_type, char* palette_pointer){ - int g1_y_start, g1_x_start; - char* bits_pointer; - - bits_pointer = dest_dpi->bits; - g1_y_start = 0; - - int start_y, end_y; - start_y = y + source_g1->y_offset - dest_dpi->y; - - //If the start position is negative reset to zero - if (start_y < 0){ - //Create the end point within the drawing area - end_y = source_g1->height + start_y; - //If the end point is now <= 0 no need to draw - if (end_y <= 0)return; - - g1_y_start -= start_y; - start_y = 0; - } - else{ - end_y = source_g1->height; - //Move the pointer to the correct starting y location - bits_pointer += (dest_dpi->width + dest_dpi->pitch)*start_y; - } - - int height = start_y + end_y; - //If the image is taller than the drawing area - if (height > dest_dpi->height){ - //Make the end within the drawing area - end_y -= height - dest_dpi->height; - //If the end is now <=0 then there is nothing to draw - if (end_y <= 0)return; - } - - - int start_x, end_x; - g1_x_start = 0; - start_x = x + source_g1->x_offset - dest_dpi->x; - - //If the start position is negative reset to zero - if (start_x < 0){ - //Create the end point within the drawing area - end_x = source_g1->width + start_x; - //If the end point is now <= 0 no need to draw - if (end_x <= 0)return; - - g1_x_start -= start_x; - start_x = 0; - } - else{ - end_x = source_g1->width; - //Increment the pointer to our start location - bits_pointer += start_x; - } - - int width = start_x + end_x; - //If the image is wider than the drawing area - if (width > dest_dpi->width){ - //Make the end within drawing area - end_x -= width - dest_dpi->width; - //If the end is now <=0 then there is nothing to draw - if (end_x <= 0)return; - } - - gfx_rle_sprite_to_buffer((char*)source_g1->offset, bits_pointer, palette_pointer, dest_dpi, image_type, g1_y_start, end_y, g1_x_start, end_x); -} - /** * * rct2: 0x0067A28E @@ -768,7 +697,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; int image_type = (image_id & 0xE0000000) >> 28; - char* palette_pointer = NULL; + uint8* palette_pointer = NULL; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; @@ -792,7 +721,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); RCT2_GLOBAL(0x9ABDA4, uint32) = eax; - palette_pointer = (char*)eax; + palette_pointer = (uint8*)eax; } else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ //Has not been tested @@ -837,7 +766,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABFDA, uint32) = esi; edx = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x9ABF0C; - palette_pointer = (char*)0x9ABF0C; + palette_pointer = (uint8*)0x9ABF0C; RCT2_GLOBAL(0x9ABFDE, uint32) = edx; edx = y; @@ -871,12 +800,15 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebp = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; - palette_pointer = (char*)0x9ABE0C; + palette_pointer = (uint8*)0x9ABE0C; RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; } ebx &= 0x7FFFF; + + rct_g1_element* g1_source = &((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[ebx]; + ebx <<= 4; ebx += RCT2_ADDRESS_G1_ELEMENTS; if (dpi->pad_0E >= 1){ //These have not been tested @@ -892,75 +824,58 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, (int)dpi, ebp); return; } - eax = *((uint32*)ebx + 2); - ebp = *((uint32*)ebx + 3); - rct_g1_element* g1_source = (rct_g1_element*)ebx; - //This is a rct2_drawpixelinfo struct - RCT2_GLOBAL(0x9E3D08, uint32) = *((uint32*)ebx); //offset to g1 bits? - RCT2_GLOBAL(0x9E3D0C, uint32) = *((uint32*)ebx + 1); - RCT2_GLOBAL(0x9E3D10, uint32) = *((uint32*)ebx + 2); //X-Y related unsigned? sets RCT2_X_RELATED_GLOBAL_1 and Y - RCT2_GLOBAL(0x9E3D14, uint32) = *((uint32*)ebx + 3); - if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){ - gfx_draw_rle_sprite(g1_source, dpi, x, y, image_type, palette_pointer); - return; - } - - int translated_x, translated_y; - char* dest_pointer; - char* source_pointer; - - source_pointer = g1_source->offset; - - dest_pointer = dpi->bits; int height = g1_source->height; + int dest_start_y = y - dpi->y + g1_source->y_offset; + int source_start_y = 0; - translated_y = y - dpi->y + g1_source->y_offset; - - if (translated_y < 0){ - height += translated_y; + if (dest_start_y < 0){ + height += dest_start_y; if (height <= 0){ return; } - translated_y = -translated_y; - source_pointer += (uint32)translated_y * g1_source->width; - - translated_y = 0; - } else { - dest_pointer += (dpi->width + dpi->pitch) * translated_y; + source_start_y -= dest_start_y; + dest_start_y = 0; } - translated_y += height - dpi->height; + int dest_end_y = dest_start_y + height; - if (translated_y > 0){ - height -= translated_y; + if (dest_end_y > dpi->height){ + height -= dest_end_y - dpi->height; if (height <= 0)return; } int width = g1_source->width; - - translated_x = x - dpi->x + g1_source->x_offset; + int source_start_x = 0; + int dest_start_x = x - dpi->x + g1_source->x_offset; - if (translated_x < 0){ - width += translated_x; + if (dest_start_x < 0){ + width += dest_start_x; if (width <= 0){ return; } - source_pointer -= translated_x; - translated_x = 0; + source_start_x -= dest_start_x; + dest_start_x = 0; } - dest_pointer += translated_x; - translated_x += width; - + int end_x = dest_start_x + width; - translated_x -= dpi->width; - - if (translated_x > 0){ - width -= translated_x; + if (end_x > dpi->width){ + width -= end_x - dpi->width; if (width <= 0)return; } - + + uint8* dest_pointer = (uint8*)dpi->bits; + dest_pointer += (dpi->width + dpi->pitch)*dest_start_y + dest_start_x; + + if (g1_source->flags & G1_FLAG_RLE_COMPRESSION){ + gfx_rle_sprite_to_buffer(g1_source->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width); + return; + } + + uint8* source_pointer = g1_source->offset; + source_pointer += g1_source->width*source_start_y + source_start_x; + if (!(g1_source->flags & 0x02)){ gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); return; @@ -1007,7 +922,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //edi poped off stack esi = ebp; esi += 0x9E3D28; - gfx_bmp_sprite_to_buffer(palette_pointer, (char*)esi, dest_pointer, g1_source, dpi, height, width, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, (uint8*)esi, dest_pointer, g1_source, dpi, height, width, image_type); return; } From 775ce9e83d2a41213918bef65fa06d18136ac314 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 25 May 2014 09:42:29 +0100 Subject: [PATCH 058/209] Added comments to code --- src/gfx.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index f64d9299fa..7aeda6e007 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -553,7 +553,7 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* source_pointer, uin if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested. I can't actually work out when this code runs. uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); - _ebp += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32); + _ebp += source_pointer - source_image->offset; for (; height > 0; --height){ for (int no_pixels = width; no_pixels > 0; --no_pixels){ @@ -825,55 +825,83 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } + //This will be the height of the drawn image int height = g1_source->height; + //This is the start y coordinate on the destination int dest_start_y = y - dpi->y + g1_source->y_offset; + //This is the start y coordinate on the source int source_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){ return; } + //The source image will start a further up the image source_start_y -= dest_start_y; + //The destination start is now reset to 0 dest_start_y = 0; } int dest_end_y = dest_start_y + 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; } + //This will be the width of the drawn image int width = g1_source->width; + //This is the source start x coordinate int source_start_x = 0; + //This is the destination start x coordinate int dest_start_x = x - dpi->x + g1_source->x_offset; 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){ return; } + //The source start will also need to cut off the side source_start_x -= dest_start_x; + //Reset the destination to 0 dest_start_x = 0; } - int end_x = dest_start_x + width; + int dest_end_x = dest_start_x + width; - if (end_x > dpi->width){ - width -= 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; } + uint8* dest_pointer = (uint8*)dpi->bits; + //Move the pointer to the start point of the destination dest_pointer += (dpi->width + dpi->pitch)*dest_start_y + dest_start_x; if (g1_source->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_source->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width); return; } uint8* source_pointer = g1_source->offset; + //Move the pointer to the start point of the source source_pointer += g1_source->width*source_start_y + source_start_x; if (!(g1_source->flags & 0x02)){ From 2a77380bcbadbeaca5f425e46d78e94207db943e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 25 May 2014 11:41:57 +0100 Subject: [PATCH 059/209] Messing about --- src/gfx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 7aeda6e007..9f430b0cf2 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -696,7 +696,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) int eax = 0, ebx = image_id, ecx = x, edx = y, esi = 0, edi = (int)dpi, ebp = 0; int image_type = (image_id & 0xE0000000) >> 28; - + int image_sub_type = (image_id & 0x1C000000) >> 26; uint8* palette_pointer = NULL; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; @@ -718,10 +718,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax &= 0x7F; } eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); + //To be fixed + palette_pointer = ((rct_g1_element**)RCT2_ADDRESS_G1_ELEMENTS)[eax]; eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); RCT2_GLOBAL(0x9ABDA4, uint32) = eax; - palette_pointer = (uint8*)eax; + palette_pointer = eax; + assert(eax == palette_pointer); } else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ //Has not been tested From 275f66d2877a23da45069f986f783020ad919f2d Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 25 May 2014 18:40:11 +0100 Subject: [PATCH 060/209] add vehicle_update_all --- projects/openrct2.vcxproj | 4 ++- projects/openrct2.vcxproj.filters | 8 ++++- src/game.c | 3 +- src/news_item.c | 12 +++---- src/park.c | 1 + src/sprite.h | 13 ++----- src/vehicle.c | 59 +++++++++++++++++++++++++++++++ src/vehicle.h | 40 +++++++++++++++++++++ 8 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 src/vehicle.c create mode 100644 src/vehicle.h diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index fef57276cd..62c7dfb183 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -46,6 +46,7 @@ + @@ -85,6 +86,7 @@ + @@ -199,4 +201,4 @@ - + \ No newline at end of file diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index f6568613c3..1635ec4952 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -132,6 +132,9 @@ Header Files + + Header Files + @@ -314,10 +317,13 @@ Source Files + + Source Files + Resource Files - + \ No newline at end of file diff --git a/src/game.c b/src/game.c index 2c0475910d..7969dca5a4 100644 --- a/src/game.c +++ b/src/game.c @@ -35,6 +35,7 @@ #include "string_ids.h" #include "title.h" #include "tutorial.h" +#include "vehicle.h" #include "viewport.h" #include "widget.h" #include "window.h" @@ -149,7 +150,7 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x006646E1); RCT2_CALLPROC_EBPSAFE(0x006A876D); peep_update_all(); - RCT2_CALLPROC_EBPSAFE(0x006D4204); // update vehicles + vehicle_update_all(); RCT2_CALLPROC_EBPSAFE(0x00672AA4); // update text effects RCT2_CALLPROC_EBPSAFE(0x006ABE4C); // update rides park_update(); diff --git a/src/news_item.c b/src/news_item.c index 85eab71a89..c1c9b7bec5 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -178,7 +178,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * int i; rct_ride *ride; rct_peep *peep; - rct_car *car; + rct_vehicle *vehicle; switch (type) { case NEWS_ITEM_RIDE: @@ -212,13 +212,13 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * } // Find the first car of the train peep is on - car = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[peep->current_train]]).car; + vehicle = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[ride->train_car_map[peep->current_train]]).vehicle; // Find the actual car peep is on for (i = 0; i < peep->current_car; i++) - car = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[car->next_car]).car; - *x = car->x; - *y = car->y; - *z = car->z; + vehicle = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[vehicle->next_vehicle_on_train]).vehicle; + *x = vehicle->x; + *y = vehicle->y; + *z = vehicle->z; break; case NEWS_ITEM_PEEP: peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]).peep; diff --git a/src/park.c b/src/park.c index f4a591e718..8d65ef999b 100644 --- a/src/park.c +++ b/src/park.c @@ -442,6 +442,7 @@ static rct_peep *park_generate_new_guest_due_to_campaign(int campaign) break; } } + return peep; } static int park_get_campaign_guest_generation_probability(int campaign) diff --git a/src/sprite.h b/src/sprite.h index a51e448c41..40d905a3a9 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -27,6 +27,7 @@ #define SPRITE_LOCATION_NULL 0x8000 #include "peep.h" +#include "vehicle.h" typedef struct { uint8 sprite_identifier; // 0x00 @@ -46,16 +47,6 @@ typedef struct { uint32 var_24; } rct_litter; -typedef struct { - uint8 sprite_idetifier; // 0x00 - uint8 pad_01[0x0D]; - sint16 x; // 0x0E - sint16 y; // 0x10 - sint16 z; // 0x12 - uint8 pad_14[0x2a]; - uint16 next_car; // 0x3E -} rct_car; - /** * Sprite structure. * size: 0x0100 @@ -65,7 +56,7 @@ typedef union { rct_unk_sprite unknown; rct_peep peep; rct_litter litter; - rct_car car; + rct_vehicle vehicle; } rct_sprite; #endif diff --git a/src/vehicle.c b/src/vehicle.c new file mode 100644 index 0000000000..a96bb51282 --- /dev/null +++ b/src/vehicle.c @@ -0,0 +1,59 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "addresses.h" +#include "sprite.h" +#include "vehicle.h" + +static void vehicle_update(rct_vehicle *vehicle); + +/** + * + * rct2: 0x006D4204 + */ +void vehicle_update_all() +{ + uint16 sprite_index; + rct_vehicle *vehicle; + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) + return; + + if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 4) && RCT2_GLOBAL(0x0141F570, uint8) != 6) + return; + + + sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); + while (sprite_index != SPRITE_INDEX_NULL) { + vehicle = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].vehicle); + sprite_index = vehicle->next; + + vehicle_update(vehicle); + } +} + +/** + * + * rct2: 0x006D77F2 + */ +static void vehicle_update(rct_vehicle *vehicle) +{ + RCT2_CALLPROC_X(0x006D77F2, 0, 0, 0, 0, (int)vehicle, 0, 0); +} \ No newline at end of file diff --git a/src/vehicle.h b/src/vehicle.h new file mode 100644 index 0000000000..cc492c076d --- /dev/null +++ b/src/vehicle.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef _VEHICLE_H_ +#define _VEHICLE_H_ + +#include "rct2.h" + +typedef struct { + uint8 sprite_idetifier; // 0x00 + uint8 pad_01[0x03]; + uint16 next; // 0x04 + uint8 pad_06[0x08]; + sint16 x; // 0x0E + sint16 y; // 0x10 + sint16 z; // 0x12 + uint8 pad_14[0x2A]; + uint16 next_vehicle_on_train; // 0x3E +} rct_vehicle; + +void vehicle_update_all(); + +#endif \ No newline at end of file From 37434bd6c2b9a322e2cb5a91f9ad01a159076c50 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Mon, 26 May 2014 01:44:08 +0900 Subject: [PATCH 061/209] add caching, IRC notifications reduce verbosity try using .cache folder valid travis file name file push travis notifications to openrct2-dev list directory contents untar in the subfolder see whats in that directory ls more dirs .patch is in subdir too dont be a dummy only download if files arent present syntax check correct files check if anything is in cache try filename with no period --- .travis.yml | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index fae0c47d0f..38bc2929ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,20 @@ language: c before_install: - - sudo apt-get update -qq - sudo apt-get install -y --force-yes binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 # fetch precompiled SDL2 + headers for MinGW and push it into the expected directory + - mkdir -p cache - export SDL2_PV=2.0.3 - - wget http://libsdl.org/release/SDL2-devel-${SDL2_PV}-mingw.tar.gz - - tar -xzvf SDL2-devel-${SDL2_PV}-mingw.tar.gz + - if [[ ! -f cache/SDL2-devel-${SDL2_PV}-mingw.tar.gz ]]; then wget http://libsdl.org/release/SDL2-devel-${SDL2_PV}-mingw.tar.gz --output-document cache/SDL2-devel-${SDL2_PV}-mingw.tar.gz; fi + - pushd cache && tar -xzf SDL2-devel-${SDL2_PV}-mingw.tar.gz && popd # but first fix SDL2 bug - - wget "https://github.com/anyc/anyc-overlay/raw/master/media-libs/libsdl2-mingw/files/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch" - - pushd SDL2-${SDL2_PV}/i686-w64-mingw32/include/SDL2/ && patch -p2 < ../../../../libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch && popd + - if [[ ! -f cache/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch ]]; then wget "https://github.com/anyc/anyc-overlay/raw/master/media-libs/libsdl2-mingw/files/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch" --output-document cache/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch; fi + - pushd cache/SDL2-${SDL2_PV}/i686-w64-mingw32/include/SDL2/ && patch -p2 < ../../../../libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch && popd - sudo mkdir -p /usr/local/cross-tools/ - - sudo mv SDL2-${SDL2_PV}/i686-w64-mingw32 /usr/local/cross-tools/ + - sudo cp -r cache/SDL2-${SDL2_PV}/i686-w64-mingw32 /usr/local/cross-tools/ # build a wrapper that looks for the sdl2.pc file in the new directory - echo -e "#! /bin/sh\\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\\npkg-config \$@" > i686-w64-mingw32-pkg-config @@ -26,8 +26,14 @@ script: - pushd build - cmake -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=Debug .. - make - #- make VERBOSE=1 - popd -#notifications: - #irc: "irc.freenode.net#openrct2" \ No newline at end of file +notifications: + irc: "irc.freenode.net#openrct2-dev" + on_failure: always + on_success: change + +cache: + directories: + - cache + apt: true From 5b568f376c6ec991e5bf56e636b0f880f39ffc02 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 25 May 2014 19:47:11 +0100 Subject: [PATCH 062/209] add peep_applause --- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 3 +++ src/peep.c | 45 +++++++++++++++++++++++++++++++ src/peep.h | 10 +++++-- src/scenario.c | 2 +- src/sprite.c | 31 +++++++++++++++++++++ src/sprite.h | 2 ++ 7 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/sprite.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 62c7dfb183..c67891ee19 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -81,6 +81,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 1635ec4952..8000ad144c 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -320,6 +320,9 @@ Source Files + + Source Files + diff --git a/src/peep.c b/src/peep.c index c6f910fe13..0486eff68d 100644 --- a/src/peep.c +++ b/src/peep.c @@ -20,6 +20,7 @@ #include #include "addresses.h" +#include "audio.h" #include "news_item.h" #include "peep.h" #include "rct2.h" @@ -293,6 +294,50 @@ void peep_update_crowd_noise() } } +/** + * + * rct2: 0x0069BE9B + */ +void peep_applause() +{ + uint16 sprite_index; + rct_peep* peep; + + // For each guest + sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); + while (sprite_index != 0xFFFF) { + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep); + sprite_index = peep->next; + + if (peep->type != PEEP_TYPE_GUEST) + continue; + if (peep->var_2A != 0) + continue; + + // Release balloon + if (peep->item_standard_flags & PEEP_ITEM_BALLOON) { + peep->item_standard_flags &= ~PEEP_ITEM_BALLOON; + if (peep->x != 0x8000) { + create_balloon(peep->x, peep->y, peep->z + 9, peep->balloon_colour); + peep->var_45 |= 8; + RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + } + } + + // Clap + if ((peep->state == PEEP_STATE_WALKING || peep->state == PEEP_STATE_QUEUING) && peep->var_71 >= 254) { + peep->var_71 = 26; + peep->var_72 = 0; + peep->var_70 = 0; + RCT2_CALLPROC_X(0x00693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); + } + } + + // Play applause noise + sound_play_panned(44, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2); +} + /** * * rct2: 0x0069A05D diff --git a/src/peep.h b/src/peep.h index 15c4c766d4..8bcf28de73 100644 --- a/src/peep.h +++ b/src/peep.h @@ -359,7 +359,7 @@ typedef struct { uint8 pad_41[0x2]; uint8 intensity; // 0x43 uint8 nausea_tolerance; // 0x44 - uint8 pad_45; + uint8 var_45; money16 paid_on_drink; // 0x46 uint8 pad_48[0x10]; uint32 item_extra_flags; // 0x58 @@ -372,8 +372,13 @@ typedef struct { uint8 current_train; // 0x6A uint8 current_car; // 0x6B uint8 current_seat; // 0x6C - uint8 pad_6D[0x09]; + uint8 pad_6D[3]; + uint8 var_70; + uint8 var_71; + uint8 var_72; + uint8 pad_73[3]; uint8 var_76; + uint8 pad_77; uint8 var_78; uint8 pad_79[0x03]; uint8 rides_been_on[32]; // 0x7C @@ -416,6 +421,7 @@ int peep_get_staff_count(); void peep_update_all(); void peep_problem_warnings_update(); void peep_update_crowd_noise(); +void peep_applause(); rct_peep *peep_generate(int x, int y, int z); #endif diff --git a/src/scenario.c b/src/scenario.c index b35584e0f8..a18407e6f8 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -336,7 +336,7 @@ void scenario_success() uint32 current_val = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_COMPANY_VALUE, uint32); RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = current_val; - RCT2_CALLPROC_EBPSAFE(0x0069BE9B); // celebration + peep_applause(); for (i = 0; i < gScenarioListCount; i++) { char *cur_scenario_name = RCT2_ADDRESS(0x135936C, char); diff --git a/src/sprite.c b/src/sprite.c new file mode 100644 index 0000000000..37157e98b6 --- /dev/null +++ b/src/sprite.c @@ -0,0 +1,31 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "addresses.h" +#include "sprite.h" + +/** + * + * rct2: 0x006736C7 + */ +void create_balloon(int x, int y, int z, int colour) +{ + RCT2_CALLPROC_X(0x006736C7, x, colour << 8, y, z, 0, 0, 0); +} \ No newline at end of file diff --git a/src/sprite.h b/src/sprite.h index 40d905a3a9..3edb1d5e6f 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -59,4 +59,6 @@ typedef union { rct_vehicle vehicle; } rct_sprite; +void create_balloon(int x, int y, int z, int colour); + #endif From c3a5ce2c7ca0e65f636a80f49407ec2dcd21886b Mon Sep 17 00:00:00 2001 From: adrian17 Date: Sun, 25 May 2014 21:51:00 +0200 Subject: [PATCH 063/209] Remove settings.h from project --- projects/openrct2.vcxproj | 1 - projects/openrct2.vcxproj.filters | 3 --- 2 files changed, 4 deletions(-) diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index c67891ee19..18ab582fc1 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -38,7 +38,6 @@ - diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 8000ad144c..e940b22b77 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -126,9 +126,6 @@ Header Files - - Header Files - Header Files From 735c42e62832b959766e3450e8d9e5262d7a9471 Mon Sep 17 00:00:00 2001 From: adrian17 Date: Sun, 25 May 2014 21:54:47 +0200 Subject: [PATCH 064/209] Fixed a typo in comment --- src/window.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window.h b/src/window.h index 25e3478852..ee8768b8ad 100644 --- a/src/window.h +++ b/src/window.h @@ -126,7 +126,7 @@ typedef struct rct_window { sint16 var_484; // viewport target y sint16 var_486; // viewport target z sint16 var_488; // viewport rotation << 8 - sint16 page; // 0x49A + sint16 page; // 0x48A sint16 var_48C; sint16 var_48E; sint16 var_490; From bbae0af0ef66ceb3cb316f01fe5b9315daa959e9 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Sun, 25 May 2014 22:27:28 +0200 Subject: [PATCH 065/209] Save screenshots in home folder, Add functions for path separator and detection of homefolder to osinterface --- src/config.c | 11 +++++++---- src/osinterface.c | 16 ++++++++++++++++ src/osinterface.h | 3 +++ src/screenshot.c | 3 ++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/config.c b/src/config.c index 4415705b28..1c428787a2 100644 --- a/src/config.c +++ b/src/config.c @@ -216,20 +216,23 @@ void config_save() */ void config_init() { - TCHAR path[MAX_PATH]; + char path[MAX_PATH]; FILE* fp; memcpy(&gGeneral_config, &gGeneral_config_default, sizeof(general_configuration_t)); - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) { // find home folder - strcat(path, "\\OpenRCT2"); + strncpy(path, osinterface_get_orct2_homefolder(), MAX_PATH); + + if (strcmp(path, "") != 0){ DWORD dwAttrib = GetFileAttributes(path); if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { // folder does not exist if (!CreateDirectory(path, NULL)) { config_error("Could not create config file (do you have write access to your documents folder?)"); } } - strcat(path, "\\config.ini"); + + sprintf(path, "%s%c%s", path, osinterface_get_path_separator(), "config.ini"); + fp = fopen(path, "r"); if (!fp) { config_create_default(path); diff --git a/src/osinterface.c b/src/osinterface.c index 8117a31198..974c9da05d 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -428,3 +428,19 @@ char* osinterface_open_directory_browser(char *title) { CoUninitialize(); return outPath; } + +char* osinterface_get_orct2_homefolder() +{ + char path[260]=""; + + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) { // find home folder + strcat(path, "\\OpenRCT2"); + } + + return path; +} + +char osinterface_get_path_separator() +{ + return '\\'; +} \ No newline at end of file diff --git a/src/osinterface.h b/src/osinterface.h index 8360d3f1c4..50f78904a0 100644 --- a/src/osinterface.h +++ b/src/osinterface.h @@ -50,4 +50,7 @@ int osinterface_open_common_file_dialog(int type, char *title, char *filename, c void osinterface_show_messagebox(char* message); char* osinterface_open_directory_browser(char *title); +char* osinterface_get_orct2_homefolder(); +char osinterface_get_path_separator(); + #endif diff --git a/src/screenshot.c b/src/screenshot.c index d557297a9e..6e040686b6 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -21,6 +21,7 @@ #include #include #include +#include "osinterface.h" #include "addresses.h" #include "config.h" #include "gfx.h" @@ -64,7 +65,7 @@ static int screenshot_get_next_path(char *path, char *extension) RCT2_GLOBAL(0x013CE952, uint16) = i; // Glue together path and filename - sprintf(path, "%sSCR%d%s", RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), i, extension); + sprintf(path, "%s%cSCR%d%s", osinterface_get_orct2_homefolder(), osinterface_get_path_separator(), i, extension); if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) return i; From 07128831fbdd659b1644609b51fd972671aa235c Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Sun, 25 May 2014 22:35:54 +0200 Subject: [PATCH 066/209] (test commit for travis please ignore) --- licence.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/licence.txt b/licence.txt index 20d40b6bce..94a9ed024d 100644 --- a/licence.txt +++ b/licence.txt @@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. \ No newline at end of file +. From 8bf7c1e025df72f037f97e83ee3a0e320d3b93dd Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 25 May 2014 22:08:36 +0100 Subject: [PATCH 067/209] add sound enum --- src/audio.h | 66 +++++++++++++++++++++++++++++-- src/game.c | 2 +- src/intro.c | 6 +-- src/news_item.c | 2 +- src/peep.c | 2 +- src/vehicle.h | 2 +- src/window.c | 2 +- src/window_footpath.c | 2 +- src/window_news.c | 4 +- src/window_title_scenarioselect.c | 2 +- 10 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/audio.h b/src/audio.h index 52a51c2cee..ed6165bdcd 100644 --- a/src/audio.h +++ b/src/audio.h @@ -64,9 +64,69 @@ void pause_sounds(); void unpause_sounds(); typedef enum { - RCT2_SOUND_SCREAM = 11, - RCT2_SOUND_CHAINLIFT = 56, - RCT2_SOUND_TRACKFRICTION = 57, + SOUND_LIFT_1 = 0, + SOUND_TRACK_FRICTION_1 = 1, + SOUND_LIFT_2 = 2, + SOUND_SCREAM_1 = 3, + SOUND_CLICK_1 = 4, + SOUND_CLICK_2 = 5, + SOUND_PLACE_ITEM = 6, + SOUND_SCREAM_2 = 7, + SOUND_SCREAM_3 = 8, + SOUND_SCREAM_4 = 9, + SOUND_SCREAM_5 = 10, + SOUND_SCREAM_6 = 11, + SOUND_LIFT_3 = 12, + SOUND_PURCHASE = 13, + SOUND_CRASH = 14, + SOUND_LAYING_OUT_WATER = 15, + SOUND_WATER_1 = 16, + SOUND_WATER_2 = 17, + SOUND_TRAIN_WHISTLE = 18, + SOUND_TRAIN_CHUGGING = 19, + SOUND_WATER_SPLASH = 20, + SOUND_HAMMERING = 21, + SOUND_RIDE_LAUNCH_1 = 22, + SOUND_RIDE_LAUNCH_2 = 23, + SOUND_COUGH_1 = 24, + SOUND_COUGH_2 = 25, + SOUND_COUGH_3 = 26, + SOUND_COUGH_4 = 27, + SOUND_RAIN_1 = 28, + SOUND_THUNDER_1 = 29, + SOUND_THUNDER_2 = 30, + SOUND_RAIN_2 = 31, + SOUND_RAIN_3 = 32, + SOUND_BALLOON_POP = 33, + SOUND_MECHANIC_FIX = 34, + SOUND_SCREAM_7 = 35, + SOUND_TOILET_FLUSH = 36, + SOUND_CLICK_3 = 37, + SOUND_QUACK = 38, + SOUND_NEWS_ITEM = 39, + SOUND_WINDOW_OPEN = 40, + SOUND_LAUGH_1 = 41, + SOUND_LAUGH_2 = 42, + SOUND_LAUGH_3 = 43, + SOUND_APPLAUSE = 44, + SOUND_HAUNTED_HOUSE_SCARE = 45, + SOUND_HAUNTED_HOUSE_SCREAM_1 = 46, + SOUND_HAUNTED_HOUSE_SCREAM_2 = 47, + SOUND_48 = 48, + SOUND_49 = 49, + SOUND_ERROR = 50, + SOUND_51 = 51, + SOUND_LIFT_4 = 52, + SOUND_LIFT_5 = 53, + SOUND_TRACK_FRICTION_2 = 54, + SOUND_LIFT_6 = 55, + SOUND_LIFT_7 = 56, + SOUND_TRACK_FRICTION_3 = 57, + SOUND_SCREAM_8 = 58, + SOUND_TRAM = 59, + SOUND_DOOR_OPEN = 60, + SOUND_DOOR_CLOSE = 61, + SOUND_62 = 62 } RCT2_SOUND; #endif diff --git a/src/game.c b/src/game.c index 7969dca5a4..d1529dacab 100644 --- a/src/game.c +++ b/src/game.c @@ -755,7 +755,7 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex) if (widget_is_disabled(w, widgetIndex)) break; - sound_play_panned(4, w->x + (widget->left + widget->right) / 2); + sound_play_panned(SOUND_CLICK_1, w->x + (widget->left + widget->right) / 2); // Set new cursor down widget RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = windowClass; diff --git a/src/intro.c b/src/intro.c index aee44c43d1..2d19d04312 100644 --- a/src/intro.c +++ b/src/intro.c @@ -82,7 +82,7 @@ void intro_update() _sound_playing_flag = 0; if (RCT2_GLOBAL(0x009AF280, sint32) != -1) { // Prepare and play the sound - if (sound_prepare(RCT2_SOUND_CHAINLIFT, &_prepared_sound, 0, 1)) + if (sound_prepare(SOUND_LIFT_7, &_prepared_sound, 0, 1)) if (sound_play(&_prepared_sound, 1, 0, 0, 0)) _sound_playing_flag = 1; } @@ -159,7 +159,7 @@ void intro_update() // Play the track friction sound if (RCT2_GLOBAL(0x009AF280, sint32) != -1) { // Prepare and play the sound - if (sound_prepare(RCT2_SOUND_TRACKFRICTION, &_prepared_sound, 1, 1)) + if (sound_prepare(SOUND_TRACK_FRICTION_3, &_prepared_sound, 1, 1)) if (sound_play(&_prepared_sound, 1, -800, 0, 0x3A98)) _sound_playing_flag = 1; } @@ -189,7 +189,7 @@ void intro_update() // Play long peep scream sound if (RCT2_GLOBAL(0x009AF280, sint32) != -1) - if (sound_prepare(RCT2_SOUND_SCREAM, &_prepared_sound, 0, 1)) + if (sound_prepare(SOUND_SCREAM_1, &_prepared_sound, 0, 1)) if (sound_play(&_prepared_sound, 0, 0, 0, 0)) _sound_playing_flag = 1; diff --git a/src/news_item.c b/src/news_item.c index c1c9b7bec5..c286097201 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -97,7 +97,7 @@ void news_item_update_current() newsItems[0].ticks++; if (newsItems[0].ticks == 1 && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1)) { // Play sound - sound_play_panned(39, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2); + sound_play_panned(SOUND_NEWS_ITEM, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2); } // Removal of current news item diff --git a/src/peep.c b/src/peep.c index 0486eff68d..b80f838776 100644 --- a/src/peep.c +++ b/src/peep.c @@ -335,7 +335,7 @@ void peep_applause() } // Play applause noise - sound_play_panned(44, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2); + sound_play_panned(SOUND_APPLAUSE, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2); } /** diff --git a/src/vehicle.h b/src/vehicle.h index cc492c076d..3bddf738fc 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -24,7 +24,7 @@ #include "rct2.h" typedef struct { - uint8 sprite_idetifier; // 0x00 + uint8 sprite_identifier; // 0x00 uint8 pad_01[0x03]; uint16 next; // 0x04 uint8 pad_06[0x08]; diff --git a/src/window.c b/src/window.c index 01333e8809..0a1e9168e1 100644 --- a/src/window.c +++ b/src/window.c @@ -376,7 +376,7 @@ rct_window *window_create(int x, int y, int width, int height, uint32 *event_han // Play sound if (!(flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT))) - sound_play_panned(40, x + (width / 2)); + sound_play_panned(SOUND_WINDOW_OPEN, x + (width / 2)); w->number = 0; w->x = x; diff --git a/src/window_footpath.c b/src/window_footpath.c index be584cde20..0b764ec02f 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -894,7 +894,7 @@ static void window_footpath_place_path_at_point(int x, int y) // bp = 0x009DEA62 // dx = 0x009DEA60 // cx = 0x009DEA5E - sound_play_panned(6, 0x8001); + sound_play_panned(SOUND_PLACE_ITEM, 0x8001); } } diff --git a/src/window_news.c b/src/window_news.c index 4cf448c5ca..3d2c1347ec 100644 --- a/src/window_news.c +++ b/src/window_news.c @@ -161,7 +161,7 @@ static void window_news_update(rct_window *w) return; window_invalidate(w); - sound_play_panned(5, w->x + (w->width / 2)); + sound_play_panned(SOUND_CLICK_2, w->x + (w->width / 2)); newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item); j = w->var_480; @@ -282,7 +282,7 @@ static void window_news_scrollmousedown() w->var_482 = buttonIndex; w->var_484 = 4; window_invalidate(w); - sound_play_panned(4, w->x + (w->width / 2)); + sound_play_panned(SOUND_CLICK_1, w->x + (w->width / 2)); } } diff --git a/src/window_title_scenarioselect.c b/src/window_title_scenarioselect.c index 8f0f34329b..caecf96013 100644 --- a/src/window_title_scenarioselect.c +++ b/src/window_title_scenarioselect.c @@ -292,7 +292,7 @@ static void window_scenarioselect_scrollmousedown() if (y >= 0) continue; - sound_play_panned(4, w->width / 2 + w->x); + sound_play_panned(SOUND_CLICK_1, w->width / 2 + w->x); scenario_load_and_play(scenario); break; } From 4b55a116fea0c89247d9b557f62250e16be4799a Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 25 May 2014 22:47:08 +0100 Subject: [PATCH 068/209] add comma2dp and currency formatting --- src/string_ids.c | 173 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 6 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index 67417e4bf9..e18f7e6bc8 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1150,6 +1150,170 @@ void format_comma_separated_integer(char **dest, int value) *dest = finish; } +void format_comma_separated_fixed_2dp(char **dest, int value) +{ + int digit, groupIndex; + char *dst = *dest; + char *finish; + char tmp; + + // Negative sign + if (value < 0) { + *dst++ = '-'; + value = -value; + } + + *dest = dst; + + // Two decimal places + digit = value % 10; + value /= 10; + *dst++ = '0' + digit; + digit = value % 10; + value /= 10; + *dst++ = '0' + digit; + *dst++ = '.'; + + if (value == 0) { + *dst++ = '0'; + } else { + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; + } + } + finish = dst; + + // Reverse string + dst--; + while (*dest < dst) { + tmp = **dest; + **dest = *dst; + *dst = tmp; + (*dest)++; + dst--; + } + *dest = finish; +} + +void format_currency(char **dest, int value) +{ + int digit, groupIndex; + char *dst = *dest; + char *finish; + char tmp; + + // Negative sign + if (value < 0) { + *dst++ = '-'; + value = -value; + } + + // Currency symbol + *dst++ = '£'; + + *dest = dst; + + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; + } + finish = dst; + + // Reverse string + dst--; + while (*dest < dst) { + tmp = **dest; + **dest = *dst; + *dst = tmp; + (*dest)++; + dst--; + } + *dest = finish; +} + +void format_currency_2dp(char **dest, int value) +{ + int digit, groupIndex; + char *dst = *dest; + char *finish; + char tmp; + + // Negative sign + if (value < 0) { + *dst++ = '-'; + value = -value; + } + + // Currency symbol + *dst++ = '£'; + + *dest = dst; + + // Two decimal places + digit = value % 10; + value /= 10; + *dst++ = '0' + digit; + digit = value % 10; + value /= 10; + *dst++ = '0' + digit; + *dst++ = '.'; + + if (value == 0) { + *dst++ = '0'; + } else { + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; + } + } + finish = dst; + + // Reverse string + dst--; + while (*dest < dst) { + tmp = **dest; + **dest = *dst; + *dst = tmp; + (*dest)++; + dst--; + } + *dest = finish; +} + void format_string_code(unsigned char format_code, char **dest, char **args) { int value; @@ -1174,8 +1338,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args) value = *((sint32*)*args); *args += 4; - // TODO - printf("TODO: FORMAT_COMMA2DP32\n"); + format_comma_separated_fixed_2dp(dest, value); break; case FORMAT_COMMA16: // Pop argument @@ -1196,16 +1359,14 @@ void format_string_code(unsigned char format_code, char **dest, char **args) value = *((sint32*)*args); *args += 4; - // TODO - printf("TODO: FORMAT_CURRENCY2DP\n"); + format_currency_2dp(dest, value); break; case FORMAT_CURRENCY: // Pop argument value = *((sint32*)*args); *args += 4; - // TODO - printf("TODO: FORMAT_CURRENCY\n"); + format_currency(dest, value); break; case FORMAT_STRINGID: case FORMAT_STRINGID2: From 092764ea6b754a2a131f50d72118de39f5455a38 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 25 May 2014 23:17:55 +0100 Subject: [PATCH 069/209] separate marketing and add finances window --- projects/openrct2.vcxproj | 2 + projects/openrct2.vcxproj.filters | 6 ++ src/game.c | 2 +- src/marketing.c | 126 ++++++++++++++++++++++++++++++ src/marketing.h | 40 ++++++++++ src/news_item.c | 3 +- src/park.c | 82 +++---------------- src/park.h | 10 --- src/scenario.c | 46 +---------- src/window.h | 1 + src/window_finances.c | 13 ++- src/window_game_bottom_toolbar.c | 2 +- 12 files changed, 200 insertions(+), 133 deletions(-) create mode 100644 src/marketing.c create mode 100644 src/marketing.h diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index c67891ee19..87cb5837f5 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -26,6 +26,7 @@ + @@ -67,6 +68,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 8000ad144c..4da48f42e3 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -135,6 +135,9 @@ Header Files + + Header Files + @@ -323,6 +326,9 @@ Source Files + + Source Files + diff --git a/src/game.c b/src/game.c index d1529dacab..0a9e82f4ab 100644 --- a/src/game.c +++ b/src/game.c @@ -1022,7 +1022,7 @@ void handle_shortcut_command(int shortcutIndex) case SHORTCUT_SHOW_FINANCIAL_INFORMATION: if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800)) - RCT2_CALLPROC_EBPSAFE(0x0069DDF1); + window_finances_open(); break; case SHORTCUT_SHOW_RESEARCH_INFORMATION: if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) { diff --git a/src/marketing.c b/src/marketing.c new file mode 100644 index 0000000000..15b7192035 --- /dev/null +++ b/src/marketing.c @@ -0,0 +1,126 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "addresses.h" +#include "marketing.h" +#include "news_item.h" +#include "rct2.h" +#include "ride.h" +#include "string_ids.h" +#include "window.h" + +const int advertisingCampaignGuestGenerationProbabilities[] = { 400, 300, 200, 200, 250, 200 }; + +int marketing_get_campaign_guest_generation_probability(int campaign) +{ + int probability = advertisingCampaignGuestGenerationProbabilities[campaign]; + rct_ride *ride; + + // Lower probability of guest generation if price was already low + switch (campaign) { + case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 4) + probability /= 8; + break; + case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 6) + probability /= 8; + break; + case ADVERTISING_CAMPAIGN_RIDE_FREE: + ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[RCT2_ADDRESS(0x01358116, uint8)[campaign]]); + if (ride->price < 3) + probability /= 8; + break; + } + + return probability; +} + +/* + * Update status of marketing campaigns and send produce a news item when they have finished. + * rct2: 0x0069E0C1 + **/ +void marketing_update() +{ + for (int campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++) { + uint8 campaign_weeks_left = RCT2_ADDRESS(0x01358102, uint8)[campaign]; + if (campaign_weeks_left == 0) + continue; + + window_invalidate_by_id(WC_FINANCES, 0); + + // High bit marks the campaign as inactive, on first check the campaign is set actice + // this makes campaigns run a full x weeks even when started in the middle of a week + RCT2_ADDRESS(0x01358102, uint8)[campaign] &= ~(1 << 7); + if (campaign_weeks_left & (1 << 7)) + continue; + + RCT2_ADDRESS(0x01358102, uint8)[campaign]--; + if (campaign_weeks_left - 1 != 0) + continue; + + int campaign_item = RCT2_ADDRESS(0x01358116, uint8)[campaign]; + + // This sets the string parameters for the marketing types that have an argument. + if (campaign == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign == ADVERTISING_CAMPAIGN_RIDE) { + RCT2_GLOBAL(0x013CE952, uint16) = RCT2_GLOBAL(0x01362942 + 304 * campaign_item, uint16); + RCT2_GLOBAL(0x013CE954, uint32) = RCT2_GLOBAL(0x01362944 + 152 * campaign_item, uint32); + } else if (campaign == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) { + campaign_item += 2016; + if (campaign_item >= 2048) + campaign_item += 96; + RCT2_GLOBAL(0x013CE952, uint16) = campaign_item; + } + + news_item_add_to_queue(NEWS_ITEM_MONEY, STR_MARKETING_FINISHED_BASE + campaign, 0); + } +} + +void marketing_set_guest_campaign(rct_peep *peep, int campaign) +{ + switch (campaign) { + case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: + peep->item_standard_flags |= PEEP_ITEM_VOUCHER; + peep->var_F0 = 0; + break; + case ADVERTISING_CAMPAIGN_RIDE_FREE: + peep->item_standard_flags |= PEEP_ITEM_VOUCHER; + peep->var_F0 = 1; + peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; + peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; + peep->var_C6 = 240; + break; + case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: + peep->item_standard_flags |= PEEP_ITEM_VOUCHER; + peep->var_F0 = 2; + break; + case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE: + peep->item_standard_flags |= PEEP_ITEM_VOUCHER; + peep->var_F0 = 3; + peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; + break; + case ADVERTISING_CAMPAIGN_PARK: + break; + case ADVERTISING_CAMPAIGN_RIDE: + peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; + peep->var_C6 = 240; + break; + } +} \ No newline at end of file diff --git a/src/marketing.h b/src/marketing.h new file mode 100644 index 0000000000..43e99796c9 --- /dev/null +++ b/src/marketing.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef _MARKETING_H_ +#define _MARKETING_H_ + +#include "peep.h" + +enum { + ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE, + ADVERTISING_CAMPAIGN_RIDE_FREE, + ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE, + ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE, + ADVERTISING_CAMPAIGN_PARK, + ADVERTISING_CAMPAIGN_RIDE, + ADVERTISING_CAMPAIGN_COUNT +}; + +int marketing_get_campaign_guest_generation_probability(int campaign); +void marketing_update(); +void marketing_set_guest_campaign(rct_peep *peep, int campaign); + +#endif \ No newline at end of file diff --git a/src/news_item.c b/src/news_item.c index c286097201..5e32c37f5b 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -299,8 +299,7 @@ void news_item_open_subject(int type, int subject) { RCT2_CALLPROC_X(0x006989E9, 0, 0, 0, (int)peep, 0, 0, 0); break; case NEWS_ITEM_MONEY: - // Open finances window - RCT2_CALLPROC_EBPSAFE(0x0069DDF1); + window_finances_open(); break; case NEWS_ITEM_RESEARCH: diff --git a/src/park.c b/src/park.c index 8d65ef999b..191880ff0c 100644 --- a/src/park.c +++ b/src/park.c @@ -22,6 +22,7 @@ #include "addresses.h" #include "finance.h" #include "map.h" +#include "marketing.h" #include "park.h" #include "peep.h" #include "ride.h" @@ -30,8 +31,6 @@ #include "string_ids.h" #include "window.h" -const int advertisingCampaignGuestGenerationProbabilities[] = { 400, 300, 200, 200, 250, 200 }; - int park_is_open() { return (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) != 0; @@ -370,17 +369,6 @@ static void get_random_peep_spawn(rct2_peep_spawn *spawn) *spawn = peepSpawns[1]; } -static int park_should_generate_new_guest() -{ - if ((scenario_rand() & 0xFFFF) < RCT2_GLOBAL(0x013580EC, uint16)) { - int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0; - if (!difficultGeneration || RCT2_GLOBAL(0x0135883C, uint16) + 150 < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)) - return 1; - } - - return 0; -} - static rct_peep *park_generate_new_guest() { rct_peep *peep; @@ -412,76 +400,26 @@ static rct_peep *park_generate_new_guest() static rct_peep *park_generate_new_guest_due_to_campaign(int campaign) { rct_peep *peep = park_generate_new_guest(); - if (peep != NULL) { - switch (campaign) { - case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: - peep->item_standard_flags |= PEEP_ITEM_VOUCHER; - peep->var_F0 = 0; - break; - case ADVERTISING_CAMPAIGN_RIDE_FREE: - peep->item_standard_flags |= PEEP_ITEM_VOUCHER; - peep->var_F0 = 1; - peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; - peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; - peep->var_C6 = 240; - break; - case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: - peep->item_standard_flags |= PEEP_ITEM_VOUCHER; - peep->var_F0 = 2; - break; - case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE: - peep->item_standard_flags |= PEEP_ITEM_VOUCHER; - peep->var_F0 = 3; - peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; - break; - case ADVERTISING_CAMPAIGN_PARK: - break; - case ADVERTISING_CAMPAIGN_RIDE: - peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign]; - peep->var_C6 = 240; - break; - } - } + if (peep != NULL) + marketing_set_guest_campaign(peep, campaign); return peep; } -static int park_get_campaign_guest_generation_probability(int campaign) -{ - int probability = advertisingCampaignGuestGenerationProbabilities[campaign]; - rct_ride *ride; - - // Lower probability of guest generation if price was already low - switch (campaign) { - case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 4) - probability /= 8; - break; - case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 6) - probability /= 8; - break; - case ADVERTISING_CAMPAIGN_RIDE_FREE: - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[RCT2_ADDRESS(0x01358116, uint8)[campaign]]); - if (ride->price < 3) - probability /= 8; - break; - } - - return probability; -} - static void park_generate_new_guests() { - // Check and generate a new guest - if (park_should_generate_new_guest()) - park_generate_new_guest(); + // Generate a new guest for some probability + if ((scenario_rand() & 0xFFFF) < RCT2_GLOBAL(0x013580EC, uint16)) { + int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0; + if (!difficultGeneration || RCT2_GLOBAL(0x0135883C, uint16) + 150 < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)) + park_generate_new_guest(); + } // Extra guests generated by advertising campaigns int campaign; for (campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++) { if (RCT2_ADDRESS(0x01358102, uint8)[campaign] != 0) { // Random chance of guest generation - if ((scenario_rand() & 0xFFFF) < park_get_campaign_guest_generation_probability(campaign)) + if ((scenario_rand() & 0xFFFF) < marketing_get_campaign_guest_generation_probability(campaign)) park_generate_new_guest_due_to_campaign(campaign); } } diff --git a/src/park.h b/src/park.h index 3d4d778caa..9d3dcc4697 100644 --- a/src/park.h +++ b/src/park.h @@ -51,16 +51,6 @@ enum { PARK_AWARD_BEST_GENTLE_RIDES, }; -enum { - ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE, - ADVERTISING_CAMPAIGN_RIDE_FREE, - ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE, - ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE, - ADVERTISING_CAMPAIGN_PARK, - ADVERTISING_CAMPAIGN_RIDE, - ADVERTISING_CAMPAIGN_COUNT -}; - enum { PARK_FLAGS_PARK_OPEN = (1 << 0), PARK_FLAGS_FORBID_LANDSCAPE_CHANGES = (1 << 2), diff --git a/src/scenario.c b/src/scenario.c index a18407e6f8..9fdd0c0003 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -25,6 +25,7 @@ #include "finance.h" #include "game.h" #include "map.h" +#include "marketing.h" #include "news_item.h" #include "object.h" #include "park.h" @@ -561,49 +562,6 @@ void scenario_entrance_fee_too_high_check() } } - -/* - * Update status of marketing campaigns and send a message when they are done. - * rct2: 0x0069E0C1 - **/ -void scenario_marketing_update() -{ - for (int i = 0; i < 6; ++i) { - uint8 campaign_weeks_left = RCT2_ADDRESS(0x01358102, uint8)[i]; - int campaign_item = 0; - - if (!campaign_weeks_left) - continue; - window_invalidate_by_id(WC_FINANCES, 0); - - // high bit marks the campaign as inactive, on first check the campaign is set actice - // this makes campaigns run a full x weeks even when started in the middle of a week - RCT2_ADDRESS(0x01358102, uint8)[i] &= ~(1 << 7); - if (campaign_weeks_left & (1 << 7)) - continue; - - RCT2_ADDRESS(0x01358102, uint8)[i]--; - if (campaign_weeks_left - 1 != 0) - continue; - - campaign_item = RCT2_ADDRESS(0x01358116, uint8)[i]; - - // this sets the string parameters for the marketing types that have an argument. - if (i == 1 || i == 5) { // free RIDES oh yea - RCT2_GLOBAL(0x013CE952, uint16) = RCT2_GLOBAL(0x01362942 + 304 * campaign_item, uint16);; - RCT2_GLOBAL(0x013CE954, uint32) = RCT2_GLOBAL(0x01362944 + 152 * campaign_item, uint32); - } else if (i == 3) { // free food/merch - campaign_item += 2016; - if (campaign_item >= 2048) - campaign_item += 96; - RCT2_GLOBAL(0x013CE952, uint16) = campaign_item; - } - - news_item_add_to_queue(NEWS_ITEM_MONEY, STR_MARKETING_FINISHED_BASE + i, 0); - } -} - - /* * Scenario and finance related update iteration. * rct2: 0x006C44B1 @@ -639,7 +597,7 @@ void scenario_update() finance_pay_wages(); finance_pay_research(); finance_pay_interest(); - scenario_marketing_update(); + marketing_update(); peep_problem_warnings_update(); RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability ride_update_favourited_stat(); diff --git a/src/window.h b/src/window.h index 25e3478852..6e43bd495c 100644 --- a/src/window.h +++ b/src/window.h @@ -359,6 +359,7 @@ void window_park_entrance_open(); void window_park_guests_open(); void window_park_objective_open(); void window_park_rating_open(); +void window_finances_open(); void window_ride_list_open(); void window_banner_open(); void window_cheats_open(); diff --git a/src/window_finances.c b/src/window_finances.c index a2244518dd..0cf98b5d81 100644 --- a/src/window_finances.c +++ b/src/window_finances.c @@ -18,9 +18,7 @@ * along with this program. If not, see . *****************************************************************************/ -#include #include "addresses.h" -#include "game.h" #include "window.h" enum { @@ -30,4 +28,13 @@ enum { WINDOW_FINANCES_TAB_PROFIT_GRAPH, WINDOW_FINANCES_TAB_MARKETING, WINDOW_FINANCES_TAB_RESEARCH -} WINDOW_FINANCIAL_TAB; \ No newline at end of file +} WINDOW_FINANCIAL_TAB; + +/** + * + * rct2: 0x0069DDF1 + */ +void window_finances_open() +{ + RCT2_CALLPROC_EBPSAFE(0x0069DDF1); +} \ No newline at end of file diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index 3966c3904f..efe61f769a 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -172,7 +172,7 @@ static void window_game_bottom_toolbar_mouseup() case WIDX_LEFT_OUTSET: case WIDX_MONEY: if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800)) - RCT2_CALLPROC_EBPSAFE(0x0069DDF1); + window_finances_open(); break; case WIDX_GUESTS: window_park_guests_open(); From 8271ed5022c682f90c1acfe5990805f69a8c2eab Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 00:55:46 +0100 Subject: [PATCH 070/209] add finances window widgets --- src/string_ids.h | 39 ++++++ src/window_finances.c | 273 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 310 insertions(+), 2 deletions(-) diff --git a/src/string_ids.h b/src/string_ids.h index 928f7024dd..d0fde8f342 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -341,6 +341,13 @@ enum { STR_SHOW_SUBJECT_TIP = 1937, + STR_FINANCIAL_SUMMARY = 1949, + STR_FINANCIAL_GRAPH = 1950, + STR_PARK_VALUE_GRAPH = 1951, + STR_PROFIT_GRAPH = 1952, + STR_MARKETING = 1953, + STR_RESEARCH_FUNDING = 1954, + STR_CELSIUS_VALUE = 2216, STR_FAHRENHEIT_VALUE = 2217, @@ -365,6 +372,19 @@ enum { STR_MONTH_NOVEMBER = STR_MONTH_JANUARY + 10, STR_MONTH_DECEMBER = STR_MONTH_JANUARY + 11, + STR_RESEARCH_TRANSPORT_RIDES = 2253, + STR_RESEARCH_GENTLE_RIDES = 2254, + STR_RESEARCH_ROLLER_COASTERS = 2255, + STR_RESEARCH_THRILL_RIDES = 2256, + STR_RESEARCH_WATER_RIDES = 2257, + STR_RESEARCH_SHOPS_AND_STALLS = 2258, + STR_RESEARCH_SCENERY_AND_THEMING = 2259, + + STR_RESEARCH_FUNDING_ = 2264, + STR_RESEARCH_PRIORITIES = 2266, + + STR_FINANCES_RESEARCH = 2275, + STR_SELECT_SCENARIO = 2291, STR_CHANGE_BASE_LAND_TIP = 2294, @@ -439,6 +459,10 @@ enum { STR_OBJECTIVE_REPLAY_LOAN_AND_PARK_VALUE = STR_OBJECTIVE_NONE + 10, STR_OBJECTIVE_MONTHLY_FOOD_INCOME = STR_OBJECTIVE_NONE + 11, + STR_MARKETING_CAMPAIGNS_IN_OPERATION = 2409, + STR_MARKETING_CAMPAIGNS_AVAILABLE = 2411, + STR_START_THIS_MARKETING_CAMPAIGN = 2412, + STR_MARKETING_FINISHED_BASE = 2446, STR_MARKETING_FINISHED_FREE_ENTRY = 2446, STR_MARKETING_FINISHED_FREE_RIDES = 2447, @@ -447,6 +471,12 @@ enum { STR_MARKETING_FINISHED_PARK_ADS = 2450, STR_MARKETING_FINISHED_RIDE_ADS = 2451, + STR_FINANCES_SHOW_SUMMARY_TAB_TIP = 2457, + STR_FINANCES_SHOW_CASH_TAB_TIP = 2458, + STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP = 2459, + STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP = 2460, + STR_FINANCES_SHOW_MARKETING_TAB_TIP = 2461, + STR_PARK_ENTRANCE_TAB_TIP = 2462, STR_PARK_RATING_TAB_TIP = 2463, STR_PARK_GUESTS_TAB_TIP = 2464, @@ -455,6 +485,15 @@ enum { STR_PARK_OBJECTIVE_TAB_TIP = 2467, STR_PARK_AWARDS_TAB_TIP = 2468, + STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT = 2469, + STR_RESEARCH_NEW_TRANSPORT_RIDES = 2470, + STR_RESEARCH_NEW_GENTLE_RIDES = 2471, + STR_RESEARCH_NEW_ROLLER_COASTERS = 2472, + STR_RESEARCH_NEW_THRILL_RIDES = 2473, + STR_RESEARCH_NEW_WATER_RIDES = 2474, + STR_RESEARCH_NEW_SHOPS_AND_STALLS = 2475, + STR_RESEARCH_NEW_SCENERY_AND_THEMING = 2476, + STR_PROFIT_PER_WEEK_AND_PARK_VALUE_TIP = 2482, STR_CONTROLS = 2485, diff --git a/src/window_finances.c b/src/window_finances.c index 0cf98b5d81..1a00f51511 100644 --- a/src/window_finances.c +++ b/src/window_finances.c @@ -19,6 +19,8 @@ *****************************************************************************/ #include "addresses.h" +#include "string_ids.h" +#include "widget.h" #include "window.h" enum { @@ -28,7 +30,245 @@ enum { WINDOW_FINANCES_TAB_PROFIT_GRAPH, WINDOW_FINANCES_TAB_MARKETING, WINDOW_FINANCES_TAB_RESEARCH -} WINDOW_FINANCIAL_TAB; +}; + +enum { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_PAGE_BACKGROUND, + WIDX_TAB_1, + WIDX_TAB_2, + WIDX_TAB_3, + WIDX_TAB_4, + WIDX_TAB_5, + WIDX_TAB_6, + + WIDX_LOAN = 10, + WIDX_LOAN_INCREASE, + WIDX_LOAN_DECREASE, + + WIDX_CAMPAIGN_1 = 12, + WIDX_CAMPAIGN_2, + WIDX_CAMPAIGN_3, + WIDX_CAMPAIGN_4, + WIDX_CAMPAIGN_5, + WIDX_CAMPAIGN_6, + + WIDX_RESEARCH_FUNDING = 11, + WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON, + WIDX_TRANSPORT_RIDES = 14, + WIDX_GENTLE_RIDES, + WIDX_ROLLER_COASTERS, + WIDX_THRILL_RIDES, + WIDX_WATER_RIDES, + WIDX_SHOPS_AND_STALLS, + WIDX_SCENERY_AND_THEMING, +}; + +#pragma region Widgets + +static rct_widget window_finances_summary_widgets[] = { + { WWT_FRAME, 0, 0, 529, 0, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 528, 1, 14, STR_FINANCIAL_SUMMARY, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 517, 527, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 529, 43, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_FINANCES_SHOW_SUMMARY_TAB_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_SHOW_CASH_TAB_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_FINANCES_SHOW_MARKETING_TAB_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, + { WWT_SPINNER, 1, 64, 153, 229, 240, 1917, STR_NONE }, + { WWT_DROPDOWN_BUTTON, 1, 142, 152, 230, 234, STR_NUMERIC_UP, STR_NONE }, + { WWT_DROPDOWN_BUTTON, 1, 142, 152, 235, 239, STR_NUMERIC_DOWN, STR_NONE }, + { WIDGETS_END }, +}; + +static rct_widget window_finances_cash_widgets[] = { + { WWT_FRAME, 0, 0, 529, 0, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 528, 1, 14, STR_FINANCIAL_GRAPH, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 517, 527, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 529, 43, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_FINANCES_SHOW_SUMMARY_TAB_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_SHOW_CASH_TAB_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_FINANCES_SHOW_MARKETING_TAB_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, + { WIDGETS_END }, +}; + +static rct_widget window_finances_park_value_widgets[] = { + { WWT_FRAME, 0, 0, 529, 0, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 528, 1, 14, STR_PARK_VALUE_GRAPH, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 517, 527, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 529, 43, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_FINANCES_SHOW_SUMMARY_TAB_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_SHOW_CASH_TAB_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_FINANCES_SHOW_MARKETING_TAB_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, + { WIDGETS_END }, +}; + +static rct_widget window_finances_profit_widgets[] = { + { WWT_FRAME, 0, 0, 529, 0, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 528, 1, 14, STR_PROFIT_GRAPH, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 517, 527, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 529, 43, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_FINANCES_SHOW_SUMMARY_TAB_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_SHOW_CASH_TAB_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_FINANCES_SHOW_MARKETING_TAB_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, + { WIDGETS_END }, +}; + +static rct_widget window_finances_marketing_widgets[] = { + { WWT_FRAME, 0, 0, 529, 0, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 528, 1, 14, STR_MARKETING, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 517, 527, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 529, 43, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_FINANCES_SHOW_SUMMARY_TAB_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_SHOW_CASH_TAB_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_FINANCES_SHOW_MARKETING_TAB_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, + { WWT_GROUPBOX, 2, 3, 526, 47, 91, STR_MARKETING_CAMPAIGNS_IN_OPERATION, STR_NONE }, + { WWT_GROUPBOX, 2, 3, 526, 47, 252, STR_MARKETING_CAMPAIGNS_AVAILABLE, STR_NONE }, + { WWT_IMGBTN, 1, 8, 521, 0, 11, 0xFFFFFFFF, STR_START_THIS_MARKETING_CAMPAIGN }, + { WWT_IMGBTN, 1, 8, 521, 0, 11, 0xFFFFFFFF, STR_START_THIS_MARKETING_CAMPAIGN }, + { WWT_IMGBTN, 1, 8, 521, 0, 11, 0xFFFFFFFF, STR_START_THIS_MARKETING_CAMPAIGN }, + { WWT_IMGBTN, 1, 8, 521, 0, 11, 0xFFFFFFFF, STR_START_THIS_MARKETING_CAMPAIGN }, + { WWT_IMGBTN, 1, 8, 521, 0, 11, 0xFFFFFFFF, STR_START_THIS_MARKETING_CAMPAIGN }, + { WWT_IMGBTN, 1, 8, 521, 0, 11, 0xFFFFFFFF, STR_START_THIS_MARKETING_CAMPAIGN }, + { WIDGETS_END }, +}; + +static rct_widget window_finances_research_widgets[] = { + { WWT_FRAME, 0, 0, 529, 0, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_CAPTION, 0, 1, 528, 1, 14, STR_RESEARCH_FUNDING, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 517, 527, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_RESIZE, 1, 0, 529, 43, 256, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_FINANCES_SHOW_SUMMARY_TAB_TIP }, + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_FINANCES_SHOW_CASH_TAB_TIP }, + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_FINANCES_SHOW_PARK_VALUE_TAB_TIP }, + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, STR_FINANCES_SHOW_WEEKLY_PROFIT_TAB_TIP }, + { WWT_TAB, 1, 127, 157, 17, 43, 0x2000144E, STR_FINANCES_SHOW_MARKETING_TAB_TIP }, + { WWT_TAB, 1, 158, 188, 17, 43, 0x2000144E, STR_FINANCES_RESEARCH }, + { WWT_GROUPBOX, 2, 3, 316, 47, 91, STR_RESEARCH_FUNDING_, STR_NONE }, + { WWT_DROPDOWN, 2, 8, 167, 59, 70, 0xFFFFFFFF, STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT }, + { WWT_DROPDOWN_BUTTON, 2, 156, 166, 60, 69, 876, STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT }, + { WWT_GROUPBOX, 2, 3, 316, 96, 202, STR_RESEARCH_PRIORITIES, STR_NONE }, + { WWT_CHECKBOX, 2, 8, 311, 108, 119, STR_RESEARCH_TRANSPORT_RIDES, STR_RESEARCH_NEW_TRANSPORT_RIDES }, + { WWT_CHECKBOX, 2, 8, 311, 121, 132, STR_RESEARCH_GENTLE_RIDES, STR_RESEARCH_NEW_GENTLE_RIDES }, + { WWT_CHECKBOX, 2, 8, 311, 134, 145, STR_RESEARCH_ROLLER_COASTERS, STR_RESEARCH_NEW_ROLLER_COASTERS }, + { WWT_CHECKBOX, 2, 8, 311, 147, 158, STR_RESEARCH_THRILL_RIDES, STR_RESEARCH_NEW_THRILL_RIDES }, + { WWT_CHECKBOX, 2, 8, 311, 160, 171, STR_RESEARCH_WATER_RIDES, STR_RESEARCH_NEW_WATER_RIDES }, + { WWT_CHECKBOX, 2, 8, 311, 173, 184, STR_RESEARCH_SHOPS_AND_STALLS, STR_RESEARCH_NEW_SHOPS_AND_STALLS }, + { WWT_CHECKBOX, 2, 8, 311, 186, 197, STR_RESEARCH_SCENERY_AND_THEMING, STR_RESEARCH_NEW_SCENERY_AND_THEMING }, + { WIDGETS_END }, +}; + +static rct_widget *window_finances_page_widgets[] = { + window_finances_summary_widgets, + window_finances_cash_widgets, + window_finances_park_value_widgets, + window_finances_profit_widgets, + window_finances_marketing_widgets, + window_finances_research_widgets +}; + +#pragma endregion + +#pragma region Events + +static void* window_finances_page_events[] = { + (void*)0x00988EB8, + (void*)0x00988F28, + (void*)0x00988F98, + (void*)0x00989008, + (void*)0x00989078, + (void*)0x009890E8 +}; + +#pragma endregion + +#pragma region Enabled widgets + +static uint32 window_finances_page_enabled_widgets[] = { + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6) | + (1 << WIDX_LOAN_INCREASE) | + (1 << WIDX_LOAN_DECREASE), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6) | + (1 << WIDX_CAMPAIGN_1) | + (1 << WIDX_CAMPAIGN_2) | + (1 << WIDX_CAMPAIGN_3) | + (1 << WIDX_CAMPAIGN_4) | + (1 << WIDX_CAMPAIGN_5) | + (1 << WIDX_CAMPAIGN_6), + + (1 << WIDX_CLOSE) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3) | + (1 << WIDX_TAB_4) | + (1 << WIDX_TAB_5) | + (1 << WIDX_TAB_6) | + + (1 << WIDX_RESEARCH_FUNDING) | + (1 << WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON) | + (1 << WIDX_TRANSPORT_RIDES) | + (1 << WIDX_GENTLE_RIDES) | + (1 << WIDX_ROLLER_COASTERS) | + (1 << WIDX_THRILL_RIDES) | + (1 << WIDX_WATER_RIDES) | + (1 << WIDX_SHOPS_AND_STALLS) | + (1 << WIDX_SCENERY_AND_THEMING) +}; + +#pragma endregion /** * @@ -36,5 +276,34 @@ enum { */ void window_finances_open() { - RCT2_CALLPROC_EBPSAFE(0x0069DDF1); + rct_window *w; + + w = window_bring_to_front_by_id(WC_FINANCES, 0); + if (w == NULL) { + w = window_create_auto_pos(530, 257, window_finances_page_events[0], WC_FINANCES, WF_10); + w->widgets = window_finances_page_widgets[0]; + w->enabled_widgets = 0x1BF4; + w->number = 0; + w->page = 0; + w->var_48E = 0; + w->disabled_widgets = 0; + w->colours[0] = 1; + w->colours[1] = 19; + w->colours[2] = 19; + RCT2_CALLPROC_EBPSAFE(0x00684BAE); + } + + w->page = 0; + window_invalidate(w); + w->width = 530; + w->height = 257; + window_invalidate(w); + + w->widgets = window_finances_page_widgets[0]; + w->enabled_widgets = window_finances_page_enabled_widgets[0]; + w->var_020 = RCT2_GLOBAL(0x00988E3C, uint32); + w->event_handlers = window_finances_page_events[0]; + w->pressed_widgets = 0; + w->disabled_widgets = 0; + window_init_scroll_widgets(w); } \ No newline at end of file From ab697f8f930a0110108a4cfc058b3d51ef4ab7f3 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 01:29:59 +0100 Subject: [PATCH 071/209] add more to finances window --- src/window_finances.c | 131 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/src/window_finances.c b/src/window_finances.c index 1a00f51511..335635385e 100644 --- a/src/window_finances.c +++ b/src/window_finances.c @@ -24,12 +24,13 @@ #include "window.h" enum { - WINDOW_FINANCES_TAB_SUMMARY, - WINDOW_FINANCES_TAB_FINANCIAL_GRAPH, - WINDOW_FINANCES_TAB_VALUE_GRAPH, - WINDOW_FINANCES_TAB_PROFIT_GRAPH, - WINDOW_FINANCES_TAB_MARKETING, - WINDOW_FINANCES_TAB_RESEARCH + WINDOW_FINANCES_PAGE_SUMMARY, + WINDOW_FINANCES_PAGE_FINANCIAL_GRAPH, + WINDOW_FINANCES_PAGE_VALUE_GRAPH, + WINDOW_FINANCES_PAGE_PROFIT_GRAPH, + WINDOW_FINANCES_PAGE_MARKETING, + WINDOW_FINANCES_PAGE_RESEARCH, + WINDOW_FINANCES_PAGE_COUNT }; enum { @@ -270,6 +271,11 @@ static uint32 window_finances_page_enabled_widgets[] = { #pragma endregion +const int window_finances_tab_animation_loops[] = { 16, 32, 32, 32, 38, 16 }; + +static void window_finances_set_page(rct_window *w, int page); +static void window_finances_set_pressed_tab(rct_window *w); + /** * * rct2: 0x0069DDF1 @@ -306,4 +312,115 @@ void window_finances_open() w->pressed_widgets = 0; w->disabled_widgets = 0; window_init_scroll_widgets(w); -} \ No newline at end of file +} + +#pragma region Summary page + +/** + * + * rct2: 0x0069CA99 + */ +static void window_finances_summary_mouseup() +{ + short widgetIndex; + rct_window *w; + + #ifdef _MSC_VER + __asm mov widgetIndex, dx + #else + __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); + #endif + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); + #endif + + if (widgetIndex == WIDX_CLOSE) + window_close(w); + else if (widgetIndex >= WIDX_TAB_1 && widgetIndex <= WIDX_TAB_6) + window_finances_set_page(w, widgetIndex - WIDX_TAB_1); +} + +/** + * + * rct2: 0x0069CBA6 + */ +static void window_finances_summary_update(rct_window *w) +{ + // Tab animation + if (++w->var_48E >= window_finances_tab_animation_loops[w->page]) + w->var_48E = 0; + widget_invalidate(w->classification, w->number, WIDX_TAB_1); +} + +/** + * + * rct2: 0x0069C732 + */ +static void window_finances_summary_invalidate() +{ + rct_window *w; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); + #endif + + if (w->widgets != window_finances_page_widgets[0]) { + w->widgets = window_finances_page_widgets[0]; + window_init_scroll_widgets(w); + } + + window_finances_set_pressed_tab(w); + RCT2_GLOBAL(0x013CE952 + 6, money32) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32); +} + +#pragma endregion + +#pragma region Common + +/** + * + * rct2: 0x0069CAC5 + */ +static void window_finances_set_page(rct_window *w, int page) +{ + w->page = page; + w->var_48E = 0; + if (w->viewport != NULL) { + w->viewport->width = 0; + w->viewport = NULL; + } + + w->enabled_widgets = window_finances_page_enabled_widgets[page]; + w->var_020 = RCT2_ADDRESS(0x00988E3C, uint32)[page]; + w->widgets = window_finances_page_widgets[page]; + w->disabled_widgets = 0; + + window_invalidate(w); + if (w->page == WINDOW_FINANCES_PAGE_RESEARCH) { + w->width = 320; + w->height = 207; + } else { + w->width = 530; + w->height = 257; + } + RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0); + RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0); + + window_init_scroll_widgets(w); + window_invalidate(w); +} + +static void window_finances_set_pressed_tab(rct_window *w) +{ + int i; + for (i = 0; i < WINDOW_FINANCES_PAGE_COUNT; i++) + w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); + w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page); +} + +#pragma endregion \ No newline at end of file From 35ff9a510d41899087a8927b92eaacebcd3ebbdd Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Mon, 26 May 2014 09:27:54 +0200 Subject: [PATCH 072/209] Fixed returning pointer from a local buffer --- src/config.c | 6 +++--- src/osinterface.c | 3 ++- src/screenshot.c | 6 +++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/config.c b/src/config.c index 1c428787a2..d2ec11087f 100644 --- a/src/config.c +++ b/src/config.c @@ -216,13 +216,11 @@ void config_save() */ void config_init() { - char path[MAX_PATH]; + char *path = osinterface_get_orct2_homefolder(); FILE* fp; memcpy(&gGeneral_config, &gGeneral_config_default, sizeof(general_configuration_t)); - strncpy(path, osinterface_get_orct2_homefolder(), MAX_PATH); - if (strcmp(path, "") != 0){ DWORD dwAttrib = GetFileAttributes(path); if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { // folder does not exist @@ -245,6 +243,8 @@ void config_init() fclose(fp); } + + free(path); } /** diff --git a/src/osinterface.c b/src/osinterface.c index 974c9da05d..5a17fae968 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -431,7 +431,8 @@ char* osinterface_open_directory_browser(char *title) { char* osinterface_get_orct2_homefolder() { - char path[260]=""; + char *path; + path = malloc(sizeof(char) * MAX_PATH); if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) { // find home folder strcat(path, "\\OpenRCT2"); diff --git a/src/screenshot.c b/src/screenshot.c index 6e040686b6..475b09452c 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -60,17 +60,21 @@ void screenshot_check() static int screenshot_get_next_path(char *path, char *extension) { + char *homePath = osinterface_get_orct2_homefolder(); + int i; for (i = 1; i < 1000; i++) { RCT2_GLOBAL(0x013CE952, uint16) = i; // Glue together path and filename - sprintf(path, "%s%cSCR%d%s", osinterface_get_orct2_homefolder(), osinterface_get_path_separator(), i, extension); + sprintf(path, "%s%cSCR%d%s", homePath, osinterface_get_path_separator(), i, extension); if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) return i; } + free(homePath); + return -1; } From 16c0bde2f43811bde4aa33ed392433e66fa48b9c Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Mon, 26 May 2014 09:34:14 +0200 Subject: [PATCH 073/209] Check if path could be allocated, initialize it with an empty string. --- src/osinterface.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/osinterface.c b/src/osinterface.c index 5a17fae968..fdc237d4ad 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -431,8 +431,14 @@ char* osinterface_open_directory_browser(char *title) { char* osinterface_get_orct2_homefolder() { - char *path; + char *path=NULL; path = malloc(sizeof(char) * MAX_PATH); + if (path == NULL){ + osinterface_show_messagebox("Error allocating memory!"); + exit(EXIT_FAILURE); + } + + path[0] = '\0'; if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) { // find home folder strcat(path, "\\OpenRCT2"); From c2d5ec4381dfe999f24091d9bbe3328eaad883a2 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 13:50:37 +0100 Subject: [PATCH 074/209] fix #146, broken ride structure --- src/ride.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ride.h b/src/ride.h index 6d1c7ab6d7..faa9cb44bd 100644 --- a/src/ride.h +++ b/src/ride.h @@ -55,7 +55,7 @@ typedef struct { uint8 var_0C8; uint8 var_0C9; - uint8 pad_0CA[0x1B]; + uint8 pad_0CA[0x1A]; sint32 var_0E4; sint32 var_0E8; @@ -65,7 +65,7 @@ typedef struct { uint8 var_114; // Track length? Number of track segments? uint8 var_115; - uint8 pad_116[0x0F]; + uint8 pad_116[0x0E]; sint16 var_124; sint16 var_126; sint16 var_128; From 70d3d652c5fa134b962f779edd140a7f92ae7cde Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 14:12:43 +0100 Subject: [PATCH 075/209] add saving of screenshots in subfolder --- src/config.c | 8 +++----- src/osinterface.c | 25 +++++++++++++++++++++++-- src/osinterface.h | 4 ++++ src/screenshot.c | 10 +++++++--- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/config.c b/src/config.c index d2ec11087f..11fdf54b97 100644 --- a/src/config.c +++ b/src/config.c @@ -222,11 +222,9 @@ void config_init() memcpy(&gGeneral_config, &gGeneral_config_default, sizeof(general_configuration_t)); if (strcmp(path, "") != 0){ - DWORD dwAttrib = GetFileAttributes(path); - if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { // folder does not exist - if (!CreateDirectory(path, NULL)) { - config_error("Could not create config file (do you have write access to your documents folder?)"); - } + if (!osinterface_ensure_directory_exists(path)) { + config_error("Could not create config file (do you have write access to your documents folder?)"); + return; } sprintf(path, "%s%c%s", path, osinterface_get_path_separator(), "config.ini"); diff --git a/src/osinterface.c b/src/osinterface.c index fdc237d4ad..843b37f712 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -440,13 +440,34 @@ char* osinterface_get_orct2_homefolder() path[0] = '\0'; - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) { // find home folder + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) strcat(path, "\\OpenRCT2"); - } return path; } +char *osinterface_get_orct2_homesubfolder(const char *subFolder) +{ + char *path = osinterface_get_orct2_homefolder(); + strcat(path, "\\"); + strcat(path, subFolder); + return path; +} + +int osinterface_directory_exists(const char *path) +{ + DWORD dwAttrib = GetFileAttributes(path); + return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY); +} + +int osinterface_ensure_directory_exists(const char *path) +{ + if (osinterface_directory_exists(path)) + return 1; + + return CreateDirectory(path, NULL); +} + char osinterface_get_path_separator() { return '\\'; diff --git a/src/osinterface.h b/src/osinterface.h index 50f78904a0..88576a980a 100644 --- a/src/osinterface.h +++ b/src/osinterface.h @@ -51,6 +51,10 @@ void osinterface_show_messagebox(char* message); char* osinterface_open_directory_browser(char *title); char* osinterface_get_orct2_homefolder(); +char *osinterface_get_orct2_homesubfolder(const char *subFolder); +int osinterface_directory_exists(const char *path); +int osinterface_ensure_directory_exists(const char *path); + char osinterface_get_path_separator(); #endif diff --git a/src/screenshot.c b/src/screenshot.c index 475b09452c..42a0cd21c7 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -60,20 +60,24 @@ void screenshot_check() static int screenshot_get_next_path(char *path, char *extension) { - char *homePath = osinterface_get_orct2_homefolder(); + char *screenshotPath = osinterface_get_orct2_homesubfolder("screenshot"); + if (!osinterface_ensure_directory_exists(screenshotPath)) { + fprintf(stderr, "Unable to save screenshots in OpenRCT2 screenshot directory.\n"); + return -1; + } int i; for (i = 1; i < 1000; i++) { RCT2_GLOBAL(0x013CE952, uint16) = i; // Glue together path and filename - sprintf(path, "%s%cSCR%d%s", homePath, osinterface_get_path_separator(), i, extension); + sprintf(path, "%s%cSCR%d%s", screenshotPath, osinterface_get_path_separator(), i, extension); if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) return i; } - free(homePath); + free(screenshotPath); return -1; } From a22534e09943d6f34376773bc94ffe0851a57b01 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 14:14:03 +0100 Subject: [PATCH 076/209] free path in screenshot.c --- src/screenshot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/screenshot.c b/src/screenshot.c index 42a0cd21c7..7e74ed32f1 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -62,6 +62,8 @@ static int screenshot_get_next_path(char *path, char *extension) { char *screenshotPath = osinterface_get_orct2_homesubfolder("screenshot"); if (!osinterface_ensure_directory_exists(screenshotPath)) { + free(screenshotPath); + fprintf(stderr, "Unable to save screenshots in OpenRCT2 screenshot directory.\n"); return -1; } @@ -78,7 +80,6 @@ static int screenshot_get_next_path(char *path, char *extension) } free(screenshotPath); - return -1; } From 8bdba74ba690be5507567fb62cc96f1172f9eb3d Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 15:22:52 +0200 Subject: [PATCH 077/209] Cleanup and refactoring of ride reachability stuff --- src/map.c | 38 +++++++++++++++++++- src/map.h | 2 ++ src/ride.c | 95 ++++++++++---------------------------------------- src/scenario.c | 1 + 4 files changed, 59 insertions(+), 77 deletions(-) diff --git a/src/map.c b/src/map.c index 581eabdf30..b7e1ca0ae4 100644 --- a/src/map.c +++ b/src/map.c @@ -329,4 +329,40 @@ void sub_68B089() } while (mapElement->base_height == 255); mapElement++; RCT2_GLOBAL(0x0140E9A4, rct_map_element*) = mapElement; -} \ No newline at end of file +} + + +/** + * Checks if the tile at coordinate at height counts as connected. + * @return 1 if connected, 0 otherwisei + */ +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + diff --git a/src/map.h b/src/map.h index 88e76d7e11..1a44bd616c 100644 --- a/src/map.h +++ b/src/map.h @@ -186,5 +186,7 @@ void map_init(); void map_update_tile_pointers(); int map_element_height(int x, int y); void sub_68B089(); +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction); + #endif diff --git a/src/ride.c b/src/ride.c index 296936e935..34cba0b8ef 100644 --- a/src/ride.c +++ b/src/ride.c @@ -204,51 +204,21 @@ void ride_update_favourited_stat() } -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) -{ - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; - - do { - rct_map_element_path_properties props = tile->properties.path; - uint8 path_type = props.type >> 2, path_dir = props.type & 3; - uint8 element_type = tile->type & 0x3C; - - if (!(element_type & PATH_ROAD)) - continue; - - if (path_type & 1) { - if (path_dir == face_direction) { - if (height == tile->base_height + 2) - return 1; - } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { - return 1; - } - } else { - if (height == tile->base_height) - return 1; - } - - } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); - - return 0; -} - /** * rct2: 0x006B7C59 * @return 1 if the coordinate is reachable or has no entrance, 0 otw */ -int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { +int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] - int tile_idx = ((x << 8) | y) >> 3; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while(1) { - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { break; } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { @@ -260,37 +230,9 @@ int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { uint8 face_direction = tile->type & 3; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; return map_coord_is_connected(tile_idx, station_height, face_direction); - /* while (1) { */ - /* rct_map_element_path_properties props; */ - - /* element_type = tile->type & 0x3C; */ - /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ - /* goto end; */ - - /* props = tile->properties.path; */ - /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ - /* if ((props.type & 3) == face_direction) { */ - /* if (station_height == tile->base_height + 2) */ - /* return 1; */ - /* } */ - /* else { */ - /* uint8 madness = (props.type & 3) ^ 2; */ - /* if (madness == face_direction && station_height == tile->base_height) */ - /* return 1; */ - /* } */ - /* } else { // off-road only same height counts as connected */ - /* if (station_height == tile->base_height) */ - /* return 1; */ - /* } */ - - /* end: */ - /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ - /* return 0; */ - /* tile++; */ - /* } */ } @@ -303,14 +245,14 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; - if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); ride->var_1AF = 3; } - if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -321,18 +263,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void blue_reachable(rct_ride* ride, int ride_idx) +void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[ride_idx]; int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; - int tile_idx = ((x << 8) | y) >> 3, count = 0; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while (1) { - // First find the appropriate track element for our ride - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) break; @@ -342,7 +283,8 @@ void blue_reachable(rct_ride* ride, int ride_idx) } uint8 track_type = tile->properties.track.type; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + ride = GET_RIDE(tile->properties.track.ride_index); + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } else { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; @@ -350,7 +292,9 @@ void blue_reachable(rct_ride* ride, int ride_idx) magic = magic << (tile->type & 3); magic = ((magic >> 12) | magic) & 0xF; - + if (magic == 0) + return; + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { magic >>= 1; @@ -360,7 +304,7 @@ void blue_reachable(rct_ride* ride, int ride_idx) uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; if (map_coord_is_connected(tile, tile->base_height, face_direction)) return; @@ -379,7 +323,6 @@ void blue_reachable(rct_ride* ride, int ride_idx) **/ void ride_check_all_reachable() { -/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ rct_ride *ride; for (int i = 0; i < MAX_RIDES; i++) { @@ -392,8 +335,8 @@ void ride_check_all_reachable() continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //lightblue - blue_reachable(ride, i); + //blue + ride_is_shop_reachable(ride, i); return; } else { diff --git a/src/scenario.c b/src/scenario.c index c71abc6b55..e3137d1296 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -858,6 +858,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); + ride_check_all_reachable(); RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From c783898b361955fb440bc5a65c2401cd8d736e2b Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 14:36:07 +0100 Subject: [PATCH 078/209] fix #143, incorrect object entry group addresses --- src/object_list.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/object_list.c b/src/object_list.c index 3bb9901414..0a318e71e8 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -51,15 +51,15 @@ int object_entry_group_counts[] = { struct { void **data; rct_object_entry_extended *entries; } object_entry_groups[] = { (void**)(0x009ACFA4 ), (rct_object_entry_extended*)(0x00F3F03C ), // rides (void**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // small scenery - (void**)(0x009ACFA4 + (252 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (252 * 20)), // large scenery - (void**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // walls - (void**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // banners - (void**)(0x009ACFA4 + ( 32 * 4)), (rct_object_entry_extended*)(0x00F3F03C + ( 32 * 20)), // paths - (void**)(0x009ACFA4 + ( 16 * 4)), (rct_object_entry_extended*)(0x00F3F03C + ( 16 * 20)), // path bits - (void**)(0x009ACFA4 + ( 15 * 4)), (rct_object_entry_extended*)(0x00F3F03C + ( 15 * 20)), // scenery sets - (void**)(0x009ACFA4 + ( 19 * 4)), (rct_object_entry_extended*)(0x00F3F03C + ( 19 * 20)), // park entrance - (void**)(0x009ACFA4 + ( 1 * 4)), (rct_object_entry_extended*)(0x00F3F03C + ( 1 * 20)), // water - (void**)(0x009ACFA4 + ( 1 * 4)), (rct_object_entry_extended*)(0x00F3F03C + ( 1 * 20)) // scenario text + (void**)(0x009ACFA4 + (380 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (380 * 20)), // large scenery + (void**)(0x009ACFA4 + (508 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (508 * 20)), // walls + (void**)(0x009ACFA4 + (636 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (636 * 20)), // banners + (void**)(0x009ACFA4 + (668 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (668 * 20)), // paths + (void**)(0x009ACFA4 + (684 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (684 * 20)), // path bits + (void**)(0x009ACFA4 + (699 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (699 * 20)), // scenery sets + (void**)(0x009ACFA4 + (718 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (718 * 20)), // park entrance + (void**)(0x009ACFA4 + (719 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (719 * 20)), // water + (void**)(0x009ACFA4 + (720 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (720 * 20)) // scenario text }; /** From 4993e6bed0c9b499934a6534a12c952d488c5e2f Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 17:39:18 +0200 Subject: [PATCH 079/209] Fix lots of disgusting bugs --- src/map.c | 6 +++--- src/ride.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/map.c b/src/map.c index b7e1ca0ae4..ce32cde185 100644 --- a/src/map.c +++ b/src/map.c @@ -336,16 +336,16 @@ void sub_68B089() * Checks if the tile at coordinate at height counts as connected. * @return 1 if connected, 0 otherwisei */ -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) { - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; do { rct_map_element_path_properties props = tile->properties.path; uint8 path_type = props.type >> 2, path_dir = props.type & 3; uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; - if (!(element_type & PATH_ROAD)) + if (element_type != PATH_ROAD) continue; if (path_type & 1) { diff --git a/src/ride.c b/src/ride.c index 34cba0b8ef..8a8aba7d39 100644 --- a/src/ride.c +++ b/src/ride.c @@ -284,10 +284,10 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; - } else { + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } magic = magic << (tile->type & 3); @@ -295,18 +295,19 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) if (magic == 0) return; - for (int count = 0; magic != 0; ++count) { + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { - magic >>= 1; + magic >>= 1; continue; } + magic >>= 1; uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; - if (map_coord_is_connected(tile, tile->base_height, face_direction)) + if (map_coord_is_connected(tile_idx, tile->base_height, face_direction)) return; } @@ -337,7 +338,6 @@ void ride_check_all_reachable() if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { //blue ride_is_shop_reachable(ride, i); - return; } else { //pink From ee67b3b7037adface5d38dc6e92e00597d543852 Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 18:19:34 +0200 Subject: [PATCH 080/209] More critical bugfixes for the reachability code. --- src/ride.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ride.c b/src/ride.c index 8a8aba7d39..0110d83caa 100644 --- a/src/ride.c +++ b/src/ride.c @@ -265,13 +265,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { - uint16 coordinate = ride->station_starts[ride_idx]; + uint16 coordinate = ride->station_starts[0]; + if (coordinate == 0xFFFF) + return; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while (1) { uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) From 7190e4c3f635d0ca29db1393bb261dcc45f9b23d Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 17:59:42 +0100 Subject: [PATCH 081/209] implement object_get_scenario_text --- src/object.c | 190 +++++++++++++++++++++++++++++++++++++++++++--- src/object.h | 5 +- src/object_list.c | 36 +-------- src/scenario.c | 6 +- 4 files changed, 191 insertions(+), 46 deletions(-) diff --git a/src/object.c b/src/object.c index c09c3de10a..58f4dd33b6 100644 --- a/src/object.c +++ b/src/object.c @@ -18,8 +18,11 @@ * along with this program. If not, see . *****************************************************************************/ +#include +#include #include "addresses.h" #include "object.h" +#include "sawyercoding.h" /** * @@ -47,19 +50,188 @@ void object_unload(int groupIndex, rct_object_entry_extended *entry) RCT2_CALLPROC_X(0x006A9CAF, 0, groupIndex, 0, 0, 0, 0, (int)entry); } +static int object_entry_compare(rct_object_entry *a, rct_object_entry *b) +{ + if (a->flags & 0xF0) { + if ((a->flags & 0x0F) != (b->flags & 0x0F)) + return 0; + if (*((uint32*)a->name) != *((uint32*)b->name)) + return 0; + if (*((uint32*)(&a->name[4])) != *((uint32*)(&b->name[4]))) + return 0; + } else { + if (a->flags != b->flags) + return 0; + if (*((uint32*)a->name) != *((uint32*)b->name)) + return 0; + if (*((uint32*)(&a->name[4])) != *((uint32*)(&b->name[4]))) + return 0; + if (a->checksum != b->checksum) + return 0; + } + + return 1; +} + +static int object_calculate_checksum(rct_object_entry *entry, char *data, int dataLength) +{ + int i; + char *eee = (char*)entry; + int checksum = 0xF369A75B; + char *ccc = (char*)&checksum; + + *ccc ^= eee[0]; + checksum = rol32(checksum, 11); + for (i = 4; i < 12; i++) { + *ccc ^= eee[i]; + checksum = rol32(checksum, 11); + } + for (i = 0; i < dataLength; i++) { + *ccc ^= data[i]; + checksum = rol32(checksum, 11); + } + + return checksum; +} + +int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp) +{ + RCT2_CALLPROC_X(RCT2_ADDRESS(0x0098D9D4, uint32)[type], eax, ebx, ecx, edx, esi, edi, ebp); + #ifdef _MSC_VER + __asm jb success + #else + __asm__ goto ( "jb %l0" : : : : success ); + #endif + return 0; +success: + return 1; +} + /** * * rct2: 0x006A9428 */ -int sub_6A9428(rct_object_entry* entry) +int object_get_scenario_text(rct_object_entry *entry) { - RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry); - #ifdef _MSC_VER - __asm jb fail - #else - __asm__ goto ( "jb %l0" : : : : fail ); - #endif - return 1; -fail: + // RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry); return; + + int i; + rct_object_entry *installedObject = RCT2_GLOBAL(0x009ADAE8, rct_object_entry*); + for (i = 0; i < RCT2_GLOBAL(0x00F42B6C, sint32); i++) { + if (object_entry_compare(installedObject, entry)) { + char path[260]; + char *objectPath = (char*)installedObject + 16; + subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath); + + rct_object_entry openedEntry; + FILE *file = fopen(path, "rb"); + if (file != NULL) { + fread(&openedEntry, sizeof(rct_object_entry), 1, file); + if (object_entry_compare(&openedEntry, entry)) { + + // Get chunk size + char *pos = (char*)installedObject + 16; + do { + pos++; + } while (*(pos - 1) != 0); + + // Read chunk + int chunkSize = *((uint32*)pos); + char *chunk; + if (chunkSize == 0xFFFFFFFF) { + chunk = malloc(0x600000); + chunkSize = sawyercoding_read_chunk(file, chunk); + chunk = realloc(chunk, chunkSize); + } else { + chunk = malloc(chunkSize); + sawyercoding_read_chunk(file, chunk); + } + fclose(file); + + // Calculate and check checksum + if (object_calculate_checksum(&openedEntry, chunk, chunkSize) != openedEntry.checksum) { + RCT2_GLOBAL(0x00F42BD9, uint8) = 2; + free(chunk); + return 0; + } + + if (object_paint(openedEntry.flags & 0x0F, 2, 0, 0, 0, (int)chunk, 0, 0)) { + RCT2_GLOBAL(0x00F42BD9, uint8) = 3; + free(chunk); + return 0; + } + + int yyy = RCT2_GLOBAL(0x009ADAF0, uint32); + RCT2_GLOBAL(0x009ADAF0, uint32) = 0x726E; + RCT2_GLOBAL(0x009ADAF8, uint32) = (int)chunk; + *((rct_object_entry*)0x00F42BC8) = openedEntry; + + RCT2_GLOBAL(0x009ADAFC, uint8) = 255; + RCT2_GLOBAL(0x009ADAFD, uint8) = 1; + object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0); + RCT2_GLOBAL(0x009ADAFC, uint8) = 0; + RCT2_GLOBAL(0x009ADAFD, uint8) = 0; + RCT2_GLOBAL(0x009ADAF0, uint32) = yyy; + return 1; + } + fclose(file); + } + } + installedObject = object_get_next(installedObject); + } + + RCT2_GLOBAL(0x00F42BD9, uint8) = 0; return 0; +} + +/** + * + * rct2: 0x006A982D + */ +void object_free_scenario_text() +{ + if (RCT2_GLOBAL(0x009ADAF8, void*) != NULL) { + free(RCT2_GLOBAL(0x009ADAF8, void*)); + RCT2_GLOBAL(0x009ADAF8, void*) = NULL; + } +} + +int object_get_length(rct_object_entry *entry) +{ + return (int)object_get_next(entry) - (int)entry; +} + +rct_object_entry *object_get_next(rct_object_entry *entry) +{ + char *pos = (char*)entry; + + // Skip + pos += 16; + + // Skip filename + do { + pos++; + } while (*(pos - 1) != 0); + + // Skip + pos += 4; + + // Skip name + do { + pos++; + } while (*(pos - 1) != 0); + + // Skip + pos += 4; + + // Skip + pos += *pos++ * 16; + + // Skip theme objects + pos += *pos++ * 16; + + // Skip + pos += 4; + + return (rct_object_entry*)pos; } \ No newline at end of file diff --git a/src/object.h b/src/object.h index ea6f47103f..a9d8bdbdfc 100644 --- a/src/object.h +++ b/src/object.h @@ -52,6 +52,9 @@ void object_unload_all(); int object_load(int groupIndex, rct_object_entry *entry); void object_unload(int groupIndex, rct_object_entry_extended *entry); -int sub_6A9428(rct_object_entry* entry); +int object_get_scenario_text(rct_object_entry *entry); +void object_free_scenario_text(); +int object_get_length(rct_object_entry *entry); +rct_object_entry *object_get_next(rct_object_entry *entry); #endif diff --git a/src/object_list.c b/src/object_list.c index 0a318e71e8..78d5686d07 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -69,42 +69,14 @@ struct { void **data; rct_object_entry_extended *entries; } object_entry_groups[ static void object_list_examine() { int i; - char *object; + rct_object_entry *object; - object = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, char*); + object = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); for (i = 0; i < RCT2_GLOBAL(0x00F42B6C, sint32); i++) { - if (*object & 0xF0) + if (object->flags & 0xF0) RCT2_GLOBAL(0x00F42BDA, uint8) |= 1; - // Skip - object += 16; - - // Skip filename - // printf("%d %s : ", i, object); - do { - object++; - } while (*(object - 1) != 0); - - // Skip - object += 4; - - // Skip name - // printf("%s\n", object); - do { - object++; - } while (*(object - 1) != 0); - - // Skip - object += 4; - - // Skip - object += *object++ * 16; - - // Skip theme objects - object += *object++ * 16; - - // Skip - object += 4; + object = object_get_next(object); } } diff --git a/src/scenario.c b/src/scenario.c index 9fdd0c0003..c6a9c4d6d3 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -59,14 +59,12 @@ int scenario_load_basic(const char *path) // Checks for a scenario string object (possibly for localisation) if ((s6Info->entry.flags & 0xFF) != 255) { - if (sub_6A9428(&s6Info->entry)) { + if (object_get_scenario_text(&s6Info->entry)) { int ebp = RCT2_GLOBAL(0x009ADAF8, uint32); format_string(s6Info->name, RCT2_GLOBAL(ebp, sint16), NULL); format_string(s6Info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL); RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8); - - // Disposes the scenario string object (0x009ADAF8) - RCT2_CALLPROC_EBPSAFE(0x006A982D); + object_free_scenario_text(); } } return 1; From c07edd0d1039f45e515417a9d80c411935fca41f Mon Sep 17 00:00:00 2001 From: anyc Date: Mon, 26 May 2014 11:46:38 +0200 Subject: [PATCH 082/209] fix warning --- src/window_options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window_options.c b/src/window_options.c index fbb9897940..62939efcef 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -309,7 +309,7 @@ static void window_options_mousedown() // populate the list with the sound devices for (i = 0; i < gAudioDeviceCount; i++) { gDropdownItemsFormat[i] = 1142; - gDropdownItemsArgs[i] = 1170 | ((uint64)gAudioDevices[i].name << 16); + gDropdownItemsArgs[i] = 1170 | ((uint64)(intptr_t)gAudioDevices[i].name << 16); } gDropdownItemsChecked |= (1 << RCT2_GLOBAL(0x9AF280, uint32)); break; From fafc8083acda0040114c8d99e1078a57429efa24 Mon Sep 17 00:00:00 2001 From: anyc Date: Mon, 26 May 2014 22:22:05 +0200 Subject: [PATCH 083/209] don't show confirmation prompt for loading on title screen, fixes #145 --- src/window.h | 2 +- src/window_save_prompt.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/window.h b/src/window.h index be464a82b3..b46ff6fe59 100644 --- a/src/window.h +++ b/src/window.h @@ -286,7 +286,7 @@ enum { } WINDOW_CLASS; enum PROMPT_MODE { - PM_SAVE_BEFORE_LOAD, + PM_SAVE_BEFORE_LOAD = 0, PM_SAVE_BEFORE_QUIT, PM_SAVE_BEFORE_QUIT2, PM_QUIT diff --git a/src/window_save_prompt.c b/src/window_save_prompt.c index e4893c6414..a941875889 100644 --- a/src/window_save_prompt.c +++ b/src/window_save_prompt.c @@ -117,6 +117,12 @@ void window_save_prompt_open() prompt_mode = RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16); + // do not show save prompt if we're in the title demo and click on load game + if (prompt_mode != PM_QUIT && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO) { + game_load_or_quit_no_save_prompt(); + return; + } + // Check if window is already open window = window_bring_to_front_by_id(WC_SAVE_PROMPT, 0); if (window == NULL) { @@ -146,14 +152,13 @@ void window_save_prompt_open() y, (uint32*)window_save_prompt_events, WC_SAVE_PROMPT, - 0 + WF_TRANSPARENT | WF_STICK_TO_FRONT ); window->widgets = widgets; window->enabled_widgets = enabled_widgets; window_init_scroll_widgets(window); window->colours[0] = 154; - window->flags |= WF_TRANSPARENT; // Pause the game RCT2_GLOBAL(0x009DEA6E, uint8) |= 2; @@ -170,6 +175,12 @@ void window_save_prompt_open() window_save_prompt_widgets[WIDX_LABEL].image = prompt_mode + STR_SAVE_BEFORE_LOADING; if (!gGeneral_config.confirmation_prompt) { + /* game_load_or_quit_no_save_prompt() will exec requested task and close this window + * immediately again. + * TODO restructure these functions when we're sure game_load_or_quit_no_save_prompt() + * and game_load_or_quit() are not called by the original binary anymore. + */ + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0D) { game_load_or_quit_no_save_prompt(); return; From b8887876ea3ec2ddcb4fe987a395612e75f69c3b Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 26 May 2014 22:28:26 +0100 Subject: [PATCH 084/209] Cleaned up more asm code --- src/gfx.c | 78 ++++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 9f430b0cf2..ec8f0532bc 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -718,13 +718,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax &= 0x7F; } eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); - //To be fixed - palette_pointer = ((rct_g1_element**)RCT2_ADDRESS_G1_ELEMENTS)[eax]; - eax <<= 4; - eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - RCT2_GLOBAL(0x9ABDA4, uint32) = eax; - palette_pointer = eax; - assert(eax == palette_pointer); + + palette_pointer = ((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[eax].offset; + RCT2_GLOBAL(0x9ABDA4, uint32) = palette_pointer; } else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ //Has not been tested @@ -782,7 +778,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - + //G1_element bits? ebp = *((uint32*)(eax + 0xF3)); esi = *((uint32*)(eax + 0xF7)); RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; @@ -912,48 +908,42 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) return; } //0x67A60A - - esi -= (uint32)g1_source->offset; - ebp = (int)source_pointer; - eax = g1_source->width*g1_source->height; - esi = (int)g1_source->offset; - edx = eax; - edi = 0x9E3D28; - eax = 0; - while (edx>0){ - eax = *((sint8*)esi); - if (eax >= 0){ - esi++; - ecx = eax; - edx -= eax; - memcpy((char*)edi, (char*)esi, ecx); - edi += ecx; - esi += ecx; + int total_no_pixels = g1_source->width*g1_source->height; + source_pointer = g1_source->offset; + uint8* new_source_pointer_start = malloc(total_no_pixels); + uint8* new_source_pointer = new_source_pointer_start;// 0x9E3D28; + + while (total_no_pixels>0){ + sint8 no_pixels = *source_pointer; + if (no_pixels >= 0){ + source_pointer++; + total_no_pixels -= no_pixels; + memcpy((char*)new_source_pointer, (char*)source_pointer, no_pixels); + new_source_pointer += no_pixels; + source_pointer += no_pixels; continue; } - ecx = eax; - ebx = edi; - eax &= 0x7; - ecx >>= 3; + ecx = no_pixels; + no_pixels &= 0x7; + ecx >>= 3;//SAR eax <<= 8; - ecx = -ecx; - eax = eax & 0xFF00 + *((sint8*)esi); - edx -= ecx; - esi += 2; - ebx -= eax; - eax = esi; - esi = ebx; + ecx = -ecx;//Odd + eax = eax & 0xFF00 + *(source_pointer+1); + total_no_pixels -= ecx; + source_pointer += 2; + ebx = new_source_pointer - eax; + eax = source_pointer; + source_pointer = ebx; ebx = eax; eax = 0; - memcpy((char*)edi, (char*)esi, ecx); - edi += ecx; - esi += ecx; - esi = ebx; + memcpy((char*)new_source_pointer, (char*)source_pointer, ecx); + new_source_pointer += ecx; + source_pointer += ecx; + source_pointer = ebx; } - //edi poped off stack - esi = ebp; - esi += 0x9E3D28; - gfx_bmp_sprite_to_buffer(palette_pointer, (uint8*)esi, dest_pointer, g1_source, dpi, height, width, image_type); + source_pointer = new_source_pointer_start + g1_source->width*source_start_y + source_start_x; + gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); + free(new_source_pointer_start); return; } From 1b3c46c17d3f92756a52c332bc2c3fda23cd9001 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 26 May 2014 23:44:47 +0100 Subject: [PATCH 085/209] implement park_calculate_guest_generation_probability --- src/addresses.h | 3 + src/park.c | 134 +++++++++++++++++++++++++++++++++++++++++++-- src/park.h | 1 + src/ride.h | 14 ++++- src/ride_ratings.h | 12 +--- src/scenario.c | 6 +- 6 files changed, 149 insertions(+), 21 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index a13f7d286b..af36597a5a 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -176,6 +176,7 @@ #define RCT2_ADDRESS_PARK_FLAGS 0x013573E4 #define RCT2_ADDRESS_PARK_ENTRANCE_FEE 0x013573E8 #define RCT2_ADDRESS_GUESTS_IN_PARK 0x01357844 +#define RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK 0x01357846 #define RCT2_ADDRESS_MONTHLY_RIDE_INCOME 0x01357894 #define RCT2_ADDRESS_CURRENT_PARK_RATING 0x01357CB0 #define RCT2_ADDRESS_PARK_RATING_HISTORY 0x01357CB2 @@ -210,6 +211,8 @@ #define RCT2_ADDRESS_MAP_SIZE 0x01358834 #define RCT2_ADDRESS_PARK_SIZE 0x013580EA +#define RCT2_TOTAL_RIDE_VALUE 0x013580EE + #define RCT2_ADDRESS_SCENARIO_NAME 0x0135920A #define RCT2_ADDRESS_SCENARIO_DETAILS 0x0135924A diff --git a/src/park.c b/src/park.c index 191880ff0c..bd8984f684 100644 --- a/src/park.c +++ b/src/park.c @@ -31,6 +31,24 @@ #include "string_ids.h" #include "window.h" +int _suggestedGuestMaximum; + +int park_is_award_positive(int type) +{ + // Check if award is negative + switch (type) { + case PARK_AWARD_MOST_UNTIDY: + case PARK_AWARD_WORST_VALUE: + case PARK_AWARD_WORST_FOOD: + case PARK_AWARD_MOST_DISAPPOINTING: + case PARK_AWARD_MOST_CONFUSING_LAYOUT: + return 0; + } + + // Otherwise its positive + return 1; +} + int park_is_open() { return (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) != 0; @@ -55,7 +73,7 @@ void park_init() RCT2_GLOBAL(0x013573FE, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_GUEST_GENERATION_PROBABILITY, uint16) = 0; - RCT2_GLOBAL(0x013580EE, uint16) = 0; + RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, uint16) = 0; RCT2_GLOBAL(0x01357CF4, sint32) = -1; for (i = 0; i < 20; i++) @@ -349,14 +367,118 @@ void reset_park_entrances() } /** - * + * Calculates the probability of a new guest. Also sets total ride value and suggested guest maximum. + * Total ride value should probably be set else where, as its not just used for guest generation. + * Suggested guest maximum should probably be an output result, not a global. + * @returns A probability out of 65535 * rct2: 0x0066730A */ static int park_calculate_guest_generation_probability() { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_CALLFUNC_X(0x0066730A, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return eax & 0xFFFF; + unsigned int probability; + int i, suggestedMaxGuests, totalRideValue; + + // Calculate suggested guest maximum (based on ride type) and total ride value + suggestedMaxGuests = 0; + totalRideValue = 0; + for (i = 0; i < MAX_RIDES; i++) { + rct_ride *ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]; + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->status != RIDE_STATUS_OPEN) + continue; + if (ride->lifecycle_flags & 0x80) + continue; + if (ride->lifecycle_flags & 0x400) + continue; + + // Add guest score for ride type + suggestedMaxGuests += RCT2_GLOBAL(0x0097D21E + (ride->type * 8), uint8); + + // Add ride value + if (ride->reliability != RIDE_RELIABILITY_UNDEFINED) { + int rideValue = ride->reliability - ride->price; + if (rideValue > 0) + totalRideValue += rideValue * 2; + } + } + + // If difficult guest generation, extra guests are available for good rides + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) { + suggestedMaxGuests = min(suggestedMaxGuests, 1000); + for (i = 0; i < MAX_RIDES; i++) { + rct_ride *ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]; + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->lifecycle_flags & 0x80) + continue; + if (ride->lifecycle_flags & 0x400) + continue; + + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x10000000)) + continue; + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x200)) + continue; + if (!(ride->lifecycle_flags & 0x02)) + continue; + if (ride->var_0E4 < 0x2580000) + continue; + if (ride->excitement < RIDE_RATING(6,00)) + continue; + + // Bonus guests for good ride + suggestedMaxGuests += RCT2_GLOBAL(0x0097D21E + (ride->type * 8), uint8) * 2; + } + } + + suggestedMaxGuests = min(suggestedMaxGuests, 65535); + RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, uint16) = totalRideValue; + _suggestedGuestMaximum = suggestedMaxGuests; + + // Begin with 50 + park rating + probability = 50 + clamp(0, RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, uint16) - 200, 650); + + // The more guests, the lower the chance of a new one + int numGuests = RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16); + if (numGuests > suggestedMaxGuests) { + probability /= 4; + + // Even lower for difficult guest generation + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) + probability /= 4; + } + + // Reduces chance for any more than 7000 guests + if (numGuests > 7000) + probability /= 4; + + // Check if money is enabled + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11)) { + // Penalty for overpriced entrance fee relative to total ride value + money16 entranceFee = RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16); + if (entranceFee > totalRideValue) { + probability /= 4; + + // Extra penalty for very overpriced entrance fee + if (entranceFee / 2 > totalRideValue) + probability /= 4; + } + } + + // Reward or penalties for park awards + for (i = 0; i < 4; i++) { + rct_award *award = &RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i]; + if (award->time == 0) + continue; + + // +/- 0.25% of the probability + if (park_is_award_positive(award->type)) + probability += probability / 4; + else + probability -= probability / 4; + } + + return probability; } static void get_random_peep_spawn(rct2_peep_spawn *spawn) @@ -410,7 +532,7 @@ static void park_generate_new_guests() // Generate a new guest for some probability if ((scenario_rand() & 0xFFFF) < RCT2_GLOBAL(0x013580EC, uint16)) { int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0; - if (!difficultGeneration || RCT2_GLOBAL(0x0135883C, uint16) + 150 < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)) + if (!difficultGeneration || _suggestedGuestMaximum + 150 >= RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)) park_generate_new_guest(); } diff --git a/src/park.h b/src/park.h index 9d3dcc4697..658ee71023 100644 --- a/src/park.h +++ b/src/park.h @@ -68,6 +68,7 @@ enum { PARK_FLAGS_18 = (1 << 18) }; +int park_is_award_positive(int type); int park_is_open(); void park_init(); void park_reset_awards_and_history(); diff --git a/src/ride.h b/src/ride.h index faa9cb44bd..157cd72baf 100644 --- a/src/ride.h +++ b/src/ride.h @@ -23,6 +23,17 @@ #include "rct2.h" +typedef fixed16_2dp ride_rating; + +#define RIDE_RATING(whole, fraction) FIXED_2DP(whole, fraction) + +// Used for return values, for functions that modify all three. +typedef struct { + ride_rating excitement; + ride_rating intensity; + ride_rating nausea; +} rating_tuple; + /** * Ride structure. * size: 0x0260 @@ -102,7 +113,7 @@ typedef struct { uint8 pad_1BC[0x11]; uint8 var_1CD; uint16 guests_favourite; // 0x1CE - uint32 lifecycle_flags; + uint32 lifecycle_flags; // 0x1D0 uint8 pad_1D4[0x20]; // Example value for wild mouse ride is d5 (before it's been constructed) // I tried searching the IDA file for "1F4" but couldn't find places where @@ -297,6 +308,7 @@ enum { #define MAX_RIDES 255 #define MAX_RIDE_MEASUREMENTS 8 +#define RIDE_RELIABILITY_UNDEFINED 0xFFFF extern const uint8 gRideClassifications[255]; diff --git a/src/ride_ratings.h b/src/ride_ratings.h index 28ad8bc451..7b6463c525 100644 --- a/src/ride_ratings.h +++ b/src/ride_ratings.h @@ -22,17 +22,7 @@ #define _RIDE_RATINGS_H_ #include "rct2.h" - -typedef fixed16_2dp ride_rating; - -#define RIDE_RATING(whole, fraction) FIXED_2DP(whole, fraction) - -// Used for return values, for functions that modify all three. -typedef struct { - ride_rating excitement; - ride_rating intensity; - ride_rating nausea; -} rating_tuple; +#include "ride.h" void crooked_house_excitement(rct_ride *ride); void sub_655FD6(rct_ride *ride); diff --git a/src/scenario.c b/src/scenario.c index c6a9c4d6d3..01b656626d 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -544,9 +544,9 @@ void scenario_objectives_check() void scenario_entrance_fee_too_high_check() { uint16 x, y; - uint16 magic = RCT2_GLOBAL(0x013580EE, uint16), - park_entrance_fee = RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16); - int max_fee = magic + (magic / 2); + uint16 totalRideValue = RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, uint16); + uint16 park_entrance_fee = RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, uint16); + int max_fee = totalRideValue + (totalRideValue / 2); uint32 game_flags = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32), packed_xy; if ((game_flags & PARK_FLAGS_PARK_OPEN) && park_entrance_fee > max_fee) { From a8182b945b6b51f90c55110c656a1b0162ecb34e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 00:09:33 +0100 Subject: [PATCH 086/209] improve guest generation with comments --- src/addresses.h | 1 - src/park.c | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index af36597a5a..6b3c87e294 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -181,7 +181,6 @@ #define RCT2_ADDRESS_CURRENT_PARK_RATING 0x01357CB0 #define RCT2_ADDRESS_PARK_RATING_HISTORY 0x01357CB2 #define RCT2_ADDRESS_GUESTS_IN_PARK_HISTORY 0x01357CD2 -#define RCT2_ADDRESS_GUEST_GENERATION_PROBABILITY 0x013580EC #define RCT2_ADDRESS_OBJECTIVE_TYPE 0x013580F8 #define RCT2_ADDRESS_OBJECTIVE_YEAR 0x013580F9 #define RCT2_ADDRESS_OBJECTIVE_CURRENCY 0x013580FC diff --git a/src/park.c b/src/park.c index bd8984f684..741137e30d 100644 --- a/src/park.c +++ b/src/park.c @@ -31,8 +31,19 @@ #include "string_ids.h" #include "window.h" +/** + * In a difficult guest generation scenario, no guests will be generated if over this value. + */ int _suggestedGuestMaximum; +/** + * Probability out of 65535, of gaining a new guest per game tick. + * new guests per second = 40 * (probability / 65535) + * With a full park rating, non-overpriced entrance fee, less guests than the suggested maximum and four positive awards, + * approximately 1 guest per second can be generated (+60 guests in one minute). + */ +int _guestGenerationProbability; + int park_is_award_positive(int type) { // Check if award is negative @@ -530,7 +541,7 @@ static rct_peep *park_generate_new_guest_due_to_campaign(int campaign) static void park_generate_new_guests() { // Generate a new guest for some probability - if ((scenario_rand() & 0xFFFF) < RCT2_GLOBAL(0x013580EC, uint16)) { + if ((scenario_rand() & 0xFFFF) < _guestGenerationProbability) { int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0; if (!difficultGeneration || _suggestedGuestMaximum + 150 >= RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)) park_generate_new_guest(); @@ -562,7 +573,7 @@ void park_update() RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, money32) = calculate_park_value(); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_COMPANY_VALUE, money32) = calculate_company_value(); window_invalidate_by_id(WC_FINANCES, 0); - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_GENERATION_PROBABILITY, uint16) = park_calculate_guest_generation_probability(); + _guestGenerationProbability = park_calculate_guest_generation_probability(); RCT2_GLOBAL(0x009A9804, uint16) |= 0x10; window_invalidate_by_id(WC_PARK_INFORMATION, 0); } From 6d824fd3a82c1c44e1148c22701585f348217195 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 00:35:14 +0100 Subject: [PATCH 087/209] fix compile error and add update history placeholder --- src/park.c | 11 ++++++++++- src/park.h | 1 + src/scenario.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/park.c b/src/park.c index 741137e30d..027c08aa26 100644 --- a/src/park.c +++ b/src/park.c @@ -83,7 +83,7 @@ void park_init() RCT2_GLOBAL(0x01357846, uint16) = 0; RCT2_GLOBAL(0x013573FE, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_GENERATION_PROBABILITY, uint16) = 0; + _guestGenerationProbability = 0; RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, uint16) = 0; RCT2_GLOBAL(0x01357CF4, sint32) = -1; @@ -580,4 +580,13 @@ void park_update() // Generate new guests park_generate_new_guests(); +} + +/** + * + * rct2: 0x0066A231 + */ +void park_update_histories() +{ + RCT2_CALLPROC_EBPSAFE(0x0066A231); } \ No newline at end of file diff --git a/src/park.h b/src/park.h index 658ee71023..94a98789fc 100644 --- a/src/park.h +++ b/src/park.h @@ -80,5 +80,6 @@ money32 calculate_company_value(); void reset_park_entrances(); void park_update(); +void park_update_histories(); #endif diff --git a/src/scenario.c b/src/scenario.c index 01b656626d..51ea46cc00 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -616,7 +616,7 @@ void scenario_update() break; } } - RCT2_CALLPROC_EBPSAFE(0x0066A231); // update histories (finance, ratings, etc) + park_update_histories(); park_calculate_size(); } From b036a51cfdaf3d8082c68cca0c966cc08647c763 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Tue, 27 May 2014 02:06:57 +0900 Subject: [PATCH 088/209] Move build instructions from travis into shell scripts fix syntax use elif run it with bash fix directory incantations add missing build steps dont use colors if not terminal update install.sh add sanity check changes set verbose mode enable debug output changes to get it working on mac Platform specific cmakelists fix issue with intptr_t not being found/defined update build scripts see if it can find the pkg-config try running it outside of cmake check whether excho works way we expect try -e remove debug info --- .gitignore | 6 ++++ .travis.yml | 26 ++------------ CMakeLists_mingw.txt | 21 ++++++++---- build.sh | 19 +++++++++++ clean.sh | 10 ++++++ install.sh | 80 ++++++++++++++++++++++++++++++++++++++++++++ src/window_options.c | 4 ++- 7 files changed, 135 insertions(+), 31 deletions(-) create mode 100755 build.sh create mode 100644 clean.sh create mode 100755 install.sh diff --git a/.gitignore b/.gitignore index b7d9f54188..c159c2b889 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,12 @@ sdl +# Compiled dll +openrct2.dll + +# Build artifacts +.cache + ################# ## Eclipse ################# diff --git a/.travis.yml b/.travis.yml index 38bc2929ec..067ef67593 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,32 +1,10 @@ language: c before_install: - - sudo apt-get install -y --force-yes binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 - - # fetch precompiled SDL2 + headers for MinGW and push it into the expected directory - - mkdir -p cache - - export SDL2_PV=2.0.3 - - if [[ ! -f cache/SDL2-devel-${SDL2_PV}-mingw.tar.gz ]]; then wget http://libsdl.org/release/SDL2-devel-${SDL2_PV}-mingw.tar.gz --output-document cache/SDL2-devel-${SDL2_PV}-mingw.tar.gz; fi - - pushd cache && tar -xzf SDL2-devel-${SDL2_PV}-mingw.tar.gz && popd - - # but first fix SDL2 bug - - if [[ ! -f cache/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch ]]; then wget "https://github.com/anyc/anyc-overlay/raw/master/media-libs/libsdl2-mingw/files/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch" --output-document cache/libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch; fi - - pushd cache/SDL2-${SDL2_PV}/i686-w64-mingw32/include/SDL2/ && patch -p2 < ../../../../libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch && popd - - - sudo mkdir -p /usr/local/cross-tools/ - - sudo cp -r cache/SDL2-${SDL2_PV}/i686-w64-mingw32 /usr/local/cross-tools/ - - # build a wrapper that looks for the sdl2.pc file in the new directory - - echo -e "#! /bin/sh\\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\\npkg-config \$@" > i686-w64-mingw32-pkg-config - - chmod +x i686-w64-mingw32-pkg-config - - sudo mv i686-w64-mingw32-pkg-config /usr/local/bin/ + - bash install.sh script: - - mkdir build - - pushd build - - cmake -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=Debug .. - - make - - popd + - bash build.sh notifications: irc: "irc.freenode.net#openrct2-dev" diff --git a/CMakeLists_mingw.txt b/CMakeLists_mingw.txt index a891576ae6..df0bbfacd1 100644 --- a/CMakeLists_mingw.txt +++ b/CMakeLists_mingw.txt @@ -1,11 +1,20 @@ SET(CMAKE_SYSTEM_NAME Windows) -SET(COMPILER_PREFIX i686-w64-mingw32) -SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc) -SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-c++) -SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres) -SET(CMAKE_PKGCONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config) -SET(PKG_CONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config) +if (APPLE) + SET(COMPILER_PREFIX i586-mingw32) + SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc) + SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-c++) + SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres) + SET(CMAKE_PKGCONFIG_EXECUTABLE i686-w64-mingw32-pkg-config) + SET(PKG_CONFIG_EXECUTABLE i686-w64-mingw32-pkg-config) +else() + SET(COMPILER_PREFIX i686-w64-mingw32) + SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc) + SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-c++) + SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres) + SET(CMAKE_PKGCONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config) + SET(PKG_CONFIG_EXECUTABLE ${COMPILER_PREFIX}-pkg-config) +endif (APPLE) # potential flags to make code more similar to MSVC: # -fshort-wchar -fshort-enums -mms-bitfields -fpack-struct=1 diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000..85da2f5efe --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +if [[ ! -d build ]]; then + mkdir -p build +fi + +pushd build + cmake -DCMAKE_TOOLCHAIN_FILE=../CMakeLists_mingw.txt -DCMAKE_BUILD_TYPE=Debug .. + make +popd + +if [[ -t 1 ]]; then + echo "\033[95mDone! Run OpenRCT2 by typing:\n\nwine openrct2.exe\n\033[0m" +else + echo "Done! Run OpenRCT2 by typing:\n\nwine openrct2.exe\n" +fi + diff --git a/clean.sh b/clean.sh new file mode 100644 index 0000000000..03b524eee0 --- /dev/null +++ b/clean.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -ev + +sudo rm -rf /usr/local/cross-tools/i686-w64-mingw32 +#rm -rf .cache +rm -rf .cache/*.patch +rm -rf .cache/SDL2-2.0.3 +rm -rf .cache/i686-w64-mingw32-pkg-config +rm -rf build diff --git a/install.sh b/install.sh new file mode 100755 index 0000000000..e5466b5f2c --- /dev/null +++ b/install.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +set -e + +SDL2_PV=2.0.3 + +cachedir=.cache +mkdir -p $cachedir + +echo `uname` + +if [[ `uname` == "Darwin" ]]; then + echo "Installation of OpenRCT2 assumes you have homebrew and use it to install packages." + # Very possible I'm missing some dependencies here. + brew install cmake wine + + if [[ ! -d /usr/include/wine ]]; then + # This will almost certainly break as brew changes. Better ideas + # welcome. + sudo ln -s /usr/local/Cellar/wine/1.6.2/include/wine /usr/include + fi + + mingw_dmg=gcc-4.8.0-qt-4.8.4-for-mingw32.dmg + mingw_path=/usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin + if [[ ! -f $cachedir/$mingw_dmg ]]; then + wget http://crossgcc.rts-software.org/download/gcc-4.8.0-qt-4.8.4-win32/$mingw_dmg --output-document $cachedir/$mingw_dmg + fi + + if [[ ! -d $mingw_path ]]; then + echo "Open the DMG file and install its contents" + open $cachedir/$mingw_dmg + fi + + echo "You will need to add $mingw_path to your \$PATH" +elif [[ `uname` == "Linux" ]]; then + sudo apt-get install -y --force-yes binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 +fi + +if [[ ! -f $cachedir/SDL2-devel-${SDL2_PV}-mingw.tar.gz ]]; then + wget http://libsdl.org/release/SDL2-devel-${SDL2_PV}-mingw.tar.gz --output-document $cachedir/SDL2-devel-${SDL2_PV}-mingw.tar.gz; +fi +if [[ ! -d $cachedir/SDL2-${SDL2_PV} ]]; then + pushd $cachedir + tar -xzf SDL2-devel-${SDL2_PV}-mingw.tar.gz + popd +fi + +# Apply platform patch +mingw_patch=libsdl2-mingw-2.0.3-fix-platform-detection-for-mingw.patch +if [[ ! -f $cachedir/$mingw_patch ]]; then + wget "https://github.com/anyc/anyc-overlay/raw/master/media-libs/libsdl2-mingw/files/$mingw_patch" --output-document $cachedir/$mingw_patch; + + # XXX not sure how to make this idempotent. + pushd $cachedir/SDL2-${SDL2_PV}/i686-w64-mingw32/include/SDL2/ + echo "Applying patch." + patch -p2 < ../../../../$mingw_patch + popd +fi + +if [[ ! -d /usr/local/cross-tools ]]; then + sudo mkdir -p /usr/local/cross-tools +fi +if [[ ! -d /usr/local/cross-tools/i686-w64-mingw32 ]]; then + sudo cp -r $cachedir/SDL2-${SDL2_PV}/i686-w64-mingw32 /usr/local/cross-tools/ +fi + +if [[ ! -f $cachedir/i686-w64-mingw32-pkg-config ]]; then + if [[ `uname` == "Darwin" ]]; then + # BSD echo doesn't recognize the -e flag. + echo "#! /bin/sh\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\npkg-config \$@" > $cachedir/i686-w64-mingw32-pkg-config; + else + echo -e "#! /bin/sh\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\npkg-config \$@" > $cachedir/i686-w64-mingw32-pkg-config; + fi +fi + +chmod +x $cachedir/i686-w64-mingw32-pkg-config +sudo cp $cachedir/i686-w64-mingw32-pkg-config /usr/local/bin/ + +ls -al /usr/local/bin | grep pkg-config +cat /usr/local/bin/i686-w64-mingw32-pkg-config diff --git a/src/window_options.c b/src/window_options.c index 62939efcef..edc4730f25 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -28,6 +28,8 @@ #include "window.h" #include "window_dropdown.h" +#include + enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_BACKGROUND, WIDX_TITLE, @@ -676,4 +678,4 @@ static void window_options_update_height_markers() config_save(); gfx_invalidate_screen(); -} \ No newline at end of file +} From b40d92f3593cddc686622dd8500e5bc43972f2df Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Tue, 27 May 2014 20:24:25 +0900 Subject: [PATCH 089/209] tweaks --- build.sh | 4 ++-- install.sh | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/build.sh b/build.sh index 85da2f5efe..965c72cbbf 100755 --- a/build.sh +++ b/build.sh @@ -12,8 +12,8 @@ pushd build popd if [[ -t 1 ]]; then - echo "\033[95mDone! Run OpenRCT2 by typing:\n\nwine openrct2.exe\n\033[0m" + echo -e "\nDone! Run OpenRCT2 by typing:\n\n\033[95mwine openrct2.exe\n\033[0m" else - echo "Done! Run OpenRCT2 by typing:\n\nwine openrct2.exe\n" + echo -e "\nDone! Run OpenRCT2 by typing:\n\nwine openrct2.exe\n" fi diff --git a/install.sh b/install.sh index e5466b5f2c..f74e9bcf92 100755 --- a/install.sh +++ b/install.sh @@ -65,12 +65,10 @@ if [[ ! -d /usr/local/cross-tools/i686-w64-mingw32 ]]; then fi if [[ ! -f $cachedir/i686-w64-mingw32-pkg-config ]]; then - if [[ `uname` == "Darwin" ]]; then - # BSD echo doesn't recognize the -e flag. - echo "#! /bin/sh\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\npkg-config \$@" > $cachedir/i686-w64-mingw32-pkg-config; - else - echo -e "#! /bin/sh\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\npkg-config \$@" > $cachedir/i686-w64-mingw32-pkg-config; - fi + # If this fails to work because of newlines, be sure you are running this + # script with Bash, and not sh. We should really move this to a separate + # file. + echo -e "#! /bin/sh\nexport PKG_CONFIG_LIBDIR=/usr/local/cross-tools/i686-w64-mingw32/lib/pkgconfig\npkg-config \$@" > $cachedir/i686-w64-mingw32-pkg-config; fi chmod +x $cachedir/i686-w64-mingw32-pkg-config From 1df8b061d866eee2929de3c3c5d8ad72c02c2358 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Tue, 27 May 2014 20:57:27 +0900 Subject: [PATCH 090/209] Document RIDE_RATING macro --- src/rct2.h | 5 +++-- src/ride.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rct2.h b/src/rct2.h index b95864f69c..f5b765b206 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -64,7 +64,7 @@ typedef unsigned long long uint64; #define OPENRCT2_PLATFORM "Windows" #define OPENRCT2_TIMESTAMP __DATE__ " " __TIME__ -// Represent fixed point numbers +// Represent fixed point numbers. dp = decimal point typedef sint16 fixed16_1dp; typedef sint16 fixed16_2dp; typedef sint32 fixed32_1dp; @@ -74,7 +74,8 @@ typedef sint32 fixed32_2dp; typedef fixed16_1dp money16; typedef fixed32_1dp money32; -// Construct a fixed point number. +// Construct a fixed point number. For example, to create the value 3.65 you +// would write FIXED_2DP(3,65) #define FIXED_XDP(x, whole, fraction) ((whole) * (10 * x) + (fraction)) #define FIXED_1DP(whole, fraction) FIXED_XDP(1, whole, fraction) #define FIXED_2DP(whole, fraction) FIXED_XDP(2, whole, fraction) diff --git a/src/ride.h b/src/ride.h index 157cd72baf..5c1101e310 100644 --- a/src/ride.h +++ b/src/ride.h @@ -25,6 +25,8 @@ typedef fixed16_2dp ride_rating; +// Convenience function for writing ride ratings. The result is a 16 bit signed +// integer. To create the ride rating 3.65 type RIDE_RATING(3,65) #define RIDE_RATING(whole, fraction) FIXED_2DP(whole, fraction) // Used for return values, for functions that modify all three. From 88ffb17a4a5f33051cd3da0e89c079d824de5cee Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 14:00:13 +0100 Subject: [PATCH 091/209] add initial update awards implementation --- src/park.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++- src/park.h | 4 ++ src/scenario.c | 2 +- src/string_ids.h | 18 ++++++++ 4 files changed, 135 insertions(+), 2 deletions(-) diff --git a/src/park.c b/src/park.c index 027c08aa26..f879a409ef 100644 --- a/src/park.c +++ b/src/park.c @@ -23,6 +23,7 @@ #include "finance.h" #include "map.h" #include "marketing.h" +#include "news_item.h" #include "park.h" #include "peep.h" #include "ride.h" @@ -477,7 +478,7 @@ static int park_calculate_guest_generation_probability() } // Reward or penalties for park awards - for (i = 0; i < 4; i++) { + for (i = 0; i < MAX_AWARDS; i++) { rct_award *award = &RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i]; if (award->time == 0) continue; @@ -589,4 +590,114 @@ void park_update() void park_update_histories() { RCT2_CALLPROC_EBPSAFE(0x0066A231); +} + +static int park_is_award_deserved(int awardType, int activeAwardTypes) +{ + switch (awardType) { + case PARK_AWARD_MOST_UNTIDY: + break; + case PARK_AWARD_MOST_TIDY: + break; + case PARK_AWARD_BEST_ROLLERCOASTERS: + break; + case PARK_AWARD_BEST_VALUE: + if (activeAwardTypes & (1 << PARK_AWARD_WORST_VALUE)) + return 0; + if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & (PARK_FLAGS_11 | PARK_FLAGS_PARK_FREE_ENTRY)) + return 0; + if (RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) < MONEY(10, 00)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) + MONEY(0, 10) >= RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) / 2) + return 0; + return 1; + case PARK_AWARD_MOST_BEAUTIFUL: + break; + case PARK_AWARD_WORST_VALUE: + if (activeAwardTypes & (1 << PARK_AWARD_BEST_VALUE)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == MONEY(0, 00)) + return 0; + if (RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) >= RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16)) + return 0; + return 1; + break; + case PARK_AWARD_SAFEST: + break; + case PARK_AWARD_BEST_STAFF: + break; + case PARK_AWARD_BEST_FOOD: + break; + case PARK_AWARD_WORST_FOOD: + break; + case PARK_AWARD_BEST_RESTROOMS: + break; + case PARK_AWARD_MOST_DISAPPOINTING: + break; + case PARK_AWARD_BEST_WATER_RIDES: + break; + case PARK_AWARD_BEST_CUSTOM_DESIGNED_RIDES: + break; + case PARK_AWARD_MOST_DAZZLING_RIDE_COLOURS: + break; + case PARK_AWARD_MOST_CONFUSING_LAYOUT: + break; + case PARK_AWARD_BEST_GENTLE_RIDES: + break; + } + + return 0; +} + +/** + * + * rct2: 0x0066A86C + */ +void park_update_awards() +{ + int i, activeAwardTypes, freeAwardEntryIndex; + rct_award *awards; + + awards = RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award); + + // Only add new awards if park is open + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) { + // Set active award types as flags + activeAwardTypes = 0; + freeAwardEntryIndex = -1; + for (i = 0; i < MAX_AWARDS; i++) { + if (awards[i].time != 0) + activeAwardTypes |= (1 << awards[i].type); + else if (freeAwardEntryIndex != -1) + freeAwardEntryIndex = i; + } + + // Check if there was a free award entry + if (freeAwardEntryIndex != -1) { + // Get a random award type not already active + int awardType; + do { + awardType = (((scenario_rand() & 0xFF) * 17) >> 8) & 0xFF; + } while (activeAwardTypes & (1 << awardType)); + + // Check if award is deserved + if (park_is_award_deserved(awardType, activeAwardTypes)) { + // Add award + awards[freeAwardEntryIndex].type = awardType; + awards[freeAwardEntryIndex].time = 5; + news_item_add_to_queue(NEWS_ITEM_AWARD, STR_NEWS_ITEM_AWARD_MOST_UNTIDY + awardType, 0); + window_invalidate_by_id(WC_PARK_INFORMATION, 0); + } + } + } + + // Decrease award times + for (i = 0; i < MAX_AWARDS; i++) + if (awards[i].time != 0) + if (--awards[i].time == 0) + window_invalidate_by_id(WC_PARK_INFORMATION, 0); } \ No newline at end of file diff --git a/src/park.h b/src/park.h index 94a98789fc..eb7d61e358 100644 --- a/src/park.h +++ b/src/park.h @@ -49,6 +49,7 @@ enum { PARK_AWARD_MOST_DAZZLING_RIDE_COLOURS, PARK_AWARD_MOST_CONFUSING_LAYOUT, PARK_AWARD_BEST_GENTLE_RIDES, + PARK_AWARD_COUNT }; enum { @@ -68,6 +69,8 @@ enum { PARK_FLAGS_18 = (1 << 18) }; +#define MAX_AWARDS 4 + int park_is_award_positive(int type); int park_is_open(); void park_init(); @@ -81,5 +84,6 @@ void reset_park_entrances(); void park_update(); void park_update_histories(); +void park_update_awards(); #endif diff --git a/src/scenario.c b/src/scenario.c index 51ea46cc00..93b93fbbbf 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -634,7 +634,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069DEAD); scenario_objectives_check(); scenario_entrance_fee_too_high_check(); - RCT2_CALLPROC_EBPSAFE(0x0066A86C); // award checks + park_update_awards(); } } diff --git a/src/string_ids.h b/src/string_ids.h index d0fde8f342..6812f33eeb 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -547,6 +547,24 @@ enum { STR_MOST_CONFUSING_LAYOUT = STR_AWARD_MOST_UNTIDY + 15, STR_BEST_GENTLE_RIDES = STR_AWARD_MOST_UNTIDY + 16, + STR_NEWS_ITEM_AWARD_MOST_UNTIDY = 2831, + STR_NEWS_ITEM_MOST_TIDY = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 1, + STR_NEWS_ITEM_BEST_ROLLERCOASTERS = STR_AWARD_MOST_UNTIDY + 2, + STR_NEWS_ITEM_BEST_VALUE = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 3, + STR_NEWS_ITEM_MOST_BEAUTIFUL = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 4, + STR_NEWS_ITEM_WORST_VALUE = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 5, + STR_NEWS_ITEM_SAFEST = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 6, + STR_NEWS_ITEM_BEST_STAFF = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 7, + STR_NEWS_ITEM_BEST_FOOD = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 8, + STR_NEWS_ITEM_WORST_FOOD = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 9, + STR_NEWS_ITEM_BEST_RESTROOMS = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 10, + STR_NEWS_ITEM_MOST_DISAPPOINTING = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 11, + STR_NEWS_ITEM_BEST_WATER_RIDES = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 12, + STR_NEWS_ITEM_BEST_CUSTOM_DESIGNED_RIDES = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 13, + STR_NEWS_ITEM_MOST_DAZZLING_RIDE_COLOURS = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 14, + STR_NEWS_ITEM_MOST_CONFUSING_LAYOUT = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 15, + STR_NEWS_ITEM_BEST_GENTLE_RIDES = STR_NEWS_ITEM_AWARD_MOST_UNTIDY + 16, + STR_NO_RECENT_AWARDS = 2848, STR_TUTORIAL = 2856, From 30e6358fd4491615514c10b334be047eab77bb4c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 15:14:45 +0100 Subject: [PATCH 092/209] implement more awards WIP --- projects/openrct2.vcxproj | 2 + projects/openrct2.vcxproj.filters | 6 + src/award.c | 324 ++++++++++++++++++++++++++++++ src/award.h | 57 ++++++ src/park.c | 129 +----------- src/park.h | 30 --- src/ride.c | 3 - src/ride.h | 20 ++ src/scenario.c | 3 +- src/window_park.c | 1 + 10 files changed, 414 insertions(+), 161 deletions(-) create mode 100644 src/award.c create mode 100644 src/award.h diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index e492c0aa92..00362abcc4 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -17,6 +17,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index dc799bd2b0..dd606605a9 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -135,6 +135,9 @@ Header Files + + Header Files + @@ -326,6 +329,9 @@ Source Files + + Source Files + diff --git a/src/award.c b/src/award.c new file mode 100644 index 0000000000..b627b07c17 --- /dev/null +++ b/src/award.c @@ -0,0 +1,324 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include "addresses.h" +#include "award.h" +#include "news_item.h" +#include "ride.h" +#include "scenario.h" +#include "window.h" + +#define NEGATIVE 0 +#define POSITIVE 1 + +int _awardPositiveMap[] = { + NEGATIVE, // PARK_AWARD_MOST_UNTIDY + POSITIVE, // PARK_AWARD_MOST_TIDY + POSITIVE, // PARK_AWARD_BEST_ROLLERCOASTERS + POSITIVE, // PARK_AWARD_BEST_VALUE + POSITIVE, // PARK_AWARD_MOST_BEAUTIFUL + NEGATIVE, // PARK_AWARD_WORST_VALUE + POSITIVE, // PARK_AWARD_SAFEST + POSITIVE, // PARK_AWARD_BEST_STAFF + POSITIVE, // PARK_AWARD_BEST_FOOD + NEGATIVE, // PARK_AWARD_WORST_FOOD + POSITIVE, // PARK_AWARD_BEST_RESTROOMS + NEGATIVE, // PARK_AWARD_MOST_DISAPPOINTING + POSITIVE, // PARK_AWARD_BEST_WATER_RIDES + POSITIVE, // PARK_AWARD_BEST_CUSTOM_DESIGNED_RIDES + POSITIVE, // PARK_AWARD_MOST_DAZZLING_RIDE_COLOURS + NEGATIVE, // PARK_AWARD_MOST_CONFUSING_LAYOUT + POSITIVE, // PARK_AWARD_BEST_GENTLE_RIDES +}; + +int award_is_positive(int type) +{ + return _awardPositiveMap[type]; +} + +#pragma region Award checks + +static int award_is_deserved_most_untidy(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_most_tidy(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_best_rollercoasters(int awardType, int activeAwardTypes) +{ + int i, rollerCoasters; + rct_ride *ride; + char *object; + + rollerCoasters = 0; + FOR_ALL_RIDES(i, ride) { + object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype]; + if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_ROLLERCOASTER && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_ROLLERCOASTER) + continue; + + if (ride->status != RIDE_STATUS_OPEN || ride->lifecycle_flags & 0x400) + continue; + + rollerCoasters++; + } + + return (rollerCoasters >= 6); +} + +/** Entrance fee is 0.10 less than half of the total ride value. */ +static int award_is_deserved_best_value(int awardType, int activeAwardTypes) +{ + if (activeAwardTypes & (1 << PARK_AWARD_WORST_VALUE)) + return 0; + if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & (PARK_FLAGS_11 | PARK_FLAGS_PARK_FREE_ENTRY)) + return 0; + if (RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) < MONEY(10, 00)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) + MONEY(0, 10) >= RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) / 2) + return 0; + return 1; +} + +static int award_is_deserved_most_beautiful(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +/** Entrance fee is more than total ride value. */ +static int award_is_deserved_worse_value(int awardType, int activeAwardTypes) +{ + if (activeAwardTypes & (1 << PARK_AWARD_BEST_VALUE)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == MONEY(0, 00)) + return 0; + if (RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) >= RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16)) + return 0; + return 1; +} +static int award_is_deserved_safest(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_best_staff(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_best_food(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_worst_food(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_best_restrooms(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +/** More than half of the rides have satisfication <= 6 and park rating <= 650. */ +static int award_is_deserved_most_disappointing(int awardType, int activeAwardTypes) +{ + unsigned int i, countedRides, disappointingRides; + rct_ride *ride; + + if (activeAwardTypes & (1 << PARK_AWARD_BEST_VALUE)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, uint16) > 650) + return 0; + + // Count the number of disappointing rides + countedRides = 0; + disappointingRides = 0; + + FOR_ALL_RIDES(i, ride) { + if (ride->excitement == 0xFFFF || ride->var_158 == 0xFF) + continue; + + countedRides++; + + // Satification maybe? + if (ride->var_158 <= 6) + disappointingRides++; + } + + // Half of the rides are disappointing + return (disappointingRides >= countedRides / 2); +} + +/** At least 6 open water rides. */ +static int award_is_deserved_best_water_rides(int awardType, int activeAwardTypes) +{ + int i, waterRides; + rct_ride *ride; + char *object; + + waterRides = 0; + FOR_ALL_RIDES(i, ride) { + object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype]; + if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_WATER && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_WATER) + continue; + + if (ride->status != RIDE_STATUS_OPEN || ride->lifecycle_flags & 0x400) + continue; + + waterRides++; + } + + return (waterRides >= 6); +} + +static int award_is_deserved_best_custom_designed_rides(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_most_dazzling_ride_colours(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +static int award_is_deserved_most_confusing_layout(int awardType, int activeAwardTypes) +{ + // TODO + return 0; +} + +/** At least 10 open gentle rides. */ +static int award_is_deserved_best_gentle_rides(int awardType, int activeAwardTypes) +{ + int i, gentleRides; + rct_ride *ride; + char *object; + + gentleRides = 0; + FOR_ALL_RIDES(i, ride) { + object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype]; + if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_GENTLE && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_GENTLE) + continue; + + if (ride->status != RIDE_STATUS_OPEN || ride->lifecycle_flags & 0x400) + continue; + + gentleRides++; + } + + return (gentleRides >= 10); +} + +typedef int (*award_deserved_check)(int, int); + +award_deserved_check _awardChecks[] = { + award_is_deserved_most_untidy, + award_is_deserved_most_tidy, + award_is_deserved_best_rollercoasters, + award_is_deserved_best_value, + award_is_deserved_most_beautiful, + award_is_deserved_worse_value, + award_is_deserved_safest, + award_is_deserved_best_staff, + award_is_deserved_best_food, + award_is_deserved_worst_food, + award_is_deserved_best_restrooms, + award_is_deserved_most_disappointing, + award_is_deserved_best_water_rides, + award_is_deserved_best_custom_designed_rides, + award_is_deserved_most_dazzling_ride_colours, + award_is_deserved_most_confusing_layout, + award_is_deserved_best_gentle_rides +}; + +static int award_is_deserved(int awardType, int activeAwardTypes) +{ + return _awardChecks[awardType](awardType, activeAwardTypes); +} + +#pragma endregion + +/** + * + * rct2: 0x0066A86C + */ +void award_update_all() +{ + int i, activeAwardTypes, freeAwardEntryIndex; + rct_award *awards; + + awards = RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award); + + // Only add new awards if park is open + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) { + // Set active award types as flags + activeAwardTypes = 0; + freeAwardEntryIndex = -1; + for (i = 0; i < MAX_AWARDS; i++) { + if (awards[i].time != 0) + activeAwardTypes |= (1 << awards[i].type); + else if (freeAwardEntryIndex != -1) + freeAwardEntryIndex = i; + } + + // Check if there was a free award entry + if (freeAwardEntryIndex != -1) { + // Get a random award type not already active + int awardType; + do { + awardType = (((scenario_rand() & 0xFF) * 17) >> 8) & 0xFF; + } while (activeAwardTypes & (1 << awardType)); + + // Check if award is deserved + if (award_is_deserved(awardType, activeAwardTypes)) { + // Add award + awards[freeAwardEntryIndex].type = awardType; + awards[freeAwardEntryIndex].time = 5; + news_item_add_to_queue(NEWS_ITEM_AWARD, STR_NEWS_ITEM_AWARD_MOST_UNTIDY + awardType, 0); + window_invalidate_by_id(WC_PARK_INFORMATION, 0); + } + } + } + + // Decrease award times + for (i = 0; i < MAX_AWARDS; i++) + if (awards[i].time != 0) + if (--awards[i].time == 0) + window_invalidate_by_id(WC_PARK_INFORMATION, 0); +} \ No newline at end of file diff --git a/src/award.h b/src/award.h new file mode 100644 index 0000000000..26074cdaa8 --- /dev/null +++ b/src/award.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#ifndef _AWARD_H_ +#define _AWARD_H_ + +#include "rct2.h" + +typedef struct { + uint16 time; + uint16 type; +} rct_award; + +enum { + PARK_AWARD_MOST_UNTIDY, + PARK_AWARD_MOST_TIDY, + PARK_AWARD_BEST_ROLLERCOASTERS, + PARK_AWARD_BEST_VALUE, + PARK_AWARD_MOST_BEAUTIFUL, + PARK_AWARD_WORST_VALUE, + PARK_AWARD_SAFEST, + PARK_AWARD_BEST_STAFF, + PARK_AWARD_BEST_FOOD, + PARK_AWARD_WORST_FOOD, + PARK_AWARD_BEST_RESTROOMS, + PARK_AWARD_MOST_DISAPPOINTING, + PARK_AWARD_BEST_WATER_RIDES, + PARK_AWARD_BEST_CUSTOM_DESIGNED_RIDES, + PARK_AWARD_MOST_DAZZLING_RIDE_COLOURS, + PARK_AWARD_MOST_CONFUSING_LAYOUT, + PARK_AWARD_BEST_GENTLE_RIDES, + PARK_AWARD_COUNT +}; + +#define MAX_AWARDS 4 + +int award_is_positive(int type); +void award_update_all(); + +#endif \ No newline at end of file diff --git a/src/park.c b/src/park.c index f879a409ef..4ab075f148 100644 --- a/src/park.c +++ b/src/park.c @@ -20,6 +20,7 @@ #include #include "addresses.h" +#include "award.h" #include "finance.h" #include "map.h" #include "marketing.h" @@ -45,22 +46,6 @@ int _suggestedGuestMaximum; */ int _guestGenerationProbability; -int park_is_award_positive(int type) -{ - // Check if award is negative - switch (type) { - case PARK_AWARD_MOST_UNTIDY: - case PARK_AWARD_WORST_VALUE: - case PARK_AWARD_WORST_FOOD: - case PARK_AWARD_MOST_DISAPPOINTING: - case PARK_AWARD_MOST_CONFUSING_LAYOUT: - return 0; - } - - // Otherwise its positive - return 1; -} - int park_is_open() { return (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) != 0; @@ -484,7 +469,7 @@ static int park_calculate_guest_generation_probability() continue; // +/- 0.25% of the probability - if (park_is_award_positive(award->type)) + if (award_is_positive(award->type)) probability += probability / 4; else probability -= probability / 4; @@ -590,114 +575,4 @@ void park_update() void park_update_histories() { RCT2_CALLPROC_EBPSAFE(0x0066A231); -} - -static int park_is_award_deserved(int awardType, int activeAwardTypes) -{ - switch (awardType) { - case PARK_AWARD_MOST_UNTIDY: - break; - case PARK_AWARD_MOST_TIDY: - break; - case PARK_AWARD_BEST_ROLLERCOASTERS: - break; - case PARK_AWARD_BEST_VALUE: - if (activeAwardTypes & (1 << PARK_AWARD_WORST_VALUE)) - return 0; - if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & (PARK_FLAGS_11 | PARK_FLAGS_PARK_FREE_ENTRY)) - return 0; - if (RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) < MONEY(10, 00)) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) + MONEY(0, 10) >= RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) / 2) - return 0; - return 1; - case PARK_AWARD_MOST_BEAUTIFUL: - break; - case PARK_AWARD_WORST_VALUE: - if (activeAwardTypes & (1 << PARK_AWARD_BEST_VALUE)) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == MONEY(0, 00)) - return 0; - if (RCT2_GLOBAL(RCT2_TOTAL_RIDE_VALUE, money16) >= RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16)) - return 0; - return 1; - break; - case PARK_AWARD_SAFEST: - break; - case PARK_AWARD_BEST_STAFF: - break; - case PARK_AWARD_BEST_FOOD: - break; - case PARK_AWARD_WORST_FOOD: - break; - case PARK_AWARD_BEST_RESTROOMS: - break; - case PARK_AWARD_MOST_DISAPPOINTING: - break; - case PARK_AWARD_BEST_WATER_RIDES: - break; - case PARK_AWARD_BEST_CUSTOM_DESIGNED_RIDES: - break; - case PARK_AWARD_MOST_DAZZLING_RIDE_COLOURS: - break; - case PARK_AWARD_MOST_CONFUSING_LAYOUT: - break; - case PARK_AWARD_BEST_GENTLE_RIDES: - break; - } - - return 0; -} - -/** - * - * rct2: 0x0066A86C - */ -void park_update_awards() -{ - int i, activeAwardTypes, freeAwardEntryIndex; - rct_award *awards; - - awards = RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award); - - // Only add new awards if park is open - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) { - // Set active award types as flags - activeAwardTypes = 0; - freeAwardEntryIndex = -1; - for (i = 0; i < MAX_AWARDS; i++) { - if (awards[i].time != 0) - activeAwardTypes |= (1 << awards[i].type); - else if (freeAwardEntryIndex != -1) - freeAwardEntryIndex = i; - } - - // Check if there was a free award entry - if (freeAwardEntryIndex != -1) { - // Get a random award type not already active - int awardType; - do { - awardType = (((scenario_rand() & 0xFF) * 17) >> 8) & 0xFF; - } while (activeAwardTypes & (1 << awardType)); - - // Check if award is deserved - if (park_is_award_deserved(awardType, activeAwardTypes)) { - // Add award - awards[freeAwardEntryIndex].type = awardType; - awards[freeAwardEntryIndex].time = 5; - news_item_add_to_queue(NEWS_ITEM_AWARD, STR_NEWS_ITEM_AWARD_MOST_UNTIDY + awardType, 0); - window_invalidate_by_id(WC_PARK_INFORMATION, 0); - } - } - } - - // Decrease award times - for (i = 0; i < MAX_AWARDS; i++) - if (awards[i].time != 0) - if (--awards[i].time == 0) - window_invalidate_by_id(WC_PARK_INFORMATION, 0); } \ No newline at end of file diff --git a/src/park.h b/src/park.h index eb7d61e358..8908e4a31f 100644 --- a/src/park.h +++ b/src/park.h @@ -26,32 +26,6 @@ #define DECRYPT_MONEY(money) rol32((money) ^ 0xF4EC9621, 13) #define ENCRYPT_MONEY(money) (ror32((money), 13) ^ 0xF4EC9621) -typedef struct { - uint16 time; - uint16 type; -} rct_award; - -enum { - PARK_AWARD_MOST_UNTIDY, - PARK_AWARD_MOST_TIDY, - PARK_AWARD_BEST_ROLLERCOASTERS, - PARK_AWARD_BEST_VALUE, - PARK_AWARD_MOST_BEAUTIFUL, - PARK_AWARD_WORST_VALUE, - PARK_AWARD_SAFEST, - PARK_AWARD_BEST_STAFF, - PARK_AWARD_BEST_FOOD, - PARK_AWARD_WORST_FOOD, - PARK_AWARD_BEST_RESTROOMS, - PARK_AWARD_MOST_DISAPPOINTING, - PARK_AWARD_BEST_WATER_RIDES, - PARK_AWARD_BEST_CUSTOM_DESIGNED_RIDES, - PARK_AWARD_MOST_DAZZLING_RIDE_COLOURS, - PARK_AWARD_MOST_CONFUSING_LAYOUT, - PARK_AWARD_BEST_GENTLE_RIDES, - PARK_AWARD_COUNT -}; - enum { PARK_FLAGS_PARK_OPEN = (1 << 0), PARK_FLAGS_FORBID_LANDSCAPE_CHANGES = (1 << 2), @@ -69,9 +43,6 @@ enum { PARK_FLAGS_18 = (1 << 18) }; -#define MAX_AWARDS 4 - -int park_is_award_positive(int type); int park_is_open(); void park_init(); void park_reset_awards_and_history(); @@ -84,6 +55,5 @@ void reset_park_entrances(); void park_update(); void park_update_histories(); -void park_update_awards(); #endif diff --git a/src/ride.c b/src/ride.c index 7490f60dd3..1535bc7406 100644 --- a/src/ride.c +++ b/src/ride.c @@ -25,9 +25,6 @@ #include "peep.h" #include "window.h" -#define GET_RIDE(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[x])) -#define GET_RIDE_MEASUREMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_MEASUREMENTS, rct_ride_measurement)[x])) - #pragma region Ride classification table const uint8 gRideClassifications[255] = { diff --git a/src/ride.h b/src/ride.h index 5c1101e310..e5dff8e8f1 100644 --- a/src/ride.h +++ b/src/ride.h @@ -308,10 +308,30 @@ enum { RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR }; +enum { + RIDE_GROUP_TRANSPORT, + RIDE_GROUP_GENTLE, + RIDE_GROUP_ROLLERCOASTER, + RIDE_GROUP_THRILL, + RIDE_GROUP_WATER, + RIDE_GROUP_SHOP +}; + #define MAX_RIDES 255 #define MAX_RIDE_MEASUREMENTS 8 #define RIDE_RELIABILITY_UNDEFINED 0xFFFF +/** Helper macros until rides are stored in this module. */ +#define GET_RIDE(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[x])) +#define GET_RIDE_MEASUREMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_MEASUREMENTS, rct_ride_measurement)[x])) + +/** + * Helper macro loop for enumerating through all the non null rides. + */ +#define FOR_ALL_RIDES(i, ride) \ + for (i = 0; i < MAX_RIDES; i++) \ + if ((ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]))->type != RIDE_TYPE_NULL) + extern const uint8 gRideClassifications[255]; int ride_get_count(); diff --git a/src/scenario.c b/src/scenario.c index 93b93fbbbf..26bc659709 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -21,6 +21,7 @@ #include #include #include "addresses.h" +#include "award.h" #include "date.h" #include "finance.h" #include "game.h" @@ -634,7 +635,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069DEAD); scenario_objectives_check(); scenario_entrance_fee_too_high_check(); - park_update_awards(); + award_update_all(); } } diff --git a/src/window_park.c b/src/window_park.c index a87c9d0ee4..782cbe65c5 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -20,6 +20,7 @@ #include #include "addresses.h" +#include "award.h" #include "config.h" #include "date.h" #include "game.h" From a70021d53ac6f9ae7ce040bb0950fb27b81fc18f Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 16:48:15 +0200 Subject: [PATCH 093/209] Add function for checking wether file exists to osinterface, BMP screenshots can now be saved without WIN32 specific methods. --- src/config.c | 5 ++--- src/osinterface.c | 5 +++++ src/osinterface.h | 1 + src/rct2.c | 3 +-- src/screenshot.c | 44 +++++++++++++++++++++++--------------------- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/config.c b/src/config.c index 11fdf54b97..8d99760217 100644 --- a/src/config.c +++ b/src/config.c @@ -254,7 +254,7 @@ void config_init() static int config_find_rct2_path(char *resultPath) { int i; - DWORD dwAttrib; + const char *searchLocations[] = { "C:\\Program Files\\Infogrames\\RollerCoaster Tycoon 2", "C:\\Program Files (x86)\\Infogrames\\RollerCoaster Tycoon 2", @@ -266,8 +266,7 @@ static int config_find_rct2_path(char *resultPath) }; for (i = 0; i < countof(searchLocations); i++) { - dwAttrib = GetFileAttributes(searchLocations[i]); - if (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + if ( osinterface_directory_exists(searchLocations[i]) ) { strcpy(resultPath, searchLocations[i]); return 1; } diff --git a/src/osinterface.c b/src/osinterface.c index 843b37f712..274c2a5f3a 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -454,6 +454,11 @@ char *osinterface_get_orct2_homesubfolder(const char *subFolder) return path; } +int osinterface_file_exists(const char *path) +{ + return !(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND); +} + int osinterface_directory_exists(const char *path) { DWORD dwAttrib = GetFileAttributes(path); diff --git a/src/osinterface.h b/src/osinterface.h index 88576a980a..59691835c6 100644 --- a/src/osinterface.h +++ b/src/osinterface.h @@ -52,6 +52,7 @@ char* osinterface_open_directory_browser(char *title); char* osinterface_get_orct2_homefolder(); char *osinterface_get_orct2_homesubfolder(const char *subFolder); +int osinterface_file_exists(const char *path); int osinterface_directory_exists(const char *path); int osinterface_ensure_directory_exists(const char *path); diff --git a/src/rct2.c b/src/rct2.c index 76b81e5e6e..7ab6254c34 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -189,8 +189,7 @@ void rct2_init() void rct2_init_directories() { // check install directory - DWORD dwAttrib = GetFileAttributes(gGeneral_config.game_path); - if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + if ( !osinterface_directory_exists(gGeneral_config.game_path) ) { osinterface_show_messagebox("Invalid RCT2 installation path. Please correct in config.ini."); exit(-1); } diff --git a/src/screenshot.c b/src/screenshot.c index 7e74ed32f1..10350f39da 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -17,10 +17,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *****************************************************************************/ +#pragma pack(1) #include #include -#include #include "osinterface.h" #include "addresses.h" #include "config.h" @@ -75,8 +75,9 @@ static int screenshot_get_next_path(char *path, char *extension) // Glue together path and filename sprintf(path, "%s%cSCR%d%s", screenshotPath, osinterface_get_path_separator(), i, extension); - if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) + if (!osinterface_file_exists(path)) { return i; + } } free(screenshotPath); @@ -129,22 +130,23 @@ int screenshot_dump_bmp() int i, y, index, width, height, stride; char *buffer, path[MAX_PATH], *row; - HANDLE hFile; - DWORD bytesWritten; + FILE *fp; + unsigned int bytesWritten; // Get a free screenshot path if ((index = screenshot_get_next_path(path, ".bmp")) == -1) return -1; - // Open file for writing - hFile = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) + // Open binary file for writing + if ((fp = fopen(path, "wb")) == NULL){ return -1; + } // Allocate buffer buffer = malloc(0xFFFF); if (buffer == NULL) { - CloseHandle(hFile); + //CloseHandle(hFile); + fclose(fp); return -1; } @@ -159,9 +161,9 @@ int screenshot_dump_bmp() header.bfSize = height * stride + 1038; header.bfOffBits = 1038; - WriteFile(hFile, &header, sizeof(header), &bytesWritten, NULL); - if (bytesWritten != sizeof(header)) { - CloseHandle(hFile); + bytesWritten = fwrite(&header, sizeof(BitmapFileHeader), 1, fp); + if (bytesWritten != 1) { + fclose(fp); free(buffer); } @@ -176,9 +178,9 @@ int screenshot_dump_bmp() info.biYPelsPerMeter = 2520; info.biClrUsed = 246; - WriteFile(hFile, &info, sizeof(info), &bytesWritten, NULL); - if (bytesWritten != sizeof(info)) { - CloseHandle(hFile); + bytesWritten=fwrite(&info, sizeof(BitmapInfoHeader), 1, fp); + if (bytesWritten != 1) { + fclose(fp); free(buffer); } @@ -190,9 +192,9 @@ int screenshot_dump_bmp() buffer[i * 4 + 2] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2]; } - WriteFile(hFile, buffer, 246 * 4, &bytesWritten, NULL); - if (bytesWritten != 246 * 4) { - CloseHandle(hFile); + bytesWritten = fwrite(buffer, sizeof(char), 246*4, fp); + if (bytesWritten != 246*4){ + fclose(fp); free(buffer); } @@ -204,14 +206,14 @@ int screenshot_dump_bmp() memset(buffer, 0, stride); memcpy(buffer, row, dpi->width); - WriteFile(hFile, buffer, stride, &bytesWritten, NULL); - if (bytesWritten != stride) { - CloseHandle(hFile); + bytesWritten=fwrite(buffer, sizeof(char), stride, fp); + if (bytesWritten != stride){ + fclose(fp); free(buffer); } } - CloseHandle(hFile); + fclose(fp); free(buffer); return index; From 76a7cc98b8754f90c9181c7b24f48651247cc8b8 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 17:14:27 +0200 Subject: [PATCH 094/209] replaced WIN32 file i/o in config_load() --- src/config.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/config.c b/src/config.c index 8d99760217..0883849bd2 100644 --- a/src/config.c +++ b/src/config.c @@ -117,20 +117,21 @@ void config_reset_shortcut_keys() */ void config_load() { - HANDLE hFile; - DWORD bytesRead; + unsigned int bytesRead; + FILE *fp=NULL; char* path = get_file_path(PATH_ID_GAMECFG); - hFile = CreateFile(get_file_path(PATH_ID_GAMECFG), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) { + + fp = fopen(path, "rb"); + + if (fp != NULL) { // Read and check magic number - ReadFile(hFile, RCT2_ADDRESS(0x013CE928, void), 4, &bytesRead, NULL); + fread(RCT2_ADDRESS(0x013CE928, void), 1, 4, fp); + if (RCT2_GLOBAL(0x013CE928, int) == MagicNumber) { // Read options - ReadFile(hFile, (void*)0x009AAC5C, 2155, &bytesRead, NULL); - CloseHandle(hFile); - + fread((void*)0x009AAC5C, 1, 2155, fp); + fclose(fp); //general configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, sint8) = gGeneral_config.edge_scrolling; From 1aa7e33aae55ed06024e4f987d1a2c0b4a86945e Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 27 May 2014 16:35:11 +0100 Subject: [PATCH 095/209] Added notes about splitting gfx_draw_sprite --- src/gfx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index ec8f0532bc..c0ae8c3751 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -803,7 +803,8 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; } - + //Some parts of rct jump into the function here + //will require splitting the function in two. Inputs image_id, palette_pointer,dpi,x,y,0x9e3cdc pointer,image_type(0xEDF81C) ebx &= 0x7FFFF; rct_g1_element* g1_source = &((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[ebx]; From cdee1dddeac9fce2c6a271ec65a5c90f7c692b6e Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 19:00:21 +0200 Subject: [PATCH 096/209] replaced WIN32 file i/o in config_save() --- src/config.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/config.c b/src/config.c index 0883849bd2..c17625f328 100644 --- a/src/config.c +++ b/src/config.c @@ -117,7 +117,6 @@ void config_reset_shortcut_keys() */ void config_load() { - unsigned int bytesRead; FILE *fp=NULL; char* path = get_file_path(PATH_ID_GAMECFG); @@ -198,14 +197,12 @@ void config_load() */ void config_save() { - HANDLE hFile; - DWORD bytesWritten; - - hFile = CreateFile(get_file_path(PATH_ID_GAMECFG), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) { - WriteFile(hFile, &MagicNumber, 4, &bytesWritten, NULL); - WriteFile(hFile, (LPCVOID)0x009AAC5C, 2155, &bytesWritten, NULL); - CloseHandle(hFile); + FILE *fp=NULL; + fp = fopen(get_file_path(PATH_ID_GAMECFG), "wb"); + if (fp != NULL){ + fwrite(&MagicNumber, 4, 1, fp); + fwrite((LPCVOID)0x009AAC5C, 2155, 1, fp); + fclose(fp); } } From 72b2272b1f9d48aab50dfe9531fa3da0e194f9fe Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 18:03:25 +0100 Subject: [PATCH 097/209] apply loop macros and implement more awards --- src/award.c | 135 ++++++++++++++++++++++++++++++++++++---- src/finance.c | 17 ++--- src/news_item.c | 6 +- src/park.c | 24 ++----- src/peep.c | 49 ++++----------- src/peep.h | 19 ++++++ src/ride.c | 31 ++++----- src/ride.h | 9 ++- src/scenario.c | 26 +++----- src/window_cheats.c | 13 ++-- src/window_guest_list.c | 61 +++++------------- src/window_ride_list.c | 20 ++---- 12 files changed, 216 insertions(+), 194 deletions(-) diff --git a/src/award.c b/src/award.c index b627b07c17..3d295bd519 100644 --- a/src/award.c +++ b/src/award.c @@ -21,8 +21,10 @@ #include "addresses.h" #include "award.h" #include "news_item.h" +#include "peep.h" #include "ride.h" #include "scenario.h" +#include "sprite.h" #include "window.h" #define NEGATIVE 0 @@ -67,6 +69,7 @@ static int award_is_deserved_most_tidy(int awardType, int activeAwardTypes) return 0; } +/** At least 6 open roller coasters. */ static int award_is_deserved_best_rollercoasters(int awardType, int activeAwardTypes) { int i, rollerCoasters; @@ -79,7 +82,7 @@ static int award_is_deserved_best_rollercoasters(int awardType, int activeAwardT if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_ROLLERCOASTER && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_ROLLERCOASTER) continue; - if (ride->status != RIDE_STATUS_OPEN || ride->lifecycle_flags & 0x400) + if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & 0x400)) continue; rollerCoasters++; @@ -123,10 +126,32 @@ static int award_is_deserved_worse_value(int awardType, int activeAwardTypes) return 0; return 1; } + +/** No more than 2 people who think the vandalism is bad and no crashes. */ static int award_is_deserved_safest(int awardType, int activeAwardTypes) { - // TODO - return 0; + int i; + uint16 spriteIndex; + rct_peep *peep; + int peepsWhoDislikeVandalism = 0; + rct_ride *ride; + + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM) + peepsWhoDislikeVandalism++; + } + + if (peepsWhoDislikeVandalism > 2) + return 0; + + // Check for rides that have crashed maybe? + FOR_ALL_RIDES(i, ride) + if (ride->var_1AE != 0) + return 0; + + return 1; } static int award_is_deserved_best_staff(int awardType, int activeAwardTypes) @@ -147,10 +172,39 @@ static int award_is_deserved_worst_food(int awardType, int activeAwardTypes) return 0; } +/** At least 4 restrooms, 1 restroom per 128 guests and no more than 16 guests who think they need the restroom. */ static int award_is_deserved_best_restrooms(int awardType, int activeAwardTypes) { - // TODO - return 0; + unsigned int i, numRestrooms, guestsWhoNeedRestroom; + rct_ride *ride; + uint16 spriteIndex; + rct_peep *peep; + + // Count open restrooms + numRestrooms = 0; + FOR_ALL_RIDES(i, ride) + if (ride->type == RIDE_TYPE_BATHROOM && ride->status == RIDE_STATUS_OPEN) + numRestrooms++; + + // At least 4 open restrooms + if (numRestrooms < 4) + return 0; + + // At least one open restroom for every 128 guests + if (numRestrooms < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) / 128U) + return 0; + + // Count number of guests who are thinking they need the restroom + guestsWhoNeedRestroom = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BATHROOM) + guestsWhoNeedRestroom++; + } + + return (guestsWhoNeedRestroom <= 16); } /** More than half of the rides have satisfication <= 6 and park rating <= 650. */ @@ -196,7 +250,7 @@ static int award_is_deserved_best_water_rides(int awardType, int activeAwardType if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_WATER && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_WATER) continue; - if (ride->status != RIDE_STATUS_OPEN || ride->lifecycle_flags & 0x400) + if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & 0x400)) continue; waterRides++; @@ -205,22 +259,74 @@ static int award_is_deserved_best_water_rides(int awardType, int activeAwardType return (waterRides >= 6); } +/** At least 6 custom designed rides. */ static int award_is_deserved_best_custom_designed_rides(int awardType, int activeAwardTypes) { - // TODO - return 0; + int i, customDesignedRides; + rct_ride *ride; + + if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) + return 0; + + customDesignedRides = 0; + FOR_ALL_RIDES(i, ride) { + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x10000000)) + continue; + if (ride->lifecycle_flags & 0x40000) + continue; + if (ride->excitement < RIDE_RATING(5, 50)) + continue; + if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & 0x400)) + continue; + + customDesignedRides++; + } + + return (customDesignedRides >= 6); } +/** At least 5 colourful rides and more than half of the rides are colourful. */ static int award_is_deserved_most_dazzling_ride_colours(int awardType, int activeAwardTypes) { - // TODO - return 0; + int i, countedRides, colourfulRides; + rct_ride *ride; + + if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) + return 0; + + countedRides = 0; + colourfulRides = 0; + FOR_ALL_RIDES(i, ride) { + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x10000000)) + continue; + + countedRides++; + if (ride->var_1BC == 5 || ride->var_1BC == 14 || ride->var_1BC == 20 || ride->var_1BC == 30) + colourfulRides++; + } + + return (colourfulRides >= 5 && colourfulRides >= countedRides - colourfulRides); } +/** At least 10 peeps and more than 1/64 of total guests are lost or can't find something. */ static int award_is_deserved_most_confusing_layout(int awardType, int activeAwardTypes) { - // TODO - return 0; + unsigned int peepsCounted, peepsLost; + uint16 spriteIndex; + rct_peep *peep; + + peepsCounted = 0; + peepsLost = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + peepsCounted++; + if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND) + peepsLost++; + } + + return (peepsLost >= 10 && peepsLost >= peepsCounted / 64); } /** At least 10 open gentle rides. */ @@ -236,7 +342,7 @@ static int award_is_deserved_best_gentle_rides(int awardType, int activeAwardTyp if (RCT2_GLOBAL(object + 0x1BE, uint8) != RIDE_GROUP_GENTLE && RCT2_GLOBAL(object + 0x1BF, uint8) != RIDE_GROUP_GENTLE) continue; - if (ride->status != RIDE_STATUS_OPEN || ride->lifecycle_flags & 0x400) + if (ride->status != RIDE_STATUS_OPEN || (ride->lifecycle_flags & 0x400)) continue; gentleRides++; @@ -283,6 +389,9 @@ void award_update_all() int i, activeAwardTypes, freeAwardEntryIndex; rct_award *awards; + RCT2_CALLPROC_EBPSAFE(0x0066A86C); + return; + awards = RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award); // Only add new awards if park is open diff --git a/src/finance.c b/src/finance.c index cceea4ee5d..f61def04c4 100644 --- a/src/finance.c +++ b/src/finance.c @@ -71,16 +71,13 @@ void finance_payment(money32 amount, rct_expenditure_type type) void finance_pay_wages() { rct_peep* peep; - uint16 sprite_idx; + uint16 spriteIndex; - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800) + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11) return; - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); - if (peep->type == PEEP_TYPE_STAFF) - finance_payment(wage_table[peep->staff_type] / 4, RCT_EXPENDITURE_TYPE_WAGES); - } + FOR_ALL_STAFF(spriteIndex, peep) + finance_payment(wage_table[peep->staff_type] / 4, RCT_EXPENDITURE_TYPE_WAGES); } /** @@ -120,12 +117,10 @@ void finance_pay_interest() */ void finance_pay_ride_upkeep() { + int i; rct_ride* ride; - for (int i = 0; i < MAX_RIDES; i++) { - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]); - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_EVER_BEEN_OPENED)) { ride->build_date = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16); ride->var_196 = 25855; // durability? diff --git a/src/news_item.c b/src/news_item.c index 5e32c37f5b..f9584cdaa4 100644 --- a/src/news_item.c +++ b/src/news_item.c @@ -192,7 +192,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *z = map_element_height(*x, *y); break; case NEWS_ITEM_PEEP_ON_RIDE: - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]).peep; + peep = GET_PEEP(subject); *x = peep->x; *y = peep->y; *z = peep->z; @@ -221,7 +221,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int * *z = vehicle->z; break; case NEWS_ITEM_PEEP: - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]).peep; + peep = GET_PEEP(subject); *x = peep->x; *y = peep->y; *z = peep->z; @@ -295,7 +295,7 @@ void news_item_open_subject(int type, int subject) { break; case NEWS_ITEM_PEEP_ON_RIDE: case NEWS_ITEM_PEEP: - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[subject]).peep; + peep = GET_PEEP(subject); RCT2_CALLPROC_X(0x006989E9, 0, 0, 0, (int)peep, 0, 0, 0); break; case NEWS_ITEM_MONEY: diff --git a/src/park.c b/src/park.c index 4ab075f148..e007cb335c 100644 --- a/src/park.c +++ b/src/park.c @@ -182,7 +182,7 @@ int calculate_park_rating() // Guests { rct_peep* peep; - uint16 sprite_idx; + uint16 spriteIndex; int num_happy_peeps; short _bp; @@ -192,10 +192,7 @@ int calculate_park_rating() // Guests, happiness, ? num_happy_peeps = 0; _bp = 0; - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); - if (peep->type != PEEP_TYPE_GUEST) - continue; + FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; if (peep->happiness > 128) @@ -228,11 +225,7 @@ int calculate_park_rating() // _ax = 0; num_rides = 0; - for (i = 0; i < 255; i++) { - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]); - - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { _ax += 100 - ride->var_199; if (ride->excitement != -1){ @@ -374,14 +367,12 @@ static int park_calculate_guest_generation_probability() { unsigned int probability; int i, suggestedMaxGuests, totalRideValue; + rct_ride *ride; // Calculate suggested guest maximum (based on ride type) and total ride value suggestedMaxGuests = 0; totalRideValue = 0; - for (i = 0; i < MAX_RIDES; i++) { - rct_ride *ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]; - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (ride->status != RIDE_STATUS_OPEN) continue; if (ride->lifecycle_flags & 0x80) @@ -403,10 +394,7 @@ static int park_calculate_guest_generation_probability() // If difficult guest generation, extra guests are available for good rides if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) { suggestedMaxGuests = min(suggestedMaxGuests, 1000); - for (i = 0; i < MAX_RIDES; i++) { - rct_ride *ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]; - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (ride->lifecycle_flags & 0x80) continue; if (ride->lifecycle_flags & 0x400) diff --git a/src/peep.c b/src/peep.c index b80f838776..f64ee2679a 100644 --- a/src/peep.c +++ b/src/peep.c @@ -30,18 +30,12 @@ int peep_get_staff_count() { - uint16 sprite_index; + uint16 spriteIndex; rct_peep *peep; int count = 0; - sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (sprite_index != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep); - sprite_index = peep->next; - - if (peep->type == PEEP_TYPE_STAFF) - count++; - } + FOR_ALL_STAFF(spriteIndex, peep) + count++; return count; } @@ -53,18 +47,14 @@ int peep_get_staff_count() void peep_update_all() { int i; - uint16 sprite_index; + uint16 spriteIndex; rct_peep* peep; if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E) return; - sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); i = 0; - while (sprite_index != 0xFFFF) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep); - sprite_index = peep->next; - + FOR_ALL_PEEPS(spriteIndex, peep) { if ((i & 0x7F) != (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) { RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); } else { @@ -86,7 +76,7 @@ void peep_problem_warnings_update() { rct_peep* peep; rct_ride* ride; - uint16 sprite_idx; + uint16 spriteIndex; uint16 guests_in_park = RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16); int hunger_counter = 0, lost_counter = 0, noexit_counter = 0, thirst_counter = 0, litter_counter = 0, disgust_counter = 0, bathroom_counter = 0 ,vandalism_counter = 0; @@ -94,11 +84,8 @@ void peep_problem_warnings_update() RCT2_GLOBAL(RCT2_ADDRESS_RIDE_COUNT, sint16) = ride_get_count(); // refactor this to somewhere else - - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); - - if (peep->type != PEEP_TYPE_GUEST || peep->var_2A != 0 || peep->thoughts[0].pad_3 > 5) + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0 || peep->thoughts[0].pad_3 > 5) continue; switch (peep->thoughts[0].type) { @@ -213,7 +200,7 @@ void peep_problem_warnings_update() void peep_update_crowd_noise() { rct_viewport *viewport; - uint16 sprite_index; + uint16 spriteIndex; rct_peep *peep; int visiblePeeps; @@ -235,15 +222,10 @@ void peep_update_crowd_noise() // Count the number of peeps visible visiblePeeps = 0; - sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (sprite_index != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep); - sprite_index = peep->next; + FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_16 == 0x8000) continue; - if (peep->type != PEEP_TYPE_GUEST) - continue; if (viewport->view_x > peep->var_1A) continue; if (viewport->view_x + viewport->view_width < peep->var_16) @@ -300,17 +282,10 @@ void peep_update_crowd_noise() */ void peep_applause() { - uint16 sprite_index; + uint16 spriteIndex; rct_peep* peep; - // For each guest - sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (sprite_index != 0xFFFF) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep); - sprite_index = peep->next; - - if (peep->type != PEEP_TYPE_GUEST) - continue; + FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; diff --git a/src/peep.h b/src/peep.h index 8bcf28de73..2bac8ed735 100644 --- a/src/peep.h +++ b/src/peep.h @@ -417,6 +417,25 @@ typedef struct { uint32 item_standard_flags; // 0xFC } rct_peep; +/** Helper macro until rides are stored in this module. */ +#define GET_PEEP(sprite_index) &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_index].peep) + +/** + * Helper macro loop for enumerating through all the non null rides. To avoid needing a end loop counterpart, statements are + * applied in tautology if statements. + */ +#define FOR_ALL_PEEPS(sprite_index, peep) \ + for (sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next) \ + if ((peep = GET_PEEP(sprite_index)) || 1) + +#define FOR_ALL_GUESTS(sprite_index, peep) \ + FOR_ALL_PEEPS(sprite_index, peep) \ + if (peep->type == PEEP_TYPE_GUEST) + +#define FOR_ALL_STAFF(sprite_index, peep) \ + FOR_ALL_PEEPS(sprite_index, peep) \ + if (peep->type == PEEP_TYPE_STAFF) + int peep_get_staff_count(); void peep_update_all(); void peep_problem_warnings_update(); diff --git a/src/ride.c b/src/ride.c index 1535bc7406..56149ba2a9 100644 --- a/src/ride.c +++ b/src/ride.c @@ -101,11 +101,8 @@ int ride_get_count() rct_ride *ride; int i, count = 0; - for (i = 0; i < MAX_RIDES; i++) { - ride = GET_RIDE(i); - if (ride->type != RIDE_TYPE_NULL) - count++; - } + FOR_ALL_RIDES(i, ride) + count++; return count; } @@ -159,13 +156,10 @@ void ride_init_all() void reset_all_ride_build_dates() { int i; rct_ride *ride; - for (i = 0; i < MAX_RIDES; i++) { - ride = GET_RIDE(i); - if (ride->type != RIDE_TYPE_NULL) { - //mov ax, current_month_year - //sub [esi + 180h], ax - ride->build_date -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16); - } + FOR_ALL_RIDES(i, ride) { + //mov ax, current_month_year + //sub [esi + 180h], ax + ride->build_date -= RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16); } } @@ -174,17 +168,15 @@ void reset_all_ride_build_dates() { */ void ride_update_favourited_stat() { + int i; rct_ride *ride; + uint16 spriteIndex; rct_peep* peep; - for (int i = 0; i < MAX_RIDES; i++) { - ride = GET_RIDE(i); - if (ride->type != RIDE_TYPE_NULL) - ride->guests_favourite = 0; + FOR_ALL_RIDES(i, ride) + ride->guests_favourite = 0; - } - for (int sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); + FOR_ALL_PEEPS(spriteIndex, peep) { if (peep->var_08 != 4) return; if (peep->favourite_ride != 0xff) { @@ -195,6 +187,7 @@ void ride_update_favourited_stat() } } + window_invalidate_by_id(WC_RIDE_LIST, 0); } diff --git a/src/ride.h b/src/ride.h index e5dff8e8f1..9d53d72864 100644 --- a/src/ride.h +++ b/src/ride.h @@ -109,10 +109,13 @@ typedef struct { // used in computing excitement, nausea, etc uint8 var_198; uint8 var_199; - uint8 pad_19A[0x1A]; + uint8 pad_19A[0x14]; + uint8 var_1AE; + uint8 pad_1AF[0x05]; money32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 - uint8 pad_1BC[0x11]; + uint8 var_1BC; + uint8 pad_1BD[0x10]; uint8 var_1CD; uint16 guests_favourite; // 0x1CE uint32 lifecycle_flags; // 0x1D0 @@ -330,7 +333,7 @@ enum { */ #define FOR_ALL_RIDES(i, ride) \ for (i = 0; i < MAX_RIDES; i++) \ - if ((ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]))->type != RIDE_TYPE_NULL) + if ((ride = GET_RIDE(i))->type != RIDE_TYPE_NULL) extern const uint8 gRideClassifications[255]; diff --git a/src/scenario.c b/src/scenario.c index 26bc659709..f52f17a9db 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -365,20 +365,15 @@ void scenario_success() **/ void scenario_objective5_check() { - int rcs = 0; + int i, rcs = 0; uint8 type_already_counted[256]; rct_ride* ride; memset(type_already_counted, 0, 256); - for (int i = 0; i < MAX_RIDES; i++) { - uint8 subtype_id; - uint32 subtype_p; - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]); - if (ride->type == RIDE_TYPE_NULL) - continue; - subtype_id = (uint8)ride->subtype; - subtype_p = RCT2_GLOBAL(0x009ACFA4 + subtype_id * 4, uint32); + FOR_ALL_RIDES(i, ride) { + uint8 subtype_id = ride->subtype; + uint32 subtype_p = RCT2_GLOBAL(0x009ACFA4 + subtype_id * 4, uint32); if ((RCT2_GLOBAL(subtype_p + 0x1BE, sint8) == 2 || RCT2_GLOBAL(subtype_p + 0x1BF, sint8) == 2) && @@ -400,21 +395,16 @@ void scenario_objective5_check() **/ void scenario_objective8_check() { - int rcs = 0; + int i, rcs = 0; uint8 type_already_counted[256]; rct_ride* ride; sint16 objective_length = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16); memset(type_already_counted, 0, 256); - for (int i = 0; i < MAX_RIDES; i++) { - uint8 subtype_id; - uint32 subtype_p; - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]); - if (ride->type == RIDE_TYPE_NULL) - continue; - subtype_id = (uint8)ride->subtype; - subtype_p = RCT2_GLOBAL(0x009ACFA4 + subtype_id * 4, uint32); + FOR_ALL_RIDES(i, ride) { + uint8 subtype_id = ride->subtype; + uint32 subtype_p = RCT2_GLOBAL(0x009ACFA4 + subtype_id * 4, uint32); if ((RCT2_GLOBAL(subtype_p + 0x1BE, sint8) == 2 || RCT2_GLOBAL(subtype_p + 0x1BF, sint8) == 2) && diff --git a/src/window_cheats.c b/src/window_cheats.c index 0a18ff0ada..84301284fa 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -239,7 +239,7 @@ static void window_cheats_guests_mouseup() #endif rct_peep* peep; - uint16 sprite_idx; + uint16 spriteIndex; switch (widgetIndex) { case WIDX_CLOSE: @@ -250,14 +250,9 @@ static void window_cheats_guests_mouseup() window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_HAPPY_GUESTS: - for (sprite_idx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = peep->next) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[sprite_idx].peep); - if (peep->type != PEEP_TYPE_GUEST) - continue; - if (peep->var_2A != 0) - continue; - peep->happiness = 255; - } + FOR_ALL_GUESTS(spriteIndex, peep) + if (peep->var_2A == 0) + peep->happiness = 255; window_invalidate_by_id(0x40 | WC_BOTTOM_TOOLBAR, 0); break; } diff --git a/src/window_guest_list.c b/src/window_guest_list.c index d235cab756..95284c0b88 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -388,7 +388,7 @@ static void window_guest_list_update(rct_window *w) */ static void window_guest_list_scrollgetsize() { - int i, y, numGuests, spriteIdx; + int i, y, numGuests, spriteIndex; rct_window *w; rct_peep *peep; @@ -404,13 +404,7 @@ static void window_guest_list_scrollgetsize() // Count the number of guests numGuests = 0; - spriteIdx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (spriteIdx != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIdx].peep); - spriteIdx = peep->next; - - if (peep->type != PEEP_TYPE_GUEST) - continue; + FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; if (_window_guest_list_selected_filter != -1) @@ -470,7 +464,7 @@ static void window_guest_list_scrollgetsize() */ static void window_guest_list_scrollmousedown() { - int i, spriteIdx; + int i, spriteIndex; short y; rct_window *w; rct_peep *peep; @@ -492,13 +486,7 @@ static void window_guest_list_scrollmousedown() case PAGE_INDIVIDUAL: i = y / 10; i += _window_guest_list_selected_page * 3173; - spriteIdx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (spriteIdx != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIdx].peep); - spriteIdx = peep->next; - - if (peep->type != PEEP_TYPE_GUEST) - continue; + FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; if (_window_guest_list_selected_filter != -1) @@ -683,7 +671,7 @@ static void window_guest_list_paint() static void window_guest_list_scrollpaint() { int eax, ebx, ecx, edx, esi, edi, ebp; - int spriteIdx, format, numGuests, i, j, y; + int spriteIndex, format, numGuests, i, j, y; rct_window *w; rct_drawpixelinfo *dpi; rct_peep *peep; @@ -711,13 +699,7 @@ static void window_guest_list_scrollpaint() y = _window_guest_list_selected_page * -0x7BF2; // For each guest - spriteIdx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (spriteIdx != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIdx].peep); - spriteIdx = peep->next; - - if (peep->type != PEEP_TYPE_GUEST) - continue; + FOR_ALL_GUESTS(spriteIndex, peep) { peep->var_0C &= ~0x200; if (peep->var_2A != 0) continue; @@ -907,7 +889,7 @@ static int sub_69B7EA(rct_peep *peep, int *outEAX) */ static void window_guest_list_find_groups() { - int spriteIdx, spriteIdx2, groupIndex, faceIndex; + int spriteIndex, spriteIndex2, groupIndex, faceIndex; rct_peep *peep, *peep2; int eax = RCT2_GLOBAL(0x00F663AC, uint32) & 0xFFFFFF00; @@ -921,24 +903,13 @@ static void window_guest_list_find_groups() _window_guest_list_num_groups = 0; // Set all guests to unassigned - spriteIdx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (spriteIdx != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIdx].peep); - spriteIdx = peep->next; - - if (peep->type != PEEP_TYPE_GUEST || peep->var_2A != 0) - continue; - - peep->var_0C |= (1 << 8); - } + FOR_ALL_GUESTS(spriteIndex, peep) + if (peep->var_2A == 0) + peep->var_0C |= (1 << 8); // For each guest / group - spriteIdx = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); - while (spriteIdx != SPRITE_INDEX_NULL) { - peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIdx].peep); - spriteIdx = peep->next; - - if (peep->type != PEEP_TYPE_GUEST || peep->var_2A != 0 || !(peep->var_0C & (1 << 8))) + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0 || !(peep->var_0C & (1 << 8))) continue; // New group, cap at 240 though @@ -961,12 +932,8 @@ static void window_guest_list_find_groups() _window_guest_list_groups_guest_faces[faceIndex++] = get_guest_face_sprite_small(peep) - 5486; // Find more peeps that belong to same group - spriteIdx2 = peep->next; - while (spriteIdx2 != SPRITE_INDEX_NULL) { - peep2 = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIdx2].peep); - spriteIdx2 = peep2->next; - - if (peep2->type != PEEP_TYPE_GUEST || peep2->var_2A != 0 || !(peep2->var_0C & (1 << 8))) + FOR_ALL_GUESTS(spriteIndex2, peep2) { + if (peep2->var_2A != 0 || !(peep2->var_0C & (1 << 8))) continue; // Get and check if in same group diff --git a/src/window_ride_list.c b/src/window_ride_list.c index b365ee8eec..4d0f29da66 100644 --- a/src/window_ride_list.c +++ b/src/window_ride_list.c @@ -695,10 +695,7 @@ static void window_ride_list_refresh_list(rct_window *w) rct_ride *ride, *otherRide; countA = countB = 0; - for (i = 0; i < MAX_RIDES; i++) { - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]); - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (w->page != gRideClassifications[ride->type]) continue; @@ -717,10 +714,7 @@ static void window_ride_list_refresh_list(rct_window *w) w->var_476 = countA; j = 0; - for (i = 0; i < MAX_RIDES; i++) { - ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]); - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (w->page != gRideClassifications[ride->type]) continue; @@ -844,10 +838,7 @@ static void window_ride_list_close_all(rct_window *w) int i; rct_ride *ride; - for (i = 0; i < MAX_RIDES; i++) { - ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]; - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (w->page != gRideClassifications[ride->type]) continue; if (ride->status == RIDE_STATUS_CLOSED) @@ -864,10 +855,7 @@ static void window_ride_list_open_all(rct_window *w) int i; rct_ride *ride; - for (i = 0; i < MAX_RIDES; i++) { - ride = &RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[i]; - if (ride->type == RIDE_TYPE_NULL) - continue; + FOR_ALL_RIDES(i, ride) { if (w->page != gRideClassifications[ride->type]) continue; if (ride->status == RIDE_STATUS_OPEN) From 66e6dfc3f9699cc0c6ef8d68b1df4605e0de619a Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 19:22:06 +0200 Subject: [PATCH 098/209] clean up header files, keep windows.h for MAX_PATH --- src/config.c | 8 +++----- src/config.h | 2 +- src/screenshot.c | 2 ++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/config.c b/src/config.c index c17625f328..ad58991810 100644 --- a/src/config.c +++ b/src/config.c @@ -19,14 +19,12 @@ *****************************************************************************/ #include -#include -#include -#include #include +#include #include "addresses.h" #include "config.h" #include "rct2.h" -#include + #include "osinterface.h" @@ -201,7 +199,7 @@ void config_save() fp = fopen(get_file_path(PATH_ID_GAMECFG), "wb"); if (fp != NULL){ fwrite(&MagicNumber, 4, 1, fp); - fwrite((LPCVOID)0x009AAC5C, 2155, 1, fp); + fwrite((void*)0x009AAC5C, 2155, 1, fp); fclose(fp); } } diff --git a/src/config.h b/src/config.h index ef04a12386..c1139c0a96 100644 --- a/src/config.h +++ b/src/config.h @@ -21,8 +21,8 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#include #include "rct2.h" +#include // for MAX_PATH enum { CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES = (1 << 0), diff --git a/src/screenshot.c b/src/screenshot.c index 10350f39da..cc8d3d84bc 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -30,6 +30,8 @@ #include "string_ids.h" #include "window_error.h" +#include // For MAX_PATH + static int screenshot_dump_bmp(); static int screenshot_dump_png(); From a0380fc1f83baef96d02cf185ad75401c1d5c3a0 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 19:28:22 +0200 Subject: [PATCH 099/209] travis doesn't like capitalized ... --- src/config.h | 2 +- src/screenshot.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.h b/src/config.h index c1139c0a96..eb86ab5da2 100644 --- a/src/config.h +++ b/src/config.h @@ -22,7 +22,7 @@ #define _CONFIG_H_ #include "rct2.h" -#include // for MAX_PATH +#include // for MAX_PATH enum { CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES = (1 << 0), diff --git a/src/screenshot.c b/src/screenshot.c index cc8d3d84bc..6db7d4f2bb 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -30,7 +30,7 @@ #include "string_ids.h" #include "window_error.h" -#include // For MAX_PATH +#include // For MAX_PATH static int screenshot_dump_bmp(); From fcb9a407f5635f6f1bc077b371009ded01ae0f2e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 18:28:24 +0100 Subject: [PATCH 100/209] fix peep loop bug --- src/peep.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/peep.c b/src/peep.c index f64ee2679a..cde8015f4e 100644 --- a/src/peep.c +++ b/src/peep.c @@ -53,8 +53,12 @@ void peep_update_all() if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E) return; + spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); i = 0; - FOR_ALL_PEEPS(spriteIndex, peep) { + while (spriteIndex != SPRITE_INDEX_NULL) { + peep = &(RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite)[spriteIndex].peep); + spriteIndex = peep->next; + if ((i & 0x7F) != (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) { RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); } else { From 4e7ec2feb6b2a3901a7ba4cc26dba221966aa17f Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 20:45:40 +0100 Subject: [PATCH 101/209] finish award checks --- src/award.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 202 insertions(+), 14 deletions(-) diff --git a/src/award.c b/src/award.c index 3d295bd519..6b9e6844a7 100644 --- a/src/award.c +++ b/src/award.c @@ -57,16 +57,73 @@ int award_is_positive(int type) #pragma region Award checks +/** More than 1/16 of the total guests must be thinking untidy thoughts. */ static int award_is_deserved_most_untidy(int awardType, int activeAwardTypes) { - // TODO - return 0; + uint16 spriteIndex; + rct_peep *peep; + int negativeCount; + + if (activeAwardTypes & (1 << PARK_AWARD_MOST_BEAUTIFUL)) + return 0; + if (activeAwardTypes & (1 << PARK_AWARD_BEST_STAFF)) + return 0; + if (activeAwardTypes & (1 << PARK_AWARD_MOST_TIDY)) + return 0; + + negativeCount = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + if (peep->thoughts[0].pad_3 > 5) + continue; + + if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BAD_LITTER || + peep->thoughts[0].type == PEEP_THOUGHT_TYPE_PATH_DISGUSTING || + peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM + ) { + negativeCount++; + } + } + + return (negativeCount > RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) / 16); } +/** More than 1/64 of the total guests must be thinking tidy thoughts and less than 6 guests thinking untidy thoughts. */ static int award_is_deserved_most_tidy(int awardType, int activeAwardTypes) { - // TODO - return 0; + uint16 spriteIndex; + rct_peep *peep; + int positiveCount; + int negativeCount; + + if (activeAwardTypes & (1 << PARK_AWARD_MOST_UNTIDY)) + return 0; + if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) + return 0; + + positiveCount = 0; + negativeCount = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + if (peep->thoughts[0].pad_3 > 5) + continue; + + if (peep->thoughts[0].type == PEEP_THOUGHT_VERY_CLEAN) + positiveCount++; + + if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BAD_LITTER || + peep->thoughts[0].type == PEEP_THOUGHT_TYPE_PATH_DISGUSTING || + peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM + ) { + negativeCount++; + } + } + + return (negativeCount <= 5 && positiveCount > RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) / 64); } /** At least 6 open roller coasters. */ @@ -107,10 +164,40 @@ static int award_is_deserved_best_value(int awardType, int activeAwardTypes) return 1; } +/** More than 1/128 of the total guests must be thinking scenic thoughts and less than 16 untidy thoughts. */ static int award_is_deserved_most_beautiful(int awardType, int activeAwardTypes) { - // TODO - return 0; + uint16 spriteIndex; + rct_peep *peep; + int positiveCount; + int negativeCount; + + if (activeAwardTypes & (1 << PARK_AWARD_MOST_UNTIDY)) + return 0; + if (activeAwardTypes & (1 << PARK_AWARD_MOST_DISAPPOINTING)) + return 0; + + positiveCount = 0; + negativeCount = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + if (peep->thoughts[0].pad_3 > 5) + continue; + + if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_SCENERY) + positiveCount++; + + if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BAD_LITTER || + peep->thoughts[0].type == PEEP_THOUGHT_TYPE_PATH_DISGUSTING || + peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM + ) { + negativeCount++; + } + } + + return (negativeCount <= 15 && positiveCount > RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) / 128); } /** Entrance fee is more than total ride value. */ @@ -130,12 +217,12 @@ static int award_is_deserved_worse_value(int awardType, int activeAwardTypes) /** No more than 2 people who think the vandalism is bad and no crashes. */ static int award_is_deserved_safest(int awardType, int activeAwardTypes) { - int i; + int i, peepsWhoDislikeVandalism; uint16 spriteIndex; rct_peep *peep; - int peepsWhoDislikeVandalism = 0; rct_ride *ride; + peepsWhoDislikeVandalism = 0; FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; @@ -154,22 +241,123 @@ static int award_is_deserved_safest(int awardType, int activeAwardTypes) return 1; } +/** All staff types, at least 20 staff, one staff per 32 peeps. */ static int award_is_deserved_best_staff(int awardType, int activeAwardTypes) { - // TODO - return 0; + uint16 spriteIndex; + rct_peep *peep; + int peepCount, staffCount; + int staffTypeFlags; + + if (activeAwardTypes & (1 << PARK_AWARD_MOST_UNTIDY)) + return 0; + + peepCount = 0; + staffCount = 0; + staffTypeFlags = 0; + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->type == PEEP_TYPE_STAFF) { + staffCount++; + staffTypeFlags |= (1 << peep->staff_type); + } else { + peepCount++; + } + } + + return ((staffTypeFlags & 0xF) && staffCount >= 20 && staffCount >= peepCount / 32); + } +/** At least 7 shops, 4 unique, one shop per 128 guests and no more than 12 hungry guests. */ static int award_is_deserved_best_food(int awardType, int activeAwardTypes) { - // TODO - return 0; + int i, hungryPeeps, shops, uniqueShops; + uint64 shopTypes; + rct_ride *ride; + char *object; + uint16 spriteIndex; + rct_peep *peep; + + if (activeAwardTypes & (1 << PARK_AWARD_WORST_FOOD)) + return 0; + + shops = 0; + uniqueShops = 0; + shopTypes = 0; + FOR_ALL_RIDES(i, ride) { + if (ride->status != RIDE_STATUS_OPEN) + continue; + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x800000)) + continue; + + shops++; + object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype]; + if (!(shopTypes & (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8)))) { + shopTypes |= (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8)); + uniqueShops++; + } + } + + if (shops < 7 || uniqueShops < 4 || shops < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) / 128) + return 0; + + // Count hungry peeps + hungryPeeps = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) + hungryPeeps++; + } + + return (hungryPeeps <= 12); } +/** No more than 2 unique shops, less than one shop per 256 guests and more than 15 hungry guests. */ static int award_is_deserved_worst_food(int awardType, int activeAwardTypes) { - // TODO - return 0; + int i, hungryPeeps, shops, uniqueShops; + uint64 shopTypes; + rct_ride *ride; + char *object; + uint16 spriteIndex; + rct_peep *peep; + + if (activeAwardTypes & (1 << PARK_AWARD_BEST_FOOD)) + return 0; + + shops = 0; + uniqueShops = 0; + shopTypes = 0; + FOR_ALL_RIDES(i, ride) { + if (ride->status != RIDE_STATUS_OPEN) + continue; + if (!(RCT2_GLOBAL(0x0097CF40 + (ride->type * 8), uint32) & 0x800000)) + continue; + + shops++; + object = RCT2_ADDRESS(0x009ACFA4, char*)[ride->subtype]; + if (!(shopTypes & (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8)))) { + shopTypes |= (1ULL << RCT2_GLOBAL(object + 0x1C0, uint8)); + uniqueShops++; + } + } + + if (uniqueShops > 2 || shops > RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) / 256) + return 0; + + // Count hungry peeps + hungryPeeps = 0; + FOR_ALL_GUESTS(spriteIndex, peep) { + if (peep->var_2A != 0) + continue; + + if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) + hungryPeeps++; + } + + return (hungryPeeps > 15); } /** At least 4 restrooms, 1 restroom per 128 guests and no more than 16 guests who think they need the restroom. */ From 014a2245f4478d42e3745f2db5a0999d6046c693 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 20:46:45 +0100 Subject: [PATCH 102/209] remove original call for awards --- src/award.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/award.c b/src/award.c index 6b9e6844a7..ccbba5651f 100644 --- a/src/award.c +++ b/src/award.c @@ -577,9 +577,6 @@ void award_update_all() int i, activeAwardTypes, freeAwardEntryIndex; rct_award *awards; - RCT2_CALLPROC_EBPSAFE(0x0066A86C); - return; - awards = RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award); // Only add new awards if park is open From 15e5a8b3cf24a075261bbb3d5b9d90276d29c1f8 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 21:55:53 +0200 Subject: [PATCH 103/209] Initial support for saving settings to config.ini Supported settings: * currency * measurement_format * temperature_format * sound_quality --- src/config.c | 146 ++++++++++++++++++++++++++++++++----------- src/config.h | 19 ++++++ src/window_options.c | 6 +- 3 files changed, 134 insertions(+), 37 deletions(-) diff --git a/src/config.c b/src/config.c index ad58991810..2db90e92f4 100644 --- a/src/config.c +++ b/src/config.c @@ -76,7 +76,7 @@ static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = { general_configuration_t gGeneral_config; general_configuration_t gGeneral_config_default = { - 1, + 0, 1, SCREENSHOT_FORMAT_PNG, "", @@ -100,6 +100,10 @@ static void config_create_default(char *path); static int config_parse_currency(char* currency); static void config_error(char *msg); +void config_save_ini(char *path); +void config_write_ini_general(FILE *fp); +void config_write_ini_sound(FILE *fp); + /** * * rct2: 0x006E3604 @@ -189,6 +193,7 @@ void config_load() RCT2_GLOBAL(0x009AA00D, sint8) = 1; } + /** * Save configuration to the data/config.cfg file * rct2: 0x00675487 @@ -196,14 +201,116 @@ void config_load() void config_save() { FILE *fp=NULL; + char *configIniPath = osinterface_get_orct2_homefolder();; + fp = fopen(get_file_path(PATH_ID_GAMECFG), "wb"); if (fp != NULL){ fwrite(&MagicNumber, 4, 1, fp); fwrite((void*)0x009AAC5C, 2155, 1, fp); fclose(fp); } + + sprintf(configIniPath, "%s%c%s", configIniPath, osinterface_get_path_separator(), "config.ini"); + config_save_ini(configIniPath); } +void config_save_ini(char *path) +{ + FILE *fp = NULL; + + + fp = fopen(path, "wt+"); + + config_write_ini_general(fp); + config_write_ini_sound(fp); + + fclose(fp); +} + +void config_write_ini_sound(FILE *fp) +{ + fprintf(fp, "[sound]\n"); + if (gSound_config.sound_quality == SOUND_QUALITY_LOW) { + fprintf(fp, "sound_quality = low\n"); + } + else if (gSound_config.sound_quality == SOUND_QUALITY_MEDIUM) { + fprintf(fp, "sound_quality = medium\n"); + } + else{ + fprintf(fp, "sound_quality = high\n"); + } + + if (gSound_config.forced_software_buffering){ + fprintf(fp, "forced_software_buffering = true\n"); + } + else { + fprintf(fp, "forced_software_buffering = false\n"); + } +} + +void config_write_ini_general(FILE *fp) +{ + int currencyIterator = 0; + + fprintf(fp, "[general]\n"); + fprintf(fp, "game_path = %s\n", gGeneral_config.game_path); + + switch (gGeneral_config.screenshot_format) + { + case SCREENSHOT_FORMAT_BMP: + fprintf(fp, "screenshot_format = BMP\n"); + break; + case SCREENSHOT_FORMAT_PNG: + fprintf(fp, "screenshot_format = PNG\n"); + break; + default: + config_error("error saving config.ini: wrong screenshot_format"); + break; + } + + if (gGeneral_config.play_intro){ + fprintf(fp, "play_intro = true\n"); + } + else { + fprintf(fp, "play_intro = false\n"); + } + + if (gGeneral_config.confirmation_prompt){ + fprintf(fp, "confirmation_prompt = true\n"); + } + else { + fprintf(fp, "confirmation_prompt = false\n"); + } + + if (gGeneral_config.edge_scrolling){ + fprintf(fp, "edge_scrolling = true\n"); + } + else { + fprintf(fp, "edge_scrolling = false\n"); + } + + for (currencyIterator = 0; currencyIterator < countof(_currencyLookupTable); currencyIterator++) { + if (_currencyLookupTable[currencyIterator].value == gGeneral_config.currency_format) { + gGeneral_config.currency_format = _currencyLookupTable[currencyIterator].value; + fprintf(fp, "currency = %s\n", _currencyLookupTable[currencyIterator].key); + break; // There are more than one valid item for Pound, Euro and Dollar ... + } + } + + if (gGeneral_config.measurement_format == MEASUREMENT_FORMAT_IMPERIAL) { + fprintf(fp, "measurement_format = imperial\n"); + } + else { + fprintf(fp, "measurement_format = metric\n"); + } + + if (gGeneral_config.temperature_format == TEMPERATURE_FORMAT_F) { + fprintf(fp, "temperature_format = fahrenheit\n"); + } + else { + fprintf(fp, "temperature_format = celsius\n"); + } +} /** * Initilise the settings. @@ -278,8 +385,7 @@ static int config_find_rct2_path(char *resultPath) */ static void config_create_default(char *path) { - FILE* fp; - + gGeneral_config = gGeneral_config_default; if (!config_find_rct2_path(gGeneral_config.game_path)) { osinterface_show_messagebox("Unable to find RCT2 installation directory. Please select the directory where you installed RCT2!"); @@ -287,20 +393,7 @@ static void config_create_default(char *path) strcpy(gGeneral_config.game_path, res); } - fp = fopen(path, "w"); - fprintf(fp, "[general]\n"); - fprintf(fp, "game_path = %s\n", gGeneral_config.game_path); - fprintf(fp, "screenshot_format = PNG\n"); - fprintf(fp, "play_intro = false\n"); - fprintf(fp, "confirmation_prompt = true\n"); - fprintf(fp, "edge_scrolling = true\n"); - fprintf(fp, "currency = GBP\n"); - fprintf(fp, "measurement_format = imperial\n"); - fprintf(fp, "temperature_format = fahrenheit\n"); - fprintf(fp, "[sound]\n"); - fprintf(fp, "sound_quality = high\n"); - fprintf(fp, "forced_software_buffering = false\n"); - fclose(fp); + config_save_ini(path); } @@ -588,25 +681,6 @@ static int config_parse_section(FILE *fp, char *setting, char *value){ return 1; } -static const struct { char *key; int value; } _currencyLookupTable[] = { - { "GBP", CURRENCY_POUNDS }, - { "USD", CURRENCY_DOLLARS }, - { "FRF", CURRENCY_FRANC }, - { "DEM", CURRENCY_DEUTSCHMARK }, - { "YEN", CURRENCY_YEN }, - { "ESP", CURRENCY_PESETA }, - { "ITL", CURRENCY_LIRA }, - { "NLG", CURRENCY_GUILDERS }, - { "NOK", CURRENCY_KRONA }, - { "SEK", CURRENCY_KRONA }, - { "DEK", CURRENCY_KRONA }, - { "EUR", CURRENCY_EUROS }, - - { "£", CURRENCY_POUNDS }, - { "$", CURRENCY_DOLLARS }, - { "€", CURRENCY_EUROS } -}; - static int config_parse_currency(char *currency) { int i; diff --git a/src/config.h b/src/config.h index eb86ab5da2..b0b445101a 100644 --- a/src/config.h +++ b/src/config.h @@ -139,6 +139,25 @@ typedef struct general_configuration { } general_configuration_t; +static const struct { char *key; int value; } _currencyLookupTable[] = { + { "GBP", CURRENCY_POUNDS }, + { "USD", CURRENCY_DOLLARS }, + { "FRF", CURRENCY_FRANC }, + { "DEM", CURRENCY_DEUTSCHMARK }, + { "YEN", CURRENCY_YEN }, + { "ESP", CURRENCY_PESETA }, + { "ITL", CURRENCY_LIRA }, + { "NLG", CURRENCY_GUILDERS }, + { "NOK", CURRENCY_KRONA }, + { "SEK", CURRENCY_KRONA }, + { "DEK", CURRENCY_KRONA }, + { "EUR", CURRENCY_EUROS }, + + { "£", CURRENCY_POUNDS }, + { "$", CURRENCY_DOLLARS }, + { "€", CURRENCY_EUROS } +}; + //typedef struct hotkey_configuration{ //}; diff --git a/src/window_options.c b/src/window_options.c index edc4730f25..c87c5f7576 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -463,17 +463,20 @@ static void window_options_dropdown() // TODO: no clue what this does (and if it's correct) RCT2_GLOBAL(0x009AAC75, uint8) = RCT2_GLOBAL(0x009AF601 + dropdownIndex, uint8); RCT2_GLOBAL(0x009AAC76, uint8) = RCT2_GLOBAL(0x009AF604 + dropdownIndex, uint8); - + gSound_config.sound_quality = dropdownIndex; config_save(); window_invalidate(w); break; case WIDX_CURRENCY_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) = dropdownIndex | 0xC0; + gGeneral_config.currency_format = dropdownIndex; config_save(); gfx_invalidate_screen(); break; case WIDX_DISTANCE_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8) = (uint8)dropdownIndex; + gGeneral_config.measurement_format = dropdownIndex; + config_save(); window_options_update_height_markers(); break; case WIDX_RESOLUTION_DROPDOWN: @@ -488,6 +491,7 @@ static void window_options_dropdown() case WIDX_TEMPERATURE_DROPDOWN: if (dropdownIndex != RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8)) { RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8) = (uint8)dropdownIndex; + gGeneral_config.temperature_format = dropdownIndex; config_save(); gfx_invalidate_screen(); } From 20a18a8ba363364a067a0bdaf7b0df0ffe1c9655 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 21:02:20 +0100 Subject: [PATCH 104/209] fix awards window and remove original call --- src/award.c | 2 +- src/gfx.c | 14 +++++++------- src/gfx.h | 2 +- src/window_park.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/award.c b/src/award.c index ccbba5651f..12084559ca 100644 --- a/src/award.c +++ b/src/award.c @@ -587,7 +587,7 @@ void award_update_all() for (i = 0; i < MAX_AWARDS; i++) { if (awards[i].time != 0) activeAwardTypes |= (1 << awards[i].type); - else if (freeAwardEntryIndex != -1) + else if (freeAwardEntryIndex == -1) freeAwardEntryIndex = i; } diff --git a/src/gfx.c b/src/gfx.c index 8c14b8c932..c1320bc5cb 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -592,22 +592,22 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i * * rct2: 0x006C2105 * dpi (edi) - * format (esi) + * args (esi) * x (cx) * y (dx) * width (bp) - * colour (bx) - * unknown (al) + * format (bx) + * colour (al) */ -int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *format, int x, int y, int width, int colour, int unknown) +int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { int eax, ebx, ecx, edx, esi, edi, ebp; - eax = unknown; - ebx = colour; + eax = colour; + ebx = format; ecx = x; edx = y; - esi = (int)format; + esi = (int)args; edi = (int)dpi; ebp = width; RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); diff --git a/src/gfx.h b/src/gfx.h index 8eba37d27a..395543b662 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -66,7 +66,7 @@ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *a void gfx_draw_string_right(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y); void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args); int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour); -int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *format, int x, int y, int width, int colour, int unknown); +int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour); int gfx_get_string_width(char *buffer); int clip_text(char *buffer, int width); diff --git a/src/window_park.c b/src/window_park.c index 782cbe65c5..d2057e99ad 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -2265,7 +2265,7 @@ static void window_park_awards_paint() continue; gfx_draw_sprite(dpi, SPR_AWARD_MOST_UNTIDY + award->type, x, y); - gfx_draw_string_left_wrapped(dpi, (void*)STR_AWARD_MOST_UNTIDY, x + 34, y + 6, 180, 0, 0); + gfx_draw_string_left_wrapped(dpi, NULL, x + 34, y + 6, 180, STR_AWARD_MOST_UNTIDY, 0); y += 32; count++; From 65e579045cd85ed970d0297643bc175888bb14f8 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 27 May 2014 21:28:16 +0100 Subject: [PATCH 105/209] show full date in bottom right panel --- src/scenario.c | 2 ++ src/window_game_bottom_toolbar.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/scenario.c b/src/scenario.c index f52f17a9db..dbdd382f1e 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -577,6 +577,8 @@ void scenario_update() objective_type == 6 || objective_type == 5) { scenario_objectives_check(); } + + window_invalidate_by_id(WC_BOTTOM_TOOLBAR, 0); } diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c index efe61f769a..1d4b4ddf51 100644 --- a/src/window_game_bottom_toolbar.c +++ b/src/window_game_bottom_toolbar.c @@ -498,10 +498,20 @@ static void window_game_bottom_toolbar_draw_right_panel(rct_drawpixelinfo *dpi, y = window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].top + w->y + 2; // Date - RCT2_GLOBAL(0x013CE952, short) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16); + char *freeStr = (char*)0x009BC677; + freeStr[0] = FORMAT_STRINGID; + freeStr[1] = ' '; + freeStr[2] = FORMAT_MONTHYEAR; + freeStr[3] = 0; + + int month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; + int day = ((RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16) * days_in_month[month]) >> 16) & 0xFF; + + RCT2_GLOBAL(0x013CE952, short) = STR_DATE_DAY_1 + day; + RCT2_GLOBAL(0x013CE954, short) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16); gfx_draw_string_centred( dpi, - 1845, + 3165, x, y, (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass) == 2 && RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, sint32) == WIDX_DATE ? 2 : w->colours[0] & 0x7F), From a3b33c4656ebb2dca0d8d7f2ca379ba55609f26a Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 27 May 2014 22:20:00 +0100 Subject: [PATCH 106/209] Split draw_string in two for draw_sprite and others to jump in. Started decoding top and trousers code. --- src/gfx.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ec8f0532bc..d536adc688 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -683,7 +683,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point } } - +void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, int ebp, int eax); /** * * rct2: 0x0067A28E @@ -698,7 +698,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) int image_type = (image_id & 0xE0000000) >> 28; int image_sub_type = (image_id & 0x1C000000) >> 26; uint8* palette_pointer = NULL; - + uint8 palette[0x100]; RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; @@ -777,15 +777,19 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax &= 0x1f; eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; + rct_g1_element g1_palette = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); + memcpy(palette, g1_palette.offset, 0x100); //G1_element bits? ebp = *((uint32*)(eax + 0xF3)); esi = *((uint32*)(eax + 0xF7)); + //*(uint32*)(palette+0xF3) = ebp; + //*(uint32*)(palette+0xF7) = esi; RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; RCT2_GLOBAL(0x9ABF03, uint32) = esi; ebp = *((uint32*)(eax + 0xFB)); eax = ebx; - + //*(uint32*)(palette+0xFB) = ebp; RCT2_GLOBAL(0x9ABF07, uint32) = ebp; eax >>= 24; eax &= 0x1f; @@ -794,33 +798,37 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); ebp = *((uint32*)(eax + 0xF3)); esi = *((uint32*)(eax + 0xF7)); + *(uint32*)(palette+0xCA) = ebp; + *(uint32*)(palette+0xCE) = esi; RCT2_GLOBAL(0x9ABED6, uint32) = ebp; RCT2_GLOBAL(0x9ABEDA, uint32) = esi; ebp = *((uint32*)(eax + 0xFB)); RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; - palette_pointer = (uint8*)0x9ABE0C; + palette_pointer = palette;// (uint8*)0x9ABE0C; + *(uint32*)(palette+0xD2) = ebp; RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; - } + gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, ebp, eax); +} - ebx &= 0x7FFFF; +void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, int ebp, int eax){ + int image_element = 0x7FFFF&image_id; + int image_type = (image_id & 0xE0000000) >> 28; - rct_g1_element* g1_source = &((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[ebx]; + rct_g1_element* g1_source = &((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[image_element]; - ebx <<= 4; - ebx += RCT2_ADDRESS_G1_ELEMENTS; if (dpi->pad_0E >= 1){ //These have not been tested //something to do with zooming if (dpi->pad_0E == 1){ - RCT2_CALLPROC_X(0x0067BD81, eax, ebx, x, y, 0,(int) dpi, ebp); + RCT2_CALLPROC_X(0x0067BD81, eax, (int)g1_source, x, y, 0,(int) dpi, ebp); return; } if (dpi->pad_0E == 2){ - RCT2_CALLPROC_X(0x0067DADA, eax, ebx, x, y, 0, (int)dpi, ebp); + RCT2_CALLPROC_X(0x0067DADA, eax, (int)g1_source, x, y, 0, (int)dpi, ebp); return; } - RCT2_CALLPROC_X(0x0067FAAE, eax, ebx, x, y, 0, (int)dpi, ebp); + RCT2_CALLPROC_X(0x0067FAAE, eax, (int)g1_source, x, y, 0, (int)dpi, ebp); return; } @@ -912,7 +920,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) source_pointer = g1_source->offset; uint8* new_source_pointer_start = malloc(total_no_pixels); uint8* new_source_pointer = new_source_pointer_start;// 0x9E3D28; - + int ebx, ecx; while (total_no_pixels>0){ sint8 no_pixels = *source_pointer; if (no_pixels >= 0){ From 2d216ff47afe99abb3ee1036cff03b4f1dd5a087 Mon Sep 17 00:00:00 2001 From: anyc Date: Tue, 27 May 2014 23:24:09 +0200 Subject: [PATCH 107/209] better struct packing for MinGW --- CMakeLists_mingw.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists_mingw.txt b/CMakeLists_mingw.txt index df0bbfacd1..7fb25965c1 100644 --- a/CMakeLists_mingw.txt +++ b/CMakeLists_mingw.txt @@ -17,9 +17,9 @@ else() endif (APPLE) # potential flags to make code more similar to MSVC: -# -fshort-wchar -fshort-enums -mms-bitfields -fpack-struct=1 +# -fshort-wchar -fshort-enums -mms-bitfields # -set(CMAKE_C_FLAGS "-masm=intel -std=gnu99" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS "-masm=intel -std=gnu99 -fpack-struct=2" CACHE STRING "" FORCE) set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc" CACHE STRING "" FORCE) include_directories("/usr/include/wine/windows/") From 4c9c1fa5bd0f523d7c22ccacd51f7559dc0febe2 Mon Sep 17 00:00:00 2001 From: anyc Date: Tue, 27 May 2014 23:33:16 +0200 Subject: [PATCH 108/209] save_prompt actually opens save dialog --- src/game.c | 29 +++++++++++++++++++++++++++++ src/game.h | 1 + src/window_game_top_toolbar.c | 25 +------------------------ src/window_save_prompt.c | 11 ++++++----- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/game.c b/src/game.c index 0a9e82f4ab..07457c0bdd 100644 --- a/src/game.c +++ b/src/game.c @@ -1597,6 +1597,35 @@ static void load_game() } } +char save_game() +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + if (eax == 0) { + // user pressed "cancel" + gfx_invalidate_screen(); + return 0; + } + + char *src = (char*)0x0141EF67; + do { + src++; + } while (*src != '.' && *src != '\0'); + strcpy(src, ".SV6"); + strcpy((char*) RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*) 0x0141EF68); + + eax = 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 8) + eax |= 1; + RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0); + // check success? + + game_do_command(0, 1047, 0, -1, 0, 0, 0); + gfx_invalidate_screen(); + + return 1; +} + /** * * rct2: 0x006E3879 diff --git a/src/game.h b/src/game.h index 8619d04526..4b1bd42d4c 100644 --- a/src/game.h +++ b/src/game.h @@ -29,5 +29,6 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb void game_load_or_quit_no_save_prompt(); int game_load_save(); +char save_game(); #endif diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 5346a67b6f..2f91c6c122 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -384,30 +384,7 @@ static void window_game_top_toolbar_dropdown() break; case 1: // save game tool_cancel(); - { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - if (eax == 0) { - gfx_invalidate_screen(); - break; - } - - char *src = (char*)0x0141EF67; - do { - src++; - } while (*src != '.' && *src != '\0'); - strcpy(src, ".SV6"); - strcpy((char*) RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*) 0x0141EF68); - - eax = 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 8) - eax |= 1; - RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0); - // check success? - - game_do_command(0, 1047, 0, -1, 0, 0, 0); - gfx_invalidate_screen(); - } + save_game(); break; case 3: // about window_about_open(); diff --git a/src/window_save_prompt.c b/src/window_save_prompt.c index a941875889..52413e3cd5 100644 --- a/src/window_save_prompt.c +++ b/src/window_save_prompt.c @@ -257,11 +257,12 @@ static void window_save_prompt_mouseup() } else { switch (widgetIndex) { case WIDX_SAVE: - // TODO to avoid data loss, treat SAVE as CANCEL - RCT2_ERROR("TODO"); - window_close(w); - window_save_prompt_close(); - return; + if (!save_game()) { + // user pressed cancel + window_close(w); + window_save_prompt_close(); + return; + } break; case WIDX_DONT_SAVE: break; From cc85e93e9e1ed82bc38ceb239e3df6d639d2f705 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 00:05:11 +0100 Subject: [PATCH 109/209] add initial s6 structure --- src/scenario.h | 277 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) diff --git a/src/scenario.h b/src/scenario.h index cb3822c147..4ab1e2d2b2 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -83,6 +83,283 @@ typedef struct { char completed_by[64]; // 0x0270 } rct_scenario_basic; +/* This will be useful for backwards compatibility +typedef struct { + // SC6[0] + rct_s6_header header; + + // SC6[1] + rct_s6_info info; + + // SC6[2] + // packed objects + + // SC6[3] + rct_object_entry objects[721]; + + // SC6[4] + uint16 elapsed_months; + uint16 current_day; + uint32 dword_F663AC; + uint32 scenario_srand_0; + uint32 scenario_srand_1; + + // SC6[5] + rct_map_element map_elements[0x30000]; + + // SC6[6] + uint32 dword_010E63B8; + rct_sprite sprites[10000]; + uint16 sprites_next_index; + uint16 sprites_start_vehicle; + uint16 sprites_start_peep; + uint16 sprites_start_textfx; + uint16 sprites_start_litter; + uint8 pad_013573C6[2]; + uint16 word_013573C8; + uint8 pad_013573CA[4]; + uint16 word_013573CE; + uint16 word_013573D0; + uint8 pad_013573D2[2]; + uint16 word_013573D4; + uint8 pad_013573D6[4]; + uint32 dword_013573D8; + uint32 dword_013573DC; + money32 current_loan; + uint32 park_flags; + money16 park_entrance_fee; + uint16 word_013573EA; + uint16 word_013573EC; + uint8 pad_013573EE[16]; + uint8 byte_013573F0; + uint8 pad_013573F1[2]; + rct2_peep_spawn peep_spawns[2]; + uint8 guest_count_change_modifier; + uint8 byte_013573FF; + uint8 pad_01357400[4]; + uint32 dword_01357404; + uint32 dword_01357408; + uint32 dword_0135740C; + uint32 dword_01357410[5]; + uint32 dword_01357424[8]; + uint32 dword_01357444[128]; + uint32 dword_01357644[128]; + + // SC6[7] + uint16 guests_in_park; + uint16 guests_heading_for_park; + + // Ignored in scenario + money32 expenditure_table[14]; + uint32 dword_01357880[5]; + uint32 dword_01357894; + uint32 dword_01357898; + uint32 dword_0135789C; + uint32 dword_013578A0; + uint32 dword_013578A4[201]; + + // SC6[8] + uint16 last_guests_in_park; + uint8 pad_01357BCA[3]; + uint8 handyman_colour; + uint8 mechanic_colour; + uint8 security_colour; + + // Ignored in scenario + uint32 dword_01357BD0[56]; + + // SC6[9] + uint16 park_rating; + + // Ignored in scenario + uint8 park_rating_history[32]; + uint8 guests_in_park_history[32]; + + // SC6[10] + uint16 word_01357CF2; + uint32 word_01357CF4; + uint8 byte_01357CF8[1000]; + uint32 dword_013580E0[32]; + uint16 word_013580E4[16]; + uint8 byte_013580E6; + uint8 byte_013580E7; + uint8 byte_013580E8; + uint8 byte_013580E9; + uint16 park_size; + uint16 guest_generation_probability; + uint16 total_ride_value; + uint32 dword_013580F0; + uint16 dword_013580F4; + uint8 dword_013580F6; + uint8 dword_013580F7; + uint8 objective_type; + uint8 objective_year; + uint8 pad_013580FA[4]; + money32 objective_currency; + uint16 objective_guests; + uint8 campaign_weeks_left[20]; + uint8 campaign_ride_index[22]; + + // Ignored in scenario + money32 balance_history[128]; + + // SC6[11] + uint32 dword_0135832C; + uint32 current_profit; + uint32 dword_01358334; + uint16 word_01358338; + uint8 pad_0135833A[2]; + + // Ignored in scenario + uint8 pad_0135833C[2]; + money32 park_value; + money32 park_value_history[128]; + + // SC6[12] + money32 completed_company_value; + uint32 total_admissions; + money32 income_from_admissions; + money32 company_value; + uint8 byte_01358750[16]; + rct_award awards[4]; + uint16 word_01358770; + uint16 word_01358772; + uint16 word_01358774; + uint8 pad_01358776[4]; + uint32 dword_01358778[17]; + uint32 dword_013587BC; + uint32 dword_013587C0; + uint32 dword_013587C4; + uint16 dword_013587C8; + uint8 pad_013587CA[16]; + uint32 dword_013587D0; + uint8 pad_013587D4[8]; + uint16 word_013587D8[16]; + money32 cash; + uint8 pad_013587FC[50]; + uint16 word_0135882E; + uint16 word_01358830; + uint16 word_01358832; + uint16 map_size; + uint16 word_01358836; + uint32 word_01358838; + uint16 suggested_max_guests; + uint16 word_0135883E; + uint8 word_01358840; + uint8 word_01358841; + uint8 pad_01358842[4]; + uint32 dword_01358844; + uint8 pad_01358848; + uint32 dword_01358849; + uint8 pad_0135884D[2]; + uint8 dword_0135884E[622]; + uint8 pad_01359206[2]; + uint16 word_01359208; + char scenario_name[64]; + char scenario_description[255]; + uint8 byte_01359349; + uint8 byte_0135934A; + uint8 pad_0135934B[3]; + uint32 dword_0135934C; + uint16 park_entrance_x[4]; + uint16 park_entrance_y[4]; + uint16 park_entrance_z[4]; + uint8 byte_01359368; + uint8 pad_01359369[3]; + uint8 byte_0135936C[256]; + uint8 byte_0135946C[3256]; + uint8 byte_0135A124; + uint8 byte_0135A125; + uint16 word_0135A126; + uint8 byte_0135A128; + uint8 byte_0135A129; + uint8 byte_0135A12A; + uint8 byte_0135A12B[793]; + uint8 byte_0135A444[1200]; + char custom_strings[0x8000]; + uint32 game_ticks_1; + rct_ride rides[255]; + uint16 word_01388698; + uint16 saved_view_x; + uint16 saved_view_y; + uint16 saved_view_zoom_and_rotation; + uint8 byte_013886A0[6000]; + uint8 byte_01389E10[6000]; + uint16 word_0138B580; + uint8 pad_0138B580[2]; + uint16 word_0138B584; + uint16 word_0138B586; + uint16 word_0138B588; + uint16 word_0138B58A; + uint16 word_0138B58C; + uint16 word_0138B58E; + uint8 byte_0138B590; + uint8 byte_0138B591; + uint8 byte_0138B592; + uint8 byte_0138B593; + uint16 word_0138B594; + uint16 word_0138B596; + uint16 word_0138B598; + uint16 word_0138B59A; + uint16 word_0138B59C; + uint16 word_0138B59E; + uint16 word_0138B5A0; + uint16 word_0138B5A2; + uint16 word_0138B5A4; + uint16 word_0138B5A6; + uint16 word_0138B5A8; + uint16 word_0138B5AA; + uint16 word_0138B5AC; + uint16 word_0138B5AE; + uint16 word_0138B5B0; + uint16 word_0138B5B2; + uint16 word_0138B5B4; + uint16 word_0138B5B6; + uint16 word_0138B5B8; + uint16 word_0138B5BA; + uint16 word_0138B5BC; + uint16 word_0138B5BE; + uint16 word_0138B5C0; + uint16 word_0138B5C2; + uint16 word_0138B5C4; + uint16 word_0138B5C6; + uint16 word_0138B5C8; + uint16 word_0138B5CA; + uint16 word_0138B5CC; + uint16 word_0138B5CE[31]; + uint8 ride_measurements[0x25860]; + uint32 dword_13B0E6C; + uint16 word_13B0E70; + uint32 dword_13B0E72[0x6600]; + uint8 byte_13CA672[116]; + uint8 byte_13CA6E6[84]; + uint8 byte_13CA73A[4]; + uint8 unk_13CA73E; + uint8 pad_13CA73E; + uint8 byte_13CA740; + uint8 byte_13CA741; + uint8 byte_13CA7424[4]; + uint8 climate; + uint8 pad_013CA747; + uint16 climate_update_timer; + uint8 current_weather; + uint8 next_weather; + uint8 temperature; + uint8 next_temperature; + uint8 current_weather_effect; + uint8 next_weather_effect; + uint8 current_weather_gloom; + uint8 next_weather_gloom; + uint8 current_rain_level; + uint8 next_rain_level; + rct_news_item news_items[61]; + uint8 byte_13CE730[64]; + uint32 dword_13CE770; + uint16 word_13CE774; + uint16 word_13CE776[217]; +} rct_s6_data; +*/ + enum { SCENARIO_FLAGS_VISIBLE = (1 << 0), SCENARIO_FLAGS_COMPLETED = (1 << 1), From d8a61d97921971c6ae30a57c69f40e05df07a00e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 01:50:50 +0100 Subject: [PATCH 110/209] fix award window bug and clean reset history --- src/award.c | 7 +++++++ src/award.h | 1 + src/finance.c | 9 +++++++++ src/finance.h | 1 + src/park.c | 19 ++++--------------- src/park.h | 2 +- src/scenario.c | 4 +++- src/window_park.c | 4 ++-- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/award.c b/src/award.c index 12084559ca..25c843ddd9 100644 --- a/src/award.c +++ b/src/award.c @@ -568,6 +568,13 @@ static int award_is_deserved(int awardType, int activeAwardTypes) #pragma endregion +void award_reset() +{ + int i; + for (i = 0; i < MAX_AWARDS; i++) + RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i].time = 0; +} + /** * * rct2: 0x0066A86C diff --git a/src/award.h b/src/award.h index 26074cdaa8..aba8cb9456 100644 --- a/src/award.h +++ b/src/award.h @@ -52,6 +52,7 @@ enum { #define MAX_AWARDS 4 int award_is_positive(int type); +void award_reset(); void award_update_all(); #endif \ No newline at end of file diff --git a/src/finance.c b/src/finance.c index f61def04c4..a900c9ec82 100644 --- a/src/finance.c +++ b/src/finance.c @@ -137,6 +137,15 @@ void finance_pay_ride_upkeep() } } +void finance_reset_history() +{ + int i; + for (i = 0; i < 128; i++) { + RCT2_ADDRESS(RCT2_ADDRESS_BALANCE_HISTORY, money32)[i] = MONEY32_UNDEFINED; + RCT2_ADDRESS(RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY, money32)[i] = MONEY32_UNDEFINED; + RCT2_ADDRESS(RCT2_ADDRESS_PARK_VALUE_HISTORY, money32)[i] = MONEY32_UNDEFINED; + } +} /** * diff --git a/src/finance.h b/src/finance.h index fb63ae127f..ace3b157ae 100644 --- a/src/finance.h +++ b/src/finance.h @@ -38,6 +38,7 @@ void finance_pay_wages(); void finance_pay_research(); void finance_pay_interest(); void finance_pay_ride_upkeep(); +void finance_reset_history(); void finance_init(); void sub_69E869(); diff --git a/src/park.c b/src/park.c index e007cb335c..e897bf3eb4 100644 --- a/src/park.c +++ b/src/park.c @@ -104,7 +104,9 @@ void park_init() RCT2_GLOBAL(0x01358772, uint16) = 400; RCT2_GLOBAL(0x01358774, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = PARK_FLAGS_11 | PARK_FLAGS_SHOW_REAL_GUEST_NAMES; - park_reset_awards_and_history(); + park_reset_history(); + finance_reset_history(); + award_reset(); rct_s6_info *info = (rct_s6_info*)0x0141F570; info->name[0] = '\0'; @@ -115,26 +117,13 @@ void park_init() * * rct2: 0x0066729F */ -void park_reset_awards_and_history() +void park_reset_history() { int i; - - // Reset park rating and guests in park history for (i = 0; i < 32; i++) { RCT2_ADDRESS(RCT2_ADDRESS_PARK_RATING_HISTORY, uint8)[i] = 255; RCT2_ADDRESS(RCT2_ADDRESS_GUESTS_IN_PARK_HISTORY, uint8)[i] = 255; } - - // Reset finance history - for (i = 0; i < 128; i++) { - RCT2_ADDRESS(RCT2_ADDRESS_BALANCE_HISTORY, money32)[i] = MONEY32_UNDEFINED; - RCT2_ADDRESS(RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY, money32)[i] = MONEY32_UNDEFINED; - RCT2_ADDRESS(RCT2_ADDRESS_PARK_VALUE_HISTORY, money32)[i] = MONEY32_UNDEFINED; - } - - // Reset awards - for (i = 0; i < 4; i++) - RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i].time = 0; } /** diff --git a/src/park.h b/src/park.h index 8908e4a31f..12808a50c3 100644 --- a/src/park.h +++ b/src/park.h @@ -45,7 +45,7 @@ enum { int park_is_open(); void park_init(); -void park_reset_awards_and_history(); +void park_reset_history(); int park_calculate_size(); int calculate_park_rating(); diff --git a/src/scenario.c b/src/scenario.c index dbdd382f1e..7d0957031b 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -279,7 +279,9 @@ void scenario_load_and_play(const rct_scenario_basic *scenario) RCT2_GLOBAL(RCT2_ADDRESS_INCOME_FROM_ADMISSIONS, uint32) = 0; RCT2_GLOBAL(0x013587D8, uint16) = 63; sub_69E869(); // (loan related, called above already) - park_reset_awards_and_history(); + park_reset_history(); + finance_reset_history(); + award_reset(); reset_all_ride_build_dates(); date_reset(); RCT2_CALLPROC_EBPSAFE(0x00674576); diff --git a/src/window_park.c b/src/window_park.c index d2057e99ad..9899bda5bf 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -2259,13 +2259,13 @@ static void window_park_awards_paint() y = w->y + window_park_awards_widgets[WIDX_PAGE_BACKGROUND].top + 4; count = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < MAX_AWARDS; i++) { award = &RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i]; if (award->time == 0) continue; gfx_draw_sprite(dpi, SPR_AWARD_MOST_UNTIDY + award->type, x, y); - gfx_draw_string_left_wrapped(dpi, NULL, x + 34, y + 6, 180, STR_AWARD_MOST_UNTIDY, 0); + gfx_draw_string_left_wrapped(dpi, NULL, x + 34, y + 6, 180, STR_AWARD_MOST_UNTIDY + award->type, 0); y += 32; count++; From c89cd803f66463c4a3d50537f2d2b6aee07d2c7e Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 09:56:49 +0200 Subject: [PATCH 111/209] edge_scrolling and forced_software_buffering can now be edited ingame. * edge_scrolling * forced_software_buffering --- src/window_options.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/window_options.c b/src/window_options.c index c87c5f7576..4fe88b75d0 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -223,6 +223,7 @@ static void window_options_mouseup() break; case WIDX_SCREEN_EDGE_SCROLLING: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) ^= 1; + gGeneral_config.edge_scrolling ^= 1; config_save(); window_invalidate(w); break; @@ -271,6 +272,7 @@ static void window_options_mouseup() case WIDX_SOUND_SW_BUFFER_CHECKBOX: pause_sounds(); RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint8) ^= 1; + gSound_config.forced_software_buffering ^= 1; config_save(); unpause_sounds(); window_invalidate(w); From 0e6e11798bdb6b55c2bfc1db138f0d4a781a69b7 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 10:36:55 +0200 Subject: [PATCH 112/209] New setting: always_show_gridlines. --- src/config.c | 44 ++++++++++++++++++++++++++++++++++---------- src/config.h | 2 +- src/window_options.c | 2 ++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/config.c b/src/config.c index 2db90e92f4..f79357266f 100644 --- a/src/config.c +++ b/src/config.c @@ -76,15 +76,16 @@ static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = { general_configuration_t gGeneral_config; general_configuration_t gGeneral_config_default = { - 0, - 1, - SCREENSHOT_FORMAT_PNG, - "", - MEASUREMENT_FORMAT_IMPERIAL, - TEMPERATURE_FORMAT_F, - 0, - 0, - 1, + 0, // play_intro + 1, // confirmation_prompt + SCREENSHOT_FORMAT_PNG, // screenshot_format + "", // game_path + MEASUREMENT_FORMAT_IMPERIAL, // measurement_format + TEMPERATURE_FORMAT_F, // temperature_format + CURRENCY_POUNDS, // currency_format + 0, // construction_marker_colour + 1, // edge_scrolling + 0, // always_show_gridlines }; sound_configuration_t gSound_config; @@ -140,6 +141,15 @@ void config_load() RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gGeneral_config.measurement_format; RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gGeneral_config.temperature_format; + // always show gridlines + if (gGeneral_config.always_show_gridlines){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; + } + + //sound configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality; @@ -310,6 +320,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "temperature_format = celsius\n"); } + + if (gGeneral_config.always_show_gridlines){ + fprintf(fp, "always_show_gridlines = true\n"); + } + else { + fprintf(fp, "always_show_gridlines = false\n"); + } } /** @@ -508,7 +525,14 @@ static void config_general(char *setting, char *value){ else if (strcmp(setting, "currency") == 0){ config_parse_currency(value); } - + else if (strcmp(setting, "always_show_gridlines") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.always_show_gridlines = 1; + } + else { + gGeneral_config.always_show_gridlines = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index b0b445101a..44079612d4 100644 --- a/src/config.h +++ b/src/config.h @@ -136,7 +136,7 @@ typedef struct general_configuration { sint8 currency_format; sint8 construction_marker_colour; sint8 edge_scrolling; - + sint8 always_show_gridlines; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 4fe88b75d0..48175172cf 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -254,6 +254,8 @@ static void window_options_mouseup() break; case WIDX_GRIDLINES_CHECKBOX: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) ^= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; + gGeneral_config.always_show_gridlines = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) + & CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; config_save(); gfx_invalidate_screen(); From fe9757acfff9b691f9667443083dcdfe17dfa0b3 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Wed, 28 May 2014 17:39:58 +0900 Subject: [PATCH 113/209] add note about debugging routines --- src/window_game_top_toolbar.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 2f91c6c122..5fd19964d2 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -166,6 +166,11 @@ static void window_game_top_toolbar_mouseup() game_do_command(0, 1, 0, 0, 2, 0, 0); break; case WIDX_FASTFORWARD: + // This is an excellent place to add in debugging statements and + // print routines, that will be triggered when you press the + // button in the game. Use "git update-index --skip-worktree + // src/window_game_top_toolbar" to avoid committing these changes to + // version control. window_cheats_open(); break; From 098fe08fdf830c82e78a017924b98ce567607572 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 10:55:35 +0200 Subject: [PATCH 114/209] New setting: landscape_smoothing --- src/config.c | 24 ++++++++++++++++++++++++ src/config.h | 1 + src/window_options.c | 2 ++ 3 files changed, 27 insertions(+) diff --git a/src/config.c b/src/config.c index f79357266f..ea93527872 100644 --- a/src/config.c +++ b/src/config.c @@ -86,6 +86,7 @@ general_configuration_t gGeneral_config_default = { 0, // construction_marker_colour 1, // edge_scrolling 0, // always_show_gridlines + 1, // landscape_smoothing }; sound_configuration_t gSound_config; @@ -148,6 +149,14 @@ void config_load() else { RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; } + + // landscape smoothing + if (!gGeneral_config.landscape_smoothing){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; + } @@ -327,6 +336,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "always_show_gridlines = false\n"); } + + if (gGeneral_config.landscape_smoothing){ + fprintf(fp, "landscape_smoothing = true\n"); + } + else { + fprintf(fp, "landscape_smoothing = false\n"); + } } /** @@ -533,6 +549,14 @@ static void config_general(char *setting, char *value){ gGeneral_config.always_show_gridlines = 0; } } + else if (strcmp(setting, "landscape_smoothing") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.landscape_smoothing = 1; + } + else { + gGeneral_config.landscape_smoothing = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index 44079612d4..9bdb7d6f4c 100644 --- a/src/config.h +++ b/src/config.h @@ -137,6 +137,7 @@ typedef struct general_configuration { sint8 construction_marker_colour; sint8 edge_scrolling; sint8 always_show_gridlines; + sint8 landscape_smoothing; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 48175172cf..26f8d4d1d0 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -249,6 +249,8 @@ static void window_options_mouseup() break; case WIDX_TILE_SMOOTHING_CHECKBOX: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) ^= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; + gGeneral_config.landscape_smoothing = !(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) + & CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE); config_save(); gfx_invalidate_screen(); break; From 4ae98b18e6865d3456dee958bb98c901a2cd4d30 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 11:12:12 +0200 Subject: [PATCH 115/209] New setting: show_height_as_units --- src/config.c | 24 +++++++++++++++++++++++- src/config.h | 1 + src/window_options.c | 7 +++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index ea93527872..e038dc3cab 100644 --- a/src/config.c +++ b/src/config.c @@ -87,6 +87,7 @@ general_configuration_t gGeneral_config_default = { 1, // edge_scrolling 0, // always_show_gridlines 1, // landscape_smoothing + 0, // show_height_as_units }; sound_configuration_t gSound_config; @@ -158,7 +159,13 @@ void config_load() RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; } - + // show height as units + if (gGeneral_config.show_height_as_units){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + } //sound configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality; @@ -343,6 +350,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "landscape_smoothing = false\n"); } + + if (gGeneral_config.show_height_as_units){ + fprintf(fp, "show_height_as_units = true\n"); + } + else { + fprintf(fp, "show_height_as_units = false\n"); + } } /** @@ -557,6 +571,14 @@ static void config_general(char *setting, char *value){ gGeneral_config.landscape_smoothing = 0; } } + else if (strcmp(setting, "show_height_as_units") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.show_height_as_units = 1; + } + else { + gGeneral_config.show_height_as_units = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index 9bdb7d6f4c..be7d72c473 100644 --- a/src/config.h +++ b/src/config.h @@ -138,6 +138,7 @@ typedef struct general_configuration { sint8 edge_scrolling; sint8 always_show_gridlines; sint8 landscape_smoothing; + sint8 show_height_as_units; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 26f8d4d1d0..9aaf38e397 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -451,9 +451,12 @@ static void window_options_dropdown() case WIDX_HEIGHT_LABELS_DROPDOWN: // reset flag and set it to 1 if height as units is selected RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= ~CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + gGeneral_config.show_height_as_units = 0; - if (dropdownIndex == 0) - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + if (dropdownIndex == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + gGeneral_config.show_height_as_units = 1; + } window_options_update_height_markers(); break; From d8b735a1ef81af70c125a14f9fb694c8ee600e2b Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 11:19:49 +0200 Subject: [PATCH 116/209] New setting: save_plugin_data --- src/config.c | 24 ++++++++++++++++++++++++ src/config.h | 1 + src/window_options.c | 2 ++ 3 files changed, 27 insertions(+) diff --git a/src/config.c b/src/config.c index e038dc3cab..41551d94a5 100644 --- a/src/config.c +++ b/src/config.c @@ -88,6 +88,7 @@ general_configuration_t gGeneral_config_default = { 0, // always_show_gridlines 1, // landscape_smoothing 0, // show_height_as_units + 1, // save_plugin_data }; sound_configuration_t gSound_config; @@ -167,6 +168,14 @@ void config_load() RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; } + // save plugin data + if (gGeneral_config.save_plugin_data){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SAVE_PLUGIN_DATA; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_SAVE_PLUGIN_DATA; + } + //sound configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality; RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, sint8) = gSound_config.forced_software_buffering; @@ -357,6 +366,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "show_height_as_units = false\n"); } + + if (gGeneral_config.save_plugin_data){ + fprintf(fp, "save_plugin_data = true\n"); + } + else { + fprintf(fp, "save_plugin_data = false\n"); + } } /** @@ -579,6 +595,14 @@ static void config_general(char *setting, char *value){ gGeneral_config.show_height_as_units = 0; } } + else if (strcmp(setting, "save_plugin_data") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.save_plugin_data = 1; + } + else { + gGeneral_config.save_plugin_data = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index be7d72c473..6e43a04b4e 100644 --- a/src/config.h +++ b/src/config.h @@ -139,6 +139,7 @@ typedef struct general_configuration { sint8 always_show_gridlines; sint8 landscape_smoothing; sint8 show_height_as_units; + sint8 save_plugin_data; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 9aaf38e397..5a0646be66 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -270,6 +270,8 @@ static void window_options_mouseup() break; case WIDX_SAVE_PLUGIN_DATA_CHECKBOX: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) ^= CONFIG_FLAG_SAVE_PLUGIN_DATA; + gGeneral_config.save_plugin_data = !(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) + & CONFIG_FLAG_SAVE_PLUGIN_DATA); config_save(); window_invalidate(w); break; From dee0c6c730f48e2a98910b8b6d2e289ceedf0547 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 16:06:04 +0100 Subject: [PATCH 117/209] fix warnings --- src/window_options.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/window_options.c b/src/window_options.c index 5a0646be66..fa0824904e 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -474,19 +474,19 @@ static void window_options_dropdown() // TODO: no clue what this does (and if it's correct) RCT2_GLOBAL(0x009AAC75, uint8) = RCT2_GLOBAL(0x009AF601 + dropdownIndex, uint8); RCT2_GLOBAL(0x009AAC76, uint8) = RCT2_GLOBAL(0x009AF604 + dropdownIndex, uint8); - gSound_config.sound_quality = dropdownIndex; + gSound_config.sound_quality = (sint8)dropdownIndex; config_save(); window_invalidate(w); break; case WIDX_CURRENCY_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) = dropdownIndex | 0xC0; - gGeneral_config.currency_format = dropdownIndex; + gGeneral_config.currency_format = (sint8)dropdownIndex; config_save(); gfx_invalidate_screen(); break; case WIDX_DISTANCE_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8) = (uint8)dropdownIndex; - gGeneral_config.measurement_format = dropdownIndex; + gGeneral_config.measurement_format = (sint8)dropdownIndex; config_save(); window_options_update_height_markers(); break; @@ -502,7 +502,7 @@ static void window_options_dropdown() case WIDX_TEMPERATURE_DROPDOWN: if (dropdownIndex != RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8)) { RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8) = (uint8)dropdownIndex; - gGeneral_config.temperature_format = dropdownIndex; + gGeneral_config.temperature_format = (sint8)dropdownIndex; config_save(); gfx_invalidate_screen(); } From 9779128fbaa47eb664e1f34f44add03228655ec8 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 28 May 2014 18:00:28 +0100 Subject: [PATCH 118/209] Added peep_palette rewrote top and trouser code --- src/gfx.c | 79 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 863bccdfb3..db6a65a366 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -43,6 +43,26 @@ int gLastDrawStringY; uint8 _screenDirtyBlocks[5120]; +//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, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows); /** @@ -825,8 +845,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ //Has not been tested - eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; + + eax = image_id; eax >>= 19; //push edx/y eax &= 0x1F; @@ -855,7 +876,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) //image_id RCT2_GLOBAL(0xEDF81C, uint32) |= 0x20000000; - image_type |= IMAGE_TYPE_USE_PALETTE; + image_id |= IMAGE_TYPE_USE_PALETTE; eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); eax <<= 4; @@ -872,43 +893,27 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if (image_type){ - eax = image_id; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; - eax >>= 19; - eax &= 0x1f; - eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); - eax <<= 4; - rct_g1_element g1_palette = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); - eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - memcpy(palette, g1_palette.offset, 0x100); - //G1_element bits? - ebp = *((uint32*)(eax + 0xF3)); - esi = *((uint32*)(eax + 0xF7)); - //*(uint32*)(palette+0xF3) = ebp; - //*(uint32*)(palette+0xF7) = esi; - RCT2_GLOBAL(0x9ABEFF, uint32) = ebp; - RCT2_GLOBAL(0x9ABF03, uint32) = esi; - ebp = *((uint32*)(eax + 0xFB)); - eax = ebx; - //*(uint32*)(palette+0xFB) = ebp; - RCT2_GLOBAL(0x9ABF07, uint32) = ebp; - eax >>= 24; - eax &= 0x1f; - eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); - eax <<= 4; - eax = RCT2_GLOBAL(eax + RCT2_ADDRESS_G1_ELEMENTS, uint32); - ebp = *((uint32*)(eax + 0xF3)); - esi = *((uint32*)(eax + 0xF7)); - *(uint32*)(palette+0xCA) = ebp; - *(uint32*)(palette+0xCE) = esi; - RCT2_GLOBAL(0x9ABED6, uint32) = ebp; - RCT2_GLOBAL(0x9ABEDA, uint32) = esi; - ebp = *((uint32*)(eax + 0xFB)); - RCT2_GLOBAL(0x9ABDA4, uint32) = 0x009ABE0C; - palette_pointer = palette;// (uint8*)0x9ABE0C; - *(uint32*)(palette+0xD2) = ebp; - RCT2_GLOBAL(0x9ABEDE, uint32) = ebp; + //Copy the peep palette into a new palette. + //Not really required but its nice to make a copy + memcpy(palette, peep_palette, 0x100); + + //Top + int top_type = (image_id >> 19) & 0x1f; + uint32 top_offset = RCT2_ADDRESS(0x97FCBC, uint32)[top_type]; + rct_g1_element top_palette = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[top_offset]; + memcpy(palette + 0xF3, top_palette.offset + 0xF3, 12); + + //Trousers + int trouser_type = (image_id >> 24) & 0x1f; + uint32 trouser_offset = RCT2_ADDRESS(0x97FCBC, uint32)[trouser_type]; + rct_g1_element trouser_palette = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[trouser_offset]; + memcpy(palette + 0xCA, trouser_palette.offset + 0xF3, 12); + + //For backwards compatibility until the zooming function is done + RCT2_GLOBAL(0x9ABDA4, uint8*) = palette; + palette_pointer = palette; } gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, ebp, eax); From e489b999f3fb9085ec00f27ebfa5d23223059e21 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 18:11:33 +0100 Subject: [PATCH 119/209] fix picked-up staff and rain drawing --- src/addresses.h | 4 ++++ src/game.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 6b3c87e294..fa8640de7d 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -111,6 +111,10 @@ #define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545 #define RCT2_ADDRESS_TOOL_WIDGETINDEX 0x009DE546 +#define RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE 0x009DE550 +#define RCT2_ADDRESS_PICKEDUP_PEEP_X 0x009DE554 +#define RCT2_ADDRESS_PICKEDUP_PEEP_Y 0x009DE556 + #define RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS 0x009DE55C #define RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER 0x009DE55E #define RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX 0x009DE560 diff --git a/src/game.c b/src/game.c index 07457c0bdd..ad4b94ed32 100644 --- a/src/game.c +++ b/src/game.c @@ -59,10 +59,47 @@ void game_create_windows() RCT2_CALLPROC_EBPSAFE(0x0066B905); } +/** + * + * rct2: 0x006838BD + */ +void update_water_animation() +{ + RCT2_CALLPROC_EBPSAFE(0x006838BD); +} + +/** + * + * rct2: 0x00684218 + */ +void update_rain_animation() +{ + if (RCT2_GLOBAL(0x009ABDF2, uint8) == 0) + return; + + // Draw picked-up peep + if (RCT2_GLOBAL(0x009DE550, uint32) != 0xFFFFFFFF) { + gfx_draw_sprite( + (rct_drawpixelinfo*)RCT2_ADDRESS_SCREEN_DPI, + RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32), + RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16) + ); + } + + // Get rain draw function and draw rain + uint32 eax = RCT2_ADDRESS(0x009AC058, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8)]; + if (eax != 0xFFFFFFFF && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1)) + RCT2_CALLPROC_X(0x00684266, eax, 0, 0, 0, 0, 0, 0); +} + void game_update() { int eax, tmp; + // Handles picked-up peep and rain redraw + RCT2_CALLPROC_EBPSAFE(0x006843DC); + // 0x006E3AEC // screen_game_process_mouse_input(); // RCT2_CALLPROC_EBPSAFE(0x006E3AEC); // screen_game_process_keyboard_input(); screenshot_check(); @@ -124,8 +161,8 @@ void game_update() RCT2_GLOBAL(0x0141F568, uint8) = RCT2_GLOBAL(0x0013CA740, uint8); game_handle_input(); - RCT2_CALLPROC_EBPSAFE(0x006838BD); - RCT2_CALLPROC_EBPSAFE(0x00684218); + update_water_animation(); + update_rain_animation(); if (RCT2_GLOBAL(0x009AAC73, uint8) != 255) { RCT2_GLOBAL(0x009AAC73, uint8)++; From 0715a5122ecb165b532307c82682cfbabbecdd63 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 28 May 2014 20:52:32 +0100 Subject: [PATCH 120/209] Added unknown pointer as variable. Will be named when function determined --- src/gfx.c | 60 +++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index db6a65a366..d0ab503cb7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -579,31 +579,29 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * copies a sprite onto the buffer. There is no compression used on the sprite * image. */ -void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ +void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ //Requires use of palette? if (image_type & IMAGE_TYPE_USE_PALETTE){ //Mix with another image?? and colour adjusted - if (RCT2_GLOBAL(0x9E3CDC, uint32)){ //Not tested. I can't actually work out when this code runs. - - uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); - _ebp += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32); + if (unknown_pointer!= NULL){ //Not tested. I can't actually work out when this code runs. + unknown_pointer += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32); for (; height > 0; --height){ for (int no_pixels = width; no_pixels > 0; --no_pixels){ uint8 pixel = *source_pointer; source_pointer++; pixel = palette_pointer[pixel]; - pixel &= *((uint8*)_ebp); + pixel &= *unknown_pointer; if (pixel){ *dest_pointer = pixel; } dest_pointer++; - _ebp++; + unknown_pointer++; } source_pointer += source_image->width - width; dest_pointer += dest_dpi->width + dest_dpi->pitch - width; - _ebp += source_image->width - width; + unknown_pointer += source_image->width - width; } return; } @@ -673,23 +671,22 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* source_pointer, uin } if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested. I can't actually work out when this code runs. - uint32 _ebp = RCT2_GLOBAL(0x9E3CDC, uint32); - _ebp += source_pointer - source_image->offset; + unknown_pointer += source_pointer - source_image->offset; for (; height > 0; --height){ for (int no_pixels = width; no_pixels > 0; --no_pixels){ uint8 pixel = *source_pointer; source_pointer++; - pixel &= *((char*)_ebp); + pixel &= *unknown_pointer; if (pixel){ *dest_pointer = pixel; } dest_pointer++; - _ebp++; + unknown_pointer++; } source_pointer += source_image->width - width; dest_pointer += dest_dpi->width + dest_dpi->pitch - width; - _ebp += source_image->width - width; + unknown_pointer += source_image->width - width; } } @@ -804,7 +801,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point } } -void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, int ebp, int eax); +void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); /** * * rct2: 0x0067A28E @@ -823,6 +820,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) RCT2_GLOBAL(0x00EDF81C, uint32) = image_id & 0xE0000000; eax = (image_id >> 26) & 0x7; + uint8* unknown_pointer = (uint8*)(RCT2_ADDRESS(0x9E3CE4, uint32*)[image_sub_type]); RCT2_GLOBAL(0x009E3CDC, uint32) = RCT2_GLOBAL(0x009E3CE4 + eax * 4, uint32); if (image_type && !(image_type & IMAGE_TYPE_UNKNOWN)) { @@ -831,6 +829,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = image_id; eax >>= 19; eax &= 0xFF; + unknown_pointer = NULL; RCT2_GLOBAL(0x009E3CDC, uint32) = 0; } else{ @@ -841,11 +840,12 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) eax = RCT2_GLOBAL(eax * 4 + 0x97FCBC, uint32); palette_pointer = ((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[eax].offset; - RCT2_GLOBAL(0x9ABDA4, uint32) = palette_pointer; + RCT2_GLOBAL(0x9ABDA4, uint32) = (uint32)palette_pointer; } else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ //Has not been tested RCT2_GLOBAL(0x9E3CDC, uint32) = 0; + unknown_pointer = NULL; eax = image_id; eax >>= 19; @@ -894,7 +894,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } else if (image_type){ RCT2_GLOBAL(0x9E3CDC, uint32) = 0; - + unknown_pointer = NULL; //Copy the peep palette into a new palette. //Not really required but its nice to make a copy memcpy(palette, peep_palette, 0x100); @@ -916,10 +916,10 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) palette_pointer = palette; } - gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, ebp, eax); + gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer); } -void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, int ebp, int eax){ +void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer){ int image_element = 0x7FFFF&image_id; int image_type = (image_id & 0xE0000000) >> 28; @@ -928,14 +928,14 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in if (dpi->pad_0E >= 1){ //These have not been tested //something to do with zooming if (dpi->pad_0E == 1){ - RCT2_CALLPROC_X(0x0067BD81, eax, (int)g1_source, x, y, 0,(int) dpi, ebp); + RCT2_CALLPROC_X(0x0067BD81, 0, (int)g1_source, x, y, 0,(int) dpi, 0); return; } if (dpi->pad_0E == 2){ - RCT2_CALLPROC_X(0x0067DADA, eax, (int)g1_source, x, y, 0, (int)dpi, ebp); + RCT2_CALLPROC_X(0x0067DADA, 0, (int)g1_source, x, y, 0, (int)dpi, 0); return; } - RCT2_CALLPROC_X(0x0067FAAE, eax, (int)g1_source, x, y, 0, (int)dpi, ebp); + RCT2_CALLPROC_X(0x0067FAAE, 0, (int)g1_source, x, y, 0, (int)dpi, 0); return; } @@ -1019,15 +1019,15 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in source_pointer += g1_source->width*source_start_y + source_start_x; if (!(g1_source->flags & 0x02)){ - gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); return; } - //0x67A60A + //0x67A60A Not tested int total_no_pixels = g1_source->width*g1_source->height; source_pointer = g1_source->offset; uint8* new_source_pointer_start = malloc(total_no_pixels); uint8* new_source_pointer = new_source_pointer_start;// 0x9E3D28; - int ebx, ecx; + int ebx, ecx, eax; while (total_no_pixels>0){ sint8 no_pixels = *source_pointer; if (no_pixels >= 0){ @@ -1041,23 +1041,23 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in ecx = no_pixels; no_pixels &= 0x7; ecx >>= 3;//SAR - eax <<= 8; + int eax = ((int)no_pixels)<<8; ecx = -ecx;//Odd eax = eax & 0xFF00 + *(source_pointer+1); total_no_pixels -= ecx; source_pointer += 2; - ebx = new_source_pointer - eax; - eax = source_pointer; - source_pointer = ebx; + ebx = (uint32)new_source_pointer - eax; + eax = (uint32)source_pointer; + source_pointer = (uint8*)ebx; ebx = eax; eax = 0; memcpy((char*)new_source_pointer, (char*)source_pointer, ecx); new_source_pointer += ecx; source_pointer += ecx; - source_pointer = ebx; + source_pointer = (uint8*)ebx; } source_pointer = new_source_pointer_start + g1_source->width*source_start_y + source_start_x; - gfx_bmp_sprite_to_buffer(palette_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); free(new_source_pointer_start); return; } From c006e277005f1da391a3a453978b82d2d65ca3e0 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 28 May 2014 21:15:19 +0100 Subject: [PATCH 121/209] Started adding draw_string --- src/gfx.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/gfx.c b/src/gfx.c index d0ab503cb7..05fd02cfaa 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1434,4 +1434,59 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in gLastDrawStringX = ecx; gLastDrawStringY = edx; + + RCT2_GLOBAL(0xEDF840, uint16) = ecx; + RCT2_GLOBAL(0xEDF842, uint16) = edx; + RCT2_GLOBAL(0x9E3CDC, uint32) = 0; + + if (eax & 0xFF == 0xFE){ + //jmp 0x682853 + } + + ebx = dpi->x; + ebx += dpi->width; + if (ecx >= ebx){ + return; + //jmp 0x6828DF + } + ebx = ecx; + ebx += 0x280; + if (ebx <= dpi->x){ + return; + } + ebx = dpi->y; + ebx += dpi->height; + if (edx >= ebx){ + return; + } + ebx = edx; + ebx += 0x5A; + if (ebx <= dpi->y){ + return; + } + if (eax & 0xff == 0xff){ + //jmp 0x682853 + } + + RCT2_GLOBAL(0x13CE9A2, uint16) = 0; + if (RCT2_GLOBAL(0x13CE950, sint16) < 0){ + RCT2_GLOBAL(0x13CE9A2, uint16) |= 0x4; + if (RCT2_GLOBAL(0x13CE950, uint16)!=0xFFFF){ + RCT2_GLOBAL(0x13CE9A2, uint16) |= 0x8; + } + RCT2_GLOBAL(0x13CE950, uint16) = 0xE0; + } + if (eax&(1 << 5)){ + RCT2_GLOBAL(0x13CE9A2, uint16) |= 0x2; + } + eax &= ~(1 << 5); + if (!(eax & 0x40)){ + //jmp 0x682aa9 + } + RCT2_GLOBAL(0x13CE9A2, uint16) |= 0x1; + eax &= 0x1F; + + ebp = eax; + //0x6827c9 + } From 7dc750bd554f316c343a01f05a6804a13e31a82e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 28 May 2014 22:22:09 +0100 Subject: [PATCH 122/209] Switched to cdecl for mouse down. --- src/game.c | 32 ++++++++++++++++++++- src/gfx.h | 2 +- src/window_banner.c | 8 +++--- src/window_footpath.c | 27 ++---------------- src/window_game_top_toolbar.c | 26 ++--------------- src/window_guest_list.c | 27 ++---------------- src/window_land.c | 26 ++--------------- src/window_map.c | 4 +-- src/window_options.c | 20 ++------------ src/window_park.c | 46 +++---------------------------- src/window_ride_list.c | 26 ++--------------- src/window_title_menu.c | 27 ++---------------- src/window_title_scenarioselect.c | 20 ++------------ 13 files changed, 58 insertions(+), 233 deletions(-) diff --git a/src/game.c b/src/game.c index ad4b94ed32..e9fea477da 100644 --- a/src/game.c +++ b/src/game.c @@ -654,6 +654,36 @@ static void input_mouseover_widget_flatbutton_invalidate() widget_invalidate(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windownumber), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, rct_windownumber)); } +static void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_window*w, rct_widget* widget ) +{ +#ifdef _MSC_VER + __asm { + push address + push widget + push w + push widgetIndex + mov edi, widget + mov edx, widgetIndex + mov esi, w + call[esp + 12] + add esp, 16 + } +#else + __asm__("\ + push %[address]\n\ + mov edx, widgetIndex \n\ + mov edi, widget + mov eax, %[w] \n\ + push edx \n\ + push eax \n\ + push edi \n\ + mov esi, %[w] \n\ + call [esp+12] \n\ + add esp, 16 \n\ + " :[address] "+m" (address), [w] "+m" (w) : : "eax", "esi"); +#endif +} + /** * * rct2: 0x006E95F9 @@ -803,7 +833,7 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex) RCT2_GLOBAL(0x009DE528, uint16) = 1; widget_invalidate(windowClass, windowNumber, widgetIndex); - RCT2_CALLPROC_X(w->event_handlers[WE_MOUSE_DOWN], 0, 0, 0, widgetIndex, (int)w, (int)widget, 0); + RCT2_CALLPROC_WE_MOUSE_DOWN(w->event_handlers[WE_MOUSE_DOWN], widgetIndex, w, widget); break; } } diff --git a/src/gfx.h b/src/gfx.h index 395543b662..b266ea3dc2 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -31,7 +31,7 @@ typedef struct { short width; // 0x08 short height; // 0x0A short pitch; // 0x0C note: this is actually (pitch - width) - char pad_0E; // 0x0E + uint8 zoom_level; // 0x0E char var_0F; // 0x0F } rct_drawpixelinfo; diff --git a/src/window_banner.c b/src/window_banner.c index 10564eb994..663e42ba64 100644 --- a/src/window_banner.c +++ b/src/window_banner.c @@ -55,7 +55,7 @@ rct_widget window_banner_widgets[] = { static void window_banner_emptysub() { } static void window_banner_mouseup(); -static void window_banner_mousedown(); +static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_banner_dropdown(); static void window_banner_textinput(); static void window_banner_invalidate(); @@ -182,12 +182,12 @@ static void window_banner_mouseup() } } -static void window_banner_mousedown() +static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; + //short widgetIndex; #ifdef _MSC_VER - __asm mov widgetIndex, dx + //__asm mov widgetIndex, dx #else __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); #endif diff --git a/src/window_footpath.c b/src/window_footpath.c index 0b764ec02f..ab2b8c979a 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -111,7 +111,7 @@ static rct_widget window_footpath_widgets[] = { static void window_footpath_emptysub() { } static void window_footpath_close(); static void window_footpath_mouseup(); -static void window_footpath_mousedown(); +static void window_footpath_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_footpath_dropdown(); static void window_footpath_update(rct_window *w); static void window_footpath_toolupdate(); @@ -307,31 +307,8 @@ static void window_footpath_mouseup() * * rct2: 0x006A7EC5 */ -static void window_footpath_mousedown() +static void window_footpath_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - switch (widgetIndex) { case WIDX_FOOTPATH_TYPE: window_footpath_show_footpath_types_dialog(w, widget, 0); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 5fd19964d2..8a78975390 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -78,7 +78,7 @@ static rct_widget window_game_top_toolbar_widgets[] = { static void window_game_top_toolbar_emptysub() { } static void window_game_top_toolbar_mouseup(); -static void window_game_top_toolbar_mousedown(); +static void window_game_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_game_top_toolbar_dropdown(); static void window_game_top_toolbar_invalidate(); static void window_game_top_toolbar_paint(); @@ -259,32 +259,10 @@ static void window_game_top_toolbar_mouseup() * * rct2: 0x0066CA3B */ -static void window_game_top_toolbar_mousedown() +static void window_game_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; rct_viewport *mainViewport; - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - if (widgetIndex == WIDX_FILE_MENU) { gDropdownItemsFormat[0] = 882; gDropdownItemsFormat[1] = 883; diff --git a/src/window_guest_list.c b/src/window_guest_list.c index 95284c0b88..d26c91993a 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -73,7 +73,7 @@ static rct_widget window_guest_list_widgets[] = { static void window_guest_list_emptysub() { } static void window_guest_list_mouseup(); static void window_guest_list_resize(); -static void window_guest_list_mousedown(); +static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_guest_list_dropdown(); static void window_guest_list_update(rct_window *w); static void window_guest_list_scrollgetsize(); @@ -241,32 +241,9 @@ static void window_guest_list_resize() * * rct2: 0x00699AC4 */ -static void window_guest_list_mousedown() +static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - switch (widgetIndex) { case WIDX_TAB_1: case WIDX_TAB_2: diff --git a/src/window_land.c b/src/window_land.c index 0e092a771b..823c2f3011 100644 --- a/src/window_land.c +++ b/src/window_land.c @@ -52,7 +52,7 @@ static rct_widget window_land_widgets[] = { static void window_land_emptysub() { } static void window_land_close(); static void window_land_mouseup(); -static void window_land_mousedown(); +static void window_land_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_land_dropdown(); static void window_land_update(rct_window *w); static void window_land_invalidate(); @@ -217,31 +217,9 @@ static void window_land_mouseup() * * rct2: 0x0066407B */ -static void window_land_mousedown() +static void window_land_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - switch (widgetIndex) { case WIDX_FLOOR: diff --git a/src/window_map.c b/src/window_map.c index 4c14fb8dd2..84cfd99af1 100644 --- a/src/window_map.c +++ b/src/window_map.c @@ -77,7 +77,7 @@ static rct_widget window_map_widgets[] = { static void window_map_emptysub() { } static void window_map_close(); static void window_map_mouseup(); -static void window_map_mousedown(); +static void window_map_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_map_update(rct_window *w); static void window_map_scrollgetsize(); static void window_map_scrollmousedown(); @@ -228,7 +228,7 @@ static void window_map_mouseup() * * rct2: 0x0068D040 */ -static void window_map_mousedown() +static void window_map_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { RCT2_CALLPROC_EBPSAFE(0x0068D040); } diff --git a/src/window_options.c b/src/window_options.c index fa0824904e..d370b185c5 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -105,7 +105,7 @@ static rct_widget window_options_widgets[] = { static void window_options_emptysub() { } static void window_options_mouseup(); -static void window_options_mousedown(); +static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_options_dropdown(); static void window_options_update(rct_window *w); static void window_options_paint(); @@ -290,25 +290,9 @@ static void window_options_mouseup() * * rct2: 0x006BB01B */ -static void window_options_mousedown() +static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int num_items, i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - widget = &w->widgets[widgetIndex - 1]; diff --git a/src/window_park.c b/src/window_park.c index 9899bda5bf..d47358c7fd 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -218,7 +218,7 @@ static void window_park_emptysub() { } static void window_park_entrance_close(); static void window_park_entrance_mouseup(); static void window_park_entrance_resize(); -static void window_park_entrance_mousedown(); +static void window_park_entrance_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_park_entrance_dropdown(); static void window_park_entrance_update(rct_window *w); static void window_park_entrance_toolupdate(); @@ -243,7 +243,7 @@ static void window_park_guests_paint(); static void window_park_price_mouseup(); static void window_park_price_resize(); -static void window_park_price_mousedown(); +static void window_park_price_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_park_price_update(rct_window *w); static void window_park_price_invalidate(); static void window_park_price_paint(); @@ -731,31 +731,8 @@ static void window_park_entrance_resize() * * rct2: 0x006681BF */ -static void window_park_entrance_mousedown() +static void window_park_entrance_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - if (widgetIndex == WIDX_OPEN_OR_CLOSE) { gDropdownItemsFormat[0] = 1142; gDropdownItemsFormat[1] = 1142; @@ -1617,24 +1594,9 @@ static void window_park_price_resize() * * rct2: 0x0066902C */ -static void window_park_price_mousedown() +static void window_park_price_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int newFee; - short widgetIndex; - rct_window *w; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - switch (widgetIndex) { case WIDX_CLOSE: diff --git a/src/window_ride_list.c b/src/window_ride_list.c index 4d0f29da66..8dff8e2433 100644 --- a/src/window_ride_list.c +++ b/src/window_ride_list.c @@ -68,7 +68,7 @@ static rct_widget window_ride_list_widgets[] = { static void window_ride_list_emptysub() { } static void window_ride_list_mouseup(); static void window_ride_list_resize(); -static void window_ride_list_mousedown(); +static void window_ride_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_ride_list_dropdown(); static void window_ride_list_update(rct_window *w); static void window_ride_list_scrollgetsize(); @@ -248,31 +248,9 @@ static void window_ride_list_resize() * * rct2: 0x006B3532 */ -static void window_ride_list_mousedown() +static void window_ride_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int numItems, i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - if (widgetIndex == WIDX_OPEN_CLOSE_ALL) { gDropdownItemsFormat[0] = STR_CLOSE_ALL; diff --git a/src/window_title_menu.c b/src/window_title_menu.c index 087b6cd41e..8e2e5aab45 100644 --- a/src/window_title_menu.c +++ b/src/window_title_menu.c @@ -45,7 +45,7 @@ static rct_widget window_title_menu_widgets[] = { static void window_title_menu_emptysub() { } static void window_title_menu_mouseup(); -static void window_title_menu_mousedown(); +static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_title_menu_dropdown(); static void window_title_menu_unknown17(); static void window_title_menu_paint(); @@ -122,31 +122,8 @@ static void window_title_menu_mouseup() } } -static void window_title_menu_mousedown() +static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - if (widgetIndex == WIDX_SHOW_TUTORIAL) { gDropdownItemsFormat[0] = STR_TUTORIAL_BEGINNERS; gDropdownItemsFormat[1] = STR_TUTORIAL_CUSTOM_RIDES; diff --git a/src/window_title_scenarioselect.c b/src/window_title_scenarioselect.c index caecf96013..09d185238f 100644 --- a/src/window_title_scenarioselect.c +++ b/src/window_title_scenarioselect.c @@ -59,7 +59,7 @@ static void window_scenarioselect_init_tabs(); static void window_scenarioselect_emptysub() { } static void window_scenarioselect_mouseup(); -static void window_scenarioselect_mousedown(); +static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_scenarioselect_scrollgetsize(); static void window_scenarioselect_scrollmousedown(); static void window_scenarioselect_scrollmouseover(); @@ -190,24 +190,8 @@ static void window_scenarioselect_mouseup() window_close(w); } -static void window_scenarioselect_mousedown() +static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - if (widgetIndex >= WIDX_TAB1 && widgetIndex <= WIDX_TAB5) { w->selected_tab = widgetIndex - 4; w->var_494 = 0; From 423db671482120108c733e13e2c986577631a93c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 22:53:28 +0100 Subject: [PATCH 123/209] add climate_update_sound --- src/addresses.h | 2 + src/climate.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++- src/climate.h | 1 + src/game.c | 2 +- 4 files changed, 152 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index fa8640de7d..cfadc3fea7 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -84,6 +84,8 @@ #define RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS 0x009ABDE8 #define RCT2_ADDRESS_DIRTY_BLOCK_ROWS 0x009ABDEC +#define RCT2_ADDRESS_LIGHTNING_ACTIVE 0x009AC068 + #define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319 #define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8 diff --git a/src/climate.c b/src/climate.c index 6c1d4a1fd7..37bae75fda 100644 --- a/src/climate.c +++ b/src/climate.c @@ -19,10 +19,19 @@ *****************************************************************************/ #include "addresses.h" +#include "audio.h" #include "climate.h" #include "date.h" #include "gfx.h" #include "rct2.h" +#include "scenario.h" + +enum { + THUNDER_STATUS_NULL = 0, + THUNDER_STATUS_PLAYING = 1, + + MAX_THUNDER_INSTANCES = 2 +}; typedef struct { sint8 base_temperature; @@ -32,6 +41,8 @@ typedef struct { int gClimateNextWeather; +static int _climateCurrentWeatherEffect; + static int _climateNextTemperature; static int _climateNextWeatherEffect; static int _climateNextWeatherGloom; @@ -39,8 +50,24 @@ static int _climateNextRainLevel; static const rct_weather_transition* climate_transitions[4]; +// Sound data +static int _rainVolume = 1; +static rct_sound _rainSoundInstance; +static unsigned int _lightningTimer, _thunderTimer; +static rct_sound _thunderSoundInstance[MAX_THUNDER_INSTANCES]; +static int _thunderStatus[MAX_THUNDER_INSTANCES] = { THUNDER_STATUS_NULL, THUNDER_STATUS_NULL }; +static unsigned int _thunderSoundId; +static int _thunderVolume; +static int _thunderStereoEcho = 0; + static void climate_determine_future_weather(); +static void climate_update_rain_sound(); +static void climate_update_thunder_sound(); +static void climate_update_lightning(); +static void climate_update_thunder(); +static int climate_play_thunder(int instanceIndex, int soundId, int volume, int pan); + int climate_celsius_to_fahrenheit(int celsius) { return (celsius * 29) / 16 + 32; @@ -88,7 +115,7 @@ void climate_update() if (temperature == target_temperature) { if (cur_gloom == next_gloom) { - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = _climateNextWeatherEffect; + _climateCurrentWeatherEffect = _climateNextWeatherEffect; if (cur_rain == next_rain) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = gClimateNextWeather; @@ -152,7 +179,127 @@ static void climate_determine_future_weather() RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } +/** + * + * rct2: 0x006BCB91 + */ +void climate_update_sound() +{ + if (RCT2_GLOBAL(0x009AF280, uint32) == 0xFFFFFFFF) + return; + if (RCT2_GLOBAL(0x009AF59C, uint8) != 0) + return; + if (!(RCT2_GLOBAL(0x009AF59D, uint8) & 1)) + return; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1) + return; + climate_update_rain_sound(); + climate_update_thunder_sound(); +} + +static void climate_update_rain_sound() +{ + if (_climateCurrentWeatherEffect == 1 || _climateCurrentWeatherEffect == 2) { + if (_rainVolume == 1) { + // Start playing the rain sound + if (sound_prepare(SOUND_RAIN_1, &_rainSoundInstance, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32))) + sound_play(&_rainSoundInstance, 1, -4000, 0, 0); + _rainVolume = -4000; + } else { + // Increase rain sound + _rainVolume = min(-1400, _rainVolume + 80); + RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume); + } + } else if (_rainVolume != 1) { + // Decrease rain sound + _rainVolume -= 80; + if (_rainVolume > -4000) { + RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume); + } else { + sound_stop(&_rainSoundInstance); + _rainVolume = 1; + } + } +} + +static void climate_update_thunder_sound() +{ + if (_thunderStereoEcho) { + // Play thunder on right side + _thunderStereoEcho = 0; + climate_play_thunder(1, _thunderSoundId, _thunderVolume, 10000); + } else if (_thunderTimer != 0) { + climate_update_lightning(); + climate_update_thunder(); + } else if (_climateCurrentWeatherEffect == 2) { + // Create new thunder and lightning + unsigned int randomNumber = scenario_rand(); + if ((randomNumber & 0xFFFF) <= 0x1B4) { + randomNumber >>= 16; + _thunderTimer = 43 + (randomNumber % 64); + _lightningTimer = randomNumber % 32; + } + } + + // Stop thunder sounds if they have finished + for (int i = 0; i < MAX_THUNDER_INSTANCES; i++) { + if (_thunderStatus[i] == THUNDER_STATUS_NULL) + continue; + + if (!RCT2_CALLFUNC_1(0x00404E53, int, rct_sound*, &_thunderSoundInstance[i])) { + sound_stop(&_thunderSoundInstance[i]); + _thunderStatus[i] = THUNDER_STATUS_NULL; + } + } +} + +static void climate_update_lightning() +{ + if (_lightningTimer == 0) + return; + + _lightningTimer--; + if (RCT2_GLOBAL(RCT2_ADDRESS_LIGHTNING_ACTIVE, uint16) == 0) + if ((scenario_rand() & 0xFFFF) <= 0x2000) + RCT2_GLOBAL(RCT2_ADDRESS_LIGHTNING_ACTIVE, uint16) = 1; +} + +static void climate_update_thunder() +{ + _thunderTimer--; + if (_thunderTimer != 0) + return; + + unsigned int randomNumber = scenario_rand(); + if (randomNumber & 0x10000) { + if (_thunderStatus[0] == THUNDER_STATUS_NULL && _thunderStatus[1] == THUNDER_STATUS_NULL) { + // Play thunder on left side + _thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2; + _thunderVolume = (-((int)((randomNumber >> 18) & 0xFF))) << 3; + climate_play_thunder(0, _thunderSoundId, _thunderVolume, -10000); + + // Let thunder play on right side + _thunderStereoEcho = 1; + } + } else { + _thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2; + int pan = (((randomNumber >> 18) & 0xFF) - 128) * 16; + climate_play_thunder(0, _thunderSoundId, 0, pan); + } +} + +static int climate_play_thunder(int instanceIndex, int soundId, int volume, int pan) +{ + if (sound_prepare(soundId, &_thunderSoundInstance[instanceIndex], 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32))) { + sound_play(&_thunderSoundInstance[instanceIndex], 0, volume, pan, 0); + + _thunderStatus[instanceIndex] = THUNDER_STATUS_PLAYING; + return 1; + } + + return 0; +} #pragma region Climate / Weather data tables diff --git a/src/climate.h b/src/climate.h index 814039f10f..376323d907 100644 --- a/src/climate.h +++ b/src/climate.h @@ -44,5 +44,6 @@ extern const rct_weather climate_weather_data[6]; int climate_celsius_to_fahrenheit(int celsius); void climate_reset(int climate); void climate_update(); +void climate_update_sound(); #endif diff --git a/src/game.c b/src/game.c index ad4b94ed32..bb6236379c 100644 --- a/src/game.c +++ b/src/game.c @@ -197,7 +197,7 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x0068AFAD); RCT2_CALLPROC_EBPSAFE(0x006BBC6B); // vehicle and scream sounds peep_update_crowd_noise(); - RCT2_CALLPROC_EBPSAFE(0x006BCB91); // weather sound effects + climate_update_sound(); news_item_update_current(); RCT2_CALLPROC_EBPSAFE(0x0067009A); // scenario editor opening of windows for a phase From 2a27ea0689786dc833b15322f269a6373cea4d8f Mon Sep 17 00:00:00 2001 From: anyc Date: Thu, 29 May 2014 01:19:09 +0200 Subject: [PATCH 124/209] fix ASM for MinGW --- src/game.c | 11 ++++++----- src/window_banner.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/game.c b/src/game.c index 8a619de450..16de96fbcd 100644 --- a/src/game.c +++ b/src/game.c @@ -671,16 +671,17 @@ static void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_windo #else __asm__("\ push %[address]\n\ - mov edx, widgetIndex \n\ - mov edi, widget + mov edi, %[widget] \n\ mov eax, %[w] \n\ - push edx \n\ - push eax \n\ + mov edx, %[widgetIndex] \n\ push edi \n\ + push eax \n\ + push edx \n\ mov esi, %[w] \n\ call [esp+12] \n\ add esp, 16 \n\ - " :[address] "+m" (address), [w] "+m" (w) : : "eax", "esi"); + " :[address] "+m" (address), [w] "+m" (w), [widget] "+m" (widget), [widgetIndex] "+m" (widgetIndex): : "eax", "esi", "edx", "edi" + ); #endif } diff --git a/src/window_banner.c b/src/window_banner.c index 663e42ba64..7b27b8fbe2 100644 --- a/src/window_banner.c +++ b/src/window_banner.c @@ -189,7 +189,7 @@ static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* w #ifdef _MSC_VER //__asm mov widgetIndex, dx #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); +// __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); #endif From a6912160447fa59afc7f5332e2eee94dd8897f14 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 29 May 2014 17:22:32 +0100 Subject: [PATCH 125/209] Fixed small issue with mouse down code --- src/game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game.c b/src/game.c index 16de96fbcd..ac83922df2 100644 --- a/src/game.c +++ b/src/game.c @@ -1098,7 +1098,7 @@ void handle_shortcut_command(int shortcutIndex) RCT2_CALLPROC_EBPSAFE(0x006B3CFF); window = window_find_by_id(WC_CONSTRUCT_RIDE, 0); if (window != NULL) - window_event_helper(window, 10, WE_MOUSE_DOWN); + RCT2_CALLPROC_WE_MOUSE_DOWN(window->event_handlers[WE_MOUSE_DOWN], 10, window, NULL); } break; case SHORTCUT_SHOW_RIDES_LIST: From 33833b413f982795f86ab089e60365e813774a3c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 29 May 2014 17:55:52 +0100 Subject: [PATCH 126/209] Added more gfx_draw_string --- src/gfx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 05fd02cfaa..3250927a68 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1027,7 +1027,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in source_pointer = g1_source->offset; uint8* new_source_pointer_start = malloc(total_no_pixels); uint8* new_source_pointer = new_source_pointer_start;// 0x9E3D28; - int ebx, ecx, eax; + int ebx, ecx; while (total_no_pixels>0){ sint8 no_pixels = *source_pointer; if (no_pixels >= 0){ @@ -1430,7 +1430,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in esi = (int)format; edi = (int)dpi; ebp = 0; - RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + //RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); gLastDrawStringX = ecx; gLastDrawStringY = edx; @@ -1439,7 +1439,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in RCT2_GLOBAL(0xEDF842, uint16) = edx; RCT2_GLOBAL(0x9E3CDC, uint32) = 0; - if (eax & 0xFF == 0xFE){ + if ((eax & 0xFF) == 0xFE){ + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; //jmp 0x682853 } @@ -1447,7 +1449,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in ebx += dpi->width; if (ecx >= ebx){ return; - //jmp 0x6828DF } ebx = ecx; ebx += 0x280; @@ -1464,7 +1465,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in if (ebx <= dpi->y){ return; } - if (eax & 0xff == 0xff){ + if ((eax & 0xff) == 0xff){ + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; //jmp 0x682853 } @@ -1481,12 +1484,51 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in } eax &= ~(1 << 5); if (!(eax & 0x40)){ + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; //jmp 0x682aa9 } RCT2_GLOBAL(0x13CE9A2, uint16) |= 0x1; eax &= 0x1F; ebp = eax; - //0x6827c9 + if (!(RCT2_GLOBAL(0x13CE9A2, uint16) & 0x4)){ + eax = RCT2_GLOBAL(0x141FC4A + ebp * 8,uint8); + eax <<= 0x10; + eax |= RCT2_GLOBAL(0x141FC48 + ebp * 8, uint8); + } + else if (!(RCT2_GLOBAL(0x13CE9A2, uint16) & 0x8)){ + eax = RCT2_GLOBAL(0x141FC49 + ebp * 8, uint8); + eax <<= 0x10; + eax |= RCT2_GLOBAL(0x141FC47 + ebp * 8, uint8); + + } + else{ + eax = RCT2_GLOBAL(0x141FC48 + ebp * 8, uint8); + eax <<= 0x10; + eax |= RCT2_GLOBAL(0x141FC46 + ebp * 8, uint8); + } + RCT2_GLOBAL(0x9abe05, uint32) = eax; + RCT2_GLOBAL(0x9abda4, uint32) = 0x9abe04; + eax = 0; + if (0){ + add0x682818: + if (!(RCT2_GLOBAL(0x13CE9A2, uint16) & 0x1)){ + eax &= 0xFF; + ebp = RCT2_GLOBAL(0x9ff048, uint32); + eax = *((uint32*)(eax * 4 + ebp)); + if (!(RCT2_GLOBAL(0x13CE9A2, uint16) & 0x2)){ + eax &= 0xff0000ff; + } + RCT2_GLOBAL(0x9abe05, uint32) = eax; + RCT2_GLOBAL(0x9abda4, uint32) = 0x9abe04; + eax = 0; + } + } + eax = edx; + eax += 0x13; + //0x68285a + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; } From 64bece02468cf766e689f6ae2a8dadbf311a7582 Mon Sep 17 00:00:00 2001 From: lnz Date: Wed, 21 May 2014 14:04:08 +0200 Subject: [PATCH 127/209] Initial implementation of ride reachability checks --- src/ride.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ride.h | 6 +- src/scenario.c | 2 +- 3 files changed, 209 insertions(+), 3 deletions(-) diff --git a/src/ride.c b/src/ride.c index 56149ba2a9..5b301cfd36 100644 --- a/src/ride.c +++ b/src/ride.c @@ -20,6 +20,9 @@ #include #include "addresses.h" +#include "map.h" +#include "news_item.h" +#include "sprite.h" #include "ride.h" #include "sprite.h" #include "peep.h" @@ -191,3 +194,204 @@ void ride_update_favourited_stat() window_invalidate_by_id(WC_RIDE_LIST, 0); } + +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & 0x3C; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + + + +/** + * rct2: 0x006B7C59 + * @return 1 if the coordinate is reachable or has no entrance, 0 otw + */ +int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + int tile_idx = ((x << 8) | y) >> 3; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while(1) { + uint8 element_type = tile->type & 0x3C; + if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { + break; + } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { + return 1; + } + tile++; + } + + uint8 face_direction = tile->type & 3; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + return map_coord_is_connected(tile_idx, station_height, face_direction); + /* while (1) { */ + /* rct_map_element_path_properties props; */ + + /* element_type = tile->type & 0x3C; */ + /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ + /* goto end; */ + + /* props = tile->properties.path; */ + /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ + /* if ((props.type & 3) == face_direction) { */ + /* if (station_height == tile->base_height + 2) */ + /* return 1; */ + /* } */ + /* else { */ + /* uint8 madness = (props.type & 3) ^ 2; */ + /* if (madness == face_direction && station_height == tile->base_height) */ + /* return 1; */ + /* } */ + /* } else { // off-road only same height counts as connected */ + /* if (station_height == tile->base_height) */ + /* return 1; */ + /* } */ + + /* end: */ + /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ + /* return 0; */ + /* tile++; */ + /* } */ +} + + +void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) +{ + for (int i = 0; i < 4; ++i) { + uint16 station_start = ride->station_starts[i], + entrance = ride->entrances[i], + exit = ride->exits[i]; + + if (station_start == -1 ) + continue; + if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; + } + + if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb27, ride_idx); + ride->var_1AF = 3; + } + + } +} + + +void blue_reachable(rct_ride* ride, int ride_idx) +{ + uint16 coordinate = ride->station_starts[ride_idx]; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint16 magic = 0; + int tile_idx = ((x << 8) | y) >> 3, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while (1) { + // First find the appropriate track element for our ride + uint8 element_type = tile->type & 0x3C; + if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) + break; + + if(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) + return; + tile++; + } + + uint8 track_type = tile->properties.track.type; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } + + magic = magic << (tile->type & 3); + magic = ((magic >> 12) | magic) & 0xF; + + for (int count = 0; magic != 0; ++count) { + if (!(magic & 1)) { + magic >>= 1; + continue; + } + + uint8 face_direction = count ^ 2; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + if (map_coord_is_connected(tile, tile->base_height, face_direction)) + return; + } + + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; +} + + + +/** + * rct2: 0x006B7A5E + **/ +void ride_check_all_reachable() +{ +/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ + rct_ride *ride; + + for (int i = 0; i < MAX_RIDES; i++) { + ride = GET_RIDE(i); + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->var_1AF != 0) + ride->var_1AF--; + if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + continue; + + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { + //lightblue + blue_reachable(ride, i); + return; + } + else { + //pink + ride_entrance_exit_connected(ride, i); + } + + } +} + diff --git a/src/ride.h b/src/ride.h index 9d53d72864..32653a3211 100644 --- a/src/ride.h +++ b/src/ride.h @@ -111,8 +111,9 @@ typedef struct { uint8 var_199; uint8 pad_19A[0x14]; uint8 var_1AE; - uint8 pad_1AF[0x05]; - money32 profit; // 0x1B4 + uint8 var_1AF; + uint32 pad_1B0; + sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 uint8 var_1BC; uint8 pad_1BD[0x10]; @@ -343,5 +344,6 @@ int ride_get_max_queue_time(rct_ride *ride); void ride_init_all(); void reset_all_ride_build_dates(); void ride_update_favourited_stat(); +void ride_check_all_reachable(); #endif diff --git a/src/scenario.c b/src/scenario.c index 7d0957031b..6dc29fa1bf 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -592,7 +592,7 @@ void scenario_update() finance_pay_interest(); marketing_update(); peep_problem_warnings_update(); - RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability + ride_check_all_reachable(); ride_update_favourited_stat(); if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) { From 5e104477d328bf09a8261ac2a0a737d19eb7292c Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 15:22:52 +0200 Subject: [PATCH 128/209] Cleanup and refactoring of ride reachability stuff --- src/map.c | 38 +++++++++++++++++++- src/map.h | 2 ++ src/ride.c | 95 ++++++++++---------------------------------------- src/scenario.c | 1 + 4 files changed, 59 insertions(+), 77 deletions(-) diff --git a/src/map.c b/src/map.c index 935f059ee0..20d85834b6 100644 --- a/src/map.c +++ b/src/map.c @@ -328,4 +328,40 @@ void sub_68B089() } while (mapElement->base_height == 255); mapElement++; RCT2_GLOBAL(0x0140E9A4, rct_map_element*) = mapElement; -} \ No newline at end of file +} + + +/** + * Checks if the tile at coordinate at height counts as connected. + * @return 1 if connected, 0 otherwisei + */ +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + diff --git a/src/map.h b/src/map.h index 355767bc81..069c0d52c9 100644 --- a/src/map.h +++ b/src/map.h @@ -195,5 +195,7 @@ void map_init(); void map_update_tile_pointers(); int map_element_height(int x, int y); void sub_68B089(); +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction); + #endif diff --git a/src/ride.c b/src/ride.c index 5b301cfd36..32f500d1ea 100644 --- a/src/ride.c +++ b/src/ride.c @@ -195,51 +195,21 @@ void ride_update_favourited_stat() } -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) -{ - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; - - do { - rct_map_element_path_properties props = tile->properties.path; - uint8 path_type = props.type >> 2, path_dir = props.type & 3; - uint8 element_type = tile->type & 0x3C; - - if (!(element_type & PATH_ROAD)) - continue; - - if (path_type & 1) { - if (path_dir == face_direction) { - if (height == tile->base_height + 2) - return 1; - } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { - return 1; - } - } else { - if (height == tile->base_height) - return 1; - } - - } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); - - return 0; -} - /** * rct2: 0x006B7C59 * @return 1 if the coordinate is reachable or has no entrance, 0 otw */ -int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { +int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] - int tile_idx = ((x << 8) | y) >> 3; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while(1) { - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { break; } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { @@ -251,37 +221,9 @@ int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { uint8 face_direction = tile->type & 3; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; return map_coord_is_connected(tile_idx, station_height, face_direction); - /* while (1) { */ - /* rct_map_element_path_properties props; */ - - /* element_type = tile->type & 0x3C; */ - /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ - /* goto end; */ - - /* props = tile->properties.path; */ - /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ - /* if ((props.type & 3) == face_direction) { */ - /* if (station_height == tile->base_height + 2) */ - /* return 1; */ - /* } */ - /* else { */ - /* uint8 madness = (props.type & 3) ^ 2; */ - /* if (madness == face_direction && station_height == tile->base_height) */ - /* return 1; */ - /* } */ - /* } else { // off-road only same height counts as connected */ - /* if (station_height == tile->base_height) */ - /* return 1; */ - /* } */ - - /* end: */ - /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ - /* return 0; */ - /* tile++; */ - /* } */ } @@ -294,14 +236,14 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; - if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); ride->var_1AF = 3; } - if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -312,18 +254,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void blue_reachable(rct_ride* ride, int ride_idx) +void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[ride_idx]; int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; - int tile_idx = ((x << 8) | y) >> 3, count = 0; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while (1) { - // First find the appropriate track element for our ride - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) break; @@ -333,7 +274,8 @@ void blue_reachable(rct_ride* ride, int ride_idx) } uint8 track_type = tile->properties.track.type; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + ride = GET_RIDE(tile->properties.track.ride_index); + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } else { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; @@ -341,7 +283,9 @@ void blue_reachable(rct_ride* ride, int ride_idx) magic = magic << (tile->type & 3); magic = ((magic >> 12) | magic) & 0xF; - + if (magic == 0) + return; + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { magic >>= 1; @@ -351,7 +295,7 @@ void blue_reachable(rct_ride* ride, int ride_idx) uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; if (map_coord_is_connected(tile, tile->base_height, face_direction)) return; @@ -370,7 +314,6 @@ void blue_reachable(rct_ride* ride, int ride_idx) **/ void ride_check_all_reachable() { -/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ rct_ride *ride; for (int i = 0; i < MAX_RIDES; i++) { @@ -383,8 +326,8 @@ void ride_check_all_reachable() continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //lightblue - blue_reachable(ride, i); + //blue + ride_is_shop_reachable(ride, i); return; } else { diff --git a/src/scenario.c b/src/scenario.c index 6dc29fa1bf..5ae95f70e1 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,6 +574,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); + ride_check_all_reachable(); RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From ce270dbe1960522bb329f9db61704871d8ce45cc Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 17:39:18 +0200 Subject: [PATCH 129/209] Fix lots of disgusting bugs --- src/map.c | 6 +++--- src/ride.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/map.c b/src/map.c index 20d85834b6..d7fcfb3003 100644 --- a/src/map.c +++ b/src/map.c @@ -335,16 +335,16 @@ void sub_68B089() * Checks if the tile at coordinate at height counts as connected. * @return 1 if connected, 0 otherwisei */ -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) { - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; do { rct_map_element_path_properties props = tile->properties.path; uint8 path_type = props.type >> 2, path_dir = props.type & 3; uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; - if (!(element_type & PATH_ROAD)) + if (element_type != PATH_ROAD) continue; if (path_type & 1) { diff --git a/src/ride.c b/src/ride.c index 32f500d1ea..005b776d47 100644 --- a/src/ride.c +++ b/src/ride.c @@ -275,10 +275,10 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; - } else { + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } magic = magic << (tile->type & 3); @@ -286,18 +286,19 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) if (magic == 0) return; - for (int count = 0; magic != 0; ++count) { + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { - magic >>= 1; + magic >>= 1; continue; } + magic >>= 1; uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; - if (map_coord_is_connected(tile, tile->base_height, face_direction)) + if (map_coord_is_connected(tile_idx, tile->base_height, face_direction)) return; } @@ -328,7 +329,6 @@ void ride_check_all_reachable() if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { //blue ride_is_shop_reachable(ride, i); - return; } else { //pink From 3a3694a480fb19d0f9449598530d1feb6d3d987d Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 18:19:34 +0200 Subject: [PATCH 130/209] More critical bugfixes for the reachability code. --- src/ride.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ride.c b/src/ride.c index 005b776d47..261dfc752c 100644 --- a/src/ride.c +++ b/src/ride.c @@ -256,13 +256,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { - uint16 coordinate = ride->station_starts[ride_idx]; + uint16 coordinate = ride->station_starts[0]; + if (coordinate == 0xFFFF) + return; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while (1) { uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) From 6e32406e7b6c1965bb0d075cf1ec1190bcd826df Mon Sep 17 00:00:00 2001 From: lnz Date: Thu, 29 May 2014 23:04:52 +0200 Subject: [PATCH 131/209] Cleanup and documentatin of ride connected functions --- src/ride.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/ride.c b/src/ride.c index 261dfc752c..6eb7d7ca9f 100644 --- a/src/ride.c +++ b/src/ride.c @@ -237,6 +237,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { + // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); @@ -244,6 +245,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { + // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -254,7 +256,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void ride_is_shop_reachable(rct_ride* ride, int ride_idx) +void ride_shop_connected(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[0]; if (coordinate == 0xFFFF) @@ -262,7 +264,7 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax - uint16 magic = 0; + uint16 entrance_directions = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; @@ -280,24 +282,28 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { - magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + entrance_directions = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; } else { - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + entrance_directions = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } - magic = magic << (tile->type & 3); - magic = ((magic >> 12) | magic) & 0xF; - if (magic == 0) + + uint8 tile_direction = tile->type & MAP_ELEMENT_DIRECTION_MASK; + entrance_directions <<= tile_direction; + entrance_directions = ((entrance_directions >> 12) | entrance_directions) & 0xF; + + // now each bit in entrance_directions stands for an entrance direction to check + if (entrance_directions == 0) return; - for (int count = 0; magic != 0; ++count) { - if (!(magic & 1)) { - magic >>= 1; + for (int count = 0; entrance_directions != 0; ++count) { + if (!(entrance_directions & 1)) { + entrance_directions >>= 1; continue; } - magic >>= 1; + entrance_directions >>= 1; - uint8 face_direction = count ^ 2; + uint8 face_direction = count ^ 2; // flip direction north<->south, east<->west y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; @@ -306,9 +312,11 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) return; } + // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; - RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; } @@ -330,14 +338,10 @@ void ride_check_all_reachable() if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) continue; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //blue - ride_is_shop_reachable(ride, i); - } - else { - //pink + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) + ride_shop_connected(ride, i); + else ride_entrance_exit_connected(ride, i); - } } } From 978bc39d251c3744fb16e8ca73c7d64fde0290ab Mon Sep 17 00:00:00 2001 From: lnz Date: Thu, 29 May 2014 23:42:24 +0200 Subject: [PATCH 132/209] Name various ride variables, clear a warning in map.c, add a note in scenario --- src/map.c | 2 +- src/ride.c | 14 +++++++------- src/ride.h | 5 +++-- src/scenario.c | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/map.c b/src/map.c index d7fcfb3003..5f157b1ab7 100644 --- a/src/map.c +++ b/src/map.c @@ -352,7 +352,7 @@ int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) if (height == tile->base_height + 2) return 1; } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + else if ((path_dir ^ 2) == face_direction && height == tile->base_height) { return 1; } } else { diff --git a/src/ride.c b/src/ride.c index 6eb7d7ca9f..a709606d4d 100644 --- a/src/ride.c +++ b/src/ride.c @@ -204,7 +204,7 @@ void ride_update_favourited_stat() int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax - uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + uint8 station_height = ride->station_heights[index]; int tile_idx = ((x << 8) | y) >> 5; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; @@ -241,7 +241,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); - ride->var_1AF = 3; + ride->connected_message_throttle = 3; } if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { @@ -249,7 +249,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); - ride->var_1AF = 3; + ride->connected_message_throttle = 3; } } @@ -317,7 +317,7 @@ void ride_shop_connected(rct_ride* ride, int ride_idx) RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); - ride->var_1AF = 3; + ride->connected_message_throttle = 3; } @@ -333,9 +333,9 @@ void ride_check_all_reachable() ride = GET_RIDE(i); if (ride->type == RIDE_TYPE_NULL) continue; - if (ride->var_1AF != 0) - ride->var_1AF--; - if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + if (ride->connected_message_throttle != 0) + ride->connected_message_throttle--; + if (ride->status != RIDE_STATUS_OPEN || ride->connected_message_throttle != 0) continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) diff --git a/src/ride.h b/src/ride.h index 32653a3211..9f593c1ec5 100644 --- a/src/ride.h +++ b/src/ride.h @@ -56,7 +56,8 @@ typedef struct { uint32 var_04C; uint16 overall_view; // 0x050 uint16 station_starts[4]; // 0x052 - uint8 pad_05A[0x10]; + uint16 station_heights[4]; // 0x05A + uint8 pad_062[8]; uint16 entrances[4]; // 0x06A uint16 exits[4]; // 0x072 uint8 pad_07A[0x0C]; @@ -111,7 +112,7 @@ typedef struct { uint8 var_199; uint8 pad_19A[0x14]; uint8 var_1AE; - uint8 var_1AF; + uint8 connected_message_throttle; uint32 pad_1B0; sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 diff --git a/src/scenario.c b/src/scenario.c index 5ae95f70e1..cda9235f13 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,7 +574,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); - ride_check_all_reachable(); + ride_check_all_reachable(); // XXX remove after debugging done RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From bad9e8b7bdc7c4a58977cb4ec4c8e22291e71e33 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 29 May 2014 23:05:55 +0100 Subject: [PATCH 133/209] fix bug in format string --- src/string_ids.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/string_ids.c b/src/string_ids.c index e18f7e6bc8..28c70e4a1a 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1525,6 +1525,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) // args += (format & 0xC00) >> 9; format &= ~0xC00; strcpy(*dest, RCT2_ADDRESS(0x135A8F4 + (format * 32), char)); + *dest = strchr(*dest, 0); } else if (format < 0xE000) { // Real name format -= -0xA000; @@ -1532,6 +1533,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) real_names[format % countof(real_names)], real_name_initials[(format >> 10) % countof(real_name_initials)] ); + *dest = strchr(*dest, 0); } else { // ? RCT2_CALLPROC_EBPSAFE(RCT2_ADDRESS(0x0095AFB8, uint32)[format]); From 35b38f3c16e78fc20009df0f7112131bc7417eb0 Mon Sep 17 00:00:00 2001 From: lnz Date: Fri, 30 May 2014 00:12:29 +0200 Subject: [PATCH 134/209] Remove debug statements and add string_ids for ride connected functions. --- src/ride.c | 6 +++--- src/scenario.c | 1 - src/string_ids.h | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ride.c b/src/ride.c index a709606d4d..840d12abf9 100644 --- a/src/ride.c +++ b/src/ride.c @@ -240,7 +240,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; - news_item_add_to_queue(1, 0xb26, ride_idx); + news_item_add_to_queue(1, STR_ENTRANCE_NOT_CONNECTED, ride_idx); ride->connected_message_throttle = 3; } @@ -248,7 +248,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; - news_item_add_to_queue(1, 0xb27, ride_idx); + news_item_add_to_queue(1, STR_EXIT_NOT_CONNECTED, ride_idx); ride->connected_message_throttle = 3; } @@ -315,7 +315,7 @@ void ride_shop_connected(rct_ride* ride, int ride_idx) // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; - news_item_add_to_queue(1, 0xb26, ride_idx); + news_item_add_to_queue(1, STR_ENTRANCE_NOT_CONNECTED, ride_idx); ride->connected_message_throttle = 3; } diff --git a/src/scenario.c b/src/scenario.c index cda9235f13..6dc29fa1bf 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,7 +574,6 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); - ride_check_all_reachable(); // XXX remove after debugging done RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { diff --git a/src/string_ids.h b/src/string_ids.h index 6812f33eeb..5db27533b3 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -567,6 +567,9 @@ enum { STR_NO_RECENT_AWARDS = 2848, + STR_ENTRANCE_NOT_CONNECTED = 2854, + STR_EXIT_NOT_CONNECTED = 2855, + STR_TUTORIAL = 2856, STR_PRESS_KEY_OR_MOUSE_BUTTON_FOR_CONTROL = 2857, From d5f374d38c931395dc5786e6261a391790867ecb Mon Sep 17 00:00:00 2001 From: lnz Date: Fri, 30 May 2014 00:24:44 +0200 Subject: [PATCH 135/209] Fix station_heights bug and use FOR_ALL_RIDES in ride_check_all_reachable --- src/ride.c | 9 +++------ src/ride.h | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/ride.c b/src/ride.c index 840d12abf9..c7746e91f9 100644 --- a/src/ride.c +++ b/src/ride.c @@ -328,11 +328,9 @@ void ride_shop_connected(rct_ride* ride, int ride_idx) void ride_check_all_reachable() { rct_ride *ride; - - for (int i = 0; i < MAX_RIDES; i++) { - ride = GET_RIDE(i); - if (ride->type == RIDE_TYPE_NULL) - continue; + int i; + + FOR_ALL_RIDES(i, ride) { if (ride->connected_message_throttle != 0) ride->connected_message_throttle--; if (ride->status != RIDE_STATUS_OPEN || ride->connected_message_throttle != 0) @@ -342,7 +340,6 @@ void ride_check_all_reachable() ride_shop_connected(ride, i); else ride_entrance_exit_connected(ride, i); - } } diff --git a/src/ride.h b/src/ride.h index 9f593c1ec5..bcbc0c86dd 100644 --- a/src/ride.h +++ b/src/ride.h @@ -56,8 +56,8 @@ typedef struct { uint32 var_04C; uint16 overall_view; // 0x050 uint16 station_starts[4]; // 0x052 - uint16 station_heights[4]; // 0x05A - uint8 pad_062[8]; + uint8 station_heights[4]; // 0x05A + uint8 pad_05E[0xC]; uint16 entrances[4]; // 0x06A uint16 exits[4]; // 0x072 uint8 pad_07A[0x0C]; From e69b3540559b09a103c9a6317b04602d64269b81 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 30 May 2014 12:42:39 +0100 Subject: [PATCH 136/209] Added a small bit more to draw_string --- src/gfx.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 3250927a68..1f520efaa0 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1527,7 +1527,30 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in } eax = edx; eax += 0x13; - //0x68285a + if ( eax <= dpi->y)){ + //jmp 0x682B63 + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; + } + eax = dpi->y; + eax += dpi->height; + if (eax <= edx){ + //jmp 0x682B63 + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; + } + eax = *(*(uint8)esi); + esi++; + if (!eax)return; + if ((uint32)eax < 0x9c){ + if((uint32)eax >= 0x8e){ + //jmp 0x682a2d + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; + } + } + eax -= 0x20; + //0x68288a RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); return; From 81fe1d3494337a2ee6a1133fb731428f91a231a1 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 30 May 2014 15:33:10 +0100 Subject: [PATCH 137/209] Added more draw_string reaches first draw_sprite_call --- src/gfx.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 1f520efaa0..4c0416c694 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1440,8 +1440,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in RCT2_GLOBAL(0x9E3CDC, uint32) = 0; if ((eax & 0xFF) == 0xFE){ - RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); - return; + goto mov0x682853; //jmp 0x682853 } @@ -1466,8 +1465,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in return; } if ((eax & 0xff) == 0xff){ - RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); - return; + goto mov0x682853; //jmp 0x682853 } @@ -1512,7 +1510,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in RCT2_GLOBAL(0x9abda4, uint32) = 0x9abe04; eax = 0; if (0){ - add0x682818: +add0x682818: if (!(RCT2_GLOBAL(0x13CE9A2, uint16) & 0x1)){ eax &= 0xFF; ebp = RCT2_GLOBAL(0x9ff048, uint32); @@ -1525,6 +1523,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in eax = 0; } } +mov0x682853: eax = edx; eax += 0x13; if ( eax <= dpi->y)){ @@ -1550,6 +1549,33 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in } } eax -= 0x20; + if (eax<0){ + //jmp 0x6828f5 + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; + } + ebx = dpi->x; + ebx += dpi->width; + if (ecx>=ebx){ + //jmp 0x682b63 + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; + } + ebx = ecx; + ebx += 0x1a; + if (ebxx){ + //jmp 0x6828e0 + RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); + return; + } + + ebx = eax; + ebx += RCT2_GLOBAL(0x13CE950,uint16); + eax = *((uint32*)(ebx+0x141E9e8); + ebx += 0xf15; + RCT2_GLOBAL(0xEDF81C,uint32) = 0x20000000; + gfx_draw_sprite_palette_set(dpi,ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), RCT2_GLOBAL(0x9E3CDC, uint8*)) + //0x68288a RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); return; From ed31f96c332106ba85f47f2914f4e3590bd640bc Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 30 May 2014 17:28:06 +0100 Subject: [PATCH 138/209] Added sprite zoom function. No freeing yet leaks memory like a sive --- src/gfx.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 4c0416c694..c5e64c3222 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -706,6 +706,35 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui return; } +rct_g1_element gfx_sprite_zoom_image(rct_g1_element* source, int zoom_level){ + rct_g1_element dest; + uint8* smaller_image; + dest.offset = NULL; + if (zoom_level == 0)return dest; + if (source->flags&G1_FLAG_RLE_COMPRESSION) return dest; + smaller_image = malloc(source->width*source->height); + dest.offset = smaller_image; + uint8* source_pointer = source->offset; + source_pointer += source->y_offset*source->width + source->x_offset; + + for (int y = 0; y < source->height; y += zoom_level){ + uint8* next_line = source_pointer + source->width*zoom_level; + for (int x = 0; x < source->width; x += zoom_level){ + *smaller_image = *source_pointer; + source_pointer += zoom_level; + smaller_image++; + } + source_pointer = next_line;//source->width*zoom_level; + } + + dest.x_offset = 0; + dest.y_offset = 0; + dest.width = source->width / zoom_level; + dest.height= source->height/ zoom_level; + dest.flags = source->flags; + return dest; + //remember to free the pointer +} /* * rct2: 0x67AA18 transfers readied images onto buffers * This function copies the sprite data onto the screen @@ -924,7 +953,8 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in int image_type = (image_id & 0xE0000000) >> 28; rct_g1_element* g1_source = &((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[image_element]; - + rct_g1_element zoomed = gfx_sprite_zoom_image(g1_source, dpi->pad_0E); + if (zoomed.offset != NULL)g1_source = &zoomed; if (dpi->pad_0E >= 1){ //These have not been tested //something to do with zooming if (dpi->pad_0E == 1){ @@ -1526,7 +1556,7 @@ add0x682818: mov0x682853: eax = edx; eax += 0x13; - if ( eax <= dpi->y)){ + if ( eax <= dpi->y){ //jmp 0x682B63 RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); return; @@ -1538,7 +1568,7 @@ mov0x682853: RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); return; } - eax = *(*(uint8)esi); + eax = *((uint8*)esi); esi++; if (!eax)return; if ((uint32)eax < 0x9c){ @@ -1571,10 +1601,10 @@ mov0x682853: ebx = eax; ebx += RCT2_GLOBAL(0x13CE950,uint16); - eax = *((uint32*)(ebx+0x141E9e8); + eax = *((uint32*)(ebx+0x141E9e8)); ebx += 0xf15; RCT2_GLOBAL(0xEDF81C,uint32) = 0x20000000; - gfx_draw_sprite_palette_set(dpi,ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), RCT2_GLOBAL(0x9E3CDC, uint8*)) + gfx_draw_sprite_palette_set(dpi, ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), RCT2_GLOBAL(0x9E3CDC, uint8*)); //0x68288a RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, (int)format, (int)dpi, 0); From 6a1c5fa6ebff5e49755f18a31fdecb6c541eb418 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 30 May 2014 23:27:11 +0100 Subject: [PATCH 139/209] add initial start to peep update --- src/award.c | 16 ++++---- src/peep.c | 85 +++++++++++++++++++++++++++++++++++++++-- src/peep.h | 10 +++-- src/window_guest_list.c | 6 +-- 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/award.c b/src/award.c index 25c843ddd9..3f76984ebf 100644 --- a/src/award.c +++ b/src/award.c @@ -76,7 +76,7 @@ static int award_is_deserved_most_untidy(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 > 5) + if (peep->thoughts[0].var_2 > 5) continue; if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BAD_LITTER || @@ -109,7 +109,7 @@ static int award_is_deserved_most_tidy(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 > 5) + if (peep->thoughts[0].var_2 > 5) continue; if (peep->thoughts[0].type == PEEP_THOUGHT_VERY_CLEAN) @@ -183,7 +183,7 @@ static int award_is_deserved_most_beautiful(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 > 5) + if (peep->thoughts[0].var_2 > 5) continue; if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_SCENERY) @@ -226,7 +226,7 @@ static int award_is_deserved_safest(int awardType, int activeAwardTypes) FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM) peepsWhoDislikeVandalism++; } @@ -307,7 +307,7 @@ static int award_is_deserved_best_food(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) hungryPeeps++; } @@ -353,7 +353,7 @@ static int award_is_deserved_worst_food(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) hungryPeeps++; } @@ -388,7 +388,7 @@ static int award_is_deserved_best_restrooms(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BATHROOM) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BATHROOM) guestsWhoNeedRestroom++; } @@ -510,7 +510,7 @@ static int award_is_deserved_most_confusing_layout(int awardType, int activeAwar continue; peepsCounted++; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND) peepsLost++; } diff --git a/src/peep.c b/src/peep.c index cde8015f4e..7042c04c5d 100644 --- a/src/peep.c +++ b/src/peep.c @@ -28,6 +28,8 @@ #include "sprite.h" #include "window.h" +static void peep_update(rct_peep *peep); + int peep_get_staff_count() { uint16 spriteIndex; @@ -60,17 +62,94 @@ void peep_update_all() spriteIndex = peep->next; if ((i & 0x7F) != (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) { - RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update(peep); } else { RCT2_CALLPROC_X(0x0068F41A, 0, 0, 0, i, (int)peep, 0, 0); if (peep->var_08 == 4) - RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update(peep); } i++; } } +/** + * + * rct2: 0x0068FC1E + */ +static void peep_update(rct_peep *peep) +{ + // RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); return; + + int i, j; + + if (peep->type == PEEP_TYPE_GUEST) { + if (peep->var_AD != 255) + if (++peep->var_AE < 720) + peep->var_AD = 255; + + // Update thoughts + i = 0; + int ebp = 0; + int edi = -1; + for (i = 0; i < PEEP_MAX_THOUGHTS; i++) { + if (peep->thoughts[i].type == PEEP_THOUGHT_TYPE_NONE) + break; + + if (peep->thoughts[i].var_2 == 1) { + ebp++; + if (++peep->thoughts[i].var_3 >= 220) { + peep->thoughts[i].var_3 = 0; + peep->thoughts[i].var_2++; + ebp--; + } + } else if (peep->thoughts[i].var_2 >= 0) { + if (++peep->thoughts[i].var_3 > 255) { + if (++peep->thoughts[i].var_3 >= 28) { + peep->var_45 |= 1; + + // Clear top thought, push others up + for (j = i; j < PEEP_MAX_THOUGHTS - 1; j++) + peep->thoughts[j].type = peep->thoughts[j + 1].type; + peep->thoughts[PEEP_MAX_THOUGHTS - 1].type = PEEP_THOUGHT_TYPE_NONE; + } + } + } else { + edi = i; + } + } + if (ebp == 0 && edi != -1) { + peep->thoughts[edi].var_2 = 1; + peep->var_45 |= 1; + } + } + + // Walking speed logic + unsigned int stepsToTake = peep->energy; + if (stepsToTake < 95 && peep->state == PEEP_STATE_QUEUING) + stepsToTake = 95; + if ((peep->flags & PEEP_FLAGS_SLOW_WALK) && peep->state != PEEP_STATE_QUEUING) + stepsToTake /= 2; + if (peep->var_71 == 255 && (RCT2_GLOBAL((int)peep + 0x29, uint8) & 4)) { + stepsToTake /= 2; + if (peep->state == PEEP_STATE_QUEUING) + stepsToTake += stepsToTake / 2; + } + + unsigned int carryCheck = peep->var_73 + stepsToTake; + peep->var_73 = carryCheck; + if (carryCheck <= 255) { + // loc_68FD3A + RCT2_CALLPROC_X(0x0068FD3A, 0, 0, 0, 0, (int)peep, 0, 0); + } else { + // loc_68FD2F + RCT2_CALLPROC_X(0x0068FD2F, 0, 0, 0, 0, (int)peep, 0, 0); + switch (peep->state) { + + } + } +} + /** * @@ -89,7 +168,7 @@ void peep_problem_warnings_update() RCT2_GLOBAL(RCT2_ADDRESS_RIDE_COUNT, sint16) = ride_get_count(); // refactor this to somewhere else FOR_ALL_GUESTS(spriteIndex, peep) { - if (peep->var_2A != 0 || peep->thoughts[0].pad_3 > 5) + if (peep->var_2A != 0 || peep->thoughts[0].var_2 > 5) continue; switch (peep->thoughts[0].type) { diff --git a/src/peep.h b/src/peep.h index 2bac8ed735..74dfd3f6b8 100644 --- a/src/peep.h +++ b/src/peep.h @@ -307,8 +307,8 @@ enum PEEP_ITEM { typedef struct { uint8 type; uint8 item; - uint8 pad_3; - uint8 pad_4; + uint8 var_2; + uint8 var_3; } rct_peep_thought; typedef struct { @@ -376,7 +376,8 @@ typedef struct { uint8 var_70; uint8 var_71; uint8 var_72; - uint8 pad_73[3]; + uint8 var_73; + uint16 pad_74; uint8 var_76; uint8 pad_77; uint8 var_78; @@ -387,7 +388,8 @@ typedef struct { money32 cash_spent; // 0xA4 uint8 pad_A8; sint32 time_in_park; // 0xA9 - uint8 pad_AD[0x3]; + uint8 var_AD; + uint16 var_AE; rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 uint8 pad_C4; uint8 var_C5; diff --git a/src/window_guest_list.c b/src/window_guest_list.c index d26c91993a..14fe8d13a7 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -731,9 +731,9 @@ static void window_guest_list_scrollpaint() thought = &peep->thoughts[j]; if (thought->type == PEEP_THOUGHT_TYPE_NONE) break; - if (thought->pad_3 == 0) + if (thought->var_2 == 0) continue; - if (thought->pad_3 > 5) + if (thought->var_2 > 5) break; ebx = thought->type; @@ -837,7 +837,7 @@ static int sub_69B7EA(rct_peep *peep, int *outEAX) *outEAX = eax; return ebx & 0xFFFF; case VIEW_THOUGHTS: - if (peep->thoughts[0].pad_3 <= 5) { + if (peep->thoughts[0].var_2 <= 5) { eax = peep->thoughts[0].item; ebx = peep->thoughts[0].type; if (peep->thoughts[0].type != PEEP_THOUGHT_TYPE_NONE) { From b1e9c5c786b4d2050a9dd9f0e10fc6d65d15a211 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 14:43:29 +0100 Subject: [PATCH 140/209] fix format string bugs --- src/string_ids.c | 79 ++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index 28c70e4a1a..11a5703f12 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1085,12 +1085,16 @@ void format_integer(char **dest, int value) *dest = dst; - // Right to left - while (value > 0) { - digit = value % 10; - value /= 10; + if (value == 0) { + *dst++ = '0'; + } else { + // Right to left + while (value > 0) { + digit = value % 10; + value /= 10; - *dst++ = '0' + digit; + *dst++ = '0' + digit; + } } finish = dst; @@ -1121,20 +1125,24 @@ void format_comma_separated_integer(char **dest, int value) *dest = dst; - // Groups of three digits, right to left - groupIndex = 0; - while (value > 0) { - // Append group seperator - if (groupIndex == 3) { - groupIndex = 0; - *dst++ = ','; + if (value == 0) { + *dst++ = '0'; + } else { + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; } - - digit = value % 10; - value /= 10; - - *dst++ = '0' + digit; - groupIndex++; } finish = dst; @@ -1225,20 +1233,24 @@ void format_currency(char **dest, int value) *dest = dst; - // Groups of three digits, right to left - groupIndex = 0; - while (value > 0) { - // Append group seperator - if (groupIndex == 3) { - groupIndex = 0; - *dst++ = ','; + if (value == 0) { + *dst++ = '0'; + } else { + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; } - - digit = value % 10; - value /= 10; - - *dst++ = '0' + digit; - groupIndex++; } finish = dst; @@ -1389,11 +1401,12 @@ void format_string_code(unsigned char format_code, char **dest, char **args) value = *((uint16*)*args); *args += 2; - uint16 dateArgs[] = { date_get_year(value), date_get_month(value) }; + uint16 dateArgs[] = { date_get_month(value), date_get_year(value) + 1 }; + uint16 *dateArgs2 = dateArgs; char formatString[] = "?, Year ?"; formatString[0] = FORMAT_MONTH; formatString[8] = FORMAT_COMMA16; - format_string_part_from_raw(dest, formatString, (char**)&dateArgs); + format_string_part_from_raw(dest, formatString, (char**)&dateArgs2); break; case FORMAT_MONTH: // Pop argument From 34a9f94ac170c65a637536918ac35876da743f61 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 17 May 2014 09:34:58 +0200 Subject: [PATCH 141/209] Add gfx_get_string_width() --- src/gfx.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 929998071e..c3f5f09a8d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1041,18 +1041,70 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) } /** - * + * * rct2: 0x006C2321 * buffer (esi) */ int gfx_get_string_width(char *buffer) { - int eax, ebx, ecx, edx, esi, edi, ebp; + int base; + int width; - esi = (int)buffer; - RCT2_CALLFUNC_X(0x006C2321, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + char curr_char; - return ecx & 0xFFFF; + curr_char = 0; + base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + width = 0; + + for (curr_char = *buffer; curr_char > 0; buffer++, curr_char = *buffer) { + + if (curr_char >= 0x20) { + width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (curr_char-0x20)]; + continue; + } + switch(curr_char) { + case 1: + width = *buffer; + buffer++; + break; + case 2: + case 3: + case 4: + buffer++; + break; + case 7: + base = 0x1C0; + break; + case 8: + base = 0x2A0; + break; + case 9: + base = 0x0E0; + break; + case 0x0A: + base = 0; + break; + case 0x17: + curr_char = *buffer; + curr_char &= 0x7FFFF; + buffer += 4; + curr_char <<= 4; + width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; + curr_char = 0; + break; + default: + if (curr_char <= 0x10) { + continue; + } + buffer += 2; + if (curr_char <= 0x16) { + continue; + } + buffer += 2; + break; + } + } + return width; } /** From 6e778006a5f17445189d16a6867e570f2c89358c Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 17 May 2014 22:37:37 +0200 Subject: [PATCH 142/209] First pass for gfx_draw_string() --- src/addresses.h | 1 + src/gfx.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 331 insertions(+) diff --git a/src/addresses.h b/src/addresses.h index 3a36125e05..912461a9b3 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -249,6 +249,7 @@ #define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754 #define RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE 0x013CE950 +#define RCT2_ADDRESS_CURRENT_FONT_FLAGS 0x013CE9A2 #define RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS 0x013CE9A4 #define RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT 0x0141E9AC diff --git a/src/gfx.c b/src/gfx.c index c3f5f09a8d..ced773d864 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1285,4 +1285,334 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in gLastDrawStringX = ecx; gLastDrawStringY = edx; + + + RCT2_GLOBAL(0x00EDF840, uint16) = x; + RCT2_GLOBAL(0x00EDF842, uint16) = y; + + if (colour & 0xFE) { + // jz loc_682853 + } + + if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || + (y >= dpi->y + dpi->height) || (y <= dpi->y)) { + return; + } + if (colour == 0xFF) { + // jz loc_682853 + } + + uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); + uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + + // switch_colour: + *current_font_flags = 0; + if (*current_font_sprite_base < 0) { + *current_font_flags |= 4; + if (*current_font_sprite_base != 0xFFFF) { + *current_font_flags |= 8; + } + *current_font_sprite_base = 0xE0; + } + // loc_6827A5 + if (!(ax & (1 << 5))) { + *current_font_flags |= 2; + } + + // loc_6827B4 + if (!(colour & 0x40)) { + ebp = al; + // jmp short loc_682AC7 + } + + *current_font_flags |= 1; + colour &= 0x1F; + + ebp = colour; + + if (*current_font_flags & 4) { + if (*current_font_flags & 8) { + // loc_682805 + eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + } else { + // loc_6827E7 + eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + } + } else { + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + } + // jmp short loc_682842 + + + // ; --------------------------------------------------------------------------- + + + // ; --------------------------------------------------------------------------- + // loc_682842 + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + eax = 0; + + // loc_682853 + if (y + 0x13 <= dpi->y) { + skip_char; + } + if (dpi->y + dpi->height <= y) { + skip_char; + } + + // loc_682875 + al = *format; + format++; + + // skip_cont + if (al == 0) { + return; + } + if (al >= 0x9C) { + // jnb short loc_682888 + } + if (al >= 0x8E) { + // jnb colour_char + } + + // loc_682888 + al -= 0x20; + if (al < 0) { + // jb short loc_6828F5 + } + bx = dpi->x + dpi->width; + if (x >= bx) { + // jge skip_char + } + bx = x + 0x1A; + if (bx < dpi->x) { + // jl short loc_6828E0 + } + ebx = al + *current_font_sprite_base; + cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF) + // push dword_141E9E8[ebx] + // push ecx + // push edx + // push edi + // push esi + + eax = (int)al; + ebx += 0xF15; + esi = (int)format; + edi = (int)dpi; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + + RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + + // pop esi + // pop edi + // pop edx + // pop ecx + // pop eax + + // jmp short loc_682875 + + // loc_6828E0 + ebx = al; + ebx += *current_font_sprite_base; + cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); + // jmp short loc_682875 + + // loc_6828F5 + switch (al) { + case 0x0E5: + // jz loc_6829E3 + cx = RCT2_GLOBAL(0x0EDF840, uint16); + dx += 0x0A; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + } + dx -= 4; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + } + dx -= 0xFFF4; + // jmp loc_682875 + case 0x0E6: + // jz loc_6829AD + cx = RCT2_GLOBAL(0x0EDF840, uint16); + dx += 5; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + } + dx -= 2; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + } + dx -= 0xFFFA; + // jmp loc_682875 + case 0x0E1: + // jz loc_682A19 + al = *buffer; + buffer++; + cx = RCT2_GLOBAL(0x0EDF840, uint16); + cx += al; + // jmp loc_682875 + + case 0x0F1: + // jz loc_682A34 + ax = *buffer; + buffer += 2; + cx = RCT2_GLOBAL(0x0EDF840, uint16); + cx += (ax & 0xFF); + dx = RCT2_GLOBAL(0x0EDF842, uint16); + dx += (ax & 0xFF00) >> 8; + // jmp loc_682875 + + + case 0x0E7: + // jz loc_682A57 + *current_font_sprite_base = 0x1C0; + // jmp loc_682875 + + case 0x0E8: + // jz loc_682A65 + *current_font_sprite_base = 0x2A0; + // jmp loc_682875 + + case 0x0E9: + // jz loc_682A81 + *current_font_sprite_base = 0xE0; + // jmp loc_682875 + + case 0x0EA: + // jz loc_682A73 + *current_font_sprite_base = 0; + // jmp loc_682875 + + case 0x0EB: + // jz loc_682A8F + *current_font_flags |= 2; + // jmp loc_682875 + + case 0x0EC: + // jz loc_682A9C + *current_font_flags &= 0x0FFFD; + // jmp loc_682875 + + case 0x0ED: + // jz loc_682AAE + ebp = RCT2_GLOBAL(0x0141F740, uint8); + + // jmp short loc_682AC7 + + case 0x0EE: + // jz loc_682AC0 + ebp = RCT2_GLOBAL(0x0141F741, uint8); + + // jmp short loc_682AC7 + + case 0x0EF: + // jz loc_682AB7 + ebp = RCT2_GLOBAL(0x0141F742, uint8); + + // jmp short loc_682AC7 + + case 0x0E2: + // jz loc_682AF7 + eax = *buffer; + buffer++; + if (*current_font_flags & 1) { + // jnz loc_682853 + } + + // push ebx + // mov eax, ds:dword_97FCBC[eax*4] + // shl eax, 4 + // mov eax, g1_elements[eax] + // mov bl, [eax+0F9h] + // mov bh, 1 + + eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + // What on earth is going on here? + bx = *(g1_element + 0xF9) + (1 << 8); + + if (!(*current_font_flags & 2)) { + bx = bx & 0xFF; + } + RCT2_GLOBAL(0x09ABE05, uint16) = bx; + bx = *(g1_element + 0xF7); + RCT2_GLOBAL(0x09ABE07, uint16) = bx; + bx = *(g1_element + 0xFA); + RCT2_GLOBAL(0x09ABE09, uint16) = bx; + + // pop ebx + RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); + + // jmp loc_682853 + + case 0x0F7: + // jz short loc_68296E + buffer += 4; + if (cx >= dpi->x + dpi->width) { + skip_char; + } + ebx = *(format - 4); + eax = ebx & 0x7FFFF; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); + + gfx_draw_sprite(dpi, ebx, cx, dx); + + cx += g1_element->offset; + // jmp loc_682875 + + } + // jmp loc_682875 + + // colour_char + al -= 0x8E; + if (*current_font_flags == 1) { + // jnz short loc_682853 + } + eax = eax & 0xFF; + // mov ebp, g1_elements+13320h + ebp = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32)); + // mov eax, [ebp+eax*4+0] + eax = *(ebp + eax*4); + + if (!(*current_font_flags & 2)) { + eax = eax & 0x0FF0000FF; + } + // jump 6842 + + + // loc_682AC7 + if (*current_font_flags & 1) { + // jnz loc_682853 + } + eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; + if (*current_font_flags & 2) { + eax |= 0x0A0A00; + } + // jmp loc_682842 + + // skip_char + al = *buffer; + buffer++; + if (al < 0x20) { + // jb skip_cont + } + if (al >= 0x9C) { + // jnb short skip_char + } + if (al >= 0x8E) { + // jnb colour_char + } + // jmp short skip_char + + } From 99c7b23452077048aa9c248433530844a0256d6e Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 18 May 2014 16:02:02 +0200 Subject: [PATCH 143/209] Second pass of gfx_draw_string. Still buggy --- src/gfx.c | 683 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 384 insertions(+), 299 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ced773d864..9a5b968f5e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1261,358 +1261,443 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co gfx_draw_string(dpi, buffer, colour, x, y); } + +void colour_char(int al, uint16* current_font_flags) { + + int eax; + uint32* ebp; + + // colour_char + eax = al & 0xFF; + // mov ebp, g1_elements+13320h + ebp = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32); + // mov eax, [ebp+eax*4+0] + eax = ebp[eax*4]; + + if (!(*current_font_flags & 2)) { + eax = eax & 0x0FF0000FF; + } + // Store current colour? + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + +} + + +void sub_682AC7(int ebp, int* eax, uint16* current_font_flags) { + + // loc_682AC7 + *eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; + if (*current_font_flags & 2) { + *eax |= 0x0A0A00; + } + // Store current colour? + RCT2_GLOBAL(0x009ABE05, uint32) = *eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + *eax = 0; + // jmp loc_682842 + +} + + /** * * rct2: 0x00682702 * dpi (edi) - * format (esi) + * buffer (esi) * colour (al) * x (cx) * y (dx) */ -void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y) +void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y) { int eax, ebx, ecx, edx, esi, edi, ebp; - eax = colour; - ebx = 0; - ecx = x; - edx = y; - esi = (int)format; - edi = (int)dpi; - ebp = 0; - RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - gLastDrawStringX = ecx; - gLastDrawStringY = edx; + // eax = colour; + // ebx = 0; + // ecx = x; + // edx = y; + // esi = (int)buffer; + // edi = (int)dpi; + // ebp = 0; + // RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + int max_x = x; + int max_y = y; RCT2_GLOBAL(0x00EDF840, uint16) = x; RCT2_GLOBAL(0x00EDF842, uint16) = y; if (colour & 0xFE) { - // jz loc_682853 + // jz loc_682853 } if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || (y >= dpi->y + dpi->height) || (y <= dpi->y)) { return; } - if (colour == 0xFF) { - // jz loc_682853 - } - uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - // switch_colour: - *current_font_flags = 0; - if (*current_font_sprite_base < 0) { - *current_font_flags |= 4; - if (*current_font_sprite_base != 0xFFFF) { - *current_font_flags |= 8; + if (!(colour == 0xFF)) { + + // switch_colour: + *current_font_flags = 0; + if (*current_font_sprite_base < 0) { + *current_font_flags |= 4; + if (*current_font_sprite_base != 0xFFFF) { + *current_font_flags |= 8; + } + *current_font_sprite_base = 0xE0; + } + // loc_6827A5 + if (!(colour & (1 << 5))) { + *current_font_flags |= 2; } - *current_font_sprite_base = 0xE0; - } - // loc_6827A5 - if (!(ax & (1 << 5))) { - *current_font_flags |= 2; - } - // loc_6827B4 - if (!(colour & 0x40)) { - ebp = al; - // jmp short loc_682AC7 - } - - *current_font_flags |= 1; - colour &= 0x1F; - - ebp = colour; - - if (*current_font_flags & 4) { - if (*current_font_flags & 8) { - // loc_682805 - eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + // loc_6827B4 + if (!(colour & 0x40)) { + ebp = colour; + sub_682AC7(ebp, &colour, current_font_flags); + // jmp short loc_682AC7 } else { - // loc_6827E7 - eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + *current_font_flags |= 1; + colour &= 0x1F; + + ebp = colour; + + if (*current_font_flags & 4) { + if (*current_font_flags & 8) { + // loc_682805 + eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + } else { + // loc_6827E7 + eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + } + } else { + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + } + // loc_682842 + // Store current colour? ; + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + eax = 0; + } - } else { - eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; - } - // jmp short loc_682842 - - - // ; --------------------------------------------------------------------------- - - - // ; --------------------------------------------------------------------------- - // loc_682842 - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - eax = 0; - - // loc_682853 - if (y + 0x13 <= dpi->y) { - skip_char; - } - if (dpi->y + dpi->height <= y) { - skip_char; + // jmp short loc_682842 + // jz loc_682853 } - // loc_682875 - al = *format; - format++; + int skip_char = 0; - // skip_cont - if (al == 0) { - return; - } - if (al >= 0x9C) { - // jnb short loc_682888 - } - if (al >= 0x8E) { - // jnb colour_char + // loc_682853 + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; } - // loc_682888 - al -= 0x20; - if (al < 0) { - // jb short loc_6828F5 - } - bx = dpi->x + dpi->width; - if (x >= bx) { - // jge skip_char - } - bx = x + 0x1A; - if (bx < dpi->x) { - // jl short loc_6828E0 - } - ebx = al + *current_font_sprite_base; - cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF) - // push dword_141E9E8[ebx] - // push ecx - // push edx - // push edi - // push esi + // loc_682875 + // al = *buffer; + // buffer++; - eax = (int)al; - ebx += 0xF15; - esi = (int)format; - edi = (int)dpi; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + for (uint8 al = *buffer; al > 0; al= *buffer, ++buffer) { + // skip_char + // al = *buffer; + // buffer++; + if (skip_char) { + if (al < 0x20) { + skip_char = 0; + // jb skip_cont + } else if (al >= 0x9C) { + continue; + // jnb short skip_char + } else if (al >= 0x8E) { + al -= 0x8E; + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz short loc_682853 + } + colour_char(al, current_font_flags); + continue; + // jnb colour_char + } else { + continue; + // jmp short skip_char + } + } - RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + // skip_cont + if (al >= 0x9C) { + // jnb short loc_682888 + // loc_682888 + al -= 0x20; + if (al < 0) { + // jb short loc_6828F5 + // loc_6828F5 + switch (al) { + case 0x0E5: + // jz loc_6829E3 + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_y += 0x0A; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + break; + } + max_y -= 4; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + break; + } + max_y -= 0xFFF4; + // jmp loc_682875 + break; + case 0x0E6: + // jz loc_6829AD + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_y += 5; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + break; + } + max_y -= 2; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + break; + } + max_y -= 0xFFFA; + // jmp loc_682875 + break; + case 0x0E1: + // jz loc_682A19 + al = *buffer; + buffer++; + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_x += al; + // jmp loc_682875 + break; - // pop esi - // pop edi - // pop edx - // pop ecx - // pop eax - - // jmp short loc_682875 - - // loc_6828E0 - ebx = al; - ebx += *current_font_sprite_base; - cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); - // jmp short loc_682875 - - // loc_6828F5 - switch (al) { - case 0x0E5: - // jz loc_6829E3 - cx = RCT2_GLOBAL(0x0EDF840, uint16); - dx += 0x0A; - if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 - } - dx -= 4; - if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 - } - dx -= 0xFFF4; - // jmp loc_682875 - case 0x0E6: - // jz loc_6829AD - cx = RCT2_GLOBAL(0x0EDF840, uint16); - dx += 5; - if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 - } - dx -= 2; - if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 - } - dx -= 0xFFFA; - // jmp loc_682875 - case 0x0E1: - // jz loc_682A19 - al = *buffer; - buffer++; - cx = RCT2_GLOBAL(0x0EDF840, uint16); - cx += al; - // jmp loc_682875 - - case 0x0F1: - // jz loc_682A34 - ax = *buffer; - buffer += 2; - cx = RCT2_GLOBAL(0x0EDF840, uint16); - cx += (ax & 0xFF); - dx = RCT2_GLOBAL(0x0EDF842, uint16); - dx += (ax & 0xFF00) >> 8; - // jmp loc_682875 + case 0x0F1: + // jz loc_682A34 + eax = *((uint16*)buffer); + buffer += 2; + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_x += (eax & 0xFF); + max_y = RCT2_GLOBAL(0x0EDF842, uint16); + max_y += (eax & 0xFF00) >> 8; + // jmp loc_682875 + break; - case 0x0E7: - // jz loc_682A57 - *current_font_sprite_base = 0x1C0; - // jmp loc_682875 + case 0x0E7: + // jz loc_682A57 + *current_font_sprite_base = 0x1C0; + // jmp loc_682875 + break; - case 0x0E8: - // jz loc_682A65 - *current_font_sprite_base = 0x2A0; - // jmp loc_682875 + case 0x0E8: + // jz loc_682A65 + *current_font_sprite_base = 0x2A0; + // jmp loc_682875 + break; - case 0x0E9: - // jz loc_682A81 - *current_font_sprite_base = 0xE0; - // jmp loc_682875 + case 0x0E9: + // jz loc_682A81 + *current_font_sprite_base = 0xE0; + // jmp loc_682875 + break; - case 0x0EA: - // jz loc_682A73 - *current_font_sprite_base = 0; - // jmp loc_682875 + case 0x0EA: + // jz loc_682A73 + *current_font_sprite_base = 0; + // jmp loc_682875 + break; - case 0x0EB: - // jz loc_682A8F - *current_font_flags |= 2; - // jmp loc_682875 + case 0x0EB: + // jz loc_682A8F + *current_font_flags |= 2; + // jmp loc_682875 + break; - case 0x0EC: - // jz loc_682A9C - *current_font_flags &= 0x0FFFD; - // jmp loc_682875 + case 0x0EC: + // jz loc_682A9C + *current_font_flags &= 0x0FFFD; + // jmp loc_682875 + break; - case 0x0ED: - // jz loc_682AAE - ebp = RCT2_GLOBAL(0x0141F740, uint8); - - // jmp short loc_682AC7 - - case 0x0EE: - // jz loc_682AC0 - ebp = RCT2_GLOBAL(0x0141F741, uint8); + case 0x0ED: + // jz loc_682AAE + 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; + } + continue; + // jnz loc_682853 + } + sub_682AC7(ebp, &al, current_font_flags); + // jmp short loc_682AC7 + break; + case 0x0EE: + // jz loc_682AC0 + 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; + } + continue; + // jnz loc_682853 + } + sub_682AC7(ebp, &al, current_font_flags); + // jmp short loc_682AC7 + break; + case 0x0EF: + // jz loc_682AB7 + 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; + } + continue; + // jnz loc_682853 + } + sub_682AC7(ebp, &al, current_font_flags); + // jmp short loc_682AC7 + break; + case 0x0E2: + // jz loc_682AF7 + eax = *buffer; + buffer++; + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + break; + } + } - // jmp short loc_682AC7 + // push ebx + // mov eax, ds:dword_97FCBC[eax*4] + // shl eax, 4 + // mov eax, g1_elements[eax] + // mov bl, [eax+0F9h] + // mov bh, 1 - case 0x0EF: - // jz loc_682AB7 - ebp = RCT2_GLOBAL(0x0141F742, uint8); + eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; + uint32* g1_element_poss = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, uint32)[eax*16]); + // What on earth is going on here? + g1_element_poss += 0xF9; + ebx = *g1_element_poss + (1 << 8); - // jmp short loc_682AC7 - - case 0x0E2: - // jz loc_682AF7 - eax = *buffer; - buffer++; - if (*current_font_flags & 1) { - // jnz loc_682853 - } + if (!(*current_font_flags & 2)) { + ebx = ebx & 0xFF; + } + RCT2_GLOBAL(0x09ABE05, uint16) = ebx; + ebx = *(g1_element_poss + 0xF7); + RCT2_GLOBAL(0x09ABE07, uint16) = ebx; + ebx = *(g1_element_poss + 0xFA); + RCT2_GLOBAL(0x09ABE09, uint16) = ebx; + + // pop ebx + RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + break; + // jmp loc_682853 + + case 0x0F7: + // jz short loc_68296E + buffer += 4; + if (max_x >= dpi->x + dpi->width) { + skip_char = 1; + break; + } + ebx = *(buffer - 4); + eax = ebx & 0x7FFFF; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); - // push ebx - // mov eax, ds:dword_97FCBC[eax*4] - // shl eax, 4 - // mov eax, g1_elements[eax] - // mov bl, [eax+0F9h] - // mov bh, 1 + gfx_draw_sprite(dpi, ebx, max_x, max_y); - eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - // What on earth is going on here? - bx = *(g1_element + 0xF9) + (1 << 8); + max_x = max_x + g1_element->offset; + // jmp loc_682875 + break; + } - if (!(*current_font_flags & 2)) { - bx = bx & 0xFF; - } - RCT2_GLOBAL(0x09ABE05, uint16) = bx; - bx = *(g1_element + 0xF7); - RCT2_GLOBAL(0x09ABE07, uint16) = bx; - bx = *(g1_element + 0xFA); - RCT2_GLOBAL(0x09ABE09, uint16) = bx; + } + if (x >= dpi->x + dpi->width) { + skip_char = 1; + } + if (x + 0x1A < dpi->x) { + // jl short loc_6828E0 + // loc_6828E0 + ebx = al; + ebx += *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + continue; + // jmp short loc_682875 + } + ebx = al + *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); + // push dword_141E9E8[ebx] + // push ecx + // push edx + // push edi + // push esi - // pop ebx - RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); - - // jmp loc_682853 - - case 0x0F7: - // jz short loc_68296E - buffer += 4; - if (cx >= dpi->x + dpi->width) { - skip_char; - } - ebx = *(format - 4); - eax = ebx & 0x7FFFF; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); - - gfx_draw_sprite(dpi, ebx, cx, dx); - - cx += g1_element->offset; - // jmp loc_682875 - - } - // jmp loc_682875 - - // colour_char - al -= 0x8E; - if (*current_font_flags == 1) { - // jnz short loc_682853 - } - eax = eax & 0xFF; - // mov ebp, g1_elements+13320h - ebp = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32)); - // mov eax, [ebp+eax*4+0] - eax = *(ebp + eax*4); - - if (!(*current_font_flags & 2)) { - eax = eax & 0x0FF0000FF; - } - // jump 6842 - - - // loc_682AC7 - if (*current_font_flags & 1) { - // jnz loc_682853 - } - eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; - if (*current_font_flags & 2) { - eax |= 0x0A0A00; - } - // jmp loc_682842 - - // skip_char - al = *buffer; - buffer++; - if (al < 0x20) { - // jb skip_cont - } - if (al >= 0x9C) { - // jnb short skip_char - } - if (al >= 0x8E) { - // jnb colour_char - } - // jmp short skip_char + eax = (int)al; + ebx += 0xF15; + ecx = max_x; + edx = max_y; + esi = (int)buffer; + edi = (int)dpi; + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + + // pop esi + // pop edi + // pop edx + // pop ecx + // pop eax + + continue; + // jmp short loc_682875 + + } else if (al >= 0x8E) { + al -= 0x8E; + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz short loc_682853 + } + colour_char(al, current_font_flags); + continue; + // jnb colour_char + } + + } + + gLastDrawStringX = max_x; + gLastDrawStringY = max_y; + } From 702a97b185d5a952c03577f5609daf84d69fc9f0 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 18 May 2014 22:06:08 +0200 Subject: [PATCH 144/209] Fix some bugs, tidy up Still buggy... --- src/gfx.c | 290 ++++++++++++++++++++---------------------------------- 1 file changed, 109 insertions(+), 181 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 9a5b968f5e..35cd38f30f 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1265,14 +1265,9 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co void colour_char(int al, uint16* current_font_flags) { int eax; - uint32* ebp; - // colour_char - eax = al & 0xFF; - // mov ebp, g1_elements+13320h - ebp = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32); - // mov eax, [ebp+eax*4+0] - eax = ebp[eax*4]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332]); + eax = g1_element->offset[(al & 0xFF) * 4]; if (!(*current_font_flags & 2)) { eax = eax & 0x0FF0000FF; @@ -1280,7 +1275,6 @@ void colour_char(int al, uint16* current_font_flags) { // Store current colour? RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - } @@ -1328,72 +1322,69 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF840, uint16) = x; RCT2_GLOBAL(0x00EDF842, uint16) = y; - if (colour & 0xFE) { - // jz loc_682853 - } - - if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || - (y >= dpi->y + dpi->height) || (y <= dpi->y)) { - return; - } uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - if (!(colour == 0xFF)) { + if (colour != 0xFE) { - // switch_colour: - *current_font_flags = 0; - if (*current_font_sprite_base < 0) { - *current_font_flags |= 4; - if (*current_font_sprite_base != 0xFFFF) { - *current_font_flags |= 8; - } - *current_font_sprite_base = 0xE0; - } - // loc_6827A5 - if (!(colour & (1 << 5))) { - *current_font_flags |= 2; + if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || + (y >= dpi->y + dpi->height) || (y <= dpi->y)) { + return; } - // loc_6827B4 - if (!(colour & 0x40)) { - ebp = colour; - sub_682AC7(ebp, &colour, current_font_flags); - // jmp short loc_682AC7 - } else { - *current_font_flags |= 1; - colour &= 0x1F; + if (colour != 0xFF) { - ebp = colour; - - if (*current_font_flags & 4) { - if (*current_font_flags & 8) { - // loc_682805 - eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; - } else { - // loc_6827E7 - eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + // switch_colour: + *current_font_flags = 0; + if (*current_font_sprite_base < 0) { + *current_font_flags |= 4; + if (*current_font_sprite_base != 0xFFFF) { + *current_font_flags |= 8; } - } else { - eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + *current_font_sprite_base = 0xE0; + } + // loc_6827A5 + if (!(colour & (1 << 5))) { + *current_font_flags |= 2; } - // loc_682842 - // Store current colour? ; - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - eax = 0; + // loc_6827B4 + if (!(colour & 0x40)) { + ebp = colour; + sub_682AC7(ebp, &colour, current_font_flags); + // jmp short loc_682AC7 + } else { + *current_font_flags |= 1; + colour &= 0x1F; + + ebp = colour; + + if (*current_font_flags & 4) { + if (*current_font_flags & 8) { + // loc_682805 + eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + } else { + // loc_6827E7 + eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + } + } else { + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + } + // loc_682842 + // Store current colour? ; + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + eax = 0; + + } } - // jmp short loc_682842 - // jz loc_682853 } - int skip_char = 0; // loc_682853 @@ -1402,20 +1393,15 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } // loc_682875 - // al = *buffer; - // buffer++; - - for (uint8 al = *buffer; al > 0; al= *buffer, ++buffer) { + for (uint8 al = *buffer; al > 0; ++buffer, al = *buffer) { // skip_char // al = *buffer; // buffer++; if (skip_char) { if (al < 0x20) { skip_char = 0; - // jb skip_cont } else if (al >= 0x9C) { continue; - // jnb short skip_char } else if (al >= 0x8E) { al -= 0x8E; if (*current_font_flags == 1) { @@ -1425,117 +1411,89 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in skip_char = 0; } continue; - // jnz short loc_682853 } colour_char(al, current_font_flags); continue; - // jnb colour_char } else { continue; - // jmp short skip_char } } // skip_cont - if (al >= 0x9C) { - // jnb short loc_682888 + if ((al >= 0x8E) && (al < 0x9C)){ + al -= 0x8E; + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + } + colour_char(al, current_font_flags); + continue; + } else { // loc_682888 - al -= 0x20; - if (al < 0) { - // jb short loc_6828F5 - // loc_6828F5 + if (al < 0x20) { + al -= 0x20; switch (al) { case 0x0E5: - // jz loc_6829E3 max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_y += 0x0A; if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 break; } max_y -= 4; if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 break; } max_y -= 0xFFF4; - // jmp loc_682875 break; case 0x0E6: - // jz loc_6829AD max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_y += 5; if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 break; } max_y -= 2; if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 break; } max_y -= 0xFFFA; - // jmp loc_682875 break; case 0x0E1: - // jz loc_682A19 al = *buffer; buffer++; max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_x += al; - // jmp loc_682875 break; - case 0x0F1: - // jz loc_682A34 eax = *((uint16*)buffer); buffer += 2; max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_x += (eax & 0xFF); max_y = RCT2_GLOBAL(0x0EDF842, uint16); max_y += (eax & 0xFF00) >> 8; - // jmp loc_682875 break; - - case 0x0E7: - // jz loc_682A57 *current_font_sprite_base = 0x1C0; - // jmp loc_682875 break; - case 0x0E8: - // jz loc_682A65 *current_font_sprite_base = 0x2A0; - // jmp loc_682875 break; - case 0x0E9: - // jz loc_682A81 *current_font_sprite_base = 0xE0; - // jmp loc_682875 break; - case 0x0EA: - // jz loc_682A73 *current_font_sprite_base = 0; - // jmp loc_682875 break; - case 0x0EB: - // jz loc_682A8F *current_font_flags |= 2; - // jmp loc_682875 break; - case 0x0EC: - // jz loc_682A9C *current_font_flags &= 0x0FFFD; - // jmp loc_682875 break; - case 0x0ED: - // jz loc_682AAE ebp = RCT2_GLOBAL(0x0141F740, uint8); if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1543,14 +1501,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { skip_char = 0; } - continue; - // jnz loc_682853 + break; } sub_682AC7(ebp, &al, current_font_flags); - // jmp short loc_682AC7 break; case 0x0EE: - // jz loc_682AC0 ebp = RCT2_GLOBAL(0x0141F741, uint8); if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1558,14 +1513,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { skip_char = 0; } - continue; - // jnz loc_682853 + break; } sub_682AC7(ebp, &al, current_font_flags); - // jmp short loc_682AC7 break; case 0x0EF: - // jz loc_682AB7 ebp = RCT2_GLOBAL(0x0141F742, uint8); if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1573,14 +1525,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { skip_char = 0; } - continue; - // jnz loc_682853 + break; } sub_682AC7(ebp, &al, current_font_flags); - // jmp short loc_682AC7 break; case 0x0E2: - // jz loc_682AF7 eax = *buffer; buffer++; if (*current_font_flags & 1) { @@ -1618,10 +1567,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in skip_char = 1; } break; - // jmp loc_682853 - case 0x0F7: - // jz short loc_68296E buffer += 4; if (max_x >= dpi->x + dpi->width) { skip_char = 1; @@ -1634,67 +1580,49 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in gfx_draw_sprite(dpi, ebx, max_x, max_y); max_x = max_x + g1_element->offset; - // jmp loc_682875 break; } - } - if (x >= dpi->x + dpi->width) { - skip_char = 1; - } - if (x + 0x1A < dpi->x) { - // jl short loc_6828E0 - // loc_6828E0 - ebx = al; - ebx += *current_font_sprite_base; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - continue; - // jmp short loc_682875 - } - ebx = al + *current_font_sprite_base; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); - // push dword_141E9E8[ebx] - // push ecx - // push edx - // push edi - // push esi - - eax = (int)al; - ebx += 0xF15; - ecx = max_x; - edx = max_y; - esi = (int)buffer; - edi = (int)dpi; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - - RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); - - // pop esi - // pop edi - // pop edx - // pop ecx - // pop eax - - continue; - // jmp short loc_682875 - - } else if (al >= 0x8E) { - al -= 0x8E; - if (*current_font_flags == 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + } else { + al -= 0x20; + if (max_x >= dpi->x + dpi->width) { skip_char = 1; - } else { - skip_char = 0; } - continue; - // jnz short loc_682853 - } - colour_char(al, current_font_flags); - continue; - // jnb colour_char - } + if (max_x + 0x1A < dpi->x) { + ebx = al; + ebx += *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + continue; + } + ebx = al + *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + // push dword_141E9E8[ebx] + // push ecx + // push edx + // push edi + // push esi + eax = (int)al; + ebx += 0xF15; + ecx = max_x; + edx = max_y; + esi = (int)buffer; + edi = (int)dpi; + ebp = 0; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + + RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + + // pop esi + // pop edi + // pop edx + // pop ecx + // pop eax + + continue; + } + } } gLastDrawStringX = max_x; From c3ea45062b7a377a28c74c1c28f3aea94c93554f Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 22 May 2014 22:01:37 +0200 Subject: [PATCH 145/209] gfx_draw_string complete. Needs tidying --- src/gfx.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 35cd38f30f..297c0564d9 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1278,17 +1278,19 @@ void colour_char(int al, uint16* current_font_flags) { } -void sub_682AC7(int ebp, int* eax, uint16* current_font_flags) { +void sub_682AC7(int ebp, uint16* current_font_flags) { + + int eax; // loc_682AC7 - *eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; if (*current_font_flags & 2) { - *eax |= 0x0A0A00; + eax |= 0x0A0A00; } - // Store current colour? - RCT2_GLOBAL(0x009ABE05, uint32) = *eax; + //Store current colour? + RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - *eax = 0; + eax = 0; // jmp loc_682842 } @@ -1325,10 +1327,20 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + int skip_char = 0; + if (colour != 0xFE) { - if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || - (y >= dpi->y + dpi->height) || (y <= dpi->y)) { + if (x >= dpi->x + dpi->width) + return; + + if (x + 0x280 <= dpi->x) + return; + + if (y >= dpi->y + dpi->height) + return; + + if (y + 0x5A <= dpi->y) { return; } @@ -1344,14 +1356,25 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in *current_font_sprite_base = 0xE0; } // loc_6827A5 - if (!(colour & (1 << 5))) { + // also reset bit 5 + if (colour & (1 << 5)) { *current_font_flags |= 2; } + colour &= ~(1 << 5); // loc_6827B4 if (!(colour & 0x40)) { ebp = colour; - sub_682AC7(ebp, &colour, current_font_flags); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + } else { + sub_682AC7(ebp, current_font_flags); + } // jmp short loc_682AC7 } else { *current_font_flags |= 1; @@ -1385,7 +1408,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } } } - int skip_char = 0; // loc_682853 if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1503,7 +1525,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; } - sub_682AC7(ebp, &al, current_font_flags); + sub_682AC7(ebp, current_font_flags); break; case 0x0EE: ebp = RCT2_GLOBAL(0x0141F741, uint8); @@ -1515,7 +1537,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; } - sub_682AC7(ebp, &al, current_font_flags); + sub_682AC7(ebp, current_font_flags); break; case 0x0EF: ebp = RCT2_GLOBAL(0x0141F742, uint8); @@ -1527,7 +1549,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; } - sub_682AC7(ebp, &al, current_font_flags); + sub_682AC7(ebp, current_font_flags); break; case 0x0E2: eax = *buffer; @@ -1595,6 +1617,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in continue; } ebx = al + *current_font_sprite_base; + + ecx = max_x; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); // push dword_141E9E8[ebx] // push ecx @@ -1604,7 +1629,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in eax = (int)al; ebx += 0xF15; - ecx = max_x; + edx = max_y; esi = (int)buffer; edi = (int)dpi; From 67b7ca8d1eeb605c6236543bc83ce7d7f428ae0d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Tue, 27 May 2014 19:16:05 +0200 Subject: [PATCH 146/209] Fix use of g1_elements and tidy comments --- src/gfx.c | 95 ++++++++++++++++--------------------------------------- 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 297c0564d9..916b1eecf4 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1308,25 +1308,21 @@ 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; + rct_g1_element* g1_element; - // eax = colour; - // ebx = 0; - // ecx = x; - // edx = y; - // esi = (int)buffer; - // edi = (int)dpi; - // ebp = 0; - // RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - + // Maximum length/height of string int max_x = x; int max_y = y; + // Store original x, y RCT2_GLOBAL(0x00EDF840, uint16) = x; RCT2_GLOBAL(0x00EDF842, uint16) = y; + // uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + // Flag for skipping non-printing characters int skip_char = 0; if (colour != 0xFE) { @@ -1355,76 +1351,62 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } *current_font_sprite_base = 0xE0; } - // loc_6827A5 - // also reset bit 5 if (colour & (1 << 5)) { *current_font_flags |= 2; } colour &= ~(1 << 5); - // loc_6827B4 if (!(colour & 0x40)) { ebp = colour; if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; - } - else { + } else { skip_char = 0; } } else { sub_682AC7(ebp, current_font_flags); } - // jmp short loc_682AC7 } else { *current_font_flags |= 1; colour &= 0x1F; - ebp = colour; - if (*current_font_flags & 4) { if (*current_font_flags & 8) { - // loc_682805 - eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8]; } else { - // loc_6827E7 - eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8]; eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]; } } else { - eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; } - // loc_682842 // Store current colour? ; RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; eax = 0; - } } } - - // loc_682853 + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; } - // loc_682875 for (uint8 al = *buffer; al > 0; ++buffer, al = *buffer) { - // skip_char - // al = *buffer; - // buffer++; + + // Skip to the next printing character if (skip_char) { if (al < 0x20) { + // Control codes skip_char = 0; - } else if (al >= 0x9C) { - continue; - } else if (al >= 0x8E) { + } else if (al >= 0x8E && al < 0x9C) { + // Colour codes al -= 0x8E; if (*current_font_flags == 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1440,9 +1422,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in continue; } } - - // skip_cont + if ((al >= 0x8E) && (al < 0x9C)){ + // Colour codes al -= 0x8E; if (*current_font_flags == 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1455,8 +1437,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in colour_char(al, current_font_flags); continue; } else { - // loc_682888 if (al < 0x20) { + // Control codes al -= 0x20; switch (al) { case 0x0E5: @@ -1552,7 +1534,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in sub_682AC7(ebp, current_font_flags); break; case 0x0E2: - eax = *buffer; + al = *buffer; buffer++; if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1561,29 +1543,19 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } } - // push ebx - // mov eax, ds:dword_97FCBC[eax*4] - // shl eax, 4 - // mov eax, g1_elements[eax] - // mov bl, [eax+0F9h] - // mov bh, 1 - - eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; - uint32* g1_element_poss = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, uint32)[eax*16]); - // What on earth is going on here? - g1_element_poss += 0xF9; - ebx = *g1_element_poss + (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; } RCT2_GLOBAL(0x09ABE05, uint16) = ebx; - ebx = *(g1_element_poss + 0xF7); + ebx = g1_element->offset[0xF7]; RCT2_GLOBAL(0x09ABE07, uint16) = ebx; - ebx = *(g1_element_poss + 0xFA); + ebx = g1_element->offset[0xFA]; RCT2_GLOBAL(0x09ABE09, uint16) = ebx; - // pop ebx RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; @@ -1597,7 +1569,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } ebx = *(buffer - 4); eax = ebx & 0x7FFFF; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); + g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); gfx_draw_sprite(dpi, ebx, max_x, max_y); @@ -1621,11 +1593,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in ecx = max_x; max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - // push dword_141E9E8[ebx] - // push ecx - // push edx - // push edi - // push esi eax = (int)al; ebx += 0xF15; @@ -1639,12 +1606,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); - // pop esi - // pop edi - // pop edx - // pop ecx - // pop eax - continue; } } From 504ce150ea2485cc24c2a3da348ed30b8f6b7cf3 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Tue, 27 May 2014 19:58:31 +0200 Subject: [PATCH 147/209] Fix bug in gfx_get_string_width --- src/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 916b1eecf4..456f788442 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1041,6 +1041,7 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) } /** + * Return the width of the string in buffer * * rct2: 0x006C2321 * buffer (esi) @@ -1050,9 +1051,8 @@ int gfx_get_string_width(char *buffer) int base; int width; - char curr_char; + uint8 curr_char; - curr_char = 0; base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; From 55183d05897368315fcbf71ec6004c4c3bb2f097 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Tue, 27 May 2014 20:00:44 +0200 Subject: [PATCH 148/209] draw_string_centred --- src/gfx.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 456f788442..5b45d2b781 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -900,7 +900,18 @@ void gfx_transpose_palette(int pal, unsigned char product) */ void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args) { - RCT2_CALLPROC_X(0x006C1D6C, colour, format, x, y, (int)args, (int)dpi, 0); + char* buffer; + buffer = (char*)0x0141ED68; + format_string(buffer, format, args); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + + int width = gfx_get_string_width(buffer); + + if (width <= 0xFFF) { + x -= width / 2; + gfx_draw_string(dpi, buffer, colour, x, y); + } } /** From 4fdba86b0168696dbc6511d12d0aafa3145e1adb Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:43:38 +0200 Subject: [PATCH 149/209] Add address for common string format buffer --- src/addresses.h | 2 ++ src/gfx.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 912461a9b3..974a9c7507 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -258,6 +258,8 @@ #define RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID 0x0141E9AE #define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0 +#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68 + #define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738 #define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C diff --git a/src/gfx.c b/src/gfx.c index 5b45d2b781..c19b433554 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1188,7 +1188,7 @@ void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int c char* buffer; short text_width; - buffer = (char*)0x0141ED68; + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, format, args); // Measure text width @@ -1267,7 +1267,7 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co { char* buffer; - buffer = (char*)0x0141ED68; + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, format, args); gfx_draw_string(dpi, buffer, colour, x, y); } From 130796052f66d7a68e1675f56f0cffd1860dcb7d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:44:33 +0200 Subject: [PATCH 150/209] More string functions --- src/gfx.c | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c19b433554..e1c3c1bcc9 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -901,15 +901,19 @@ void gfx_transpose_palette(int pal, unsigned char product) void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args) { char* buffer; - buffer = (char*)0x0141ED68; + short text_width; + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, format, args); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - int width = gfx_get_string_width(buffer); + // Measure text width + text_width = gfx_get_string_width(buffer); - if (width <= 0xFFF) { - x -= width / 2; + // Draw the text centred + if (text_width <= 0xFFF) { + x -= text_width / 2; gfx_draw_string(dpi, buffer, colour, x, y); } } @@ -1132,15 +1136,19 @@ int gfx_get_string_width(char *buffer) */ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y, int width) { - RCT2_CALLPROC_X(0x006C1B83, colour, format, x, y, (int)args, (int)dpi, width); + // RCT2_CALLPROC_X(0x006C1B83, colour, format, x, y, (int)args, (int)dpi, width); - //char* buffer; + char* buffer; - //buffer = (char*)0x0141ED68; - //format_string(buffer, format, args); - //rctmem->current_font_sprite_base = 224; - //clip_text(buffer, width); - //gfx_draw_string(dpi, buffer, colour, x, y); + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + format_string(buffer, format, args); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + + // Clip text + RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + + gfx_draw_string(dpi, buffer, colour, x, y); } /** @@ -1157,19 +1165,24 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args */ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width) { - RCT2_CALLPROC_X(0x006C1BBA, colour, format, x, y, (int)args, (int)dpi, width); + char* buffer; + short text_width; - //char* buffer; - //short text_width; + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + format_string(buffer, format, args); - //buffer = (char*)0x0141ED68; - //format_string(buffer, format, args); - //rctmem->current_font_sprite_base = 224; - //text_width = clip_text(buffer, width); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - //// Draw the text centred - //x -= (text_width - 1) / 2; - //gfx_draw_string(dpi, buffer, colour, x, y); + // Clip text + RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + // // Measure text width + // text_width = gfx_get_string_width(buffer); + + // Draw the text centred + if (text_width <= 0xFFF) { + x -= text_width / 2; + gfx_draw_string(dpi, buffer, colour, x, y); + } } From b5d11159b38d9e1153ea39b5270fd2d231ade9a1 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:44:47 +0200 Subject: [PATCH 151/209] Start of clip_text --- src/gfx.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/gfx.c b/src/gfx.c index e1c3c1bcc9..d35357875b 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1122,6 +1122,116 @@ int gfx_get_string_width(char *buffer) return width; } +/** + * Clip the text in buffer to width and return the new width of the clipped string + * + * rct2: 0x006C2460 + * buffer (esi) + * width (edi) + */ +int gfx_clip_string(char *buffer, int width) +{ + uint16 base; + + if (width < 6) { + *buffer = 0; + return 0; + } + + base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + edx = rct2_address(0x141E9F6, uint32)[base]; + + edx = &(edx + edx*2); + // lea edx, [edx+edx*2] + dx = -(edx & 0xFFFF); + dx += width; + eax = 0; + cx = 0; + max_x = 0; + ebp = buffer; + + + // loc_6C2485: ; CODE XREF: clip_text+42j + for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { + + if (al < 0x20) { + switch(curr_char) { + case 1: + width = *buffer; + buffer++; + continue; + case 2: + case 3: + case 4: + buffer++; + continue; + case 7: + base = 0x1C0; + // jmp short loc_6C2523 + break; + case 8: + base = 0x2A0; + // jmp short loc_6C2523 + break; + case 9: + base = 0x0E0; + // jmp short loc_6C2523 + break; + case 0x0A: + base = 0; + // jmp short loc_6C2523 + break; + case 0x17: + curr_char = *buffer; + curr_char &= 0x7FFFF; + buffer += 4; + curr_char <<= 4; + width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; + curr_char = 0; + break; + default: + if (curr_char <= 0x10) { + continue; + } + buffer += 2; + if (curr_char <= 0x16) { + continue; + } + buffer += 2; + break; + } + + + // loc_6C2523: ; CODE XREF: clip_text+AEj + // ; clip_text+B5j ... + // movzx edx, byte_141E9F6[ebx] + // lea edx, [edx+edx*2] + // neg dx + // add dx, di + // jmp loc_6C2485 + + } else { + + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + + // loc_6C249A: ; CODE XREF: clip_text+AAj + if (max_x > width) { + rct2_global(ebp + 0, uint32) = 0x2E2E2E; + max_x = width; + // pop esi + return; + } + if (max_x > dx) { + continue; + // ja short loc_6C2485 + } + ebp = buffer; + continue; + } + } +} + + /** * 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 9fecf42e518e665aaa4289c3e25832be4d01f158 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:52:42 +0200 Subject: [PATCH 152/209] Tidy up loop on pointer --- src/gfx.c | 241 ++++++++++++++++++++++++++---------------------------- 1 file changed, 118 insertions(+), 123 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d35357875b..7c14ab2ec6 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1066,26 +1066,24 @@ int gfx_get_string_width(char *buffer) int base; int width; - uint8 curr_char; - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (curr_char = *buffer; curr_char > 0; buffer++, curr_char = *buffer) { + for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { - if (curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (curr_char-0x20)]; + if (*curr_char >= 0x20) { + width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (*curr_char-0x20)]; continue; } - switch(curr_char) { + switch(*curr_char) { case 1: - width = *buffer; - buffer++; + width = *curr_char; + curr_char++; break; case 2: case 3: case 4: - buffer++; + curr_char++; break; case 7: base = 0x1C0; @@ -1100,22 +1098,19 @@ int gfx_get_string_width(char *buffer) base = 0; break; case 0x17: - curr_char = *buffer; - curr_char &= 0x7FFFF; - buffer += 4; - curr_char <<= 4; - width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; - curr_char = 0; + width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + curr_char += 4; + *curr_char = 0; break; default: - if (curr_char <= 0x10) { + if (*curr_char <= 0x10) { continue; } - buffer += 2; - if (curr_char <= 0x16) { + curr_char += 2; + if (*curr_char <= 0x16) { continue; } - buffer += 2; + curr_char += 2; break; } } @@ -1129,107 +1124,107 @@ int gfx_get_string_width(char *buffer) * buffer (esi) * width (edi) */ -int gfx_clip_string(char *buffer, int width) -{ - uint16 base; +// int gfx_clip_string(char *buffer, int width) +// { +// uint16 base; - if (width < 6) { - *buffer = 0; - return 0; - } +// if (width < 6) { +// *buffer = 0; +// return 0; +// } - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - edx = rct2_address(0x141E9F6, uint32)[base]; +// base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); +// edx = rct2_address(0x141E9F6, uint32)[base]; - edx = &(edx + edx*2); - // lea edx, [edx+edx*2] - dx = -(edx & 0xFFFF); - dx += width; - eax = 0; - cx = 0; - max_x = 0; - ebp = buffer; +// edx = &(edx + edx*2); +// // lea edx, [edx+edx*2] +// dx = -(edx & 0xFFFF); +// dx += width; +// eax = 0; +// cx = 0; +// max_x = 0; +// ebp = buffer; - // loc_6C2485: ; CODE XREF: clip_text+42j - for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { +// // loc_6C2485: ; CODE XREF: clip_text+42j +// for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { - if (al < 0x20) { - switch(curr_char) { - case 1: - width = *buffer; - buffer++; - continue; - case 2: - case 3: - case 4: - buffer++; - continue; - case 7: - base = 0x1C0; - // jmp short loc_6C2523 - break; - case 8: - base = 0x2A0; - // jmp short loc_6C2523 - break; - case 9: - base = 0x0E0; - // jmp short loc_6C2523 - break; - case 0x0A: - base = 0; - // jmp short loc_6C2523 - break; - case 0x17: - curr_char = *buffer; - curr_char &= 0x7FFFF; - buffer += 4; - curr_char <<= 4; - width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; - curr_char = 0; - break; - default: - if (curr_char <= 0x10) { - continue; - } - buffer += 2; - if (curr_char <= 0x16) { - continue; - } - buffer += 2; - break; - } +// if (al < 0x20) { +// switch(curr_char) { +// case 1: +// width = *buffer; +// buffer++; +// continue; +// case 2: +// case 3: +// case 4: +// buffer++; +// continue; +// case 7: +// base = 0x1C0; +// // jmp short loc_6C2523 +// break; +// case 8: +// base = 0x2A0; +// // jmp short loc_6C2523 +// break; +// case 9: +// base = 0x0E0; +// // jmp short loc_6C2523 +// break; +// case 0x0A: +// base = 0; +// // jmp short loc_6C2523 +// break; +// case 0x17: +// curr_char = *buffer; +// curr_char &= 0x7FFFF; +// buffer += 4; +// curr_char <<= 4; +// width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; +// curr_char = 0; +// break; +// default: +// if (curr_char <= 0x10) { +// continue; +// } +// buffer += 2; +// if (curr_char <= 0x16) { +// continue; +// } +// buffer += 2; +// break; +// } - // loc_6C2523: ; CODE XREF: clip_text+AEj - // ; clip_text+B5j ... - // movzx edx, byte_141E9F6[ebx] - // lea edx, [edx+edx*2] - // neg dx - // add dx, di - // jmp loc_6C2485 +// // loc_6C2523: ; CODE XREF: clip_text+AEj +// // ; clip_text+B5j ... +// // movzx edx, byte_141E9F6[ebx] +// // lea edx, [edx+edx*2] +// // neg dx +// // add dx, di +// // jmp loc_6C2485 - } else { +// } else { - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); +// max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - // loc_6C249A: ; CODE XREF: clip_text+AAj - if (max_x > width) { - rct2_global(ebp + 0, uint32) = 0x2E2E2E; - max_x = width; - // pop esi - return; - } - if (max_x > dx) { - continue; - // ja short loc_6C2485 - } - ebp = buffer; - continue; - } - } -} +// // loc_6C249A: ; CODE XREF: clip_text+AAj +// if (max_x > width) { +// rct2_global(ebp + 0, uint32) = 0x2E2E2E; +// max_x = width; +// // pop esi +// return; +// } +// if (max_x > dx) { +// continue; +// // ja short loc_6C2485 +// } +// ebp = buffer; +// continue; +// } +// } +// } /** @@ -1275,24 +1270,24 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args */ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width) { - char* buffer; - short text_width; + // char* buffer; + // short text_width; - buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - format_string(buffer, format, args); + // buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + // format_string(buffer, format, args); - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + // RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - // Clip text - RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); - // // Measure text width - // text_width = gfx_get_string_width(buffer); + // // Clip text + // RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + // // // Measure text width + // // text_width = gfx_get_string_width(buffer); - // Draw the text centred - if (text_width <= 0xFFF) { - x -= text_width / 2; - gfx_draw_string(dpi, buffer, colour, x, y); - } + // // Draw the text centred + // if (text_width <= 0xFFF) { + // x -= text_width / 2; + // gfx_draw_string(dpi, buffer, colour, x, y); + // } } From 9c9ece2d7bd7310917ad21a1f02fbbf8e0abfd15 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 21:21:01 +0200 Subject: [PATCH 153/209] clip text mostly working --- src/gfx.c | 188 +++++++++++++++++++++++------------------------------- 1 file changed, 80 insertions(+), 108 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 7c14ab2ec6..c9b2e5ab1e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1124,107 +1124,81 @@ int gfx_get_string_width(char *buffer) * buffer (esi) * width (edi) */ -// int gfx_clip_string(char *buffer, int width) -// { -// uint16 base; +int gfx_clip_string(char *buffer, int width) +{ + uint16 base; + int edx, ebp; + int max_x; -// if (width < 6) { -// *buffer = 0; -// return 0; -// } + if (width < 6) { + *buffer = 0; + return 0; + } -// base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); -// edx = rct2_address(0x141E9F6, uint32)[base]; + base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); -// edx = &(edx + edx*2); -// // lea edx, [edx+edx*2] -// dx = -(edx & 0xFFFF); -// dx += width; -// eax = 0; -// cx = 0; -// max_x = 0; -// ebp = buffer; + max_x = 0; + ebp = buffer; + for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { + if (*curr_char < 0x20) { + switch(*curr_char) { + case 1: + width = *curr_char; + curr_char++; + continue; + case 2: + case 3: + case 4: + curr_char++; + continue; + case 7: + base = 0x1C0; + break; + case 8: + base = 0x2A0; + break; + case 9: + base = 0x0E0; + break; + case 0x0A: + base = 0; + break; + case 0x17: + max_x = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + curr_char += 4; + *curr_char = 0; + continue; + default: + if (*curr_char <= 0x10) { + continue; + } + curr_char += 2; + if (*curr_char <= 0x16) { + continue; + } + curr_char += 2; + continue; + } -// // loc_6C2485: ; CODE XREF: clip_text+42j -// for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { + edx = RCT2_ADDRESS(0x141E9F6, uint32)[base]; + edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); + } -// if (al < 0x20) { -// switch(curr_char) { -// case 1: -// width = *buffer; -// buffer++; -// continue; -// case 2: -// case 3: -// case 4: -// buffer++; -// continue; -// case 7: -// base = 0x1C0; -// // jmp short loc_6C2523 -// break; -// case 8: -// base = 0x2A0; -// // jmp short loc_6C2523 -// break; -// case 9: -// base = 0x0E0; -// // jmp short loc_6C2523 -// break; -// case 0x0A: -// base = 0; -// // jmp short loc_6C2523 -// break; -// case 0x17: -// curr_char = *buffer; -// curr_char &= 0x7FFFF; -// buffer += 4; -// curr_char <<= 4; -// width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; -// curr_char = 0; -// break; -// default: -// if (curr_char <= 0x10) { -// continue; -// } -// buffer += 2; -// if (curr_char <= 0x16) { -// continue; -// } -// buffer += 2; -// break; -// } + max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[base] & 0xFF); - -// // loc_6C2523: ; CODE XREF: clip_text+AEj -// // ; clip_text+B5j ... -// // movzx edx, byte_141E9F6[ebx] -// // lea edx, [edx+edx*2] -// // neg dx -// // add dx, di -// // jmp loc_6C2485 - -// } else { - -// max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - -// // loc_6C249A: ; CODE XREF: clip_text+AAj -// if (max_x > width) { -// rct2_global(ebp + 0, uint32) = 0x2E2E2E; -// max_x = width; -// // pop esi -// return; -// } -// if (max_x > dx) { -// continue; -// // ja short loc_6C2485 -// } -// ebp = buffer; -// continue; -// } -// } -// } + if (max_x > width) { + RCT2_GLOBAL(ebp + 0, uint32) = 0x2E2E2E; + max_x = width; + return; + } + if (max_x <= edx) { + ebp = curr_char; + } + } + return max_x; +} /** @@ -1270,24 +1244,22 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args */ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width) { - // char* buffer; - // short text_width; + char* buffer; + short text_width; - // buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - // format_string(buffer, format, args); + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + format_string(buffer, format, args); - // RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - // // Clip text - // RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); - // // // Measure text width - // // text_width = gfx_get_string_width(buffer); + // Clip text + text_width = gfx_clip_string(buffer, width); - // // Draw the text centred - // if (text_width <= 0xFFF) { - // x -= text_width / 2; - // gfx_draw_string(dpi, buffer, colour, x, y); - // } + // Draw the text centred + if (text_width <= 0xFFF) { + x -= (text_width - 1) / 2; + gfx_draw_string(dpi, buffer, colour, x, y); + } } From 1dc794b038c2c6c1c5f445cbc05e82f1a6594912 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 23:30:05 +0200 Subject: [PATCH 154/209] Finish clip string --- src/gfx.c | 60 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c9b2e5ab1e..a546ac8231 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1118,30 +1118,35 @@ int gfx_get_string_width(char *buffer) } /** - * Clip the text in buffer to width and return the new width of the clipped string + * Clip the text in buffer to width, add ellipsis and return the new width of the clipped string * * rct2: 0x006C2460 * buffer (esi) * width (edi) */ -int gfx_clip_string(char *buffer, int width) +int gfx_clip_string(char* buffer, int width) { - uint16 base; - int edx, ebp; - int max_x; + // Location of font sprites + uint16 current_font_sprite_base; + // Width the string has to fit into + int max_width; + // Character to change to ellipsis + char* last_char; + // Width of the string, including ellipsis + int clipped_width; if (width < 6) { *buffer = 0; return 0; } - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); + current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); - max_x = 0; - ebp = buffer; + clipped_width = 0; + last_char = buffer; - for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char > 0; curr_char++) { if (*curr_char < 0x20) { switch(*curr_char) { case 1: @@ -1154,19 +1159,19 @@ int gfx_clip_string(char *buffer, int width) curr_char++; continue; case 7: - base = 0x1C0; + current_font_sprite_base = 0x1C0; break; case 8: - base = 0x2A0; + current_font_sprite_base = 0x2A0; break; case 9: - base = 0x0E0; + current_font_sprite_base = 0x0E0; break; case 0x0A: - base = 0; + current_font_sprite_base = 0; break; case 0x17: - max_x = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + clipped_width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; curr_char += 4; *curr_char = 0; continue; @@ -1181,26 +1186,23 @@ int gfx_clip_string(char *buffer, int width) curr_char += 2; continue; } - - edx = RCT2_ADDRESS(0x141E9F6, uint32)[base]; - edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); } - max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[base] & 0xFF); + clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; - if (max_x > width) { - RCT2_GLOBAL(ebp + 0, uint32) = 0x2E2E2E; - max_x = width; - return; + if (clipped_width >= width) { + RCT2_GLOBAL(last_char, uint32) = 0x2E2E2E; + clipped_width = width; + return clipped_width; } - if (max_x <= edx) { - ebp = curr_char; + if (clipped_width <= max_width) { + last_char = curr_char; } } - return max_x; + 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. @@ -1224,8 +1226,8 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - // Clip text - RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + // Clip text - return value is not needed + gfx_clip_string(buffer, width); gfx_draw_string(dpi, buffer, colour, x, y); } From 5b41528e2e726445cadeb4de407a2be74c5967bb Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 23:30:20 +0200 Subject: [PATCH 155/209] Rename variables in get_width to align with clip_string --- src/gfx.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a546ac8231..ce3c8cdac8 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1061,18 +1061,20 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) * rct2: 0x006C2321 * buffer (esi) */ -int gfx_get_string_width(char *buffer) +int gfx_get_string_width(char* buffer) { - int base; + // Current font sprites + uint16 current_font_sprite_base; + // Width of string int width; - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char > 0; curr_char++) { if (*curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (*curr_char-0x20)]; + width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; continue; } switch(*curr_char) { @@ -1086,16 +1088,16 @@ int gfx_get_string_width(char *buffer) curr_char++; break; case 7: - base = 0x1C0; + current_font_sprite_base = 0x1C0; break; case 8: - base = 0x2A0; + current_font_sprite_base = 0x2A0; break; case 9: - base = 0x0E0; + current_font_sprite_base = 0x0E0; break; case 0x0A: - base = 0; + current_font_sprite_base = 0; break; case 0x17: width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; From 583fbaa2a4357419632109cf9b37e38881b60454 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Fri, 30 May 2014 14:10:27 +0200 Subject: [PATCH 156/209] Fix some pointer issues --- src/gfx.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ce3c8cdac8..c2ec96794f 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1064,17 +1064,17 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) int gfx_get_string_width(char* buffer) { // Current font sprites - uint16 current_font_sprite_base; + uint16* current_font_sprite_base; // Width of string int width; - current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (char* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; + width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; continue; } switch(*curr_char) { @@ -1088,16 +1088,16 @@ int gfx_get_string_width(char* buffer) curr_char++; break; case 7: - current_font_sprite_base = 0x1C0; + *current_font_sprite_base = 0x1C0; break; case 8: - current_font_sprite_base = 0x2A0; + *current_font_sprite_base = 0x2A0; break; case 9: - current_font_sprite_base = 0x0E0; + *current_font_sprite_base = 0x0E0; break; case 0x0A: - current_font_sprite_base = 0; + *current_font_sprite_base = 0; break; case 0x17: width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; @@ -1129,7 +1129,7 @@ int gfx_get_string_width(char* buffer) int gfx_clip_string(char* buffer, int width) { // Location of font sprites - uint16 current_font_sprite_base; + uint16* current_font_sprite_base; // Width the string has to fit into int max_width; // Character to change to ellipsis @@ -1142,13 +1142,13 @@ int gfx_clip_string(char* buffer, int width) return 0; } - current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); clipped_width = 0; last_char = buffer; - for (char* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { switch(*curr_char) { case 1: @@ -1161,16 +1161,16 @@ int gfx_clip_string(char* buffer, int width) curr_char++; continue; case 7: - current_font_sprite_base = 0x1C0; + *current_font_sprite_base = 0x1C0; break; case 8: - current_font_sprite_base = 0x2A0; + *current_font_sprite_base = 0x2A0; break; case 9: - current_font_sprite_base = 0x0E0; + *current_font_sprite_base = 0x0E0; break; case 0x0A: - current_font_sprite_base = 0; + *current_font_sprite_base = 0; break; case 0x17: clipped_width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; @@ -1188,10 +1188,10 @@ int gfx_clip_string(char* buffer, int width) curr_char += 2; continue; } - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); } - clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; + clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; if (clipped_width >= width) { RCT2_GLOBAL(last_char, uint32) = 0x2E2E2E; @@ -1424,8 +1424,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF842, uint16) = y; // - uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); - uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + uint16* current_font_flags = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); + uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); // Flag for skipping non-printing characters int skip_char = 0; From a06f6ade8b42bbe491c84c9d5f5e7a53b62692b5 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 31 May 2014 16:39:40 +0200 Subject: [PATCH 157/209] String functions for wrapped text --- src/gfx.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 16 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c2ec96794f..2a80c2e1f5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1307,15 +1307,62 @@ void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int c int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { int eax, ebx, ecx, edx, esi, edi, ebp; + // Location of font sprites + uint16* current_font_sprite_base; + // Location of font flags + uint16 current_font_flags; - eax = colour; - ebx = format; - ecx = x; - edx = y; - esi = (int)args; - edi = (int)dpi; - ebp = width; - RCT2_CALLFUNC_X(0x006C1E53, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + *current_font_sprite_base = 0xE0; + + char* buffer = RCT2_ADDRESS(0x009C383D, char); + + gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y); + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + format_string(buffer, format, args); + + *current_font_sprite_base = 0xE0; + + esi = buffer; + edi = width; + RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + ecx &= 0xFFFF; + edi &= 0xFFFF; + + RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; + + if (ebx > 0xE0) { + RCT2_GLOBAL(0x00F43938, uint16) = 6; + if (ebx != 0x1C0) { + RCT2_GLOBAL(0x00F43938, uint16) = 0x12; + } + } + + if (*buffer == 0x0B) { + RCT2_GLOBAL(0x00F43938, uint16) = RCT2_GLOBAL(0x00F43938, uint16) + 1; + } + + ebx = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + edx = y - ebx; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + do { + int new_width = gfx_get_string_width(buffer); + new_width /= 2; + gfx_draw_string(dpi, buffer, 0xFE, x - new_width, edx); + + buffer += strlen(buffer) + 1; + + edx += RCT2_GLOBAL(0x00F43938, uint16); + eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + ebx -= eax; + + } while (ebx > 0); return (sint16)(edx & 0xFFFF) - y; } @@ -1334,17 +1381,78 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { int eax, ebx, ecx, edx, esi, edi, ebp; + + // eax = colour; + // ebx = format; + // ecx = x; + // edx = y; + // esi = (int)args; + // edi = (int)dpi; + // ebp = width; + // RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + // return (sint16)(edx & 0xFFFF) - y; - eax = colour; - ebx = format; - ecx = x; - edx = y; - esi = (int)args; - edi = (int)dpi; - ebp = width; - RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + // Location of font sprites + uint16* current_font_sprite_base; + // Location of font flags + uint16 current_font_flags; + + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + *current_font_sprite_base = 0xE0; + + char* buffer = RCT2_ADDRESS(0x009C383D, char); + + gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y); + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + format_string(buffer, format, args); + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + *current_font_sprite_base = 0xE0; + + // Add line breaks? Adds \0 rather than \n + // not working for strings with colour code? + esi = buffer; + edi = width; + RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + ecx &= 0xFFFF; + edi &= 0xFFFF; + + // Font height? + RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; + + if (ebx > 0xE0) { + RCT2_GLOBAL(0x00F43938, uint16) = 6; + if (ebx != 0x1C0) { + RCT2_GLOBAL(0x00F43938, uint16) = 0x12; + } + } + + // Number of lines? + ebx = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + esi = buffer; + + edx = y; + + do { + gfx_draw_string(dpi, buffer, 0xFE, x, edx); + + buffer += strlen(buffer) + 1; + + edx += RCT2_GLOBAL(0x00F43938, uint16); + eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2); + ebx -= eax; + + } while (ebx >= 0); return (sint16)(edx & 0xFFFF) - y; + } /** From 8b1c76b1b608fed23139629fa4a164153edd2ea2 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 31 May 2014 16:43:39 +0200 Subject: [PATCH 158/209] Replace pad_0E with zoom_level --- src/gfx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 2a80c2e1f5..8bdd35d596 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -354,7 +354,7 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } else { // 00678B7E 00678C83 - if (dpi->pad_0E < 1) { + if (dpi->zoom_level < 1) { // Location in screen buffer? uint8* pixel = top_ * (dpi->width + dpi->pitch) + left_ + dpi->bits; @@ -372,10 +372,10 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } pixel += length; } - } else if (dpi->pad_0E > 1) { + } else if (dpi->zoom_level > 1) { // 00678C8A 00678D57 right_ = right; - } else if (dpi->pad_0E == 1) { + } else if (dpi->zoom_level == 1) { // 00678C88 00678CEE right = right; } @@ -750,12 +750,12 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx &= 0x7FFFF; ebx <<= 4; ebx += RCT2_ADDRESS_G1_ELEMENTS; - if (dpi->pad_0E >= 1){ - if (dpi->pad_0E == 1){ + if (dpi->zoom_level >= 1){ + if (dpi->zoom_level == 1){ return; //jump into 0x67bd81 } - if (dpi->pad_0E >= 3){ + if (dpi->zoom_level >= 3){ return;//jump into 0x67FAAE } //jump into 0x67DADA From b5575d31eb7c0e59c0ecb2fcf7617c055719a59c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 16:47:30 +0100 Subject: [PATCH 159/209] fix more format string bugs --- src/string_ids.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index 11a5703f12..c67eba118f 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1387,6 +1387,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args) *args += 2; format_string_part(dest, value, args); + (*dest)--; break; case FORMAT_STRING: // Pop argument @@ -1538,7 +1539,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) // args += (format & 0xC00) >> 9; format &= ~0xC00; strcpy(*dest, RCT2_ADDRESS(0x135A8F4 + (format * 32), char)); - *dest = strchr(*dest, 0); + *dest = strchr(*dest, 0) + 1; } else if (format < 0xE000) { // Real name format -= -0xA000; @@ -1546,7 +1547,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) real_names[format % countof(real_names)], real_name_initials[(format >> 10) % countof(real_name_initials)] ); - *dest = strchr(*dest, 0); + *dest = strchr(*dest, 0) + 1; } else { // ? RCT2_CALLPROC_EBPSAFE(RCT2_ADDRESS(0x0095AFB8, uint32)[format]); From 7ae52df001cc0c0e02938d7a01867a60450b770e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 16:57:00 +0100 Subject: [PATCH 160/209] fix format_string currency 2dp --- src/string_ids.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index c67eba118f..c6d5c7e196 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1285,9 +1285,7 @@ void format_currency_2dp(char **dest, int value) *dest = dst; // Two decimal places - digit = value % 10; - value /= 10; - *dst++ = '0' + digit; + *dst++ = '0'; digit = value % 10; value /= 10; *dst++ = '0' + digit; From b701eb82220cc1f947d9948042eee85c44dabe66 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 17:11:26 +0100 Subject: [PATCH 161/209] fix format_string currency --- src/string_ids.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/string_ids.c b/src/string_ids.c index c6d5c7e196..2ce1f8085e 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1233,6 +1233,7 @@ void format_currency(char **dest, int value) *dest = dst; + value /= 10; if (value == 0) { *dst++ = '0'; } else { From f1c8981e7982027b65b09d5d84c9db06ca7924d5 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 1 Jun 2014 09:25:53 +0100 Subject: [PATCH 162/209] Switched to draw_sprite in draw_string function. Added freeing of zoomed image --- src/gfx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 62bc70faf0..6d91090cb7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -948,6 +948,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer); } +/* +* 0x67A46E +*/ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer){ int image_element = 0x7FFFF&image_id; int image_type = (image_id & 0xE0000000) >> 28; @@ -1050,6 +1053,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in if (!(g1_source->flags & 0x02)){ gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); + if (zoomed.offset)free(zoomed.offset); return; } //0x67A60A Not tested @@ -2048,7 +2052,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); + //RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); continue; } From e7688ad51b2b2d4203ce2af32723debbe395309d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 1 Jun 2014 14:35:03 +0200 Subject: [PATCH 163/209] Fix monthyear format bug --- src/string_ids.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/string_ids.c b/src/string_ids.c index 2ce1f8085e..805049777d 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1407,6 +1407,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args) formatString[0] = FORMAT_MONTH; formatString[8] = FORMAT_COMMA16; format_string_part_from_raw(dest, formatString, (char**)&dateArgs2); + (*dest)--; break; case FORMAT_MONTH: // Pop argument @@ -1674,4 +1675,4 @@ void reset_saved_strings() { for (int i = 0; i < 1024; i++) { RCT2_ADDRESS(0x135A8F4, uint8)[i * 32] = 0; } -} \ No newline at end of file +} From 3aa2d4ace9094ef123954eabe0784b5461cb0db1 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 1 Jun 2014 16:23:15 +0100 Subject: [PATCH 164/209] fix #163 --- src/park.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/park.c b/src/park.c index e897bf3eb4..0d45e8a597 100644 --- a/src/park.c +++ b/src/park.c @@ -472,9 +472,8 @@ static rct_peep *park_generate_new_guest() get_random_peep_spawn(&spawn); if (spawn.x != 0xFFFF) { - spawn.z *= 16; spawn.direction ^= 2; - peep = peep_generate(spawn.x, spawn.y, spawn.z); + peep = peep_generate(spawn.x, spawn.y, spawn.z * 16); if (peep != NULL) { peep->var_1E = spawn.direction << 3; From 1629b3fce79cdc410923e49f254a69c1f1923851 Mon Sep 17 00:00:00 2001 From: Duncan Date: Mon, 2 Jun 2014 16:55:02 +0100 Subject: [PATCH 165/209] Fixed possible small palette bug. Added notes on what is happening in draw_string. --- src/gfx.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 6d91090cb7..76865b1ae1 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -63,6 +63,11 @@ uint8 peep_palette[0x100] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; +//Originally 0x9ABE04 +uint8 text_palette[0x8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows); /** @@ -1720,7 +1725,7 @@ void colour_char(int al, uint16* current_font_flags) { if (!(*current_font_flags & 2)) { eax = eax & 0x0FF0000FF; } - // Store current colour? + // Adjust text palette. Store current colour? RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; } @@ -1735,7 +1740,7 @@ void sub_682AC7(int ebp, uint16* current_font_flags) { if (*current_font_flags & 2) { eax |= 0x0A0A00; } - //Store current colour? + //Adjust text palette. Store current colour? RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; eax = 0; @@ -1834,7 +1839,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in eax = eax << 10; eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; } - // Store current colour? ; + // Adjust text palette. Store current colour? ; RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; eax = 0; @@ -1998,13 +2003,14 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in if (!(*current_font_flags & 2)) { ebx = ebx & 0xFF; } + //Adjust the text palette RCT2_GLOBAL(0x09ABE05, uint16) = ebx; ebx = g1_element->offset[0xF7]; RCT2_GLOBAL(0x09ABE07, uint16) = ebx; ebx = g1_element->offset[0xFA]; RCT2_GLOBAL(0x09ABE09, uint16) = ebx; - - RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); + //Set the palette pointer + RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04; if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; } From bf2227437b07745a2b0d97dcbe21898fa353975b Mon Sep 17 00:00:00 2001 From: ZedThree Date: Mon, 2 Jun 2014 19:59:56 +0200 Subject: [PATCH 166/209] String control codes skip wrong number of chars --- src/string_ids.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index 805049777d..081e602b77 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1513,10 +1513,12 @@ void format_string_part_from_raw(char **dest, const char *src, char **args) *(*dest)++ = code; *(*dest)++ = *src++; *(*dest)++ = *src++; - *(*dest)++ = *src++; - *(*dest)++ = *src++; } else { *(*dest)++ = code; + *(*dest)++ = *src++; + *(*dest)++ = *src++; + *(*dest)++ = *src++; + *(*dest)++ = *src++; } } else if (code <= 'z') { *(*dest)++ = code; From 49432dd96f7efedf42fa43987034595b0f01cee6 Mon Sep 17 00:00:00 2001 From: Duncan Date: Tue, 3 Jun 2014 12:57:58 +0100 Subject: [PATCH 167/209] Added a few notes to draw_string. --- src/gfx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 76865b1ae1..441a201120 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1894,8 +1894,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in // Control codes al -= 0x20; switch (al) { - case 0x0E5: - max_x = RCT2_GLOBAL(0x0EDF840, uint16); + case 0x0E5://Start New Line at set y lower + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_y += 0x0A; if (*current_font_sprite_base <= 0x0E) { break; @@ -1906,8 +1906,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } max_y -= 0xFFF4; break; - case 0x0E6: - max_x = RCT2_GLOBAL(0x0EDF840, uint16); + case 0x0E6://Start New Line at set y lower + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_y += 5; if (*current_font_sprite_base <= 0x0E) { break; @@ -1916,20 +1916,20 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in if (*current_font_sprite_base == 0x1C0) { break; } - max_y -= 0xFFFA; + max_y -= 0xFFFA;//This does not look correct probably should be an add break; - case 0x0E1: + case 0x0E1://Start New Line at start+buffer x, same y. (Overwrite?) al = *buffer; buffer++; - max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_x += al; break; - case 0x0F1: + case 0x0F1: //Start new line at specified x,y eax = *((uint16*)buffer); buffer += 2; - max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_x += (eax & 0xFF); - max_y = RCT2_GLOBAL(0x0EDF842, uint16); + max_y = y;//RCT2_GLOBAL(0x0EDF842, uint16); max_y += (eax & 0xFF00) >> 8; break; case 0x0E7: @@ -2023,11 +2023,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } ebx = *(buffer - 4); eax = ebx & 0x7FFFF; - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); + 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->offset; + max_x = max_x + g1_element->width; break; } From 8b233c2f794b8513db76d37e949e57887c391aba Mon Sep 17 00:00:00 2001 From: Duncan Date: Wed, 4 Jun 2014 12:30:53 +0100 Subject: [PATCH 168/209] More gfx_draw_string notes. --- src/gfx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 441a201120..850f5fffff 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1307,13 +1307,15 @@ int gfx_get_string_width(char* buffer) uint16* current_font_sprite_base; // Width of string int width; - + rct_g1_element* g1_element; + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; for (char* 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; } @@ -1340,7 +1342,8 @@ int gfx_get_string_width(char* buffer) *current_font_sprite_base = 0; break; case 0x17: - width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + 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]; curr_char += 4; *curr_char = 0; break; From 55e8fe74ffd1e84d645e5e988e758764b3e69097 Mon Sep 17 00:00:00 2001 From: Duncan Date: Wed, 4 Jun 2014 17:04:33 +0100 Subject: [PATCH 169/209] more small changes --- src/gfx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 850f5fffff..ac7639a1a3 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1343,9 +1343,8 @@ int gfx_get_string_width(char* buffer) break; 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]; + width += g1_element.width; //RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; curr_char += 4; - *curr_char = 0; break; default: if (*curr_char <= 0x10) { @@ -1416,9 +1415,8 @@ int gfx_clip_string(char* buffer, int width) *current_font_sprite_base = 0; break; case 0x17: - clipped_width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; curr_char += 4; - *curr_char = 0; continue; default: if (*curr_char <= 0x10) { From c333e9f0429171a85b7a71146edd2ed647784d0c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 4 Jun 2014 19:47:46 +0100 Subject: [PATCH 170/209] Fix small dereference mistake --- src/gfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index ac7639a1a3..85ac18c4be 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1343,7 +1343,7 @@ int gfx_get_string_width(char* buffer) break; 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]; + width += g1_element->width; //RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; curr_char += 4; break; default: From f6a3c2dd04d4e1a722e923403d6139b2406af40f Mon Sep 17 00:00:00 2001 From: Duncan Date: Thu, 5 Jun 2014 16:49:30 +0100 Subject: [PATCH 171/209] Fix small palette issue. --- src/gfx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 85ac18c4be..d3ec14b9b7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -2006,10 +2006,12 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } //Adjust the text palette RCT2_GLOBAL(0x09ABE05, uint16) = ebx; - ebx = g1_element->offset[0xF7]; - RCT2_GLOBAL(0x09ABE07, uint16) = ebx; - ebx = g1_element->offset[0xFA]; - RCT2_GLOBAL(0x09ABE09, 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)) { From c158d98e5c9316ecab71decc3d2cd3b43f416b17 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 6 Jun 2014 09:54:30 +0100 Subject: [PATCH 172/209] Fixed graphical text glitch. Due to not copying whole dword --- src/gfx.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index d3ec14b9b7..04ad5a64d1 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1721,7 +1721,7 @@ 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 = g1_element->offset[(al & 0xFF) * 4]; + eax = ((uint32*)g1_element->offset)[al & 0xFF]; if (!(*current_font_flags & 2)) { eax = eax & 0x0FF0000FF; @@ -1761,6 +1761,20 @@ 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; + //edx = y; + //esi = (int)buffer; + //edi = (int)dpi; + //ebp = 0; + //RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + //gLastDrawStringX = ecx; + //gLastDrawStringY = edx; + int eax, ebx, ecx, edx, esi, edi, ebp; rct_g1_element* g1_element; From 9f01c5d6bf5b01ead73c0d6323b7eac594450420 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 6 Jun 2014 10:18:39 +0100 Subject: [PATCH 173/209] Fixed small positioning bug in draw_string due to incorrect signness. --- src/gfx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 04ad5a64d1..39688966ba 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1312,7 +1312,7 @@ int gfx_get_string_width(char* buffer) current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { + for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char >= 0x20) { //Maybe global not address?? @@ -1390,7 +1390,7 @@ int gfx_clip_string(char* buffer, int width) clipped_width = 0; last_char = buffer; - for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { + for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { switch(*curr_char) { case 1: @@ -1774,7 +1774,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in //gLastDrawStringX = ecx; //gLastDrawStringY = edx; - + // int eax, ebx, ecx, edx, esi, edi, ebp; rct_g1_element* g1_element; From 490fe70db85061b26da9d065416545903c1a5c05 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 7 Jun 2014 21:34:24 +0100 Subject: [PATCH 174/209] Trying different zoom technique --- src/gfx.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 39688966ba..ed6fca1458 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -747,13 +747,15 @@ rct_g1_element gfx_sprite_zoom_image(rct_g1_element* source, int zoom_level){ * There is still a small bug with this code when it is in the choose park view. */ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){ - uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start]; + int zoom_level = dpi->zoom_level + 1; + + uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start*zoom_level]; //This will now point to the first line uint8* next_source_pointer = source_bits_pointer + offset_to_first_line; uint8* next_dest_pointer = dest_bits_pointer; //For every line in the image - for (; height; height--){ + for (; height; height-=zoom_level){ uint8 last_data_line = 0; //For every data section in the line @@ -773,7 +775,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point next_source_pointer = source_pointer + no_pixels; //Calculates the start point of the image - int x_start = gap_size - source_x_start; + int x_start = gap_size - source_x_start*zoom_level; if (x_start > 0){ //Since the start is positive @@ -786,7 +788,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point source_pointer -= x_start; //The no_pixels will be reduced in this operation no_pixels += x_start; - //If there are no pixels there is nothing to draw this line + //If there are no pixels there is nothing to draw this data section if (no_pixels <= 0) continue; //Reset the start position to zero as we have taken into account all moves x_start = 0; @@ -795,9 +797,9 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point int x_end = x_start + no_pixels; //If the end position is further out than the whole image //end position then we need to shorten the line again - if (x_end > width){ + if (x_end > width/zoom_level){ //Shorten the line - no_pixels -= x_end - width; + no_pixels -= x_end - width/zoom_level; //If there are no pixels there is nothing to draw. if (no_pixels <= 0) continue; } @@ -805,7 +807,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point //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_USE_PALETTE){//In the .exe these are all unraveled loops - for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ + for (; no_pixels > 0; no_pixels-=zoom_level, source_pointer+=zoom_level, dest_pointer++){ uint8 al = *source_pointer; uint8 ah = *dest_pointer; if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested @@ -818,7 +820,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops //Doesnt use source pointer ??? mix with background only? //Not Tested - for (; no_pixels > 0; --no_pixels, source_pointer++, dest_pointer++){ + for (; no_pixels > 0; no_pixels-=zoom_level, source_pointer+=zoom_level, dest_pointer++){ uint8 pixel = *dest_pointer; pixel = palette_pointer[pixel]; *dest_pointer = pixel; @@ -826,7 +828,9 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point } else { - memcpy(dest_pointer, source_pointer, no_pixels); + for (; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){ + *dest_pointer = *source_pointer; + } } } @@ -959,10 +963,12 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer){ int image_element = 0x7FFFF&image_id; int image_type = (image_id & 0xE0000000) >> 28; - - rct_g1_element* g1_source = &((rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS)[image_element]; - rct_g1_element zoomed = gfx_sprite_zoom_image(g1_source, dpi->zoom_level); - if (zoomed.offset != NULL)g1_source = &zoomed; + dpi->zoom_level = 1; + //We add on one so that divides will create the correct number of pixels + int zoom_level = dpi->zoom_level + 1; + rct_g1_element* g1_source = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_element]); + //rct_g1_element zoomed = gfx_sprite_zoom_image(g1_source, dpi->zoom_level); + //if (zoomed.offset != NULL)g1_source = &zoomed; if (dpi->zoom_level >= 1){ //These have not been tested //something to do with zooming if (dpi->zoom_level == 1){ @@ -978,9 +984,9 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in } //This will be the height of the drawn image - int height = g1_source->height; + int height = g1_source->height / zoom_level; //This is the start y coordinate on the destination - int dest_start_y = y - dpi->y + g1_source->y_offset; + int dest_start_y = y - dpi->y + g1_source->y_offset / zoom_level; //This is the start y coordinate on the source int source_start_y = 0; @@ -994,7 +1000,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in return; } //The source image will start a further up the image - source_start_y -= dest_start_y; + source_start_y -= dest_start_y*zoom_level; //The destination start is now reset to 0 dest_start_y = 0; } @@ -1010,11 +1016,11 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in } //This will be the width of the drawn image - int width = g1_source->width; + int width = g1_source->width / zoom_level; //This is the source start x coordinate int source_start_x = 0; //This is the destination start x coordinate - int dest_start_x = x - dpi->x + g1_source->x_offset; + int dest_start_x = x - dpi->x + g1_source->x_offset / zoom_level; if (dest_start_x < 0){ //If the destination is negative reduce the width @@ -1025,7 +1031,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in return; } //The source start will also need to cut off the side - source_start_x -= dest_start_x; + source_start_x -= dest_start_x*zoom_level; //Reset the destination to 0 dest_start_x = 0; } @@ -1048,7 +1054,9 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in if (g1_source->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 + dpi->zoom_level = 1; gfx_rle_sprite_to_buffer(g1_source->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width); + dpi->zoom_level = 0; return; } @@ -1058,7 +1066,6 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in if (!(g1_source->flags & 0x02)){ gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); - if (zoomed.offset)free(zoomed.offset); return; } //0x67A60A Not tested From 100228b887bc30318e31090d8ada05ddb9a25492 Mon Sep 17 00:00:00 2001 From: Jan Horava Date: Sat, 7 Jun 2014 21:14:55 -0700 Subject: [PATCH 175/209] fix comment typo and unclear abbreviation --- src/map.c | 2 +- src/ride.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map.c b/src/map.c index 5f157b1ab7..39fcdbef7d 100644 --- a/src/map.c +++ b/src/map.c @@ -333,7 +333,7 @@ void sub_68B089() /** * Checks if the tile at coordinate at height counts as connected. - * @return 1 if connected, 0 otherwisei + * @return 1 if connected, 0 otherwise */ int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) { diff --git a/src/ride.c b/src/ride.c index c7746e91f9..bbaa1db97f 100644 --- a/src/ride.c +++ b/src/ride.c @@ -199,7 +199,7 @@ void ride_update_favourited_stat() /** * rct2: 0x006B7C59 - * @return 1 if the coordinate is reachable or has no entrance, 0 otw + * @return 1 if the coordinate is reachable or has no entrance, 0 otherwise */ int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx From 940754af8124642c93a6a127828f9a33b36598e2 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sun, 8 Jun 2014 22:00:23 +0100 Subject: [PATCH 176/209] trying to fix zooming problems. --- src/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ed6fca1458..b081a8e861 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -749,7 +749,7 @@ rct_g1_element gfx_sprite_zoom_image(rct_g1_element* source, int zoom_level){ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){ int zoom_level = dpi->zoom_level + 1; - uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start*zoom_level]; + uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start]; //This will now point to the first line uint8* next_source_pointer = source_bits_pointer + offset_to_first_line; uint8* next_dest_pointer = dest_bits_pointer; @@ -775,7 +775,7 @@ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_point next_source_pointer = source_pointer + no_pixels; //Calculates the start point of the image - int x_start = gap_size - source_x_start*zoom_level; + int x_start = gap_size / zoom_level - source_x_start*zoom_level; if (x_start > 0){ //Since the start is positive From 2b9d7af156add687ad2f697daa00f0b87ad36da0 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 9 Jun 2014 23:10:54 +0100 Subject: [PATCH 177/209] Messing with zooming code currently breaks. --- src/gfx.c | 177 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 92 insertions(+), 85 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ed6fca1458..d6f89a2627 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -749,91 +749,97 @@ rct_g1_element gfx_sprite_zoom_image(rct_g1_element* source, int zoom_level){ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){ int zoom_level = dpi->zoom_level + 1; - uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start*zoom_level]; + uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start]; //This will now point to the first line uint8* next_source_pointer = source_bits_pointer + offset_to_first_line; uint8* next_dest_pointer = dest_bits_pointer; + uint8 zoom_skip = 0; //For every line in the image - for (; height; height-=zoom_level){ + for (; height; height--){ + do{ + uint8 last_data_line = 0; + //For every data section in the line + while (!last_data_line){ + uint8* source_pointer = next_source_pointer; + uint8* dest_pointer = next_dest_pointer; - uint8 last_data_line = 0; - //For every data section in the line - while (!last_data_line){ - uint8* source_pointer = next_source_pointer; - uint8* dest_pointer = next_dest_pointer; + int no_pixels = *source_pointer++; + //gap_size is the number of non drawn pixels you require to + //jump over on your destination + uint8 gap_size = *source_pointer++; + //The last bit in no_pixels tells you if you have reached the end of a line + last_data_line = no_pixels & 0x80; + //Clear the last data line bit so we have just the no_pixels + no_pixels &= 0x7f; + //Have our next source pointer point to the next data section + next_source_pointer = source_pointer + no_pixels; - int no_pixels = *source_pointer++; - //gap_size is the number of non drawn pixels you require to - //jump over on your destination - uint8 gap_size = *source_pointer++; - //The last bit in no_pixels tells you if you have reached the end of a line - last_data_line = no_pixels & 0x80; - //Clear the last data line bit so we have just the no_pixels - no_pixels &= 0x7f; - //Have our next source pointer point to the next data section - next_source_pointer = source_pointer + no_pixels; + if (last_data_line && zoom_skip){ + zoom_skip--; + continue; + } + if (last_data_line) zoom_skip = dpi->zoom_level; + //Calculates the start point of the image + int x_start = gap_size - source_x_start; - //Calculates the start point of the image - int x_start = gap_size - source_x_start*zoom_level; + if (x_start > 0){ + //Since the start is positive + //We need to move the drawing surface to the correct position + dest_pointer += x_start; + } + else{ + //If the start is negative we require to remove part of the image. + //This is done by moving the image pointer to the correct position. + source_pointer -= x_start; + //The no_pixels will be reduced in this operation + no_pixels += x_start; + //If there are no pixels there is nothing to draw this data section + if (no_pixels <= 0) continue; + //Reset the start position to zero as we have taken into account all moves + x_start = 0; + } - if (x_start > 0){ - //Since the start is positive - //We need to move the drawing surface to the correct position - dest_pointer += x_start; - } - else{ - //If the start is negative we require to remove part of the image. - //This is done by moving the image pointer to the correct position. - source_pointer -= x_start; - //The no_pixels will be reduced in this operation - no_pixels += x_start; - //If there are no pixels there is nothing to draw this data section - if (no_pixels <= 0) continue; - //Reset the start position to zero as we have taken into account all moves - x_start = 0; - } + int x_end = x_start + no_pixels; + //If the end position is further out than the whole image + //end position then we need to shorten the line again + if (x_end > width){ + //Shorten the line + no_pixels -= x_end - width; + //If there are no pixels there is nothing to draw. + if (no_pixels <= 0) continue; + } - int x_end = x_start + no_pixels; - //If the end position is further out than the whole image - //end position then we need to shorten the line again - if (x_end > width/zoom_level){ - //Shorten the line - no_pixels -= x_end - width/zoom_level; - //If there are no pixels there is nothing to draw. - if (no_pixels <= 0) continue; - } - - //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_USE_PALETTE){//In the .exe these are all unraveled loops - for (; no_pixels > 0; no_pixels-=zoom_level, source_pointer+=zoom_level, dest_pointer++){ - uint8 al = *source_pointer; - uint8 ah = *dest_pointer; - if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested - al = palette_pointer[(al | ((int)ah) << 8) - 0x100]; - else //Adjust colours? - al = palette_pointer[al]; - *dest_pointer = al; + //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_USE_PALETTE){//In the .exe these are all unraveled loops + for (; no_pixels > 0; no_pixels--, source_pointer++, dest_pointer++){ + uint8 al = *source_pointer; + uint8 ah = *dest_pointer; + if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested + al = palette_pointer[(al | ((int)ah) << 8) - 0x100]; + else //Adjust colours? + al = palette_pointer[al]; + *dest_pointer = al; + } + } + else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops + //Doesnt use source pointer ??? mix with background only? + //Not Tested + for (; no_pixels > 0; no_pixels--, source_pointer++, dest_pointer++){ + uint8 pixel = *dest_pointer; + pixel = palette_pointer[pixel]; + *dest_pointer = pixel; + } + } + else + { + for (; no_pixels > 0; no_pixels--, source_pointer++, dest_pointer++){ + *dest_pointer = *source_pointer; + } } } - else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops - //Doesnt use source pointer ??? mix with background only? - //Not Tested - for (; no_pixels > 0; no_pixels-=zoom_level, source_pointer+=zoom_level, dest_pointer++){ - uint8 pixel = *dest_pointer; - pixel = palette_pointer[pixel]; - *dest_pointer = pixel; - } - } - else - { - for (; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){ - *dest_pointer = *source_pointer; - } - } - - } + } while (zoom_skip); //Add a line to the drawing surface pointer next_dest_pointer += (int)dpi->width + (int)dpi->pitch; } @@ -955,6 +961,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer); + dpi->zoom_level = 0; } /* @@ -963,9 +970,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer){ int image_element = 0x7FFFF&image_id; int image_type = (image_id & 0xE0000000) >> 28; - dpi->zoom_level = 1; - //We add on one so that divides will create the correct number of pixels - int zoom_level = dpi->zoom_level + 1; + rct_g1_element* g1_source = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_element]); //rct_g1_element zoomed = gfx_sprite_zoom_image(g1_source, dpi->zoom_level); //if (zoomed.offset != NULL)g1_source = &zoomed; @@ -982,11 +987,14 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in RCT2_CALLPROC_X(0x0067FAAE, 0, (int)g1_source, x, y, 0, (int)dpi, 0); return; } - + //Zoom level testing code. + dpi->zoom_level = 1; + //We add on one so that divides will create the correct number of pixels + int zoom_level = dpi->zoom_level + 1; //This will be the height of the drawn image int height = g1_source->height / zoom_level; //This is the start y coordinate on the destination - int dest_start_y = y - dpi->y + g1_source->y_offset / zoom_level; + int dest_start_y = y - dpi->y + g1_source->y_offset; //This is the start y coordinate on the source int source_start_y = 0; @@ -1000,7 +1008,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in return; } //The source image will start a further up the image - source_start_y -= dest_start_y*zoom_level; + source_start_y -= dest_start_y; //The destination start is now reset to 0 dest_start_y = 0; } @@ -1020,7 +1028,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in //This is the source start x coordinate int source_start_x = 0; //This is the destination start x coordinate - int dest_start_x = x - dpi->x + g1_source->x_offset / zoom_level; + int dest_start_x = x - dpi->x + g1_source->x_offset; if (dest_start_x < 0){ //If the destination is negative reduce the width @@ -1031,7 +1039,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in return; } //The source start will also need to cut off the side - source_start_x -= dest_start_x*zoom_level; + source_start_x -= dest_start_x; //Reset the destination to 0 dest_start_x = 0; } @@ -1054,18 +1062,15 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in if (g1_source->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 - dpi->zoom_level = 1; gfx_rle_sprite_to_buffer(g1_source->offset, dest_pointer, palette_pointer, dpi, image_type, source_start_y, height, source_start_x, width); - dpi->zoom_level = 0; return; } - uint8* source_pointer = g1_source->offset; //Move the pointer to the start point of the source source_pointer += g1_source->width*source_start_y + source_start_x; if (!(g1_source->flags & 0x02)){ - gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); + //gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); return; } //0x67A60A Not tested @@ -2083,6 +2088,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); + //Part of zoom testing code remove when done. + dpi->zoom_level = 0; //RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); continue; From b073c8eaef45aff97d8b12e942494075d2ade666 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 10 Jun 2014 22:20:44 +0100 Subject: [PATCH 178/209] Finished last part of zooming code. Appears to work good. --- src/gfx.c | 321 ++++++++++++++++++++++++------------------------------ 1 file changed, 143 insertions(+), 178 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d6f89a2627..78ddbfb8a0 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -585,6 +585,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri * image. */ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type){ + uint8 zoom_level = dest_dpi->zoom_level + 1; //Requires use of palette? if (image_type & IMAGE_TYPE_USE_PALETTE){ @@ -592,55 +593,40 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui if (unknown_pointer!= NULL){ //Not tested. I can't actually work out when this code runs. unknown_pointer += source_pointer - source_image->offset;// RCT2_GLOBAL(0x9E3CE0, uint32); - for (; height > 0; --height){ - for (int no_pixels = width; no_pixels > 0; --no_pixels){ + for (; height > 0; height -= zoom_level){ + uint8* next_source_pointer = source_pointer + source_image->width*zoom_level; + uint8* next_unknown_pointer = unknown_pointer + source_image->width*zoom_level; + uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch; + + for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, source_pointer+=zoom_level, unknown_pointer+=zoom_level, dest_pointer++){ uint8 pixel = *source_pointer; - source_pointer++; pixel = palette_pointer[pixel]; pixel &= *unknown_pointer; if (pixel){ *dest_pointer = pixel; } - dest_pointer++; - unknown_pointer++; } - source_pointer += source_image->width - width; - dest_pointer += dest_dpi->width + dest_dpi->pitch - width; - unknown_pointer += source_image->width - width; - } - return; - } - - //Quicker? - if (width == 4){ - - for (; height > 0; --height){ - for (int no_pixels = 0; no_pixels < 4; ++no_pixels){ - uint8 pixel = source_pointer[no_pixels]; - pixel = palette_pointer[pixel]; - if (pixel){ - dest_pointer[no_pixels] = pixel; - } - } - dest_pointer += dest_dpi->width + dest_dpi->pitch - width + 4; - source_pointer += source_image->width - width + 4; + source_pointer = next_source_pointer; + dest_pointer = next_dest_pointer; + unknown_pointer = next_unknown_pointer; } return; } //image colour adjusted? - for (; height > 0; --height){ - for (int no_pixels = width; no_pixels > 0; --no_pixels){ + for (; height > 0; height -= zoom_level){ + uint8* next_source_pointer = source_pointer + source_image->width*zoom_level; + uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch; + for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, source_pointer+= zoom_level, dest_pointer++){ uint8 pixel = *source_pointer; - source_pointer++; pixel = palette_pointer[pixel]; if (pixel){ *dest_pointer = pixel; } - dest_pointer++; } - source_pointer += source_image->width - width; - dest_pointer += dest_dpi->width + dest_dpi->pitch - width; + + source_pointer = next_source_pointer; + dest_pointer = next_dest_pointer; } return; } @@ -648,29 +634,37 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui //Mix with background. It only uses source pointer for //telling if it needs to be drawn not for colour. if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//Not tested - for (; height > 0; --height){ - for (int no_pixels = width; no_pixels > 0; --no_pixels){ + for (; height > 0; height -= zoom_level){ + uint8* next_source_pointer = source_pointer + source_image->width*zoom_level; + uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch; + + for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){ uint8 pixel = *source_pointer; - source_pointer++; if (pixel){ pixel = *dest_pointer; pixel = palette_pointer[pixel]; *dest_pointer = pixel; } - dest_pointer++; } - source_pointer += source_image->width - width; - dest_pointer += dest_dpi->width + dest_dpi->pitch - width; + + source_pointer = next_source_pointer; + dest_pointer = next_dest_pointer; } return; } //Basic bitmap no fancy stuff if (!(source_image->flags & G1_FLAG_BMP)){//Not tested - for (; height > 0; --height){ - memcpy(dest_pointer, source_pointer, width); - dest_pointer += dest_dpi->width + dest_dpi->pitch; - source_pointer += source_image->width; + for (; height > 0; height-=zoom_level){ + uint8* next_source_pointer = source_pointer + source_image->width*zoom_level; + uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch; + + for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++, source_pointer += zoom_level){ + *dest_pointer = *source_pointer; + } + + dest_pointer = next_dest_pointer; + source_pointer = next_source_pointer; } return; } @@ -678,68 +672,42 @@ void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, ui if (RCT2_GLOBAL(0x9E3CDC, uint32) != 0){//Not tested. I can't actually work out when this code runs. unknown_pointer += source_pointer - source_image->offset; - for (; height > 0; --height){ - for (int no_pixels = width; no_pixels > 0; --no_pixels){ + for (; height > 0; height -= zoom_level){ + uint8* next_source_pointer = source_pointer + source_image->width*zoom_level; + uint8* next_unknown_pointer = unknown_pointer + source_image->width*zoom_level; + uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch; + + for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++, source_pointer += zoom_level, unknown_pointer += zoom_level){ uint8 pixel = *source_pointer; - source_pointer++; pixel &= *unknown_pointer; if (pixel){ *dest_pointer = pixel; } - dest_pointer++; - unknown_pointer++; } - source_pointer += source_image->width - width; - dest_pointer += dest_dpi->width + dest_dpi->pitch - width; - unknown_pointer += source_image->width - width; + dest_pointer = next_dest_pointer; + source_pointer = next_source_pointer; + unknown_pointer = next_unknown_pointer; } } //Basic bitmap with no draw pixels - for (int no_lines = height; no_lines > 0; --no_lines){ - for (int no_pixels = width; no_pixels > 0; --no_pixels){ + for (; height > 0; height -= zoom_level){ + uint8* next_source_pointer = source_pointer + source_image->width*zoom_level; + uint8* next_dest_pointer = dest_pointer + dest_dpi->width + dest_dpi->pitch; + + for (int no_pixels = width; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++, source_pointer += zoom_level){ uint8 pixel = *source_pointer; - source_pointer++; if (pixel){ *dest_pointer = pixel; } - dest_pointer++; } - source_pointer += source_image->width - width; - dest_pointer += dest_dpi->width + dest_dpi->pitch - width; + dest_pointer = next_dest_pointer; + source_pointer = next_source_pointer; } return; } -rct_g1_element gfx_sprite_zoom_image(rct_g1_element* source, int zoom_level){ - rct_g1_element dest; - uint8* smaller_image; - dest.offset = NULL; - if (zoom_level == 0)return dest; - if (source->flags&G1_FLAG_RLE_COMPRESSION) return dest; - smaller_image = malloc(source->width*source->height); - dest.offset = smaller_image; - uint8* source_pointer = source->offset; - source_pointer += source->y_offset*source->width + source->x_offset; - for (int y = 0; y < source->height; y += zoom_level){ - uint8* next_line = source_pointer + source->width*zoom_level; - for (int x = 0; x < source->width; x += zoom_level){ - *smaller_image = *source_pointer; - source_pointer += zoom_level; - smaller_image++; - } - source_pointer = next_line;//source->width*zoom_level; - } - - dest.x_offset = 0; - dest.y_offset = 0; - dest.width = source->width / zoom_level; - dest.height= source->height/ zoom_level; - dest.flags = source->flags; - return dest; - //remember to free the pointer -} /* * rct2: 0x67AA18 transfers readied images onto buffers * This function copies the sprite data onto the screen @@ -749,102 +717,100 @@ rct_g1_element gfx_sprite_zoom_image(rct_g1_element* source, int zoom_level){ void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width){ int zoom_level = dpi->zoom_level + 1; - uint16 offset_to_first_line = ((uint16*)source_bits_pointer)[source_y_start]; - //This will now point to the first line - uint8* next_source_pointer = source_bits_pointer + offset_to_first_line; + uint8* next_source_pointer; uint8* next_dest_pointer = dest_bits_pointer; - - uint8 zoom_skip = 0; + //For every line in the image - for (; height; height--){ - do{ - uint8 last_data_line = 0; - //For every data section in the line - while (!last_data_line){ - uint8* source_pointer = next_source_pointer; - uint8* dest_pointer = next_dest_pointer; + for (int y = source_y_start; y < (height + source_y_start); y += zoom_level){ - int no_pixels = *source_pointer++; - //gap_size is the number of non drawn pixels you require to - //jump over on your destination - uint8 gap_size = *source_pointer++; - //The last bit in no_pixels tells you if you have reached the end of a line - last_data_line = no_pixels & 0x80; - //Clear the last data line bit so we have just the no_pixels - no_pixels &= 0x7f; - //Have our next source pointer point to the next data section - next_source_pointer = source_pointer + no_pixels; + //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. + next_source_pointer = source_bits_pointer + ((uint16*)source_bits_pointer)[y]; - if (last_data_line && zoom_skip){ - zoom_skip--; - continue; - } - if (last_data_line) zoom_skip = dpi->zoom_level; - //Calculates the start point of the image - int x_start = gap_size - source_x_start; + uint8 last_data_line = 0; - if (x_start > 0){ - //Since the start is positive - //We need to move the drawing surface to the correct position - dest_pointer += x_start; - } - else{ - //If the start is negative we require to remove part of the image. - //This is done by moving the image pointer to the correct position. - source_pointer -= x_start; - //The no_pixels will be reduced in this operation - no_pixels += x_start; - //If there are no pixels there is nothing to draw this data section - if (no_pixels <= 0) continue; - //Reset the start position to zero as we have taken into account all moves - x_start = 0; - } + //For every data section in the line + while (!last_data_line){ + uint8* source_pointer = next_source_pointer; + uint8* dest_pointer = next_dest_pointer; - int x_end = x_start + no_pixels; - //If the end position is further out than the whole image - //end position then we need to shorten the line again - if (x_end > width){ - //Shorten the line - no_pixels -= x_end - width; - //If there are no pixels there is nothing to draw. - if (no_pixels <= 0) continue; - } + int no_pixels = *source_pointer++; + //gap_size is the number of non drawn pixels you require to + //jump over on your destination + uint8 gap_size = *source_pointer++; + //The last bit in no_pixels tells you if you have reached the end of a line + last_data_line = no_pixels & 0x80; + //Clear the last data line bit so we have just the no_pixels + no_pixels &= 0x7f; + //Have our next source pointer point to the next data section + next_source_pointer = source_pointer + no_pixels; - //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_USE_PALETTE){//In the .exe these are all unraveled loops - for (; no_pixels > 0; no_pixels--, source_pointer++, dest_pointer++){ - uint8 al = *source_pointer; - uint8 ah = *dest_pointer; - if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested - al = palette_pointer[(al | ((int)ah) << 8) - 0x100]; - else //Adjust colours? - al = palette_pointer[al]; - *dest_pointer = al; - } - } - else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops - //Doesnt use source pointer ??? mix with background only? - //Not Tested - for (; no_pixels > 0; no_pixels--, source_pointer++, dest_pointer++){ - uint8 pixel = *dest_pointer; - pixel = palette_pointer[pixel]; - *dest_pointer = pixel; - } - } - else - { - for (; no_pixels > 0; no_pixels--, source_pointer++, dest_pointer++){ - *dest_pointer = *source_pointer; - } + //Calculates the start point of the image + int x_start = gap_size - source_x_start; + + if (x_start > 0){ + //Since the start is positive + //We need to move the drawing surface to the correct position + dest_pointer += x_start / zoom_level; + } + else{ + //If the start is negative we require to remove part of the image. + //This is done by moving the image pointer to the correct position. + source_pointer -= x_start; + //The no_pixels will be reduced in this operation + no_pixels += x_start; + //If there are no pixels there is nothing to draw this data section + if (no_pixels <= 0) continue; + //Reset the start position to zero as we have taken into account all moves + x_start = 0; + } + + int x_end = x_start + no_pixels; + //If the end position is further out than the whole image + //end position then we need to shorten the line again + if (x_end > width){ + //Shorten the line + no_pixels -= x_end - width; + //If there are no pixels there is nothing to draw. + if (no_pixels <= 0) continue; + } + + //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_USE_PALETTE){//In the .exe these are all unraveled loops + for (; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){ + uint8 al = *source_pointer; + uint8 ah = *dest_pointer; + if (image_type & IMAGE_TYPE_MIX_BACKGROUND)//Mix with background and image Not Tested + al = palette_pointer[(al | ((int)ah) << 8) - 0x100]; + else //Adjust colours? + al = palette_pointer[al]; + *dest_pointer = al; } } - } while (zoom_skip); + else if (image_type & IMAGE_TYPE_MIX_BACKGROUND){//In the .exe these are all unraveled loops + //Doesnt use source pointer ??? mix with background only? + //Not Tested + for (; no_pixels > 0; no_pixels -= zoom_level, dest_pointer++){ + uint8 pixel = *dest_pointer; + pixel = palette_pointer[pixel]; + *dest_pointer = pixel; + } + } + else + { + for (; no_pixels > 0; no_pixels -= zoom_level, source_pointer += zoom_level, dest_pointer++){ + *dest_pointer = *source_pointer; + } + } + } + //Add a line to the drawing surface pointer next_dest_pointer += (int)dpi->width + (int)dpi->pitch; } } + void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer); /** * @@ -961,7 +927,6 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) } gfx_draw_sprite_palette_set(dpi, image_id, x, y, palette_pointer, unknown_pointer); - dpi->zoom_level = 0; } /* @@ -972,9 +937,9 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in int image_type = (image_id & 0xE0000000) >> 28; rct_g1_element* g1_source = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_element]); - //rct_g1_element zoomed = gfx_sprite_zoom_image(g1_source, dpi->zoom_level); - //if (zoomed.offset != NULL)g1_source = &zoomed; - if (dpi->zoom_level >= 1){ //These have not been tested + + //Zooming code has been integrated into main code. + /*if (dpi->zoom_level >= 1){ //These have not been tested //something to do with zooming if (dpi->zoom_level == 1){ RCT2_CALLPROC_X(0x0067BD81, 0, (int)g1_source, x, y, 0,(int) dpi, 0); @@ -986,9 +951,8 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in } RCT2_CALLPROC_X(0x0067FAAE, 0, (int)g1_source, x, y, 0, (int)dpi, 0); return; - } - //Zoom level testing code. - dpi->zoom_level = 1; + }*/ + //We add on one so that divides will create the correct number of pixels int zoom_level = dpi->zoom_level + 1; //This will be the height of the drawn image @@ -1008,10 +972,11 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in return; } //The source image will start a further up the image - source_start_y -= dest_start_y; + source_start_y -= dest_start_y*zoom_level; //The destination start is now reset to 0 dest_start_y = 0; } + int dest_end_y = dest_start_y + height; @@ -1039,7 +1004,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in return; } //The source start will also need to cut off the side - source_start_x -= dest_start_x; + source_start_x -= dest_start_x*zoom_level; //Reset the destination to 0 dest_start_x = 0; } @@ -1059,6 +1024,9 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in //Move the pointer to the start point of the destination dest_pointer += (dpi->width + dpi->pitch)*dest_start_y + dest_start_x; + height *= zoom_level; + width *= zoom_level; + if (g1_source->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 @@ -1070,7 +1038,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in source_pointer += g1_source->width*source_start_y + source_start_x; if (!(g1_source->flags & 0x02)){ - //gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); + gfx_bmp_sprite_to_buffer(palette_pointer, unknown_pointer, source_pointer, dest_pointer, g1_source, dpi, height, width, image_type); return; } //0x67A60A Not tested @@ -2088,9 +2056,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; gfx_draw_sprite_palette_set(dpi, 0x20000000 | ebx, ecx, edx, RCT2_GLOBAL(0x9ABDA4, uint8*), NULL); - //Part of zoom testing code remove when done. - dpi->zoom_level = 0; - //RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); continue; } From 842cbe5b588bdc0d29c026e4132c3b7c28f16bf7 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 10 Jun 2014 22:47:47 +0100 Subject: [PATCH 179/209] Fix bug #114 --- src/gfx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gfx.c b/src/gfx.c index c1320bc5cb..0aec70adc5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -631,6 +631,7 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co buffer = (char*)0x0141ED68; format_string(buffer, format, args); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; gfx_draw_string(dpi, buffer, colour, x, y); } From 1e23390406ad1c2ab0a657c9d60207088ee40eda Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 1 Jun 2014 11:35:17 +0200 Subject: [PATCH 180/209] First pass of gfx_wrap_string --- src/gfx.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 4 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index cfda0c8e05..968ec01c35 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1426,6 +1426,157 @@ int gfx_clip_string(char* buffer, int width) return clipped_width; } +/** + * Wrap the text in buffer to width + * + * rct2: 0x006C21E2 + * buffer (esi) + * width (edi) + */ +int gfx_wrap_string(char* buffer, int* width) +{ + int eax, ebx, ecx; + + eax = 0; + + uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + + RCT2_GLOBAL(0x00F4392E, uint16) = 0; + + ecx = 0; + + uint16* var_F43930 = RCT2_ADDRESS(0x00F43930, uint16); + *var_F43930 = 0; + + uint32* var_F43928; + + // loc_6C2200: ; CODE XREF: sub_6C21E2+8Fj + if (ecx > *var_F43930) { + *var_F43930 = ecx; + } + ecx = 0; + + var_F43928 = RCT2_ADDRESS(0x00F43928, uint32); + *var_F43928 = 0; + + + // loc_6C221D: ; CODE XREF: sub_6C21E2+6Cj + + for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { + + if (*curr_char == ' ') { + // jnz short loc_6C2239 + *var_F43928 = curr_char; + RCT2_GLOBAL(0x00F4392C, uint16) = ecx; + } + + if (*curr_char != 5) { + if (*curr_char < ' ') { + switch(*curr_char) { + case 1: + case 2: + case 3: + case 4: + curr_char++; + continue; + case 7: + ebx = 0x1C0; + continue; + case 8: + ebx = 0x2A0; + continue; + case 9: + ebx = 0xE0; + continue; + case 0x0A: + ebx = 0; + continue; + case 0x17: + ecx = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + curr_char += 4; + // *curr_char = 0; + break; + default: + if (*curr_char < 0x10) { + continue; + } + curr_char += 2; + if (*curr_char <= 0x16) { + continue; + } + curr_char += 2; + continue; + } + } + + ecx += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; + + // do { + // loc_6C224B: ; CODE XREF: sub_6C21E2+FDj + if (ecx <= *width) { + continue; + } + if (*var_F43928 == 0) { + // jz short loc_6C2273 + // loc_6C2273: ; CODE XREF: sub_6C21E2+75j + curr_char--; + char* old_place = curr_char; + + char swap_char = 0; + char temp; + // Insert NULL at current character + // Aboslutely no guarantee that this won't overrun! + do { + temp = swap_char; + swap_char = *curr_char; + *curr_char = temp; + curr_char++; + } while(swap_char != 0); + + *curr_char = swap_char; + curr_char = old_place; + curr_char++; + RCT2_GLOBAL(0x00F4392E, uint16) += 1; + + if (ecx > *var_F43930) { + *var_F43930 = ecx; + } + ecx = 0; + + var_F43928 = RCT2_ADDRESS(0x00F43928, uint32); + *var_F43928 = 0; + continue; + } + curr_char = *var_F43928; + ecx = RCT2_GLOBAL(0x00F4392C, uint16); + } + + // loc_6C2266: ; CODE XREF: sub_6C21E2+59j + RCT2_GLOBAL(0x00F4392E, uint16) += 1; + *(curr_char - 1) = 0; + +// jmp short loc_6C2200 + // loc_6C2200: ; CODE XREF: sub_6C21E2+8Fj + if (ecx > *var_F43930) { + *var_F43930 = ecx; + } + ecx = 0; + + var_F43928 = RCT2_ADDRESS(0x00F43928, uint32); + *var_F43928 = 0; + continue; + + + } + + *width = RCT2_GLOBAL(0x00F4392E, uint16); + if (ecx <= RCT2_GLOBAL(0x00F43930, uint16)) { + ecx = RCT2_GLOBAL(0x00F4392E, uint16); + } + return ecx; +} + + /** * 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. @@ -1548,7 +1699,8 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i esi = buffer; edi = width; - RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + ecx = gfx_wrap_string(esi, &edi); + // RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); ecx &= 0xFFFF; edi &= 0xFFFF; @@ -1637,7 +1789,8 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int // not working for strings with colour code? esi = buffer; edi = width; - RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + ecx = gfx_wrap_string(esi, &edi); + // RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); ecx &= 0xFFFF; edi &= 0xFFFF; @@ -1657,9 +1810,9 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - esi = buffer; + esi = buffer; - edx = y; + edx = y; do { gfx_draw_string(dpi, buffer, 0xFE, x, edx); From 46965b0575a63f1e90159e08c433178e4ea3ce76 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 1 Jun 2014 14:52:36 +0200 Subject: [PATCH 181/209] Finish wrap_string --- src/gfx.c | 115 ++++++++++++++++++++++-------------------------------- 1 file changed, 47 insertions(+), 68 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 968ec01c35..27292409c1 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1432,44 +1432,38 @@ int gfx_clip_string(char* buffer, int width) * rct2: 0x006C21E2 * buffer (esi) * width (edi) + * line_height? (ebx) */ -int gfx_wrap_string(char* buffer, int* width) +int gfx_wrap_string(char* buffer, int* width, int* ebx) { - int eax, ebx, ecx; - - eax = 0; + unsigned int line_width = 0; + rct_g1_element* g1_element; uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - RCT2_GLOBAL(0x00F4392E, uint16) = 0; + unsigned int num_lines = 0; + // Unused? + unsigned int max_width = 0; - ecx = 0; - - uint16* var_F43930 = RCT2_ADDRESS(0x00F43930, uint16); - *var_F43930 = 0; - - uint32* var_F43928; - - // loc_6C2200: ; CODE XREF: sub_6C21E2+8Fj - if (ecx > *var_F43930) { - *var_F43930 = ecx; + if (line_width > max_width) { + max_width = line_width; } - ecx = 0; + line_width = 0; - var_F43928 = RCT2_ADDRESS(0x00F43928, uint32); - *var_F43928 = 0; + // Pointer to the start of the current word + unsigned char* curr_word = NULL; + // Width of line up to current word + unsigned int curr_width; + for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) { - // loc_6C221D: ; CODE XREF: sub_6C21E2+6Cj - - for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { - + // Remember start of current word and line width up to this word if (*curr_char == ' ') { - // jnz short loc_6C2239 - *var_F43928 = curr_char; - RCT2_GLOBAL(0x00F4392C, uint16) = ecx; + curr_word = curr_char; + curr_width = line_width; } + // 5 is RCT2 new line? if (*curr_char != 5) { if (*curr_char < ' ') { switch(*curr_char) { @@ -1509,21 +1503,16 @@ int gfx_wrap_string(char* buffer, int* width) } } - ecx += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; + line_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; - // do { - // loc_6C224B: ; CODE XREF: sub_6C21E2+FDj - if (ecx <= *width) { + if (line_width <= *width) { continue; } - if (*var_F43928 == 0) { - // jz short loc_6C2273 - // loc_6C2273: ; CODE XREF: sub_6C21E2+75j + if (curr_word == 0) { curr_char--; - char* old_place = curr_char; - - char swap_char = 0; - char temp; + unsigned char* old_char = curr_char; + unsigned char swap_char = 0; + unsigned char temp; // Insert NULL at current character // Aboslutely no guarantee that this won't overrun! do { @@ -1534,46 +1523,36 @@ int gfx_wrap_string(char* buffer, int* width) } while(swap_char != 0); *curr_char = swap_char; - curr_char = old_place; + curr_char = old_char; curr_char++; - RCT2_GLOBAL(0x00F4392E, uint16) += 1; + num_lines += 1; - if (ecx > *var_F43930) { - *var_F43930 = ecx; + if (line_width > max_width) { + max_width = line_width; } - ecx = 0; - - var_F43928 = RCT2_ADDRESS(0x00F43928, uint32); - *var_F43928 = 0; + line_width = 0; + curr_word = 0; continue; } - curr_char = *var_F43928; - ecx = RCT2_GLOBAL(0x00F4392C, uint16); + curr_char = curr_word; + line_width = curr_width; } - // loc_6C2266: ; CODE XREF: sub_6C21E2+59j - RCT2_GLOBAL(0x00F4392E, uint16) += 1; - *(curr_char - 1) = 0; + num_lines += 1; + *curr_char = 0; -// jmp short loc_6C2200 - // loc_6C2200: ; CODE XREF: sub_6C21E2+8Fj - if (ecx > *var_F43930) { - *var_F43930 = ecx; + if (line_width > max_width) { + max_width = line_width; } - ecx = 0; - - var_F43928 = RCT2_ADDRESS(0x00F43928, uint32); - *var_F43928 = 0; - continue; - - + line_width = 0; + curr_word = 0; } - *width = RCT2_GLOBAL(0x00F4392E, uint16); - if (ecx <= RCT2_GLOBAL(0x00F43930, uint16)) { - ecx = RCT2_GLOBAL(0x00F4392E, uint16); + *width = num_lines; + if (line_width <= max_width) { + line_width = max_width; } - return ecx; + return line_width; } @@ -1699,7 +1678,7 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i esi = buffer; edi = width; - ecx = gfx_wrap_string(esi, &edi); + ecx = gfx_wrap_string(esi, &edi, &ebx); // RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); ecx &= 0xFFFF; edi &= 0xFFFF; @@ -1732,10 +1711,10 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i buffer += strlen(buffer) + 1; edx += RCT2_GLOBAL(0x00F43938, uint16); - eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2); ebx -= eax; - } while (ebx > 0); + } while (ebx >= 0); return (sint16)(edx & 0xFFFF) - y; } @@ -1789,7 +1768,7 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int // not working for strings with colour code? esi = buffer; edi = width; - ecx = gfx_wrap_string(esi, &edi); + ecx = gfx_wrap_string(esi, &edi, &ebx); // RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); ecx &= 0xFFFF; edi &= 0xFFFF; From 89b199a6c8a1b9bca3e8b325f8e9251836186b91 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 1 Jun 2014 14:52:59 +0200 Subject: [PATCH 182/209] Tidy up --- src/gfx.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 27292409c1..d761bee744 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1353,11 +1353,11 @@ int gfx_clip_string(char* buffer, int width) // Location of font sprites uint16* current_font_sprite_base; // Width the string has to fit into - int max_width; + unsigned int max_width; // Character to change to ellipsis - char* last_char; + unsigned char* last_char; // Width of the string, including ellipsis - int clipped_width; + unsigned int clipped_width; if (width < 6) { *buffer = 0; @@ -1365,12 +1365,12 @@ int gfx_clip_string(char* buffer, int width) } current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); + max_width = (uint32)width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); clipped_width = 0; last_char = buffer; - for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { + for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { switch(*curr_char) { case 1: @@ -1415,7 +1415,7 @@ int gfx_clip_string(char* buffer, int width) clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; if (clipped_width >= width) { - RCT2_GLOBAL(last_char, uint32) = 0x2E2E2E; + *((uint32*)last_char) = '...'; clipped_width = width; return clipped_width; } @@ -1486,9 +1486,8 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) ebx = 0; continue; case 0x17: - ecx = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + line_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF)]; curr_char += 4; - // *curr_char = 0; break; default: if (*curr_char < 0x10) { @@ -1734,16 +1733,6 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int { int eax, ebx, ecx, edx, esi, edi, ebp; - // eax = colour; - // ebx = format; - // ecx = x; - // edx = y; - // esi = (int)args; - // edi = (int)dpi; - // ebp = width; - // RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - // return (sint16)(edx & 0xFFFF) - y; - // Location of font sprites uint16* current_font_sprite_base; // Location of font flags From fcc5e29b76c516cd2038ddcd1cedf07bc62f4df5 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 1 Jun 2014 19:10:35 +0200 Subject: [PATCH 183/209] Add comments, removed unused vars --- src/gfx.c | 133 ++++++++++++++++++++---------------------------------- 1 file changed, 50 insertions(+), 83 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d761bee744..4a3157dc6f 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1427,28 +1427,27 @@ int gfx_clip_string(char* buffer, int width) } /** - * Wrap the text in buffer to width + * Wrap the text in buffer to width, returns width of longest line. + * + * Inserts NULL where line should break (as \n is used for something else), + * so the number of lines is returned in num_lines. font_height seems to be + * a control character for line height. * * rct2: 0x006C21E2 * buffer (esi) - * width (edi) - * line_height? (ebx) + * width (edi) - in + * num_lines (edi) - out + * font_height (ebx) - out */ -int gfx_wrap_string(char* buffer, int* width, int* ebx) +int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) { unsigned int line_width = 0; + unsigned int max_width = 0; rct_g1_element* g1_element; uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - unsigned int num_lines = 0; - // Unused? - unsigned int max_width = 0; - - if (line_width > max_width) { - max_width = line_width; - } - line_width = 0; + *num_lines = 0; // Pointer to the start of the current word unsigned char* curr_word = NULL; @@ -1474,16 +1473,16 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) curr_char++; continue; case 7: - ebx = 0x1C0; + *font_height = 0x1C0; continue; case 8: - ebx = 0x2A0; + *font_height = 0x2A0; continue; case 9: - ebx = 0xE0; + *font_height = 0xE0; continue; case 0x0A: - ebx = 0; + *font_height = 0; continue; case 0x17: line_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF)]; @@ -1504,7 +1503,7 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) line_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; - if (line_width <= *width) { + if (line_width <= width) { continue; } if (curr_word == 0) { @@ -1524,7 +1523,7 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) *curr_char = swap_char; curr_char = old_char; curr_char++; - num_lines += 1; + *num_lines += 1; if (line_width > max_width) { max_width = line_width; @@ -1537,7 +1536,7 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) line_width = curr_width; } - num_lines += 1; + *num_lines += 1; *curr_char = 0; if (line_width > max_width) { @@ -1547,11 +1546,7 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) curr_word = 0; } - *width = num_lines; - if (line_width <= max_width) { - line_width = max_width; - } - return line_width; + return max_width; } @@ -1569,8 +1564,6 @@ int gfx_wrap_string(char* buffer, int* width, int* ebx) */ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y, int width) { - // RCT2_CALLPROC_X(0x006C1B83, colour, format, x, y, (int)args, (int)dpi, width); - char* buffer; buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); @@ -1616,7 +1609,6 @@ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *a } } - /** * Draws i formatted text string right aligned. * rct2: 0x006C1BFC @@ -1656,17 +1648,17 @@ void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int c */ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { - int eax, ebx, ecx, edx, esi, edi, ebp; + int font_height, line_width, line_y, num_lines; // Location of font sprites uint16* current_font_sprite_base; // Location of font flags uint16 current_font_flags; + char* buffer = RCT2_ADDRESS(0x009C383D, char); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); *current_font_sprite_base = 0xE0; - char* buffer = RCT2_ADDRESS(0x009C383D, char); - gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y); buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); @@ -1675,18 +1667,14 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i *current_font_sprite_base = 0xE0; - esi = buffer; - edi = width; - ecx = gfx_wrap_string(esi, &edi, &ebx); - // RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - ecx &= 0xFFFF; - edi &= 0xFFFF; + // line_width unused here + line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height); RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; - if (ebx > 0xE0) { + if (font_height > 0xE0) { RCT2_GLOBAL(0x00F43938, uint16) = 6; - if (ebx != 0x1C0) { + if (font_height != 0x1C0) { RCT2_GLOBAL(0x00F43938, uint16) = 0x12; } } @@ -1695,27 +1683,22 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i RCT2_GLOBAL(0x00F43938, uint16) = RCT2_GLOBAL(0x00F43938, uint16) + 1; } - ebx = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; - edx = y - ebx; + font_height = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * num_lines; + line_y = y - font_height; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; - buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - do { - int new_width = gfx_get_string_width(buffer); - new_width /= 2; - gfx_draw_string(dpi, buffer, 0xFE, x - new_width, edx); + int half_width = gfx_get_string_width(buffer) / 2; + gfx_draw_string(dpi, buffer, 0xFE, x - half_width, line_y); buffer += strlen(buffer) + 1; - edx += RCT2_GLOBAL(0x00F43938, uint16); - eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2); - ebx -= eax; + line_y += RCT2_GLOBAL(0x00F43938, uint16); + num_lines--; + } while (num_lines >= 0); - } while (ebx >= 0); - - return (sint16)(edx & 0xFFFF) - y; + return (sint16)(line_y & 0xFFFF) - y; } /** @@ -1731,14 +1714,11 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i */ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { - int eax, ebx, ecx, edx, esi, edi, ebp; + // font height might actually be something else + int font_height, line_width, line_y, num_lines; // Location of font sprites - uint16* current_font_sprite_base; - // Location of font flags - uint16 current_font_flags; - - current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); *current_font_sprite_base = 0xE0; char* buffer = RCT2_ADDRESS(0x009C383D, char); @@ -1749,51 +1729,38 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int format_string(buffer, format, args); - buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - *current_font_sprite_base = 0xE0; - // Add line breaks? Adds \0 rather than \n - // not working for strings with colour code? - esi = buffer; - edi = width; - ecx = gfx_wrap_string(esi, &edi, &ebx); - // RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - ecx &= 0xFFFF; - edi &= 0xFFFF; + // Line width unused here + line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height); + num_lines &= 0xFFFF; // Font height? RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; - if (ebx > 0xE0) { + if (font_height > 0xE0) { RCT2_GLOBAL(0x00F43938, uint16) = 6; - if (ebx != 0x1C0) { + if (font_height != 0x1C0) { RCT2_GLOBAL(0x00F43938, uint16) = 0x12; } } - // Number of lines? - ebx = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; - buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - esi = buffer; - - edx = y; + line_y = y; do { - gfx_draw_string(dpi, buffer, 0xFE, x, edx); - + gfx_draw_string(dpi, buffer, 0xFE, x, line_y); buffer += strlen(buffer) + 1; - edx += RCT2_GLOBAL(0x00F43938, uint16); - eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2); - ebx -= eax; + line_y += RCT2_GLOBAL(0x00F43938, uint16); + // Bug if this line is removed?! + font_height -= 1; - } while (ebx >= 0); + num_lines--; + } while (num_lines >= 0); - return (sint16)(edx & 0xFFFF) - y; + return (sint16)(line_y & 0xFFFF) - y; } From 0f0351d34147aa89d2259fcd4f9c3c85d77436cd Mon Sep 17 00:00:00 2001 From: ZedThree Date: Mon, 2 Jun 2014 19:58:40 +0200 Subject: [PATCH 184/209] Byte width bug fixes --- src/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 4a3157dc6f..43e1c3309e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1132,7 +1132,7 @@ void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, i text_width = gfx_get_string_width(buffer); // Draw the text centred - if (text_width <= 0xFFF) { + if (text_width <= 0xFFFF) { x -= text_width / 2; gfx_draw_string(dpi, buffer, colour, x, y); } @@ -1603,7 +1603,7 @@ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *a text_width = gfx_clip_string(buffer, width); // Draw the text centred - if (text_width <= 0xFFF) { + if (text_width <= 0xFFFF) { x -= (text_width - 1) / 2; gfx_draw_string(dpi, buffer, colour, x, y); } From 74f5fbc31a456d58f9adef140420f7a9900c9a11 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Mon, 2 Jun 2014 20:22:00 +0200 Subject: [PATCH 185/209] Bug fix for strings with non-char sprites --- src/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 43e1c3309e..5799cbd7df 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -2102,12 +2102,12 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; case 0x0F7: - buffer += 4; + buffer += 5; if (max_x >= dpi->x + dpi->width) { skip_char = 1; break; } - ebx = *(buffer - 4); + ebx = *((uint32*)(buffer - 4)); eax = ebx & 0x7FFFF; g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); From d2c80229c162c4a9a9718f5f4681668808ff8780 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Wed, 11 Jun 2014 19:37:35 +0200 Subject: [PATCH 186/209] Fixes #171 --- src/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 5799cbd7df..eb028bdbec 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1374,7 +1374,7 @@ int gfx_clip_string(char* buffer, int width) if (*curr_char < 0x20) { switch(*curr_char) { case 1: - width = *curr_char; + clipped_width = *curr_char; curr_char++; continue; case 2: @@ -1414,7 +1414,7 @@ int gfx_clip_string(char* buffer, int width) clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; - if (clipped_width >= width) { + if (clipped_width > width) { *((uint32*)last_char) = '...'; clipped_width = width; return clipped_width; From 121990d68f7c9bacf52ece02176d68aaf55de94d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Wed, 11 Jun 2014 19:41:48 +0200 Subject: [PATCH 187/209] Replace unneeded addresses with variables --- src/gfx.c | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index eb028bdbec..0ce2b204cb 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1448,6 +1448,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); *num_lines = 0; + *font_height = 0; // Pointer to the start of the current word unsigned char* curr_word = NULL; @@ -1648,7 +1649,7 @@ void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int c */ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { - int font_height, line_width, line_y, num_lines; + int font_height, line_height, line_width, line_y, num_lines; // Location of font sprites uint16* current_font_sprite_base; // Location of font flags @@ -1670,35 +1671,33 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i // line_width unused here line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height); - RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; + line_height = 0x0A; if (font_height > 0xE0) { - RCT2_GLOBAL(0x00F43938, uint16) = 6; + line_height = 6; if (font_height != 0x1C0) { - RCT2_GLOBAL(0x00F43938, uint16) = 0x12; + line_height = 0x12; } } if (*buffer == 0x0B) { - RCT2_GLOBAL(0x00F43938, uint16) = RCT2_GLOBAL(0x00F43938, uint16) + 1; + line_height = line_height + 1; } - font_height = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * num_lines; + font_height = (line_height / 2) * num_lines; line_y = y - font_height; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; - do { + for (int line = 0; line <= num_lines; ++line) { int half_width = gfx_get_string_width(buffer) / 2; gfx_draw_string(dpi, buffer, 0xFE, x - half_width, line_y); buffer += strlen(buffer) + 1; + line_y += line_height; + } - line_y += RCT2_GLOBAL(0x00F43938, uint16); - num_lines--; - } while (num_lines >= 0); - - return (sint16)(line_y & 0xFFFF) - y; + return line_y - y; } /** @@ -1715,7 +1714,7 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { // font height might actually be something else - int font_height, line_width, line_y, num_lines; + int font_height, line_height, line_width, line_y, num_lines; // Location of font sprites uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); @@ -1733,15 +1732,13 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int // Line width unused here line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height); - num_lines &= 0xFFFF; - // Font height? - RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; + line_height = 0x0A; if (font_height > 0xE0) { - RCT2_GLOBAL(0x00F43938, uint16) = 6; + line_height = 6; if (font_height != 0x1C0) { - RCT2_GLOBAL(0x00F43938, uint16) = 0x12; + line_height = 0x12; } } @@ -1749,19 +1746,13 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int line_y = y; - do { + for (int line = 0; line <= num_lines; ++line) { gfx_draw_string(dpi, buffer, 0xFE, x, line_y); buffer += strlen(buffer) + 1; + line_y += line_height; + } - line_y += RCT2_GLOBAL(0x00F43938, uint16); - // Bug if this line is removed?! - font_height -= 1; - - num_lines--; - } while (num_lines >= 0); - - return (sint16)(line_y & 0xFFFF) - y; - + return line_y - y; } /** From 6f65ba57144a75f0ccf30b10db6eb8d8189e9583 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 11 Jun 2014 19:08:00 +0100 Subject: [PATCH 188/209] Fix a few bugs to do with the buffer being incremented at start of loop --- src/gfx.c | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index cfda0c8e05..5ee2b7a336 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1342,16 +1342,16 @@ int gfx_get_string_width(char* buffer) } /** - * Clip the text in buffer to width, add ellipsis and return the new width of the clipped string - * - * rct2: 0x006C2460 - * buffer (esi) - * width (edi) - */ +* Clip the text in buffer to width, add ellipsis and return the new width of the clipped string +* +* rct2: 0x006C2460 +* buffer (esi) +* width (edi) +*/ int gfx_clip_string(char* buffer, int width) { // Location of font sprites - uint16* current_font_sprite_base; + uint16 current_font_sprite_base; // Width the string has to fit into int max_width; // Character to change to ellipsis @@ -1363,19 +1363,19 @@ int gfx_clip_string(char* buffer, int width) *buffer = 0; return 0; } - - current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); + + current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); clipped_width = 0; last_char = buffer; for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { - switch(*curr_char) { + switch (*curr_char) { case 1: - width = *curr_char; curr_char++; + clipped_width = *curr_char; continue; case 2: case 3: @@ -1383,36 +1383,37 @@ int gfx_clip_string(char* buffer, int width) curr_char++; continue; case 7: - *current_font_sprite_base = 0x1C0; + current_font_sprite_base = 0x1C0; break; case 8: - *current_font_sprite_base = 0x2A0; + current_font_sprite_base = 0x2A0; break; case 9: - *current_font_sprite_base = 0x0E0; + current_font_sprite_base = 0x0E0; break; case 0x0A: - *current_font_sprite_base = 0; + current_font_sprite_base = 0; break; case 0x17: - clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*(curr_char+1) & 0x7FFFF) << 4]; curr_char += 4; continue; default: if (*curr_char <= 0x10) { continue; } - curr_char += 2; + if (*curr_char <= 0x16) { + curr_char += 2; continue; } - curr_char += 2; + curr_char += 4; continue; } - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); } - clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; + clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char - 0x20)]; if (clipped_width >= width) { RCT2_GLOBAL(last_char, uint32) = 0x2E2E2E; @@ -1420,12 +1421,13 @@ int gfx_clip_string(char* buffer, int width) return clipped_width; } if (clipped_width <= max_width) { - last_char = curr_char; + last_char = curr_char+1; } } 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. @@ -1755,6 +1757,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in //gLastDrawStringX = ecx; //gLastDrawStringY = edx; + //return; // int eax, ebx, ecx, edx, esi, edi, ebp; rct_g1_element* g1_element; @@ -1915,13 +1918,13 @@ 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; + al = *(buffer+1); buffer++; max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_x += al; break; case 0x0F1: //Start new line at specified x,y - eax = *((uint16*)buffer); + eax = *((uint16*)(buffer+1)); buffer += 2; max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_x += (eax & 0xFF); @@ -1983,7 +1986,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in sub_682AC7(ebp, current_font_flags); break; case 0x0E2: - al = *buffer; + al = *(buffer+1); buffer++; if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -2019,7 +2022,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in skip_char = 1; break; } - ebx = *(buffer - 4); + ebx = *(buffer - 3); eax = ebx & 0x7FFFF; g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); From 08b69b636166442a71d2bd5ff8a1258dda98e8f8 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 12 Jun 2014 21:19:13 +0200 Subject: [PATCH 189/209] Bug fix: off-by-one --- src/gfx.c | 55 ++++++++++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 0ce2b204cb..77d2a37ad2 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1351,7 +1351,7 @@ int gfx_get_string_width(char* buffer) int gfx_clip_string(char* buffer, int width) { // Location of font sprites - uint16* current_font_sprite_base; + uint16 current_font_sprite_base; // Width the string has to fit into unsigned int max_width; // Character to change to ellipsis @@ -1363,19 +1363,19 @@ int gfx_clip_string(char* buffer, int width) *buffer = 0; return 0; } - - current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - max_width = (uint32)width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); + + current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); clipped_width = 0; last_char = buffer; for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { - switch(*curr_char) { + switch (*curr_char) { case 1: - clipped_width = *curr_char; curr_char++; + clipped_width = *curr_char; continue; case 2: case 3: @@ -1383,36 +1383,37 @@ int gfx_clip_string(char* buffer, int width) curr_char++; continue; case 7: - *current_font_sprite_base = 0x1C0; + current_font_sprite_base = 0x1C0; break; case 8: - *current_font_sprite_base = 0x2A0; + current_font_sprite_base = 0x2A0; break; case 9: - *current_font_sprite_base = 0x0E0; + current_font_sprite_base = 0x0E0; break; case 0x0A: - *current_font_sprite_base = 0; + current_font_sprite_base = 0; break; case 0x17: - clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*(curr_char+1) & 0x7FFFF) << 4]; curr_char += 4; continue; default: if (*curr_char <= 0x10) { continue; } - curr_char += 2; + if (*curr_char <= 0x16) { + curr_char += 2; continue; } - curr_char += 2; + curr_char += 4; continue; } - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); } - clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; + clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char - 0x20)]; if (clipped_width > width) { *((uint32*)last_char) = '...'; @@ -1420,12 +1421,13 @@ int gfx_clip_string(char* buffer, int width) return clipped_width; } if (clipped_width <= max_width) { - last_char = curr_char; + last_char = curr_char+1; } } return clipped_width; } + /** * Wrap the text in buffer to width, returns width of longest line. * @@ -1821,20 +1823,7 @@ 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; - //edx = y; - //esi = (int)buffer; - //edi = (int)dpi; - //ebp = 0; - //RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - //gLastDrawStringX = ecx; - //gLastDrawStringY = edx; - // int eax, ebx, ecx, edx, esi, edi, ebp; rct_g1_element* g1_element; @@ -1994,13 +1983,13 @@ 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; + al = *(buffer+1); buffer++; max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_x += al; break; case 0x0F1: //Start new line at specified x,y - eax = *((uint16*)buffer); + eax = *((uint16*)(buffer+1)); buffer += 2; max_x = x;//RCT2_GLOBAL(0x0EDF840, uint16); max_x += (eax & 0xFF); @@ -2062,7 +2051,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in sub_682AC7(ebp, current_font_flags); break; case 0x0E2: - al = *buffer; + al = *(buffer+1); buffer++; if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -2098,7 +2087,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in skip_char = 1; break; } - ebx = *((uint32*)(buffer - 4)); + ebx = *(buffer - 3); eax = ebx & 0x7FFFF; g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); From 0e3702f4636be8e5e38824b80748aec33e3c97f9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 12 Jun 2014 21:49:59 +0100 Subject: [PATCH 190/209] 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 191/209] 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 192/209] 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 193/209] 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 194/209] 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 4485e3dd72a29bf64555a0f54cafe960e235d2ec Mon Sep 17 00:00:00 2001 From: Patrick Wijnings Date: Fri, 13 Jun 2014 14:44:40 +0200 Subject: [PATCH 195/209] osinterface: use FAILED macro to check for success of CoInitializeEx / SHGetMalloc. --- src/osinterface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osinterface.c b/src/osinterface.c index 0843f127c5..3741f6bfd2 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -394,14 +394,14 @@ char* osinterface_open_directory_browser(char *title) { LPMALLOC lpMalloc; // Initialize COM - if (CoInitializeEx(0, COINIT_APARTMENTTHREADED) != S_OK) { + if (FAILED(CoInitializeEx(0, COINIT_APARTMENTTHREADED))) { MessageBox(NULL, _T("Error opening browse window"), _T("ERROR"), MB_OK); CoUninitialize(); return 0; } // Get a pointer to the shell memory allocator - if (SHGetMalloc(&lpMalloc) != S_OK) { + if (FAILED(SHGetMalloc(&lpMalloc))) { MessageBox(NULL, _T("Error opening browse window"), _T("ERROR"), MB_OK); CoUninitialize(); return 0; From 2e0f34222cb60d6768fa28d8ca664ffa23b2cbe4 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 15:02:34 +0100 Subject: [PATCH 196/209] 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; } } From 2e7261e9cfd03f5ee1b56a856ef8b8f2dc3b1401 Mon Sep 17 00:00:00 2001 From: anyc Date: Fri, 13 Jun 2014 16:43:52 +0200 Subject: [PATCH 197/209] fix GCC compilation --- src/addresses.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/addresses.h b/src/addresses.h index 974a9c7507..3dcd895af5 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -362,6 +362,7 @@ static void RCT2_CALLPROC_X(int address, int _eax, int _ebx, int _ecx, int _edx, static void RCT2_CALLPROC_X_EBPSAFE(int address, int _eax, int _ebx, int _ecx, int _edx, int _esi, int _edi, int _ebp) { + #ifdef _MSC_VER __asm { push ebp push address @@ -376,6 +377,28 @@ static void RCT2_CALLPROC_X_EBPSAFE(int address, int _eax, int _ebx, int _ecx, i add esp, 4 pop ebp } + #else + __asm__ ( "\ + \n\ + push ebx \n\ + push ebp \n\ + push %[address] \n\ + mov eax, %[_eax] \n\ + mov ebx, %[_ebx] \n\ + mov ecx, %[_ecx] \n\ + mov edx, %[_edx] \n\ + mov esi, %[_esi] \n\ + mov edi, %[_edi] \n\ + mov ebp, %[_ebp] \n\ + call [esp] \n\ + add esp, 4 \n\ + pop ebp \n\ + pop ebx \n\ + " : [address] "+m" (address), [_eax] "+m" (_eax), [_ebx] "+m" (_ebx), [_ecx] "+m" (_ecx), [_edx] "+m" (_edx), [_esi] "+m" (_esi), [_edi] "+m" (_edi), [_ebp] "+m" (_ebp) + : + : "eax","ecx","edx","esi","edi" + ); + #endif } static void RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_edx, int *_esi, int *_edi, int *_ebp) From a91c5532d1c299e25c51479064f78155ec2604e6 Mon Sep 17 00:00:00 2001 From: Jeroen Sack Date: Fri, 13 Jun 2014 22:40:15 +0200 Subject: [PATCH 198/209] Port function widget_scroll_get_part replace 6E9F92 with widget_scroll_get_part --- src/game.c | 28 +++------ src/widget.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++---- src/widget.h | 2 +- src/window.h | 2 +- 4 files changed, 155 insertions(+), 34 deletions(-) diff --git a/src/game.c b/src/game.c index ac83922df2..a5327e18c8 100644 --- a/src/game.c +++ b/src/game.c @@ -562,17 +562,11 @@ static void input_mouseover(int x, int y, rct_window *w, int widgetIndex) input_mouseover_widget_check(windowClass, windowNumber, widgetIndex); - if (w != NULL && widgetIndex != -1 && widget->type == WWT_SCROLL) { - int eax, ebx, ecx, edx, esi, edi, ebp; - eax = x; - ebx = y; - esi = (int)w; - edi = (int)widget; - RCT2_CALLFUNC_X(0x006E9F92, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); // widget_scoll_get_part - eax &= 0xFFFF; - ebx &= 0xFFFF; - ecx &= 0xFFFF; - edx &= 0xFFFF; + if (w != NULL && widgetIndex != -1 && widget->type == WWT_SCROLL) + { + int eax, ebx, ecx, edx; + widget_scroll_get_part(w, widget, x, y, &eax, &ebx, &ecx, &edx); + if (ecx < 0) goto showTooltip; if (ecx == 0) { @@ -764,16 +758,8 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex) RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = x; RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = y; - int eax, ebx, ecx, edx, esi, edi, ebp; - eax = x; - ebx = y; - esi = (int)w; - edi = (int)widget; - RCT2_CALLFUNC_X(0x006E9F92, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); // widget_scoll_get_part - eax &= 0xFFFF; - ebx &= 0xFFFF; - ecx &= 0xFFFF; - edx &= 0xFFFF; + int eax, ebx, ecx, edx; + widget_scroll_get_part(w, widget, x, y, &eax, &ebx, &ecx, &edx); RCT2_GLOBAL(0x009DE548, uint16) = ecx; RCT2_GLOBAL(0x009DE54C, uint32) = edx; diff --git a/src/widget.c b/src/widget.c index 55f4f1006d..28fc3543c0 100644 --- a/src/widget.c +++ b/src/widget.c @@ -958,18 +958,18 @@ int widget_is_pressed(rct_window *w, int widgetIndex) int inputState = RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8); if (w->pressed_widgets & (1LL << widgetIndex)) +return 1; +if (inputState == INPUT_STATE_WIDGET_PRESSED || inputState == INPUT_STATE_DROPDOWN_ACTIVE) { + if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) != w->classification) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) != w->number) + return 0; + if (!(RCT2_GLOBAL(0x009DE518, uint32) & 1)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint32) == widgetIndex) return 1; - if (inputState == INPUT_STATE_WIDGET_PRESSED || inputState == INPUT_STATE_DROPDOWN_ACTIVE) { - if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) != w->classification) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) != w->number) - return 0; - if (!(RCT2_GLOBAL(0x009DE518, uint32) & 1)) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint32) == widgetIndex) - return 1; - } - return 0; +} +return 0; } int widget_is_highlighted(rct_window *w, int widgetIndex) @@ -996,3 +996,138 @@ int widget_is_active_tool(rct_window *w, int widgetIndex) return 1; } + +/*void widget_scroll_get_part(rct_window *w, rct_widget* widget, int x, int y, int *output_x, int *output_y) +{ +int out_x, out_y; +rct_widget* iterator = w->widgets; +int scroll_id = 0; +while (++iterator != widget) +{ +if (iterator->type == WWT_SCROLL) +{ +scroll_id++; +break; +} +} + +if (!(w->scrolls[scroll_id].flags & 1) || x < (w->y + widget->bottom - 11)) +{ +if (!(w->scrolls[scroll_id].flags & 0x10) || y < (w->x + widget->right - 11)) +{ +out_y = y - widget->top - w->y - 1; +out_x = x - widget->left - w->x - 1; +if (out_x >= 0) +{ +if (out_y - 1 >= 0) +{ +out_y += w->scrolls[scroll_id].v_top; +} +} +} +} +return returnCoordinate; +}*/ + +void widget_scroll_get_part(rct_window *w, rct_widget* widget, int x, int y, int *output_x, int *output_y, int *output_scroll_area, int *output_dx) +{ + rct_widget* iterator = w->widgets; + int scroll_id = 0; + while (++iterator != widget) + { + if (iterator->type == WWT_SCROLL) + { + scroll_id++; + break; + } + } + + if ((w->scrolls[scroll_id].flags & 0x01) && y >= (w->y + widget->bottom - 11)) + { + //horizon scrollbar + int rightOffset = 0; + int iteratorLeft = widget->left + w->x; + int iteratorRight = widget->right + w->x; + if (w->scrolls[scroll_id].flags & 0x01) + { + rightOffset = 11; + } + if (x <= (iteratorLeft += 10)) + { + *output_scroll_area = SCROLL_PART_HSCROLLBAR_LEFT; + } + else if (x >= (iteratorRight -= rightOffset)) + { + *output_scroll_area = SCROLL_PART_NONE; + } + else if (x >= (iteratorRight -= 10)) + { + *output_scroll_area = SCROLL_PART_HSCROLLBAR_RIGHT; + } + else if (x < (widget->left + w->x + w->scrolls[scroll_id].h_thumb_left)) + { + *output_scroll_area = SCROLL_PART_HSCROLLBAR_LEFT_TROUGH; + } + else if (x >(widget->left + w->x + w->scrolls[scroll_id].h_thumb_right)) + { + *output_scroll_area = SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH; + } + else + { + *output_scroll_area = SCROLL_PART_HSCROLLBAR_THUMB; + } + } + else if ((w->scrolls[scroll_id].flags & 10) || (x >= w->x + widget->right - 11)) + { + //vertical scrollbar + int bottomOffset = 0; + int iteratorTop = widget->top + w->y; + int iteratorBottom = widget->bottom + w->y; + if (w->scrolls[scroll_id].flags & 0x01) + { + bottomOffset = 11; + } + if (y <= (iteratorTop += 10)) + { + *output_scroll_area = SCROLL_PART_VSCROLLBAR_TOP; + } + else if (y >= (iteratorBottom -= bottomOffset)) + { + *output_scroll_area = SCROLL_PART_NONE; + } + else if (y >= (iteratorBottom -= 10)) + { + *output_scroll_area = SCROLL_PART_VSCROLLBAR_BOTTOM; + } + else if (y < (widget->top + w->y + w->scrolls[scroll_id].v_thumb_top)) + { + *output_scroll_area = SCROLL_PART_VSCROLLBAR_TOP_TROUGH; + } + else if (y > (widget->top + w->y + w->scrolls[scroll_id].v_thumb_bottom)) + { + *output_scroll_area = SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH; + } + else + { + *output_scroll_area = SCROLL_PART_VSCROLLBAR_THUMB; + } + } + else + { + //view + *output_scroll_area = SCROLL_PART_VIEW; + *output_x = x - widget->left; + *output_y = y - widget->top; + *output_x -= w->x; + *output_y -= w->y; + if (--*output_x < 0 || --*output_y < 0) + { + *output_scroll_area = SCROLL_PART_NONE; + } + else + { + *output_x += w->scrolls[scroll_id].h_left; + *output_y += w->scrolls[scroll_id].v_top; + } + } +} diff --git a/src/widget.h b/src/widget.h index 310e0877c9..28019202b9 100644 --- a/src/widget.h +++ b/src/widget.h @@ -62,5 +62,5 @@ int widget_is_disabled(rct_window *w, int widgetIndex); int widget_is_pressed(rct_window *w, int widgetIndex); int widget_is_highlighted(rct_window *w, int widgetIndex); int widget_is_active_tool(rct_window *w, int widgetIndex); - +void widget_scroll_get_part(rct_window *w, rct_widget* widget, int x, int y, int *output_x, int *output_y, int *output_cx, int *output_dx); #endif diff --git a/src/window.h b/src/window.h index b46ff6fe59..ec54076f1b 100644 --- a/src/window.h +++ b/src/window.h @@ -81,7 +81,7 @@ typedef struct { * size: 0x12 */ typedef struct { - uint16 flags; // 0x00 + uint16 flags; // 0x00 (0x10 == vertical scrollbar, 0x01 == horizontal scrollbar) sint16 h_left; // 0x02 sint16 h_right; // 0x04 sint16 h_thumb_left; // 0x06 From aa5209d9f0715a5c800dc66db4f4459673c598d1 Mon Sep 17 00:00:00 2001 From: Jeroen Sack Date: Fri, 13 Jun 2014 22:47:14 +0200 Subject: [PATCH 199/209] Remove commented function Remove a forgotten commented function --- src/widget.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/widget.c b/src/widget.c index 28fc3543c0..ee93708974 100644 --- a/src/widget.c +++ b/src/widget.c @@ -997,38 +997,6 @@ int widget_is_active_tool(rct_window *w, int widgetIndex) return 1; } -/*void widget_scroll_get_part(rct_window *w, rct_widget* widget, int x, int y, int *output_x, int *output_y) -{ -int out_x, out_y; -rct_widget* iterator = w->widgets; -int scroll_id = 0; -while (++iterator != widget) -{ -if (iterator->type == WWT_SCROLL) -{ -scroll_id++; -break; -} -} - -if (!(w->scrolls[scroll_id].flags & 1) || x < (w->y + widget->bottom - 11)) -{ -if (!(w->scrolls[scroll_id].flags & 0x10) || y < (w->x + widget->right - 11)) -{ -out_y = y - widget->top - w->y - 1; -out_x = x - widget->left - w->x - 1; -if (out_x >= 0) -{ -if (out_y - 1 >= 0) -{ -out_y += w->scrolls[scroll_id].v_top; -} -} -} -} -return returnCoordinate; -}*/ - void widget_scroll_get_part(rct_window *w, rct_widget* widget, int x, int y, int *output_x, int *output_y, int *output_scroll_area, int *output_dx) { rct_widget* iterator = w->widgets; From 91cae10a1ffa15dd6d098d1acc9691b60f375b0d Mon Sep 17 00:00:00 2001 From: Jeroen Sack Date: Fri, 13 Jun 2014 22:57:51 +0200 Subject: [PATCH 200/209] Revert indention Don't know what happened here, but was not meant to happen. --- src/widget.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/widget.c b/src/widget.c index ee93708974..f686f1bd26 100644 --- a/src/widget.c +++ b/src/widget.c @@ -958,18 +958,18 @@ int widget_is_pressed(rct_window *w, int widgetIndex) int inputState = RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8); if (w->pressed_widgets & (1LL << widgetIndex)) -return 1; -if (inputState == INPUT_STATE_WIDGET_PRESSED || inputState == INPUT_STATE_DROPDOWN_ACTIVE) { - if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) != w->classification) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) != w->number) - return 0; - if (!(RCT2_GLOBAL(0x009DE518, uint32) & 1)) - return 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint32) == widgetIndex) return 1; -} -return 0; + if (inputState == INPUT_STATE_WIDGET_PRESSED || inputState == INPUT_STATE_DROPDOWN_ACTIVE) { + if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) != w->classification) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) != w->number) + return 0; + if (!(RCT2_GLOBAL(0x009DE518, uint32) & 1)) + return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint32) == widgetIndex) + return 1; + } + return 0; } int widget_is_highlighted(rct_window *w, int widgetIndex) From ba1c414165219978f62c41e2af1e901a5aec36b6 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 12 Jun 2014 21:49:59 +0100 Subject: [PATCH 201/209] Started decompiling character width loading function --- src/gfx.c | 250 ++++++++++++++++++++++++++++++----------------------- src/gfx.h | 1 + src/rct2.c | 3 +- 3 files changed, 146 insertions(+), 108 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 4304589758..2429d6cc39 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 @@ -1960,9 +2000,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) { @@ -1974,7 +2050,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) { @@ -1986,13 +2062,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); @@ -2000,93 +2127,8 @@ 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: - buffer += 5; + case 0x17: + buffer += 4; if (max_x >= dpi->x + dpi->width) { skip_char = 1; break; @@ -2102,33 +2144,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 960307e3bce36bbff07d9bb800696326109e9855 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 13 Jun 2014 00:02:52 +0100 Subject: [PATCH 202/209] 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 2429d6cc39..a0849e2821 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 3741f6bfd2..20d8778e88 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 db2f85557967db5e8c405e2e1b087378b472a6fb Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 12:49:35 +0100 Subject: [PATCH 203/209] 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 a0849e2821..d026b651f5 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 0afec9c3e8209225b3732560cdcffd25dd03e837 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 12:57:05 +0100 Subject: [PATCH 204/209] Cleaned up clip_string and string_width Both functions are very similar. They now have the same bugs fixed. --- src/gfx.c | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d026b651f5..6493308f15 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; } } @@ -1420,7 +1426,9 @@ int gfx_clip_string(char* buffer, int width) // Character to change to ellipsis unsigned char* last_char; // Width of the string, including ellipsis + unsigned int clipped_width; + rct_g1_element g1_element; if (width < 6) { *buffer = 0; @@ -1445,6 +1453,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 +1468,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 +1505,6 @@ int gfx_clip_string(char* buffer, int width) return clipped_width; } - /** * Wrap the text in buffer to width, returns width of longest line. * From a39485fcc6aab6bb2df4417ddf9a9342d49e3d63 Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 13:04:09 +0100 Subject: [PATCH 205/209] 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 cbd97facfd4582e48590162f23a12a557033090d Mon Sep 17 00:00:00 2001 From: Duncan Date: Fri, 13 Jun 2014 15:02:34 +0100 Subject: [PATCH 206/209] Added Char_control_code enum. Refactor of draw string --- src/gfx.c | 434 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 227 insertions(+), 207 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 6493308f15..b0f96e5215 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; } @@ -1444,44 +1477,44 @@ int gfx_clip_string(char* buffer, int width) for (unsigned char* 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; } @@ -1859,8 +1892,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; @@ -1901,10 +1934,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) { - //gLastDrawStringX = ecx; - //gLastDrawStringY = edx; - //return; - // int eax, ebx, ecx, edx, esi, edi, ebp; rct_g1_element* g1_element; @@ -2021,190 +2050,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; } } From 331159c9e68df94d3d2d462695b7865f28033e9e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 14 Jun 2014 09:01:59 +0100 Subject: [PATCH 207/209] Wrap string refactored to match other width functions. Error clean up. --- src/gfx.c | 59 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index b0f96e5215..2c1118324a 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -150,9 +150,6 @@ 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 (uint8 c = 0; c < 0xE0; c++, char_width_pointer++){ @@ -172,7 +169,7 @@ void gfx_load_character_widths(){ uint8 drawing_surface[0x40]; rct_drawpixelinfo dpi = { - .bits = &drawing_surface, + .bits = (char*)&drawing_surface, .width = 8, .height = 8, .x = 0, @@ -180,9 +177,9 @@ void gfx_load_character_widths(){ .pitch = 0, .zoom_level = 0}; - + for (int i = 0; i < 0xE0; ++i){ - memset(drawing_surface, 0, size_of(drawing_surface)); + memset(drawing_surface, 0, sizeof(drawing_surface)); gfx_draw_sprite(&dpi, i + 0x10D5, -1, 0); for (int x = 0; x < 8; ++x){ @@ -1388,7 +1385,7 @@ int gfx_get_string_width(char* buffer) current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (uint8* curr_char = buffer; *curr_char != NULL; curr_char++) { + for (uint8* curr_char = (uint8*)buffer; *curr_char != (uint8)NULL; curr_char++) { if (*curr_char >= 0x20) { width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; @@ -1474,7 +1471,7 @@ int gfx_clip_string(char* buffer, int width) clipped_width = 0; last_char = buffer; - for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) { + for (unsigned char* curr_char = buffer; *curr_char != (uint8)NULL; curr_char++) { if (*curr_char < 0x20) { switch (*curr_char) { case CHAR_CONTROL_CODE_MOVE_X: @@ -1526,7 +1523,7 @@ int gfx_clip_string(char* buffer, int width) clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char - 0x20)]; - if (clipped_width > width) { + if ((int)clipped_width > width) { *((uint32*)last_char) = '...'; clipped_width = width; return clipped_width; @@ -1555,7 +1552,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) { unsigned int line_width = 0; unsigned int max_width = 0; - rct_g1_element* g1_element; + rct_g1_element g1_element; uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); @@ -1567,7 +1564,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) // Width of line up to current word unsigned int curr_width; - for (unsigned char* curr_char = buffer; *curr_char != NULL; curr_char++) { + for (unsigned char* curr_char = buffer; *curr_char != (uint8)NULL; curr_char++) { // Remember start of current word and line width up to this word if (*curr_char == ' ') { @@ -1579,44 +1576,52 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) if (*curr_char != 5) { if (*curr_char < ' ') { switch(*curr_char) { - case 1: - case 2: + case CHAR_CONTROL_CODE_MOVE_X: + case CHAR_CONTROL_CODE_ADJUST_PALETTE_1: case 3: case 4: curr_char++; continue; - case 7: + case CHAR_CONTROL_CODE_NEW_LINE_FIXED: + case CHAR_CONTROL_CODE_NEW_LINE_FIXED_SMALLER: + continue; + case CHAR_CONTROL_CODE_FONT_2: *font_height = 0x1C0; continue; - case 8: + case CHAR_CONTROL_CODE_FONT_3: *font_height = 0x2A0; continue; - case 9: + case CHAR_CONTROL_CODE_FONT_1: *font_height = 0xE0; continue; - case 0x0A: + case CHAR_CONTROL_CODE_FONT_0: *font_height = 0; continue; - case 0x17: - line_width += RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF)]; + 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 CHAR_CONTROL_CODE_SPRITE: + g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char + 1)) & 0x7FFFF]; + line_width += g1_element.width; curr_char += 4; break; default: - if (*curr_char < 0x10) { - continue; - } - curr_char += 2; if (*curr_char <= 0x16) { + curr_char += 2; continue; } - curr_char += 2; + curr_char += 4; continue; } } line_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; - if (line_width <= width) { + if ((int)line_width <= width) { continue; } if (curr_word == 0) { @@ -1764,8 +1769,6 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i int font_height, line_height, line_width, line_y, num_lines; // Location of font sprites uint16* current_font_sprite_base; - // Location of font flags - uint16 current_font_flags; char* buffer = RCT2_ADDRESS(0x009C383D, char); @@ -1934,7 +1937,7 @@ 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; + int eax, ebx, ecx, ebp; rct_g1_element* g1_element; // Maximum length/height of string From b0475b3f15979880a7eb5e455102d17074a27d1b Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 14 Jun 2014 09:46:04 +0100 Subject: [PATCH 208/209] Labeled global vars, removed obselete comments and changed to local text_palette. --- src/addresses.h | 2 ++ src/gfx.c | 58 +++++++++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 3dcd895af5..abfdb3ec22 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -258,6 +258,8 @@ #define RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID 0x0141E9AE #define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0 +#define RCT2_ADDRESS_FONT_CHAR_WIDTH 0x0141E9E8 + #define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68 #define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738 diff --git a/src/gfx.c b/src/gfx.c index c12fe75369..74a38d433d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -151,7 +151,7 @@ int gfx_load_g1() */ void gfx_load_character_widths(){ - uint8* char_width_pointer = RCT2_ADDRESS(0x141E9E8, uint8); + uint8* char_width_pointer = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8); 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]; @@ -170,7 +170,6 @@ void gfx_load_character_widths(){ uint8 drawing_surface[0x40]; rct_drawpixelinfo dpi = { - .bits = (char*)&drawing_surface, .width = 8, .height = 8, @@ -1390,7 +1389,7 @@ int gfx_get_string_width(char* buffer) for (uint8* curr_char = (uint8*)buffer; *curr_char != (uint8)NULL; curr_char++) { if (*curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; + width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*current_font_sprite_base + (*curr_char - 0x20)]; continue; } switch(*curr_char) { @@ -1524,7 +1523,7 @@ int gfx_clip_string(char* buffer, int width) max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); } - clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char - 0x20)]; + clipped_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[current_font_sprite_base + (*curr_char - 0x20)]; if ((int)clipped_width > width) { *((uint32*)last_char) = '...'; @@ -1623,7 +1622,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) } } - line_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; + line_width += RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[*current_font_sprite_base + (*curr_char - 0x20)]; if ((int)line_width <= width) { continue; @@ -1906,8 +1905,11 @@ void colour_char(int al, uint16* current_font_flags) { eax = eax & 0x0FF0000FF; } // Adjust text palette. Store current colour? - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + text_palette[1] = eax & 0xFF; + text_palette[2] = (eax>>8) & 0xFF; + text_palette[3] = (eax >> 16) & 0xFF; + text_palette[4] = (eax >> 24) & 0xFF; + RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)text_palette; } @@ -1915,16 +1917,16 @@ void sub_682AC7(int ebp, uint16* current_font_flags) { int eax; - // loc_682AC7 eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; if (*current_font_flags & 2) { eax |= 0x0A0A00; } //Adjust text palette. Store current colour? - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - eax = 0; - // jmp loc_682842 + text_palette[1] = eax & 0xFF; + text_palette[2] = (eax >> 8) & 0xFF; + text_palette[3] = (eax >> 16) & 0xFF; + text_palette[4] = (eax >> 24) & 0xFF; + RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)text_palette; } @@ -1948,10 +1950,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in int max_x = x; int max_y = y; - // Store original x, y - RCT2_GLOBAL(0x00EDF840, uint16) = x; - RCT2_GLOBAL(0x00EDF842, uint16) = y; - // uint16* current_font_flags = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); @@ -2021,8 +2019,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; } // Adjust text palette. Store current colour? ; - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + text_palette[1] = eax & 0xFF; + text_palette[2] = (eax >> 8) & 0xFF; + text_palette[3] = (eax >> 16) & 0xFF; + text_palette[4] = (eax >> 24) & 0xFF; + RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)text_palette; eax = 0; } } @@ -2062,7 +2063,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in 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 = x; max_x += al; break; case CHAR_CONTROL_CODE_ADJUST_PALETTE_1: @@ -2083,17 +2084,18 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } //Adjust the text palette - memcpy((uint8*)0x09ABE07, &(g1_element->offset[0xF7]), 2); - memcpy((uint8*)0x09ABE09, &(g1_element->offset[0xFA]), 2); + memcpy(&(text_palette[3]), &(g1_element->offset[0xF7]), 2); + memcpy(&(text_palette[5]), &(g1_element->offset[0xFA]), 2); //Set the palette pointer - RCT2_GLOBAL(0x09ABDA4, uint32) = 0x09ABE04; + RCT2_GLOBAL(0x009ABDA4, uint32) = (uint32)text_palette; + 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_x = x; max_y += 0x0A; if (*current_font_sprite_base <= 0x0E) { break; @@ -2105,7 +2107,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in 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_x = x; max_y += 5; if (*current_font_sprite_base <= 0x0E) { break; @@ -2176,9 +2178,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in 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 = x; max_x += (eax & 0xFF); - max_y = y;//RCT2_GLOBAL(0x0EDF842, uint16); + max_y = y; max_y += (eax & 0xFF00) >> 8; break; case CHAR_CONTROL_CODE_SPRITE: @@ -2218,13 +2220,13 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in if (max_x + 0x1A < dpi->x) { ebx = al-0x20; ebx += *current_font_sprite_base; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + max_x = max_x + (RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[ebx] & 0xFF); continue; } ebx = al-0x20 + *current_font_sprite_base; ecx = max_x; - max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + max_x += (RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[ebx] & 0xFF); ebx += 0xF15; RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; From 80cdcb6fbf3a867abf25bf11137e52c4ab9f2a21 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 14 Jun 2014 10:19:42 +0100 Subject: [PATCH 209/209] Added text info to cheat tab --- src/window_cheats.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/window_cheats.c b/src/window_cheats.c index 84301284fa..c493268c3e 100644 --- a/src/window_cheats.c +++ b/src/window_cheats.c @@ -58,7 +58,7 @@ static rct_widget window_cheats_money_widgets[] = { { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535}, // tab content panel { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462}, // tab 1 { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462}, // tab 2 - { WWT_CLOSEBOX, 1, 4, 74, 47, 63, STR_VERY_HIGH, STR_VERY_HIGH}, // high money + { WWT_CLOSEBOX, 1, 4, 74, 67, 83, STR_VERY_HIGH, STR_VERY_HIGH}, // high money { WIDGETS_END }, }; @@ -69,7 +69,7 @@ static rct_widget window_cheats_guests_widgets[] = { { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 - { WWT_CLOSEBOX, 1, 4, 74, 47, 63, STR_EXTREME, STR_EXTREME}, // happy guests + { WWT_CLOSEBOX, 1, 4, 74, 77, 93, STR_EXTREME, STR_EXTREME}, // happy guests { WIDGETS_END }, }; @@ -317,6 +317,26 @@ static void window_cheats_paint() window_draw_widgets(w, dpi); window_cheats_draw_tab_images(dpi, w); + + if (w->page == WINDOW_CHEATS_PAGE_MONEY){ + char buffer[256]; + // Format text (name and version) + sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Increases your money by 1,000."); + // Draw shadow + gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 50); + } + else if (w->page == WINDOW_CHEATS_PAGE_GUESTS){ + char buffer[256]; + // Format text (name and version) + sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "Increases every peeps happiness "); + // Draw shadow + gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 50); + // Format text (name and version) + sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, "to max."); + // Draw shadow + gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 60); + } + } static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) @@ -328,7 +348,7 @@ static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) sprite_idx = 5261; if (w->page == WINDOW_CHEATS_PAGE_MONEY) sprite_idx += (w->var_48E / 2) % 8; - gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_1].left, w->y + w->widgets[WIDX_TAB_1].top); + gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_1].left, w->y + w->widgets[WIDX_TAB_1].top); } // Guests tab