diff --git a/src/editor.c b/src/editor.c index 8c604bc726..f9f2a43c70 100644 --- a/src/editor.c +++ b/src/editor.c @@ -25,6 +25,7 @@ #include "gfx.h" #include "map.h" #include "news_item.h" +#include "object.h" #include "park.h" #include "ride.h" #include "window.h" @@ -47,7 +48,7 @@ void editor_load() pause_sounds(); unpause_sounds(); - RCT2_CALLPROC_EBPSAFE(0x006A9CE8); + object_unload_all(); map_init(); RCT2_CALLPROC_EBPSAFE(0x006B9CB0); reset_park_entrances(); @@ -95,7 +96,7 @@ void trackdesigner_load() { rct_window *mainWindow; - RCT2_CALLPROC_EBPSAFE(0x006A9CE8); + object_unload_all(); map_init(); set_all_land_owned(); RCT2_CALLPROC_EBPSAFE(0x006B9CB0); @@ -133,7 +134,7 @@ void trackmanager_load() { rct_window *mainWindow; - RCT2_CALLPROC_EBPSAFE(0x006A9CE8); + object_unload_all(); map_init(); set_all_land_owned(); RCT2_CALLPROC_EBPSAFE(0x006B9CB0); diff --git a/src/object.c b/src/object.c index fa4a95e255..86afab0c57 100644 --- a/src/object.c +++ b/src/object.c @@ -25,11 +25,20 @@ * * rct2: 0x006A985D */ -int object_load(int ecx, rct_object_entry *ebp) +int object_load(int groupIndex, rct_object_entry *entry) { - RCT2_CALLPROC_X(0x006A985D, 0, 0, ecx, 0, 0, 0, (int)ebp); + RCT2_CALLPROC_X(0x006A985D, 0, 0, groupIndex, 0, 0, 0, (int)entry); __asm jb fail return 1; fail: return 0; +} + +/** + * + * rct2: 0x006A9CAF + */ +void object_unload(int groupIndex, rct_object_entry_extended *entry) +{ + RCT2_CALLPROC_X(0x006A9CAF, 0, groupIndex, 0, 0, 0, 0, (int)entry); } \ No newline at end of file diff --git a/src/object.h b/src/object.h index 58db73cd10..28fd824b81 100644 --- a/src/object.h +++ b/src/object.h @@ -29,15 +29,28 @@ * size: 0x10 */ typedef struct { - uint32 var_00; - char name[8]; // 0x04 - uint32 var_0C; + uint32 flags; + char name[8]; + uint32 checksum; } rct_object_entry; +/** + * Object entry structure extended. + * size: 0x14 + */ +typedef struct { + uint32 flags; + char name[8]; + uint32 checksum; + uint32 extended; +} rct_object_entry_extended; + void object_list_load(); void object_read_and_load_entries(HANDLE hFile); int object_load_packed(); +void object_unload_all(); -int object_load(int ecx, rct_object_entry *ebp); +int object_load(int groupIndex, rct_object_entry *entry); +void object_unload(int groupIndex, rct_object_entry_extended *entry); #endif diff --git a/src/object_list.c b/src/object_list.c index 9b92b307b1..1bceaebcb4 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -23,6 +23,8 @@ #include "object.h" #include "sawyercoding.h" +#define OBJECT_ENTRY_GROUP_COUNT 11 + typedef struct { uint32 total_files; uint32 total_file_size; @@ -31,6 +33,34 @@ typedef struct { uint32 var_10; } rct_plugin_header; +int object_entry_group_counts[] = { + 128, // rides + 252, // small scenery + 128, // large scenery + 128, // walls + 32, // banners + 16, // paths + 15, // path bits + 19, // scenery sets + 1, // park entrance + 1, // water + 1 // stex +}; + +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)) // stex +}; + /** * * rct2: 0x006A93CD @@ -156,10 +186,9 @@ static int check_object_entry(rct_object_entry *entry) */ void object_read_and_load_entries(HANDLE hFile) { - // - RCT2_CALLPROC_EBPSAFE(0x006A9CE8); + object_unload_all(); - int i; + int i, j; rct_object_entry *entries; // Maximum of 721 object entries in a scenario / saved game @@ -171,22 +200,20 @@ void object_read_and_load_entries(HANDLE hFile) if (!check_object_entry(&entries[i])) continue; - // - int eax; - int ecx = i; - int ebx = 0; - while (ecx >= (eax = RCT2_ADDRESS(0x0098DA00, uint16)[ebx])) { - ecx -= eax; - ebx++; - }; + // Get entry group index + int entryGroupIndex = i; + for (j = 0; j < countof(object_entry_group_counts); j++) { + if (entryGroupIndex < object_entry_group_counts[j]) + break; + entryGroupIndex -= object_entry_group_counts[j]; + } // Load the obect - if (!object_load(ecx, &entries[i])) { + if (!object_load(entryGroupIndex, &entries[i])) { // Failed to load the object free(entries); - // - RCT2_CALLPROC_EBPSAFE(0x006A9CE8); + object_unload_all(); return; } } @@ -204,3 +231,17 @@ int object_load_packed() RCT2_CALLFUNC_X(0x006AA2B7, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); return eax; } + +/** + * + * rct2: 0x006A9CE8 + */ +void object_unload_all() +{ + int i, j; + + for (i = 0; i < OBJECT_ENTRY_GROUP_COUNT; i++) + for (j = 0; j < object_entry_group_counts[i]; j++) + if (object_entry_groups[i].data[j] != (void**)0xFFFFFFFF) + object_unload(j, &object_entry_groups[i].entries[j]); +} \ No newline at end of file