diff --git a/src/addresses.h b/src/addresses.h index 18f012969f..82d7bce548 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -285,6 +285,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 022b35e1a2..8f663827f5 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; @@ -144,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); } +#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){ + + 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) - dpi->y; + RCT2_GLOBAL(0xEDF808, uint32) = 0; + 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; + if (RCT2_GLOBAL(RCT2_Y_RELATED_GLOBAL_2, sint16) <= 0)return; + RCT2_GLOBAL(0xEDF808, sint16) -= translated_y; + translated_y = 0; + } + else{ + bits_pointer += (dpi->width + dpi->pitch)*translated_y; + } + + 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(RCT2_X_RELATED_GLOBAL_1, uint16) - dpi->x; + + 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{ + 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; + } + + 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); +} + /** * * rct2: 0x0067A28E @@ -153,7 +217,175 @@ 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) = image_id & 0xE0000000; + eax &= 0x7; + 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; + 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; + + 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;*/ + return; + } else if ((image_id & (1 << 31))){ + return; + //jump into 0x67a361 + } else if ((image_id & (1 << 30))){ + return; + //jump into 0x67a445 + } + + ebx &= 0x7FFFF; + ebx <<= 4; + ebx += RCT2_ADDRESS_G1_ELEMENTS; + if (dpi->pad_0E >= 1){ + if (dpi->pad_0E == 1){ + return; + //jump into 0x67bd81 + } + if (dpi->pad_0E >= 3){ + return;//jump into 0x67FAAE + } + //jump into 0x67DADA + return; + } + eax = *((uint32*)ebx + 2); + ebp = *((uint32*)ebx + 3); + 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 + 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; + 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){ + return; + } + 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 { + eax = (dpi->width + dpi->pitch) * translated_y; + bits_pointer += eax; + } + + 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(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, 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; + } + + translated_x -= RCT2_GLOBAL(0x9ABDAE, sint16); + esi -= translated_x; + RCT2_GLOBAL(0x9E3CE0, sint32) -= translated_x; + RCT2_GLOBAL(0x9ABDB0, sint16) -= translated_x; + translated_x = 0; + } + + 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(0x9ABDAE, sint16) += translated_x; + RCT2_GLOBAL(0x9ABDB0, sint16) += translated_x; + } + + if (!(RCT2_GLOBAL(0x9E3D14, uint16) & 0x02)){ + 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); + 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; + + } /** @@ -168,7 +400,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; @@ -180,8 +412,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/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; diff --git a/src/osinterface.c b/src/osinterface.c index 760f73bf63..7e070518d0 100644 --- a/src/osinterface.c +++ b/src/osinterface.c @@ -40,7 +40,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; @@ -152,7 +152,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 a42da3c6d3..9c6211ec73 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); void osinterface_show_messagebox(char* message);