diff --git a/src/addresses.h b/src/addresses.h index 9f9943aaee..027d61ab19 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -69,6 +69,8 @@ #define RCT2_ADDRESS_PLACE_OBJECT_MODIFIER 0x009DEA70 #define RCT2_ADDRESS_ON_TUTORIAL 0x009DEA71 +#define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28 + #define RCT2_ADDRESS_SPRITE_LIST 0x010E63BC #define RCT2_ADDRESS_SPRITES_NEXT_INDEX 0x013573BC #define RCT2_ADDRESS_SPRITES_START_VEHICLE 0x013573BE @@ -113,23 +115,47 @@ static void RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_ __asm { push ebp push address + + // Set register to variable address, then set register to variable value mov eax, [_eax] + mov eax, [eax] mov ebx, [_ebx] + mov ebx, [ebx] mov ecx, [_ecx] + mov ecx, [ecx] mov edx, [_edx] + mov edx, [edx] mov esi, [_esi] + mov esi, [esi] mov edi, [_edi] + mov edi, [edi] mov ebp, [_ebp] + mov ebp, [ebp] + + // Call func address call[esp] add esp, 4 pop ebp + // mov[_ebp], ebp - mov[_edi], edi - mov[_esi], esi - mov[_edx], edx - mov[_ecx], ecx - mov[_ebx], ebx - mov [_eax], eax + + // Get resulting ebx, ecx, edx, esi, edi registers + push eax + mov eax, [_edi] + mov [eax], edi + mov eax, [_esi] + mov [eax], esi + mov eax, [_edx] + mov [eax], edx + mov eax, [_ecx] + mov [eax], ecx + mov eax, [_ebx] + mov [eax], ebx + pop eax + + // Get resulting eax register + mov ebx, [_eax] + mov [ebx], eax } } diff --git a/src/gfx.c b/src/gfx.c index f4dd3bd29b..7b46886f0d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -18,10 +18,52 @@ * along with this program. If not, see . *****************************************************************************/ +#include +#include +#include #include "addresses.h" #include "gfx.h" #include "rct2.h" +/** + * + * rct2: 0x00678998 + */ +void gfx_load_g1() +{ + HANDLE hFile; + DWORD bytesRead; + DWORD header[2]; + + int i; + int g1BufferSize; + void* g1Buffer; + + rct_g1_element *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); + + hFile = CreateFile(get_file_path(PATH_ID_G1), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) { + ReadFile(hFile, header, 8, &bytesRead, NULL); + if (bytesRead == 8) { + g1BufferSize = header[1]; + g1Buffer = rct2_malloc(g1BufferSize); + ReadFile(hFile, g1Elements, 29294 * sizeof(rct_g1_element), &bytesRead, NULL); + ReadFile(hFile, g1Buffer, g1BufferSize, &bytesRead, NULL); + CloseHandle(hFile); + + for (i = 0; i < 29294; i++) + g1Elements[i].offset += (int)g1Buffer; + + return; + } + } + + // exit with error + fprintf(stderr, "Unable to load g1.dat"); + assert(0); +} + /** * Clears the screen with the specified colour. * rct2: 0x00678A9F diff --git a/src/gfx.h b/src/gfx.h index 8be5912171..6a66a863f4 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -21,6 +21,9 @@ #ifndef _GFX_H_ #define _GFX_H_ +#include "rct2.h" + +// Size: 0x10 typedef struct { char* bits; // 0x00 short x; // 0x04 @@ -32,6 +35,19 @@ typedef struct { char var_0F; // 0x0F } rct_drawpixelinfo; +// Size: 0x10 +typedef struct { + uint8* offset; // 0x00 + sint16 width; // 0x04 + sint16 height; // 0x06 + sint16 x_offset; // 0x08 + sint16 y_offset; // 0x0A + uint16 flags; // 0x0C + sint16 unused; // 0x0E +} rct_g1_element; + +void gfx_load_g1(); + void gfx_clear(rct_drawpixelinfo *dpi, int colour); void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour); void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y); diff --git a/src/rct2.c b/src/rct2.c index d2b3376122..f9d73e053a 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -100,7 +100,7 @@ void rct2_init() RCT2_CALLPROC_EBPSAFE(0x006A8B40); // object_load_list() RCT2_CALLPROC_EBPSAFE(0x006775A8); // scenario_load_list() RCT2_CALLPROC_X(0x006CED50, 0, 0, 0, 253, 0, 0, 0); // track_load_list(253) - RCT2_CALLPROC_EBPSAFE(0x00678998); // gfx_load_g1() + gfx_load_g1(); RCT2_CALLPROC_EBPSAFE(0x006C19AC); osinterface_init(); RCT2_CALLPROC_EBPSAFE(0x006BA8E0); // init_audio(); @@ -205,4 +205,26 @@ void rct2_update_2() title_update(); else game_update(); +} + +/** + * + * rct2: 0x00674E6C + */ +char *get_file_path(int pathId) +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + + ebx = pathId; + RCT2_CALLFUNC_X(0x00674E6C, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + return ebx; +} + +/** + * + * rct2: 0x004068B2 + */ +void *rct2_malloc(size_t numBytes) +{ + return RCT2_CALLFUNC_1(0x004068B2, void*, size_t, numBytes); } \ No newline at end of file diff --git a/src/rct2.h b/src/rct2.h index 9c42e2d232..880d2c4906 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -21,9 +21,7 @@ #ifndef _SDL_RCT2_H_ #define _SDL_RCT2_H_ -#ifndef NULL - #define NULL 0 -#endif +#include typedef signed char sint8; typedef signed short sint16; @@ -44,4 +42,16 @@ enum { SCREEN_FLAGS_TRACK_MANAGER = 8, }; +enum { + PATH_ID_G1, + PATH_ID_PLUGIN, + PATH_ID_CSS1, + PATH_ID_CSS2, + PATH_ID_CSS4, + PATH_ID_CSS5 +}; + +char *get_file_path(int pathId); +void *rct2_malloc(size_t numBytes); + #endif \ No newline at end of file