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