From e7db42f0fe3eac80e43ca15ae244b929ff5b12f9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 5 Mar 2015 22:00:32 +0000 Subject: [PATCH 1/4] Refactor of object.c --- src/object.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/object.c b/src/object.c index c126b85fd4..571534d39d 100644 --- a/src/object.c +++ b/src/object.c @@ -176,16 +176,16 @@ int object_load(int groupIndex, rct_object_entry *entry, int* chunkSize) * ebp : entry */ int sub_6A9F42(FILE *file, rct_object_entry* entry){ - int eax = 0, entryGroupIndex = 0, type = 0, edx = 0, edi = 0, ebp = (int)entry, chunk = 0; - RCT2_CALLFUNC_X(0x6A9DA2, &eax, &entryGroupIndex, &type, &edx, &chunk, &edi, &ebp); - if (eax == 0) return 0; + uint8 entryGroupIndex = 0, type = 0; + uint8* chunk = 0; - object_paint(type, 1, entryGroupIndex, type, edx, chunk, edi, ebp); + if (!find_object_in_entry_group(entry, &type, &entryGroupIndex))return 0; + object_paint(type, 1, entryGroupIndex, type, 0, (int)chunk, 0, 0); rct_object_entry_extended* installed_entry = &object_entry_groups[type].entries[entryGroupIndex]; uint8* dst_buffer = malloc(0x600000); - memcpy(dst_buffer, (uint8*)installed_entry, sizeof(rct_object_entry)); + memcpy(dst_buffer, installed_entry, sizeof(rct_object_entry)); uint32 size_dst = sizeof(rct_object_entry); @@ -196,7 +196,7 @@ int sub_6A9F42(FILE *file, rct_object_entry* entry){ chunkHeader.encoding = object_entry_group_encoding[type]; chunkHeader.length = installed_entry->chunk_size; - size_dst += sawyercoding_write_chunk_buffer(dst_buffer + sizeof(rct_object_entry), (uint8*)chunk, chunkHeader); + size_dst += sawyercoding_write_chunk_buffer(dst_buffer + sizeof(rct_object_entry), chunk, chunkHeader); fwrite(dst_buffer, 1, size_dst, file); free(dst_buffer); From ddcf766fea59a99067e7477c2de3a6dd1e6669a7 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 7 Mar 2015 09:44:34 +0000 Subject: [PATCH 2/4] More refactoring of object.c --- src/addresses.h | 25 +-- src/editor.c | 10 +- src/object.c | 230 +++++++++++++------------ src/object.h | 2 +- src/object_list.c | 20 +-- src/scenario.c | 30 ++-- src/scenario.h | 9 +- src/windows/editor_object_selection.c | 9 +- src/windows/editor_objective_options.c | 4 +- src/windows/footpath.c | 8 +- src/world/footpath.h | 3 + src/world/scenery.h | 13 +- 12 files changed, 197 insertions(+), 166 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index d2e8321884..e55b0cee86 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -130,11 +130,23 @@ #define RCT2_ADDRESS_RIDE_ENTRIES 0x009ACFA4 + + +#define RCT2_ADDRESS_SMALL_SCENERY_ENTRIES 0x009AD1A4 +#define RCT2_ADDRESS_LARGE_SCENERY_ENTRIES 0x009AD594 +#define RCT2_ADDRESS_WALL_SCENERY_ENTRIES 0x009AD794 +#define RCT2_ADDRESS_BANNER_SCENERY_ENTRIES 0x009AD994 +#define RCT2_ADDRESS_PATH_TYPES 0x009ADA14 +#define RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES 0x009ADA54 +#define RCT2_ADDRESS_SCENERY_SET_ENTRIES 0x009ADA90 + #define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8 #define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC - #define RCT2_ADDRESS_TOTAL_NO_IMAGES 0x009ADAF0 +#define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK 0x009ADAF8 + + #define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280 #define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288 @@ -219,15 +231,6 @@ #define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28 -#define RCT2_ADDRESS_PATH_TYPES 0x009ADA14 - -#define RCT2_ADDRESS_SMALL_SCENERY_ENTRIES 0x009AD1A4 -#define RCT2_ADDRESS_LARGE_SCENERY_ENTRIES 0x009AD594 -#define RCT2_ADDRESS_WALL_SCENERY_ENTRIES 0x009AD794 -#define RCT2_ADDRESS_BANNER_SCENERY_ENTRIES 0x009AD994 -#define RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES 0x009ADA54 -#define RCT2_ADDRESS_SCENERY_SET_ENTRIES 0x009ADA90 - //Every pixel changed by rain is stored. //32bit (pixel_offset 24 bit)(pixel_colour 8 bit) //Use the rainPixels[] global in drawing.c from now on @@ -263,6 +266,8 @@ #define RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID 0x00F42BBC #define RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER 0x00F42BC0 +#define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT 0x00F42BC8 + #define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC #define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908 diff --git a/src/editor.c b/src/editor.c index 2a083a00cc..7f85709157 100644 --- a/src/editor.c +++ b/src/editor.c @@ -152,8 +152,9 @@ void editor_convert_save_to_scenario() s6Info->objective_arg_3 = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, sint16); climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8)); - if (RCT2_GLOBAL(0x009ADAE4, uint32) != 0xFFFFFFFF) { - object_unload(0, (rct_object_entry_extended*)0x00F4287C); + rct_stex_entry* stex = g_stexEntries[0]; + if ((int)stex != 0xFFFFFFFF) { + object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]); //RCT2_CALLPROC_EBPSAFE(0x006A9FC0); sub_6A9FC0(); @@ -911,8 +912,9 @@ static int editor_read_s6(const char *path) climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8)); - if (RCT2_GLOBAL(0x009ADAE4, uint32) != 0xFFFFFFFF) { - object_unload(0, (rct_object_entry_extended*)0x00F4287C); + rct_stex_entry* stex = g_stexEntries[0]; + if ((int)stex != 0xFFFFFFFF) { + object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]); sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); diff --git a/src/object.c b/src/object.c index 571534d39d..b6ca848ee6 100644 --- a/src/object.c +++ b/src/object.c @@ -175,12 +175,14 @@ int object_load(int groupIndex, rct_object_entry *entry, int* chunkSize) * ebx : file * ebp : entry */ -int sub_6A9F42(FILE *file, rct_object_entry* entry){ +int write_object_file(FILE *file, rct_object_entry* entry){ uint8 entryGroupIndex = 0, type = 0; uint8* chunk = 0; if (!find_object_in_entry_group(entry, &type, &entryGroupIndex))return 0; + chunk = object_entry_groups[type].chunks[entryGroupIndex]; + object_paint(type, 1, entryGroupIndex, type, 0, (int)chunk, 0, 0); rct_object_entry_extended* installed_entry = &object_entry_groups[type].entries[entryGroupIndex]; @@ -211,35 +213,39 @@ int object_load_packed(FILE *file) { object_unload_all(); - rct_object_entry* entry = RCT2_ADDRESS(0xF42B84, rct_object_entry); + rct_object_entry entry; - fread((void*)entry, 16, 1, file); + fread(&entry, 16, 1, file); uint8* chunk = rct2_malloc(0x600000); uint32 chunkSize = sawyercoding_read_chunk(file, chunk); chunk = rct2_realloc(chunk, chunkSize); + if (chunk == NULL){ + log_error("Failed to allocate memory for packed object."); return 0; } - if (object_calculate_checksum(entry, chunk, chunkSize) != entry->checksum){ + if (object_calculate_checksum(&entry, chunk, chunkSize) != entry.checksum){ + log_error("Checksum missmatch from packed object: %.8s", entry.name); rct2_free(chunk); return 0; } - if (object_paint(entry->flags & 0x0F, 2, 0, entry->flags & 0x0F, 0, (int)chunk, 0, 0)) { + int type = entry.flags & 0x0F; + + if (object_paint(type, 2, 0, type, 0, (int)chunk, 0, 0)) { + log_error("Packed object failed paint test."); rct2_free(chunk); return 0; } if (RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) >= 0x4726E){ + log_error("Packed object has too many images."); rct2_free(chunk); return 0; } - int type = entry->flags & 0x0F; - - // ecx int entryGroupIndex = 0; for (; entryGroupIndex < object_entry_group_counts[type]; entryGroupIndex++){ @@ -249,21 +255,24 @@ int object_load_packed(FILE *file) } if (entryGroupIndex == object_entry_group_counts[type]){ + // This should never occur. Objects are not loaded before installing a + // packed object. So there is only one object loaded at this point. + log_error("Too many objects of the same type loaded."); rct2_free(chunk); return 0; } + // Copy the entry into the relevant entry group. object_entry_groups[type].chunks[entryGroupIndex] = chunk; - rct_object_entry_extended* edx = &object_entry_groups[type].entries[entryGroupIndex]; - memcpy(edx, (int*)entry, sizeof(rct_object_entry)); - edx->chunk_size = chunkSize; + rct_object_entry_extended* extended_entry = &object_entry_groups[type].entries[entryGroupIndex]; + memcpy(extended_entry, &entry, sizeof(rct_object_entry)); + extended_entry->chunk_size = chunkSize; - //esi + // Ensure the entry does not already exist. rct_object_entry *installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); - if (RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)){ for (uint32 i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); ++i){ - if (object_entry_compare(entry, installedObject)){ + if (object_entry_compare(&entry, installedObject)){ object_unload_all(); return 0; } @@ -271,24 +280,23 @@ int object_load_packed(FILE *file) } } - //Installing new data - //format_string(0x141ED68, 3163, 0); - //Code for updating progress bar removed. - + // Convert the entry name to a upper case path name char path[260]; - char objectPath[13] = { 0 }; + char objectPath[9] = { 0 }; for (int i = 0; i < 8; ++i){ - if (entry->name[i] != ' ') - objectPath[i] = toupper(entry->name[i]); + if (entry.name[i] != ' ') + objectPath[i] = toupper(entry.name[i]); else objectPath[i] = '\0'; } subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath); + // Require pointer to start of filename char* last_char = path + strlen(path); strcat(path, ".DAT"); - // + // Check that file does not exist + // Adjust filename if it does. for (; platform_file_exists(path);){ for (char* curr_char = last_char - 1;; --curr_char){ if (*curr_char == '\\'){ @@ -304,30 +312,19 @@ int object_load_packed(FILE *file) } } - // Removed progress bar code - - // The following section cannot be finished until 6A9F42 is finished - // Run the game once with vanila rct2 to not reach this part of code. - log_verbose("Function might not be finished."); + // Actually write the object to the file FILE* obj_file = fopen(path, "wb"); if (obj_file){ - // Removed progress bar code - sub_6A9F42(obj_file, entry); + uint8 result = write_object_file(obj_file, &entry); + fclose(obj_file); - // Removed progress bar code object_unload_all(); - // Removed progress bar code - return 1; + + return result; } - else{ - object_unload_all(); - return 0; - } - //create file - //6aa48C - int eax = 1;//, ebx = 0, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0; - //RCT2_CALLFUNC_X(0x006AA2B7, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return 1; + + object_unload_all(); + return 0; } /** @@ -341,6 +338,7 @@ void object_unload(int groupIndex, rct_object_entry_extended *entry) int object_entry_compare(const rct_object_entry *a, const rct_object_entry *b) { + // If an official object don't bother checking checksum if (a->flags & 0xF0) { if ((a->flags & 0x0F) != (b->flags & 0x0F)) return 0; @@ -1501,73 +1499,89 @@ int object_get_scenario_text(rct_object_entry *entry) { // RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry); return; - int i; rct_object_entry *installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); - for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, 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; - // Skip file name - while (*pos++); - - // 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 total_no_images = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32); - // This is being changed to force the images to be loaded into a different - // image id. - RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, 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(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = total_no_images; - return 1; - } - fclose(file); - } - } - installedObject = object_get_next(installedObject); + installedObject = object_list_find(entry); + + if (installedObject == NULL){ + log_error("Object not found: %.8s", entry->name); + RCT2_GLOBAL(0x00F42BD9, uint8) = 0; + return 0; } + 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)) { + + // Skip over the object entry + char *pos = (char*)installedObject + sizeof(rct_object_entry); + // Skip file name + while (*pos++); + + // 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) { + log_error("Opened object failed calculated checksum."); + RCT2_GLOBAL(0x00F42BD9, uint8) = 2; + free(chunk); + return 0; + } + + if (object_paint(openedEntry.flags & 0x0F, 2, 0, 0, 0, (int)chunk, 0, 0)) { + // This is impossible for STEX entries to fail. + log_error("Opened object failed paitn test."); + RCT2_GLOBAL(0x00F42BD9, uint8) = 3; + free(chunk); + return 0; + } + + // Save the real total images. + int total_no_images = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32); + + // This is being changed to force the images to be loaded into a different + // image id. + RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0x726E; + RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, uint32) = (int)chunk; + // Not used anywhere. + RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT, rct_object_entry) = openedEntry; + + // Tell text to be loaded into a different address + RCT2_GLOBAL(0x009ADAFC, uint8) = 255; + // Not used?? + RCT2_GLOBAL(0x009ADAFD, uint8) = 1; + object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0); + // Tell text to be loaded into normal address + RCT2_GLOBAL(0x009ADAFC, uint8) = 0; + // Not used?? + RCT2_GLOBAL(0x009ADAFD, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = total_no_images; + return 1; + } + log_error("Opened object didn't match."); + fclose(file); + return 0; + } + log_error("File failed to open."); RCT2_GLOBAL(0x00F42BD9, uint8) = 0; return 0; } @@ -1578,9 +1592,9 @@ int object_get_scenario_text(rct_object_entry *entry) */ void object_free_scenario_text() { - if (RCT2_GLOBAL(0x009ADAF8, void*) != NULL) { - rct2_free(RCT2_GLOBAL(0x009ADAF8, void*)); - RCT2_GLOBAL(0x009ADAF8, void*) = NULL; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, void*) != NULL) { + rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, void*)); + RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, void*) = NULL; } } @@ -1630,7 +1644,7 @@ char *object_get_name(rct_object_entry *entry) // Skip filename while (*pos++); - // Skip + // Skip no of images pos += 4; return pos; diff --git a/src/object.h b/src/object.h index dfe8e6fbc9..64b0b4d6b5 100644 --- a/src/object.h +++ b/src/object.h @@ -86,7 +86,7 @@ int object_entry_compare(const rct_object_entry *a, const rct_object_entry *b); int object_calculate_checksum(const rct_object_entry *entry, const char *data, int dataLength); int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); rct_object_entry *object_get_next(rct_object_entry *entry); -int sub_6A9F42(FILE *file, rct_object_entry* entry); +int write_object_file(FILE *file, rct_object_entry* entry); void sub_6A9FC0(); int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index); diff --git a/src/object_list.c b/src/object_list.c index 27c5688600..8446119101 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -69,16 +69,16 @@ int object_entry_group_encoding[] = { // 0x98D97C chunk address', 0x98D980 object_entries rct_object_entry_group object_entry_groups[] = { (uint8**)(0x009ACFA4 ), (rct_object_entry_extended*)(0x00F3F03C ), // rides - (uint8**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // small scenery - (uint8**)(0x009ACFA4 + (380 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (380 * 20)), // large scenery - (uint8**)(0x009ACFA4 + (508 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (508 * 20)), // walls - (uint8**)(0x009ACFA4 + (636 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (636 * 20)), // banners - (uint8**)(0x009ACFA4 + (668 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (668 * 20)), // paths - (uint8**)(0x009ACFA4 + (684 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (684 * 20)), // path bits - (uint8**)(0x009ACFA4 + (699 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (699 * 20)), // scenery sets - (uint8**)(0x009ACFA4 + (718 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (718 * 20)), // park entrance - (uint8**)(0x009ACFA4 + (719 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (719 * 20)), // water - (uint8**)(0x009ACFA4 + (720 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (720 * 20)) // scenario text + (uint8**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // small scenery 0x009AD1A4, 0xF2FA3C + (uint8**)(0x009ACFA4 + (380 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (380 * 20)), // large scenery 0x009AD594, 0xF40DEC + (uint8**)(0x009ACFA4 + (508 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (508 * 20)), // walls 0x009AD794, 0xF417EC + (uint8**)(0x009ACFA4 + (636 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (636 * 20)), // banners 0x009AD994, 0xF421EC + (uint8**)(0x009ACFA4 + (668 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (668 * 20)), // paths 0x009ADA14, 0xF4246C + (uint8**)(0x009ACFA4 + (684 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (684 * 20)), // path bits 0x009ADA54, 0xF425AC + (uint8**)(0x009ACFA4 + (699 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (699 * 20)), // scenery sets 0x009ADA90, 0xF426D8 + (uint8**)(0x009ACFA4 + (718 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (718 * 20)), // park entrance 0x009ADADC, 0xF42854 + (uint8**)(0x009ACFA4 + (719 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (719 * 20)), // water 0x009ADAE0, 0xF42868 + (uint8**)(0x009ACFA4 + (720 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (720 * 20)) // scenario text 0x009ADAE4, 0xF4287C }; static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int fileDateModifiedChecksum); diff --git a/src/scenario.c b/src/scenario.c index c506685500..f84f982cb8 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -69,10 +69,10 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in // Checks for a scenario string object (possibly for localisation) if ((info->entry.flags & 0xFF) != 255) { if (object_get_scenario_text(&info->entry)) { - int ebp = RCT2_GLOBAL(0x009ADAF8, uint32); - format_string(info->name, RCT2_GLOBAL(ebp, sint16), NULL); - format_string(info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL); - RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8); + rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*); + format_string(info->name, stex_entry->scenario_name, NULL); + format_string(info->details, stex_entry->details, NULL); + RCT2_GLOBAL(0x009AA00C, uint8) = stex_entry->var_06; object_free_scenario_text(); } } @@ -274,11 +274,10 @@ int scenario_load_and_play_from_path(const char *path) strcpy((char*)RCT2_ADDRESS_SCENARIO_DETAILS, s6Info->details); strcpy((char*)RCT2_ADDRESS_SCENARIO_NAME, s6Info->name); - if (RCT2_GLOBAL(0x009ADAE4, sint32) != -1) { - char *ebp = RCT2_GLOBAL(0x009ADAE4, char*); - + rct_stex_entry* stex = g_stexEntries[0]; + if ((int)stex != -1) { // - format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, RCT2_GLOBAL(ebp + 2, uint16), 0); + format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, stex->park_name, 0); // Set park name RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = STR_CANT_RENAME_PARK; @@ -293,12 +292,12 @@ int scenario_load_and_play_from_path(const char *path) *((int*)(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER + 28))); // - format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, RCT2_GLOBAL(ebp + 0, uint16), 0); + format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, stex->scenario_name, 0); strncpy((char*)RCT2_ADDRESS_SCENARIO_NAME, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, 31); ((char*)RCT2_ADDRESS_SCENARIO_NAME)[31] = '\0'; // Set scenario details - format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, RCT2_GLOBAL(ebp + 4, uint16), 0); + format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, stex->details, 0); strncpy((char*)RCT2_ADDRESS_SCENARIO_DETAILS, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, 255); ((char*)RCT2_ADDRESS_SCENARIO_DETAILS)[255] = '\0'; } @@ -840,11 +839,12 @@ int scenario_prepare_for_save() s6Info->entry.flags = 255; - char *stex = RCT2_GLOBAL(0x009ADAE4, char*); - if (stex != (char*)0xFFFFFFFF) { - format_string(buffer, RCT2_GLOBAL(stex, uint16), NULL); + rct_stex_entry* stex = g_stexEntries[0]; + if ((int)stex != 0xFFFFFFFF) { + format_string(buffer, stex->scenario_name, NULL); strncpy(s6Info->name, buffer, sizeof(s6Info->name)); - s6Info->entry = *((rct_object_entry*)0x00F4287C); + + memcpy(&s6Info->entry, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0], sizeof(rct_object_entry)); } if (s6Info->name[0] == 0) @@ -894,7 +894,7 @@ int scenario_write_packed_objects(FILE *file) if (RCT2_ADDRESS(0x009ACFA4, uint32)[i] == 0xFFFFFFFF || (entry->flags & 0xF0)) continue; - if (!sub_6A9F42(file, (rct_object_entry*)entry)) + if (!write_object_file(file, (rct_object_entry*)entry)) return 0; } diff --git a/src/scenario.h b/src/scenario.h index f6e710c6a6..922680cd24 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -84,11 +84,14 @@ typedef struct { } rct_scenario_basic; typedef struct { - rct_string_id scenario_name; - rct_string_id park_name; - rct_string_id details; + rct_string_id scenario_name; // 0x00 + rct_string_id park_name; // 0x02 + rct_string_id details; // 0x04 + uint8 var_06; } rct_stex_entry; +#define g_stexEntries ((rct_stex_entry**)object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].chunks) + /* This will be useful for backwards compatibility typedef struct { // SC6[0] diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 57a0940249..1f9d69de1c 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -26,6 +26,7 @@ #include "../localisation/localisation.h" #include "../object.h" #include "../ride/track.h" +#include "../scenario.h" #include "error.h" enum { @@ -571,7 +572,9 @@ static void window_editor_object_selection_paint() gfx_draw_string_left(dpi, 3164, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, x, y); } - if (w->selected_list_item == -1 || RCT2_GLOBAL(0x009ADAF8, sint32) == -1) + rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*); + + if (w->selected_list_item == -1 || stex_entry == NULL) return; highlightedEntry = (rct_object_entry*)w->var_494; @@ -581,7 +584,7 @@ static void window_editor_object_selection_paint() widget = &w->widgets[WIDX_PREVIEW]; x = w->x + (widget->left + widget->right) / 2 + 1; y = w->y + (widget->top + widget->bottom) / 2 + 1; - object_paint(type, 3, type, x, y, 0, (int)dpi, RCT2_GLOBAL(0x009ADAF8, sint32)); + object_paint(type, 3, type, x, y, 0, (int)dpi, (int)stex_entry); // Draw name of object x = w->x + (widget->left + widget->right) / 2 + 1; @@ -629,7 +632,7 @@ static void window_editor_object_selection_paint() // Draw description of object x = w->x + w->widgets[WIDX_LIST].right + 4; y += 15; - object_paint(type, 259, type, x, y, (int)w, (int)dpi, RCT2_GLOBAL(0x009ADAF8, sint32)); + object_paint(type, 259, type, x, y, (int)w, (int)dpi, (int)stex_entry); // Draw object dat name strcpy(stringBuffer, datName); diff --git a/src/windows/editor_objective_options.c b/src/windows/editor_objective_options.c index abea327c67..bc41e94f7a 100644 --- a/src/windows/editor_objective_options.c +++ b/src/windows/editor_objective_options.c @@ -835,7 +835,7 @@ static void window_editor_objective_options_main_invalidate() window_get_register(w); - stex = RCT2_GLOBAL(0x009ADAE4, rct_stex_entry*); + stex = g_stexEntries[0]; if (stex == (rct_stex_entry*)0xFFFFFFFF) stex = NULL; @@ -920,7 +920,7 @@ static void window_editor_objective_options_main_paint() window_draw_widgets(w, dpi); window_editor_objective_options_draw_tab_images(w, dpi); - stex = RCT2_GLOBAL(0x009ADAE4, rct_stex_entry*); + stex = g_stexEntries[0]; if (stex == (rct_stex_entry*)0xFFFFFFFF) stex = NULL; diff --git a/src/windows/footpath.c b/src/windows/footpath.c index 22b51b4248..15b3e08683 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -354,7 +354,7 @@ static void window_footpath_dropdown() j = 0; for (i = 0; i < 16; i++) { - pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[i]; + pathType = g_pathTypeEntries[i]; if (pathType == (rct_path_type*)-1) continue; if (pathType->flags & flags) @@ -533,7 +533,7 @@ static void window_footpath_invalidate() // Set footpath and queue type button images selectedPath = RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint16); - pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[selectedPath]; + pathType = g_pathTypeEntries[selectedPath]; int pathImage = 71 + pathType->image; window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage; @@ -570,7 +570,7 @@ static void window_footpath_paint() image = RCT2_ADDRESS(0x0098D7E0, uint8)[image]; selectedPath = RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint16); - pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[selectedPath]; + pathType = g_pathTypeEntries[selectedPath]; image += pathType->image; if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_TYPE, uint8) != SELECTED_PATH_TYPE_NORMAL) image += 51; @@ -609,7 +609,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget flags = 0; for (i = 0; i < 16; i++) { - pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[i]; + pathType = g_pathTypeEntries[i]; if (pathType == (rct_path_type*)-1) continue; if (pathType->flags & flags) diff --git a/src/world/footpath.h b/src/world/footpath.h index 3bdb3ce8f0..8205b91c47 100644 --- a/src/world/footpath.h +++ b/src/world/footpath.h @@ -23,6 +23,7 @@ #include "../common.h" #include "../interface/viewport.h" +#include "../object.h" enum { PROVISIONAL_PATH_FLAG_SHOW_ARROW = (1 << 0) @@ -36,6 +37,8 @@ typedef struct { uint8 flags; // 0x0B } rct_path_type; +#define g_pathTypeEntries ((rct_path_type**)object_entry_groups[OBJECT_TYPE_PATHS].chunks) + void game_command_place_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_remove_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); money32 footpath_place(int type, int x, int y, int z, int slope, int flags); diff --git a/src/world/scenery.h b/src/world/scenery.h index 87383a308e..d1696c10c4 100644 --- a/src/world/scenery.h +++ b/src/world/scenery.h @@ -22,6 +22,7 @@ #define _SCENERY_H_ #include "../common.h" +#include "../object.h" typedef struct { uint32 flags; // 0x06 @@ -129,12 +130,12 @@ typedef struct { uint32 var_10A; } rct_scenery_set_entry; -#define g_smallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_SMALL_SCENERY_ENTRIES, rct_scenery_entry*) -#define g_largeSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_scenery_entry*) -#define g_wallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_WALL_SCENERY_ENTRIES, rct_scenery_entry*) -#define g_bannerSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_BANNER_SCENERY_ENTRIES, rct_scenery_entry*) -#define g_pathBitSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES, rct_scenery_entry*) -#define g_scenerySetEntries RCT2_ADDRESS(RCT2_ADDRESS_SCENERY_SET_ENTRIES, rct_scenery_set_entry*) +#define g_smallSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].chunks) +#define g_largeSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_LARGE_SCENERY].chunks) +#define g_wallSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_WALLS].chunks) +#define g_bannerSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_BANNERS].chunks) +#define g_pathBitSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_PATH_BITS].chunks) +#define g_scenerySetEntries ((rct_scenery_set_entry**)object_entry_groups[OBJECT_TYPE_SCENERY_SETS].chunks) void init_scenery(); From 936f2f127ffe9d696b1a4813754997af45508715 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 7 Mar 2015 11:13:10 +0000 Subject: [PATCH 3/4] Refactor of object_list.c --- src/editor.c | 8 +++--- src/game.c | 22 +++++++++++++++- src/game.h | 3 +++ src/object.h | 2 +- src/object_list.c | 36 +++++++++++---------------- src/ride/ride.c | 9 +++++++ src/ride/ride.h | 1 + src/ride/track.c | 2 +- src/scenario.c | 4 +-- src/windows/editor_object_selection.c | 2 +- 10 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/editor.c b/src/editor.c index 7f85709157..09e1eb8c76 100644 --- a/src/editor.c +++ b/src/editor.c @@ -156,7 +156,7 @@ void editor_convert_save_to_scenario() if ((int)stex != 0xFFFFFFFF) { object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]); //RCT2_CALLPROC_EBPSAFE(0x006A9FC0); - sub_6A9FC0(); + reset_loaded_objects(); format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); s6Info->name[0] = 0; @@ -464,7 +464,7 @@ static void sub_6A2B62() object_unload_all(); RCT2_CALLPROC_EBPSAFE(0x0069F53D); - sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); + reset_loaded_objects(); RCT2_CALLPROC_EBPSAFE(0x006A2730); RCT2_CALLPROC_EBPSAFE(0x006A2956); RCT2_CALLPROC_EBPSAFE(0x006A29B9); @@ -836,7 +836,7 @@ static int editor_read_s6(const char *path) // Check expansion pack // RCT2_CALLPROC_EBPSAFE(0x006757E6); - sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); + reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); map_update_tile_pointers(); map_remove_all_rides(); @@ -915,7 +915,7 @@ static int editor_read_s6(const char *path) rct_stex_entry* stex = g_stexEntries[0]; if ((int)stex != 0xFFFFFFFF) { object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]); - sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); + reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); s6Info->name[0] = 0; diff --git a/src/game.c b/src/game.c index a0c0feafda..707af12c5a 100644 --- a/src/game.c +++ b/src/game.c @@ -663,7 +663,7 @@ int game_load_save(const char *path) } // The rest is the same as in scenario load and play - sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); + reset_loaded_objects(); map_update_tile_pointers(); reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4); RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; @@ -811,6 +811,26 @@ void game_autosave() scenario_save(path, 0x80000000); } +/** +* +* rct2: 0x006E3838 +*/ +void rct2_exit_reason(rct_string_id title, rct_string_id body){ + // Before this would set a quit message + + char exit_title[255]; + format_string(exit_title, title, 0); + + char exit_body[255]; + format_string(exit_body, body, 0); + + log_error(exit_title); + log_error(exit_body); + + rct2_exit(); +} + + /** * * rct2: 0x006E3879 diff --git a/src/game.h b/src/game.h index 63110e86fd..f84a918787 100644 --- a/src/game.h +++ b/src/game.h @@ -21,6 +21,8 @@ #ifndef _GAME_H_ #define _GAME_H_ +#include "common.h" + enum GAME_COMMAND { GAME_COMMAND_0, GAME_COMMAND_1, @@ -109,6 +111,7 @@ int game_load_save(const char *path); void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); char save_game(); void rct2_exit(); +void rct2_exit_reason(rct_string_id title, rct_string_id body); void game_autosave(); #endif diff --git a/src/object.h b/src/object.h index 64b0b4d6b5..9de3c7238e 100644 --- a/src/object.h +++ b/src/object.h @@ -87,7 +87,7 @@ int object_calculate_checksum(const rct_object_entry *entry, const char *data, i int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); rct_object_entry *object_get_next(rct_object_entry *entry); int write_object_file(FILE *file, rct_object_entry* entry); -void sub_6A9FC0(); +void reset_loaded_objects(); int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index); rct_object_entry *object_list_find(rct_object_entry *entry); diff --git a/src/object_list.c b/src/object_list.c index 8446119101..ed9e7f809a 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -24,6 +24,7 @@ #include "platform/platform.h" #include "ride/track.h" #include "util/sawyercoding.h" +#include "game.h" #define OBJECT_ENTRY_GROUP_COUNT 11 #define OBJECT_ENTRY_COUNT 721 @@ -165,19 +166,10 @@ static void object_list_examine() object_list_create_hash_table(); } -/** - * - * rct2: 0x006DED68 - */ -void reset_9E32F8() +/* rct2: 0x006A9FC0 */ +void reset_loaded_objects() { - uint8* edi = RCT2_ADDRESS(0x009E32F8, uint8); - memset(edi, 0xFF, 90); -} - -void sub_6A9FC0() -{ - reset_9E32F8(); + reset_type_to_ride_entry_index_map(); RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E; @@ -248,7 +240,7 @@ void object_list_load() //if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS, uint8) != 0) // RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS, uint8) = 0; - sub_6A9FC0(); + reset_loaded_objects(); // Dispose installed object list if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) != -1) { @@ -259,7 +251,8 @@ void object_list_load() RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) = 0; RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_malloc(4096); if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){ - RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0); + log_error("Failed to allocate memory for object list"); + rct2_exit_reason(835, 3162); return; } @@ -280,7 +273,8 @@ void object_list_load() installed_buffer_size += 0x1000; RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_realloc(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), installed_buffer_size); if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){ - RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0); + log_error("Failed to allocate memory for object list"); + rct2_exit_reason(835, 3162); return; } } @@ -288,18 +282,18 @@ void object_list_load() char path[MAX_PATH]; subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), enumFileInfo.path); - rct_object_entry* entry = RCT2_ADDRESS(0x00F42B74, rct_object_entry); - if (!object_load_entry(path, entry)) + rct_object_entry entry; + if (!object_load_entry(path, &entry)) continue; rct_object_entry* installed_entry = (rct_object_entry*)(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset); - current_item_offset += install_object_entry(entry, installed_entry, enumFileInfo.path); + current_item_offset += install_object_entry(&entry, installed_entry, enumFileInfo.path); } platform_enumerate_files_end(enumFileHandle); } - sub_6A9FC0(); + reset_loaded_objects(); object_list_cache_save(fileCount, totalFileSize, fileDateModifiedChecksum, current_item_offset); @@ -349,7 +343,7 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file log_error("Potential mismatch in file numbers. Possible corrupt file. Consider deleting plugin.dat."); fclose(file); - sub_6A9FC0(); + reset_loaded_objects(); object_list_examine(); return 1; } @@ -493,7 +487,7 @@ void object_unload_all() if (object_entry_groups[i].chunks[j] != (uint8*)0xFFFFFFFF) object_unload(j, &object_entry_groups[i].entries[j]); - sub_6A9FC0(); + reset_loaded_objects(); } diff --git a/src/ride/ride.c b/src/ride/ride.c index f662cf3654..ca298dfc09 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -140,6 +140,15 @@ rct_ride_type *ride_get_entry(rct_ride *ride) return GET_RIDE_ENTRY(ride->subtype); } +/** +* +* rct2: 0x006DED68 +*/ +void reset_type_to_ride_entry_index_map(){ + uint8* typeToRideEntryIndexMap = RCT2_ADDRESS(0x009E32F8, uint8); + memset(typeToRideEntryIndexMap, 0xFF, 90); +} + uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType) { uint8 *typeToRideEntryIndexMap = (uint8*)0x009E32F8; diff --git a/src/ride/ride.h b/src/ride/ride.h index e6cbc976a7..7427b9543e 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -674,6 +674,7 @@ track_colour ride_get_track_colour(rct_ride *ride, int colourScheme); vehicle_colour ride_get_vehicle_colour(rct_ride *ride, int vehicleIndex); rct_ride_type *ride_get_entry(rct_ride *ride); uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType); +void reset_type_to_ride_entry_index_map(); void ride_measurement_clear(rct_ride *ride); void ride_measurements_update(); rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message); diff --git a/src/ride/track.c b/src/ride/track.c index de062d30e9..28f7554b1a 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -738,7 +738,7 @@ void load_track_scenery_objects(){ scenery_entry += sizeof(rct_track_scenery); } - sub_6A9FC0(); + reset_loaded_objects(); } /** diff --git a/src/scenario.c b/src/scenario.c index f84f982cb8..65158dbffe 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -172,7 +172,7 @@ int scenario_load(const char *path) // Check expansion pack // RCT2_CALLPROC_EBPSAFE(0x006757E6); - sub_6A9FC0(); + reset_loaded_objects(); map_update_tile_pointers(); reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4); return 1; @@ -1133,7 +1133,7 @@ int scenario_save(char *path, int flags) fclose(file); if (!(flags & 0x80000000)) - sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); + reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0); gfx_invalidate_screen(); RCT2_GLOBAL(0x009DEA66, uint16) = 0; diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 1f9d69de1c..d17d85e660 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -252,7 +252,7 @@ static void window_editor_object_selection_close() RCT2_CALLPROC_EBPSAFE(0x6ABB66); editor_load_selected_objects(); - sub_6A9FC0(); + reset_loaded_objects(); object_free_scenario_text(); RCT2_CALLPROC_EBPSAFE(0x6AB316); RCT2_CALLPROC_EBPSAFE(0x685675); From a04de29bf8bc1c27705c5b8cc27ce77008ddda47 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 7 Mar 2015 12:45:13 +0000 Subject: [PATCH 4/4] Finish refactor of object_list.c --- src/addresses.h | 7 +++++++ src/editor.c | 16 ++++++++-------- src/game.c | 22 ++++++++++------------ src/object_list.c | 22 +++++++++++++--------- src/scenario.c | 12 ++++++------ src/windows/options.c | 2 +- 6 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index e55b0cee86..55cd3f585d 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -126,6 +126,10 @@ #define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319 +// 0 = none, 255 = load file, 254 = anything else +#define RCT2_ADDRESS_ERROR_TYPE 0x009AC31B +#define RCT2_ADDRESS_ERROR_STRING_ID 0x009AC31C + #define RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS 0x009AC861 #define RCT2_ADDRESS_RIDE_ENTRIES 0x009ACFA4 @@ -268,6 +272,9 @@ #define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT 0x00F42BC8 +// 1 if custom objects installed, 0 otherwise +#define RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED 0x00F42BDA + #define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC #define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908 diff --git a/src/editor.c b/src/editor.c index 09e1eb8c76..600eddf059 100644 --- a/src/editor.c +++ b/src/editor.c @@ -588,8 +588,8 @@ static int editor_load_landscape_from_sv4(const char *path) // Open file fp = fopen(path, "rb"); if (fp == NULL) { - RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = 3011; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011; return 0; } @@ -615,8 +615,8 @@ static int editor_load_landscape_from_sc4(const char *path) // Open file fp = fopen(path, "rb"); if (fp == NULL) { - RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = 3011; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011; return 0; } @@ -759,8 +759,8 @@ static int editor_read_s6(const char *path) if (file != NULL) { if (!sawyercoding_validate_checksum(file)) { fclose(file); - RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; log_error("failed to load scenario, invalid checksum"); return 0; @@ -963,8 +963,8 @@ static int editor_read_s6(const char *path) } log_error("failed to find scenario file."); - RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; return 0; } diff --git a/src/game.c b/src/game.c index 707af12c5a..dc702c2d7e 100644 --- a/src/game.c +++ b/src/game.c @@ -298,8 +298,6 @@ void game_update() void game_logic_update() { - short stringId, _dx; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32)++; RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, sint32)++; RCT2_GLOBAL(0x009DEA66, sint16)++; @@ -329,16 +327,16 @@ void game_logic_update() // Update windows window_dispatch_update_all(); - if (RCT2_GLOBAL(0x009AC31B, uint8) != 0) { - stringId = STR_UNABLE_TO_LOAD_FILE; - _dx = RCT2_GLOBAL(0x009AC31C, uint16); - if (RCT2_GLOBAL(0x009AC31B, uint8) != 254) { - stringId = RCT2_GLOBAL(0x009AC31C, uint16); - _dx = 0xFFFF; + if (RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) != 0) { + rct_string_id title_text = STR_UNABLE_TO_LOAD_FILE; + rct_string_id body_text = RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16); + if (RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) == 254) { + title_text = RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16); + body_text = 0xFFFF; } - RCT2_GLOBAL(0x009AC31B, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0; - window_error_open(stringId, _dx); + window_error_open(title_text, body_text); } } @@ -601,7 +599,7 @@ int game_load_save(const char *path) if (file == NULL) { log_error("unable to open %s", path); - RCT2_GLOBAL(0x009AC31B, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; return 0; } @@ -611,7 +609,7 @@ int game_load_save(const char *path) log_error("invalid checksum, %s", path); - RCT2_GLOBAL(0x009AC31B, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; return 0; } diff --git a/src/object_list.c b/src/object_list.c index ed9e7f809a..6de10f3a3a 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -153,10 +153,12 @@ static void object_list_examine() int i; rct_object_entry *object; + RCT2_GLOBAL(RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED, uint8) = 0; + object = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32); i++) { - if (object->flags & 0xF0) - RCT2_GLOBAL(0x00F42BDA, uint8) |= 1; + if (!(object->flags & 0xF0)) + RCT2_GLOBAL(RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED, uint8) |= 1; object = object_get_next(object); } @@ -297,7 +299,7 @@ void object_list_load() object_list_cache_save(fileCount, totalFileSize, fileDateModifiedChecksum, current_item_offset); - // + // Reload track list ride_list_item ride_list; ride_list.entry_index = 0xFC; ride_list.type = 0xFC; @@ -402,15 +404,15 @@ void set_load_objects_fail_reason(){ format_string(string_buffer, 3323, 0); //Missing object data, ID: RCT2_CALLPROC_X(0x6AB344, 0, 0, 0, 0, 0, (int)string_buffer, 0x13CE952); - RCT2_GLOBAL(0x9AC31B, uint8) = 0xFF; - RCT2_GLOBAL(0x9AC31C, uint16) = 3165; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3165; return; } char* exapansion_name = &RCT2_ADDRESS(RCT2_ADDRESS_EXPANSION_NAMES, char)[128 * expansion]; if (*exapansion_name == '\0'){ - RCT2_GLOBAL(0x9AC31B, uint8) = 0xFF; - RCT2_GLOBAL(0x9AC31C, uint16) = 3325; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3325; return; } @@ -418,8 +420,8 @@ void set_load_objects_fail_reason(){ format_string(string_buffer, 3324, 0); // Requires expansion pack strcat(string_buffer, exapansion_name); - RCT2_GLOBAL(0x9AC31B, uint8) = 0xFF; - RCT2_GLOBAL(0x9AC31C, uint16) = 3165; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3165; } /** @@ -595,7 +597,9 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in // Chunk size is set to unknown *((sint32*)installed_entry_pointer) = -1; + // No unknown objects set to 0 *(installed_entry_pointer + 4) = 0; + // No theme objects set to 0 *((sint32*)(installed_entry_pointer + 5)) = 0; *((uint16*)(installed_entry_pointer + 9)) = 0; *((uint32*)(installed_entry_pointer + 11)) = 0; diff --git a/src/scenario.c b/src/scenario.c index 65158dbffe..242dfc6b23 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -82,8 +82,8 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in } log_error("invalid scenario, %s", path); - // RCT2_GLOBAL(0x009AC31B, sint8) = -1; - // RCT2_GLOBAL(0x009AC31C, sint16) = 3011; + // RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, sint8) = -1; + // RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, sint16) = 3011; return 0; } @@ -105,8 +105,8 @@ int scenario_load(const char *path) if (file != NULL) { if (!sawyercoding_validate_checksum(file)) { fclose(file); - RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; log_error("failed to load scenario, invalid checksum"); return 0; @@ -182,8 +182,8 @@ int scenario_load(const char *path) } log_error("failed to find scenario file."); - RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; return 0; } diff --git a/src/windows/options.c b/src/windows/options.c index 0d959a466b..a7fc5f3934 100644 --- a/src/windows/options.c +++ b/src/windows/options.c @@ -803,7 +803,7 @@ static void window_options_invalidate() w->disabled_widgets |= (1ULL << WIDX_REAL_NAME_CHECKBOX); // save plugin data checkbox: visible or not - if (RCT2_GLOBAL(0x00F42BDA, uint8) == 1) + if (RCT2_GLOBAL(RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED, uint8) == 1) window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_EMPTY; else window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_CHECKBOX;