diff --git a/src/editor.c b/src/editor.c index 1ec2ecd4a8..f3a22b84de 100644 --- a/src/editor.c +++ b/src/editor.c @@ -51,6 +51,7 @@ static int editor_load_landscape_from_sv4(const char *path); static int editor_load_landscape_from_sc4(const char *path); static void editor_finalise_main_view(); static int editor_read_s6(const char *path); +static void editor_clear_map_for_editing(); /** * @@ -260,37 +261,29 @@ bool editor_load_landscape(const utf8 *path) */ static int editor_load_landscape_from_sv4(const char *path) { - rct1_s4 *s4; + rct1_load_saved_game(path); + editor_clear_map_for_editing(); - s4 = malloc(sizeof(rct1_s4)); - if (!rct1_read_sv4(path, s4)) { - free(s4); - return 0; - } - rct1_import_s4(s4); - free(s4); - - rct1_fix_landscape(); - editor_finalise_main_view(); + g_editor_step = EDITOR_STEP_LANDSCAPE_EDITOR; RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_AGE, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR; + viewport_init_all(); + window_editor_main_open(); + editor_finalise_main_view(); return 1; } static int editor_load_landscape_from_sc4(const char *path) { - rct1_s4 *s4; + rct1_load_scenario(path); + editor_clear_map_for_editing(); - s4 = malloc(sizeof(rct1_s4)); - if (!rct1_read_sc4(path, s4)) { - free(s4); - return 0; - } - rct1_import_s4(s4); - free(s4); - - rct1_fix_landscape(); - editor_finalise_main_view(); + g_editor_step = EDITOR_STEP_LANDSCAPE_EDITOR; RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_AGE, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR; + viewport_init_all(); + window_editor_main_open(); + editor_finalise_main_view(); return 1; } @@ -388,95 +381,12 @@ static int editor_read_s6(const char *path) reset_loaded_objects(); map_update_tile_pointers(); - map_remove_all_rides(); - - // - for (i = 0; i < MAX_BANNERS; i++) - if (gBanners[i].type == 255) - gBanners[i].flags &= ~BANNER_FLAG_2; - - // - rct_ride *ride; - FOR_ALL_RIDES(i, ride) - user_string_free(ride->name); - - ride_init_all(); - - // - for (i = 0; i < MAX_SPRITES; i++) { - rct_sprite *sprite = &g_sprite_list[i]; - user_string_free(sprite->unknown.name_string_idx); - } - - reset_sprite_list(); - staff_reset_modes(); - RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_LAST_GUESTS_IN_PARK, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_CHANGE_MODIFIER, uint16) = 0; - if (s6Header->type != S6_TYPE_SCENARIO) { - research_populate_list_random(); - research_remove_non_separate_vehicle_types(); - - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY_SCENARIO; - else - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_NO_MONEY_SCENARIO; - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY; - - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == 0) - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY; - else - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY; - - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18; - - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) = clamp( - MONEY(10,00), - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16), - MONEY(100,00) - ); - - RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, uint32) = min(RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, uint32), 100000); - finance_reset_cash_to_initial(); - finance_update_loan_hash(); - - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = clamp( - MONEY(0,00), - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), - MONEY(5000000,00) - ); - - RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) = clamp( - MONEY(0,00), - RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32), - MONEY(5000000,00) - ); - - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8) = clamp( - 5, - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8), - 80 - ); - } - - climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8)); - - rct_stex_entry* stex = g_stexEntries[0]; - if ((int)stex != 0xFFFFFFFF) { - object_unload_chunk((rct_object_entry*)&object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]); - reset_loaded_objects(); - - format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); - s6Info->name[0] = 0; - } + game_convert_strings_to_utf8(); RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR; viewport_init_all(); - news_item_init_queue(); window_editor_main_open(); editor_finalise_main_view(); - game_convert_strings_to_utf8(); return 1; } @@ -486,6 +396,103 @@ static int editor_read_s6(const char *path) return 0; } +static void editor_clear_map_for_editing() +{ + rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4; + rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; + + map_remove_all_rides(); + + // + for (int i = 0; i < MAX_BANNERS; i++) { + if (gBanners[i].type == 255) { + gBanners[i].flags &= ~BANNER_FLAG_2; + } + } + + // + { + int i; + rct_ride *ride; + FOR_ALL_RIDES(i, ride) { + user_string_free(ride->name); + } + } + + ride_init_all(); + + // + for (int i = 0; i < MAX_SPRITES; i++) { + rct_sprite *sprite = &g_sprite_list[i]; + user_string_free(sprite->unknown.name_string_idx); + } + + reset_sprite_list(); + staff_reset_modes(); + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_LAST_GUESTS_IN_PARK, uint16) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_CHANGE_MODIFIER, uint16) = 0; + if (s6Header->type != S6_TYPE_SCENARIO) { + research_populate_list_random(); + research_remove_non_separate_vehicle_types(); + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY_SCENARIO; + else + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_NO_MONEY_SCENARIO; + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY; + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == 0) + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY; + else + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY; + + RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18; + + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) = clamp( + MONEY(10,00), + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16), + MONEY(100,00) + ); + + RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, uint32) = min(RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, uint32), 100000); + finance_reset_cash_to_initial(); + finance_update_loan_hash(); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = clamp( + MONEY(0,00), + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), + MONEY(5000000,00) + ); + + RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) = clamp( + MONEY(0,00), + RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32), + MONEY(5000000,00) + ); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8) = clamp( + 5, + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8), + 80 + ); + } + + climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8)); + + rct_stex_entry* stex = g_stexEntries[0]; + if ((int)stex != 0xFFFFFFFF) { + object_unload_chunk((rct_object_entry*)&object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]); + reset_loaded_objects(); + + format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); + s6Info->name[0] = 0; + } + + news_item_init_queue(); +} + /** * * rct2: 0x0067009A diff --git a/src/rct1.c b/src/rct1.c index d0d76be0e9..726b10cb0a 100644 --- a/src/rct1.c +++ b/src/rct1.c @@ -40,34 +40,6 @@ #include "world/map_animation.h" #include "world/scenery.h" -typedef struct { - const rct_object_entry* entries; - int count; -} RCT1DefaultObjectsGroup; - -static const uint8 RCT1TerrainConvertTable[16]; -static const uint8 RCT1TerrainEdgeConvertTable[16]; -static const uint8 RCT1PathTypeConversionTable[96]; -static const uint8 RCT1PathAdditionConversionTable[15]; -static const RCT1DefaultObjectsGroup RCT1DefaultObjects[10]; - -static void rct1_remove_rides(); -static void rct1_load_default_objects(); -static void rct1_fix_terrain(); -static void rct1_fix_scenery(); -static void rct1_fix_entrance_positions(); -static void rct1_reset_research(); - -static void rct1_process_scenario_flags(); -static void rct1_reset_park_entrance_path_type(); -static void rct1_clear_extra_sprite_entries(); -static void rct1_clear_extra_tile_entries(); -static void rct1_fix_colours(); -static void rct1_fix_z(); -static void rct1_fix_paths(); -static void rct1_fix_walls(); -static void sub_69E891(); - bool rct1_read_sc4(const char *path, rct1_s4 *s4) { uint8 *buffer, *decodedBuffer; @@ -124,2436 +96,114 @@ bool rct1_read_sv4(const char *path, rct1_s4 *s4) return success; } -/** - * - * rct2: 0x0069EEA0 - */ -void rct1_import_s4(rct1_s4 *s4) +bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry) { - int i; - rct_banner *banner; - - memcpy((void*)RCT2_ADDRESS_CURRENT_MONTH_YEAR, &s4->month, 16); - memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, 0x30000 * sizeof(rct_map_element)); - memcpy((void*)RCT2_ADDRESS_MAP_ELEMENTS, s4->map_elements, sizeof(s4->map_elements)); - memcpy((void*)0x010E63B8, &s4->unk_counter, 4 + sizeof(s4->sprites)); - - for (i = 0; i < MAX_BANNERS; i++) - gBanners[i].type = BANNER_NULL; - - memcpy((void*)RCT2_ADDRESS_SPRITES_NEXT_INDEX, &s4->next_sprite_index, 12424); - - for (i = 0; i < MAX_BANNERS; i++) { - banner = &gBanners[i]; - if (banner->type != 255 && banner->string_idx != 3458) - banner->string_idx = 778; - } - - memcpy((void*)0x0135A8F4, &s4->string_table, 0x2F51C); - memset((void*)RCT2_ADDRESS_STAFF_MODE_ARRAY, 0, 204); - memcpy((void*)0x0138B580, &s4->map_animations, 0x258F2); - memcpy((void*)0x013C6A72, &s4->patrol_areas, sizeof(s4->patrol_areas)); - - char *esi = (char*)0x13C6A72; - char *edi = (char*)RCT2_ADDRESS_STAFF_PATROL_AREAS; - int ebx, edx = 116; - do { - ebx = 32; - do { - memcpy(edi, esi, 4); esi += 4; edi += 4; - memset(edi, 0, 4); edi += 4; - } while (--ebx > 0); - memset(edi, 0, 64); edi += 64; - } while (--edx > 0); - edi += 0xA800; - - edx = 4; - do { - ebx = 32; - do { - memcpy(edi, esi, 4); esi += 4; edi += 4; - memset(edi, 0, 4); edi += 4; - } while (--ebx); - memset(edi, 0, 64); edi += 64; - } while (--edx); - - memcpy((void*)RCT2_ADDRESS_STAFF_MODE_ARRAY, &s4->unk_1F42AA, 116); - memcpy((void*)0x013CA73A, &s4->unk_1F431E, 4); - memcpy((void*)0x013CA73E, &s4->unk_1F4322, 0x41EA); -} - -/** - * - * rct2: 0x006A2B62 - */ -void rct1_fix_landscape() -{ - int i; - rct_sprite *sprite; - rct_ride *ride; - - rct1_clear_extra_sprite_entries(); - - // Free sprite user strings - for (i = 0; i < MAX_SPRITES; i++) { - sprite = &g_sprite_list[i]; - if (sprite->unknown.sprite_identifier != 255) - user_string_free(sprite->unknown.name_string_idx); - } - - reset_sprite_list(); - - // Free ride user strings - FOR_ALL_RIDES(i, ride) - user_string_free(ride->name); - - ride_init_all(); - RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_LAST_GUESTS_IN_PARK, uint16) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_CHANGE_MODIFIER, uint8) = 0; - rct1_clear_extra_tile_entries(); - rct1_process_scenario_flags(); - rct1_fix_colours(); - rct1_fix_z(); - rct1_fix_paths(); - rct1_remove_rides(); - object_unload_all(); - rct1_load_default_objects(); - reset_loaded_objects(); - rct1_fix_walls(); - rct1_fix_terrain(); - rct1_fix_entrance_positions(); - rct1_reset_research(); - research_populate_list_random(); - research_remove_non_separate_vehicle_types(); - - climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8)); - RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR; - viewport_init_all(); - news_item_init_queue(); - window_editor_main_open(); - - rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4; - rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; - - s6Info->editor_step = EDITOR_STEP_LANDSCAPE_EDITOR; - s6Info->category = 4; - format_string(s6Info->details, STR_NO_DETAILS_YET, NULL); - s6Info->name[0] = 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) { - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY_SCENARIO; - } else { - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_NO_MONEY_SCENARIO; - } - if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == MONEY_FREE) { - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY; - } else { - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY; - } - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18; - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) = clamp( - MONEY(10,00), - RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16), - MONEY(100,00) - ); - RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) = min( - MONEY(10000,00), - RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) - ); - finance_reset_cash_to_initial(); - finance_update_loan_hash(); - - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = clamp( - MONEY(0,00), - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), - MONEY(5000000,00) - ); - - RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) = clamp( - MONEY(0,00), - RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32), - MONEY(5000000,00) - ); - - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8) = clamp( - 5, - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8), - 80 - ); - - if ( - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_NONE || - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_HAVE_FUN || - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_BUILD_THE_BEST - ) { - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) = OBJECTIVE_GUESTS_BY; - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8) = 4; - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16) = 1000; - } - - RCT2_GLOBAL(0x01358774, uint16) = 0; -} - -static void rct1_remove_rides() -{ - map_element_iterator it; - - map_element_iterator_begin(&it); - do { - switch (map_element_get_type(it.element)) { - case MAP_ELEMENT_TYPE_PATH: - if (it.element->type & 1) { - it.element->properties.path.type &= 0xF7; - it.element->properties.path.ride_index = 255; - } - break; - - case MAP_ELEMENT_TYPE_TRACK: - sub_6A7594(); - footpath_remove_edges_at(it.x * 32, it.y * 32, it.element); - map_element_remove(it.element); - map_element_iterator_restart_for_tile(&it); - break; - - case MAP_ELEMENT_TYPE_ENTRANCE: - if (it.element->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) { - sub_6A7594(); - footpath_remove_edges_at(it.x * 32, it.y * 32, it.element); - map_element_remove(it.element); - map_element_iterator_restart_for_tile(&it); - } - break; - } - } while (map_element_iterator_next(&it)); -} - -static bool is_object_name_blank(rct_object_entry *entry) -{ - for (int i = 0; i < 8; i++) { - if (entry->name[i] != ' ') { - return false; - } - } - return true; -} - -/** - * - * rct2: 0x0069F53D - */ -static void rct1_load_default_objects() -{ - for (int i = 0; i < 9; i++) { - rct_object_entry *entries = (rct_object_entry*)RCT1DefaultObjects[i].entries; - for (int j = 0; j < RCT1DefaultObjects[i].count; j++) { - if (is_object_name_blank(&entries[j])) { - continue; - } - - if (!object_load_chunk(j, &entries[j], NULL)) { - error_string_quit(0x99990000 + (i * 0x100) + j, -1); - return; - } - } - } - - // Water is a special case - rct_object_entry *waterEntries = (rct_object_entry*)RCT1DefaultObjects[9].entries; - rct_object_entry *waterEntry = &waterEntries[RCT2_GLOBAL(0x01358841, uint8) == 0 ? 0 : 1]; - if (!object_load_chunk(0, waterEntry, NULL)) { - error_string_quit(0x99990900, -1); - return; - } -} - -/** - * - * rct2: 0x006A29B9 - */ -static void rct1_fix_terrain() -{ - rct_map_element *element; - map_element_iterator it; - - map_element_iterator_begin(&it); - while (map_element_iterator_next(&it)) { - element = it.element; - - if (map_element_get_type(element) != MAP_ELEMENT_TYPE_SURFACE) - continue; - - // Convert terrain - map_element_set_terrain(element, RCT1TerrainConvertTable[map_element_get_terrain(element)]); - map_element_set_terrain_edge(element, RCT1TerrainEdgeConvertTable[map_element_get_terrain_edge(element)]); - } -} - -/** - * This isn't really RCT1 specific anymore. - * rct2: 0x006A2A68 - */ -static void rct1_fix_entrance_positions() -{ - rct_map_element *element; - map_element_iterator it; - - for (int i = 0; i < 4; i++) - RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_X, uint16)[i] = 0x8000; - - int entranceIndex = 0; - - map_element_iterator_begin(&it); - while (map_element_iterator_next(&it)) { - element = it.element; - - if (map_element_get_type(element) != MAP_ELEMENT_TYPE_ENTRANCE) - continue; - if (element->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) - continue; - if ((element->properties.entrance.index & 0x0F) != 0) - continue; - - RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_X, uint16)[entranceIndex] = it.x * 32; - RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_Y, uint16)[entranceIndex] = it.y * 32; - RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_Z, uint16)[entranceIndex] = element->base_height * 8; - RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_DIRECTION, uint8)[entranceIndex] = element->type & 3; - entranceIndex++; - - // Prevent overflow - if (entranceIndex == 4) - return; - } -} - -/** - * - * rct2: 0x0069F509 - */ -static void rct1_reset_research() -{ - rct_research_item *researchItem; - - researchItem = gResearchItems; - researchItem->entryIndex = RESEARCHED_ITEMS_SEPARATOR; - researchItem++; - researchItem->entryIndex = RESEARCHED_ITEMS_END; - researchItem++; - researchItem->entryIndex = RESEARCHED_ITEMS_END_2; - RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_LAST_RESEARCHED_ITEM_SUBJECT, sint32) = -1; - news_item_init_queue(); -} - -/** - * - * rct2: 0x0069F06A - */ -static void rct1_process_scenario_flags() -{ - uint32 scenarioFlags = RCT2_GLOBAL(0x013CE770, uint32); - - if (!(scenarioFlags & RCT1_SCENARIO_FLAG_ENABLE_BANNERS)) { - banner_init(); - } - if (!(scenarioFlags & (1 << 6))) { - sub_69E891(); - } - if (!(scenarioFlags & RCT1_SCENARIO_FLAG_CUSTOM_PARK_ENTRANCE_PATH)) { - rct1_reset_park_entrance_path_type(); - } - if (!(scenarioFlags & RCT1_SCENARIO_FLAG_NO_CASH_RESET)) { - finance_reset_cash_to_initial(); - } - if (!(scenarioFlags & RCT1_SCENARIO_FLAG_CUSTOM_MAP_SIZE)) { - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16) = 127 * 32; - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_MINUS_2, uint16) = 4350; - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16) = 128; - RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAX_XY, uint16) = 4095; - } - if (!(scenarioFlags & (1 << 15))) { - RCT2_GLOBAL(0x01358838, uint32) = 0; - } -} - -/** - * - * rct2: 0x00666DFD - */ -static void rct1_reset_park_entrance_path_type() -{ - int x, y; - rct_map_element *mapElement; - - x = RCT2_GLOBAL(0x013573EA, uint16); - y = RCT2_GLOBAL(0x013573EC, uint16); - if (x == (sint16)0x8000) - return; - - mapElement = map_get_first_element_at(x >> 5, y >> 5); - do { - if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) { - if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE) { - mapElement->properties.entrance.path_type = 0; - break; - } - } - } while (!map_element_is_last_for_tile(mapElement++)); -} - -/** - * - * rct2: 0x0069F007 - */ -static void rct1_clear_extra_sprite_entries() -{ - rct_unk_sprite *sprite; - - for (int i = 5000; i < MAX_SPRITES; i++) { - sprite = &(g_sprite_list[i].unknown); - - memset(&g_sprite_list[i], 0, sizeof(rct_sprite)); - - sprite->sprite_identifier = 255; - sprite->sprite_index = i; - sprite->linked_list_type_offset = SPRITE_LINKEDLIST_OFFSET_NULL; - sprite->previous = SPRITE_INDEX_NULL; - sprite->next = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16); - RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16) = i; - - sprite = &(g_sprite_list[sprite->next].unknown); - sprite->previous = i; - } - RCT2_GLOBAL(0x013573C8, uint16) += 5000; -} - -/** - * - * rct2: 0x0069F44B - */ -static void rct1_clear_extra_tile_entries() -{ - // Reset the map tile pointers - for (int i = 0; i < 0x10000; i++) { - gMapElementTilePointers[i] = (rct_map_element*)-1; - } - - // Get the first free map element - rct_map_element *nextFreeMapElement = gMapElements; - for (int i = 0; i < 128 * 128; i++) { - do { - - } while (!map_element_is_last_for_tile(nextFreeMapElement++)); - } - - rct_map_element *mapElement = gMapElements; - rct_map_element **tilePointer = gMapElementTilePointers; - - // 128 rows of map data from RCT1 map - for (int x = 0; x < 128; x++) { - // Assign the first half of this row - for (int y = 0; y < 128; y++) { - *tilePointer++ = mapElement; - do { - - } while (!map_element_is_last_for_tile(mapElement++)); - } - - // Fill the rest of the row with blank tiles - for (int y = 0; y < 128; y++) { - nextFreeMapElement->type = MAP_ELEMENT_TYPE_SURFACE; - nextFreeMapElement->flags = MAP_ELEMENT_FLAG_LAST_TILE; - nextFreeMapElement->base_height = 2; - nextFreeMapElement->clearance_height = 0; - nextFreeMapElement->properties.surface.slope = 0; - nextFreeMapElement->properties.surface.terrain = 0; - nextFreeMapElement->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0; - nextFreeMapElement->properties.surface.ownership = 0; - *tilePointer++ = nextFreeMapElement++; - } - } - - // 128 extra rows left to fill with blank tiles - for (int y = 0; y < 128 * 256; y++) { - nextFreeMapElement->type = MAP_ELEMENT_TYPE_SURFACE; - nextFreeMapElement->flags = MAP_ELEMENT_FLAG_LAST_TILE; - nextFreeMapElement->base_height = 2; - nextFreeMapElement->clearance_height = 0; - nextFreeMapElement->properties.surface.slope = 0; - nextFreeMapElement->properties.surface.terrain = 0; - nextFreeMapElement->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0; - nextFreeMapElement->properties.surface.ownership = 0; - *tilePointer++ = nextFreeMapElement++; - } - - RCT2_GLOBAL(RCT2_ADDRESS_NEXT_FREE_MAP_ELEMENT, rct_map_element*) = nextFreeMapElement; -} - -/** - * - * rct2: 0x0069F143 - */ -static void rct1_fix_colours() -{ - int rideIndex, colour; - rct_ride *ride; - rct_unk_sprite *sprite; - rct_peep *peep; - rct_balloon *balloon; - rct_map_element *mapElement; - - FOR_ALL_RIDES(rideIndex, ride) { - for (int i = 0; i < 4; i++) { - ride->track_colour_main[i] = RCT1ColourConversionTable[ride->track_colour_main[i]]; - ride->track_colour_additional[i] = RCT1ColourConversionTable[ride->track_colour_additional[i]]; - ride->track_colour_supports[i] = RCT1ColourConversionTable[ride->track_colour_supports[i]]; - } - - for (int i = 0; i < 32; i++) { - ride->vehicle_colours[i].body_colour = RCT1ColourConversionTable[ride->vehicle_colours[i].body_colour]; - ride->vehicle_colours[i].trim_colour = RCT1ColourConversionTable[ride->vehicle_colours[i].trim_colour]; - } - } - - for (int i = 0; i < MAX_SPRITES; i++) { - sprite = &(g_sprite_list[i].unknown); - switch (sprite->sprite_identifier) { - case SPRITE_IDENTIFIER_PEEP: - peep = (rct_peep*)sprite; - peep->tshirt_colour = RCT1ColourConversionTable[peep->tshirt_colour]; - peep->trousers_colour = RCT1ColourConversionTable[peep->trousers_colour]; - peep->balloon_colour = RCT1ColourConversionTable[peep->balloon_colour]; - peep->umbrella_colour = RCT1ColourConversionTable[peep->umbrella_colour]; - peep->hat_colour = RCT1ColourConversionTable[peep->hat_colour]; - break; - case SPRITE_IDENTIFIER_MISC: - balloon = (rct_balloon*)sprite; - balloon->colour = RCT1ColourConversionTable[balloon->colour]; - balloon->var_2D = RCT1ColourConversionTable[balloon->var_2D]; - break; - } - } - - mapElement = gMapElements; - while (mapElement < RCT2_GLOBAL(RCT2_ADDRESS_NEXT_FREE_MAP_ELEMENT, rct_map_element*)) { - if (mapElement->base_height != 255) { - switch (map_element_get_type(mapElement)) { - case MAP_ELEMENT_TYPE_SCENERY: - colour = RCT1ColourConversionTable[mapElement->properties.scenery.colour_1 & 0x1F]; - mapElement->properties.scenery.colour_1 &= 0xE0; - mapElement->properties.scenery.colour_1 |= colour; - - // Copied from [rct2: 0x006A2956] - switch (mapElement->properties.scenery.type) { - case 157: // TGE1 (Geometric Sculpture) - case 162: // TGE2 (Geometric Sculpture) - case 168: // TGE3 (Geometric Sculpture) - case 170: // TGE4 (Geometric Sculpture) - case 171: // TGE5 (Geometric Sculpture) - mapElement->properties.scenery.colour_2 = COLOUR_WHITE; - break; - } - break; - case MAP_ELEMENT_TYPE_FENCE: - colour = RCT1ColourConversionTable[ - ((mapElement->type & 0xC0) >> 3) | - ((mapElement->properties.fence.type & 0xE0) >> 5) - ]; - - mapElement->type &= 0x3F; - mapElement->properties.fence.type &= 0x1F; - mapElement->type |= (colour & 0x18) << 3; - mapElement->properties.fence.type |= (colour & 7) << 5; - break; - case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: - colour = RCT1ColourConversionTable[mapElement->properties.scenerymultiple.colour[0] & 0x1F]; - mapElement->properties.scenerymultiple.colour[0] &= 0xE0; - mapElement->properties.scenerymultiple.colour[0] |= colour; - - colour = RCT1ColourConversionTable[mapElement->properties.scenerymultiple.colour[1] & 0x1F]; - mapElement->properties.scenerymultiple.colour[1] &= 0xE0; - mapElement->properties.scenerymultiple.colour[1] |= colour; - break; - } - } - mapElement++; - } -} - -/** - * - * rct2: 0x0069F2D0 - */ -static void rct1_fix_z() -{ - int i; - rct_ride *ride; - rct_unk_sprite *sprite; - rct_peep *peep; - rct_ride_measurement *rideMeasurement; - rct_map_element *mapElement; - - FOR_ALL_RIDES(i, ride) { - for (int i = 0; i < 4; i++) { - ride->station_heights[i] /= 2; - } - ride->start_drop_height /= 2; - ride->highest_drop_height = 1; - if (ride->cur_test_track_z != 255) { - ride->cur_test_track_z /= 2; - } - ride->chairlift_bullwheel_z[0] /= 2; - ride->chairlift_bullwheel_z[1] /= 2; - } - - for (int i = 0; i < RCT2_GLOBAL(0x0138B580, uint16); i++) { - gAnimatedObjects[i].baseZ /= 2; - } - - for (int i = 0; i < MAX_SPRITES; i++) { - sprite = &(g_sprite_list[i].unknown); - if (sprite->sprite_identifier == SPRITE_IDENTIFIER_PEEP) { - peep = (rct_peep*)sprite; - peep->next_z /= 2; - RCT2_GLOBAL((int)peep + 0xCE, uint8) /= 2; - } - } - - for (int i = 0; i < MAX_RIDE_MEASUREMENTS; i++) { - rideMeasurement = get_ride_measurement(i); - if (rideMeasurement->ride_index == 255) - continue; - - for (int i = 0; i < RIDE_MEASUREMENT_MAX_ITEMS; i++) { - rideMeasurement->altitude[i] /= 2; - } - } - - mapElement = gMapElements; - while (mapElement < RCT2_GLOBAL(RCT2_ADDRESS_NEXT_FREE_MAP_ELEMENT, rct_map_element*)) { - if (mapElement->base_height != 255) { - mapElement->base_height /= 2; - mapElement->clearance_height /= 2; - } - mapElement++; - } - RCT2_GLOBAL(0x01359208, uint16) = 7; -} - -/** - * - * rct2: 0x0069F3AB - */ -static void rct1_fix_paths() -{ - rct_map_element *mapElement; - int pathType, secondaryType, additions; - - mapElement = gMapElements; - while (mapElement < RCT2_GLOBAL(RCT2_ADDRESS_NEXT_FREE_MAP_ELEMENT, rct_map_element*)) { - switch (map_element_get_type(mapElement)) { - case MAP_ELEMENT_TYPE_PATH: - // Type - pathType = ((mapElement->properties.path.type & 0xF0) >> 2) | (mapElement->type & 3); - secondaryType = (mapElement->flags & 0x60) >> 5; - pathType = RCT1PathTypeConversionTable[pathType * 4 + secondaryType]; - - mapElement->type &= 0xFC; - mapElement->flags &= ~0x60; - mapElement->properties.path.type &= 0x0F; - footpath_scenery_set_is_ghost(mapElement, false); - if (pathType & 0x80) { - mapElement->type |= 1; - } - mapElement->properties.path.type |= pathType << 4; - - // Additions - additions = RCT1PathAdditionConversionTable[footpath_element_get_path_scenery(mapElement)]; - if (footpath_element_path_scenery_is_ghost(mapElement)) { - footpath_scenery_set_is_ghost(mapElement, false); - mapElement->flags |= MAP_ELEMENT_FLAG_BROKEN; - } else { - mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN; - } - - footpath_element_set_path_scenery(mapElement, additions); - break; - case MAP_ELEMENT_TYPE_ENTRANCE: - if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE) { - pathType = mapElement->properties.entrance.path_type; - mapElement->properties.entrance.path_type = RCT1PathTypeConversionTable[pathType * 4] & 0x7F; - } - break; - } - mapElement++; - } -} - -/** - * - * rct2: 0x006A28F5 - */ -static void rct1_convert_wall(int *type, int *colourA, int *colourB, int *colourC) -{ - switch (*type) { - case 12: // creepy gate - *colourA = 24; - break; - case 26: // white wooden fence - *type = 12; - *colourA = 2; - break; - case 27: // red wooden fence - *type = 12; - *colourA = 25; - break; - case 50: // plate glass - *colourA = 24; - break; - case 13: - *colourB = *colourA; - *colourA = 24; - break; - case 11: // tall castle wall with grey gate - case 22: // brick wall with gate - *colourB = 2; - break; - case 35: // wood post fence - case 42: // tall grey castle wall - case 43: // wooden fence with snow - case 44: - case 45: - case 46: - *colourA = 1; - break; - } -} - -/** - * - * rct2: 0x006A2730 - */ -static void rct1_fix_walls() -{ - rct_map_element *mapElement, originalMapElement; - - for (int x = 0; x < 128; x++) { - for (int y = 0; y < 128; y++) { - mapElement = map_get_first_element_at(x, y); - do { - if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_FENCE) { - originalMapElement = *mapElement; - map_element_remove(mapElement); - - uint8 var_05 = originalMapElement.properties.fence.item[0]; - uint16 var_06 = ( - originalMapElement.properties.fence.item[1] | - (originalMapElement.properties.fence.item[2] << 8) - ); - - for (int edge = 0; edge < 4; edge++) { - int typeA = (var_05 >> (edge * 2)) & 3; - int typeB = (var_06 >> (edge * 4)) & 0x0F; - if (typeB != 0x0F) { - int type = typeA | (typeB << 2); - int colourA = ( - ((originalMapElement.type & 0xC0) >> 3) | - (originalMapElement.properties.fence.type >> 5) - ); - int colourB = 0; - int colourC = 0; - rct1_convert_wall(&type, &colourA, &colourB, &colourC); - map_place_fence(type, x * 32, y * 32, 0, edge, colourA, colourB, colourC, 169); - } - } - break; - } - } while (!map_element_is_last_for_tile(mapElement++)); - } - } -} - -static void rct1_fix_banners(rct1_s4 *s4) -{ - rct_map_element *mapElement; - int index; - - for (int x = 0; x < 128; x++) { - for (int y = 0; y < 128; y++) { - mapElement = map_get_first_element_at(x, y); - do { - if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_BANNER) { - index = mapElement->properties.banner.index; - gBanners[index] = s4->banners[index]; - gBanners[index].colour = RCT1ColourConversionTable[gBanners[index].colour]; - gBanners[index].string_idx = 778; - - if (is_user_string_id(s4->banners[index].string_idx)) { - const char *bannerText = s4->string_table[(s4->banners[index].string_idx - 0x8000) % 1024]; - if (bannerText[0] != 0) { - rct_string_id bannerTextStringId = user_string_allocate(128, bannerText); - if (bannerTextStringId != 0) { - gBanners[index].string_idx = bannerTextStringId; - } - } - } - } - } while (!map_element_is_last_for_tile(mapElement++)); - } - } -} - -/** - * - * rct2: 0x0069E891 - */ -static void sub_69E891() -{ - RCT2_GLOBAL(0x013587D8, uint16) = 63; -} - -#pragma region Tables - -/** - * - * rct2: 0x0097F0BC, 0x0098BC60 - */ -const colour_t RCT1ColourConversionTable[32] = { - COLOUR_BLACK, - COLOUR_GREY, - COLOUR_WHITE, - COLOUR_LIGHT_PURPLE, - COLOUR_BRIGHT_PURPLE, - COLOUR_DARK_BLUE, - COLOUR_LIGHT_BLUE, - COLOUR_TEAL, - COLOUR_SATURATED_GREEN, - COLOUR_DARK_GREEN, - COLOUR_MOSS_GREEN, - COLOUR_BRIGHT_GREEN, - COLOUR_OLIVE_GREEN, - COLOUR_DARK_OLIVE_GREEN, - COLOUR_YELLOW, - COLOUR_DARK_YELLOW, - COLOUR_LIGHT_ORANGE, - COLOUR_DARK_ORANGE, - COLOUR_LIGHT_BROWN, - COLOUR_SATURATED_BROWN, - COLOUR_DARK_BROWN, - COLOUR_SALMON_PINK, - COLOUR_BORDEAUX_RED, - COLOUR_SATURATED_RED, - COLOUR_BRIGHT_RED, - COLOUR_BRIGHT_PINK, - COLOUR_LIGHT_PINK, - COLOUR_DARK_PINK, - COLOUR_DARK_PURPLE, - COLOUR_AQUAMARINE, - COLOUR_BRIGHT_YELLOW, - COLOUR_ICY_BLUE -}; - -static const uint8 RCT1TerrainConvertTable[16] = { - TERRAIN_GRASS, - TERRAIN_SAND, - TERRAIN_DIRT, - TERRAIN_ROCK, - TERRAIN_MARTIAN, - TERRAIN_CHECKERBOARD, - TERRAIN_GRASS_CLUMPS, - TERRAIN_DIRT, // Originally TERRAIN_ROOF_BROWN - TERRAIN_ICE, - TERRAIN_DIRT, // Originally TERRAIN_ROOF_LOG - TERRAIN_DIRT, // Originally TERRAIN_ROOF_IRON - TERRAIN_ROCK, // Originally TERRAIN_ROOF_GREY - TERRAIN_GRID_RED, - TERRAIN_GRID_YELLOW, - TERRAIN_GRID_BLUE, - TERRAIN_GRID_GREEN -}; - -static const uint8 RCT1TerrainEdgeConvertTable[16] = { - TERRAIN_EDGE_ROCK, - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_BRICK - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_IRON - TERRAIN_EDGE_WOOD_RED, - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_GREY - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_YELLOW - TERRAIN_EDGE_WOOD_BLACK, - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_RED - TERRAIN_EDGE_ICE, - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_PURPLE - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_GREEN - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_STONE_BROWN - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_STONE_GREY - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_SKYSCRAPER_A - TERRAIN_EDGE_ROCK, // Originally TERRAIN_EDGE_SKYSCRAPER_B - TERRAIN_EDGE_ROCK // Unused -}; - -// rct2: 0x0098BC9F -static const uint8 RCT1PathTypeConversionTable[96] = { - 0x80 | 0, 0x80 | 1, 0x80 | 2, 0x80 | 3, - 0x80 | 0, 0x80 | 1, 0x80 | 2, 0x80 | 3, - 0x80 | 0, 0x80 | 1, 0x80 | 2, 0x80 | 3, - 0x80 | 0, 0x80 | 1, 0x80 | 2, 0x80 | 3, - 0, 0, 0, 0, - 2, 2, 2, 2, - 1, 1, 1, 1, - 0, 0, 0, 0, - 3, 3, 3, 3, - 6, 6, 6, 6, - 0, 0, 0, 0, - 0, 0, 0, 0, - 5, 5, 5, 5, - 5, 5, 5, 5, - 5, 5, 5, 5, - 5, 5, 5, 5, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; - -// rct2: 0x0098BCFF -static const uint8 RCT1PathAdditionConversionTable[15] = { - 0, - 1, 2, 3, 4, 5, 6, 7, - 0x80 | 1, 0x80 | 2, 0x80 | 3, 0x80 | 4, 0x80 | 6, 0x80 | 7, - 8, -}; - -#pragma endregion - -#pragma region RCT1 Default Objects - -static const rct_object_entry RCT1DefaultObjectsRides[] = { - /* - * Entries in this list up to and including LEMST have to stay as they are, as they line up with the RCT1 S4 structure. - * For more information, see here: https://github.com/OpenRCT2/OpenRCT2/wiki/RCT1-ride-and-vehicle-types-and-their-RCT2-equivalents - */ - { 0x00008000, { "PTCT1 " }, 0 }, - { 0x00008000, { "TOGST " }, 0 }, - { 0x00008000, { "ARRSW1 " }, 0 }, - { 0x00008000, { "NEMT " }, 0 }, - { 0x00008000, { "ZLDB " }, 0 }, - { 0x00008000, { "NRL " }, 0 }, - { 0x00008000, { "MONO2 " }, 0 }, - { 0x00008000, { "BATFL " }, 0 }, - { 0x00008000, { "RBOAT " }, 0 }, - { 0x00008000, { "WMOUSE " }, 0 }, - { 0x00008000, { "STEEP1 " }, 0 }, - { 0x00008000, { "SPCAR " }, 0 }, - { 0x00008000, { "SSC1 " }, 0 }, - { 0x00008000, { "BOB1 " }, 0 }, - { 0x00008000, { "OBS1 " }, 0 }, - { 0x00008000, { "SCHT1 " }, 0 }, - { 0x00008000, { "DING1 " }, 0 }, - { 0x00008000, { "AMT1 " }, 0 }, - { 0x00008000, { "CLIFT1 " }, 0 }, - { 0x00008000, { "ARRT1 " }, 0 }, - { 0x00008000, { "HMAZE " }, 0 }, - { 0x00008000, { "HSKELT " }, 0 }, - { 0x00008000, { "KART1 " }, 0 }, - { 0x00008000, { "LFB1 " }, 0 }, - { 0x00008000, { "RAPBOAT " }, 0 }, - { 0x00008000, { "DODG1 " }, 0 }, - { 0x00008000, { "SWSH1 " }, 0 }, - { 0x00008000, { "SWSH2 " }, 0 }, - { 0x00008000, { "ICECR1 " }, 0 }, - { 0x00008000, { "CHPSH " }, 0 }, - { 0x00008000, { "DRNKS " }, 0 }, - { 0x00008000, { "CNDYF " }, 0 }, - { 0x00008000, { "BURGB " }, 0 }, - { 0x00008000, { "MGR1 " }, 0 }, - { 0x00008000, { "BALLN " }, 0 }, - { 0x00008000, { "INFOK " }, 0 }, - { 0x00008000, { "TLT1 " }, 0 }, - { 0x00008000, { "FWH1 " }, 0 }, - { 0x00008000, { "SIMPOD " }, 0 }, - { 0x00008000, { "C3D " }, 0 }, - { 0x00008000, { "TOPSP1 " }, 0 }, - { 0x00008000, { "SRINGS " }, 0 }, - { 0x00008000, { "REVF1 " }, 0 }, - { 0x00008000, { "SOUVS " }, 0 }, - { 0x00008000, { "BMVD " }, 0 }, - { 0x00008000, { "PIZZS " }, 0 }, - { 0x00008000, { "TWIST1 " }, 0 }, - { 0x00008000, { "HHBUILD " }, 0 }, - { 0x00008000, { "POPCS " }, 0 }, - { 0x00008000, { "CIRCUS1 " }, 0 }, - { 0x00008000, { "GTC " }, 0 }, - { 0x00008000, { "BMSD " }, 0 }, - { 0x00008000, { "MFT " }, 0 }, - { 0x00008000, { "SFRIC1 " }, 0 }, - { 0x00008000, { "SMC1 " }, 0 }, - { 0x00008000, { "HOTDS " }, 0 }, - { 0x00008000, { "SQDST " }, 0 }, - { 0x00008000, { "HATST " }, 0 }, - { 0x00008000, { "TOFFS " }, 0 }, - { 0x00008000, { "VREEL " }, 0 }, - { 0x00008000, { "SPBOAT " }, 0 }, - { 0x00008000, { "MONBK " }, 0 }, - { 0x00008000, { "BMAIR " }, 0 }, - { 0x00008000, { "SMONO " }, 0 }, - { 0x00000000, { " " }, 0 }, - { 0x00008000, { "REVCAR " }, 0 }, - { 0x00008000, { "UTCAR " }, 0 }, - { 0x00008000, { "GOLF1 " }, 0 }, - { 0x00000000, { " " }, 0 }, - { 0x00008000, { "GDROP1 " }, 0 }, - { 0x00008000, { "FSAUC " }, 0 }, - { 0x00008000, { "CHBUILD " }, 0 }, - { 0x00008000, { "HELICAR " }, 0 }, - { 0x00008000, { "SLCT " }, 0 }, - { 0x00008000, { "CSTBOAT " }, 0 }, - { 0x00008000, { "THCAR " }, 0 }, - { 0x00008000, { "IVMC1 " }, 0 }, - { 0x00008000, { "JSKI " }, 0 }, - { 0x00008000, { "TSHRT " }, 0 }, - { 0x00008000, { "RFTBOAT " }, 0 }, - { 0x00008000, { "DOUGH " }, 0 }, - { 0x00008000, { "ENTERP " }, 0 }, - { 0x00008000, { "COFFS " }, 0 }, - { 0x00008000, { "CHCKS " }, 0 }, - { 0x00008000, { "LEMST " }, 0 }, - // The entries that follow from here are alternative vehicles. - { 0x00008000, { "WMSPIN " }, 0 }, - { 0x00008000, { "SWANS " }, 0 }, - { 0x00008000, { "MONO1 " }, 0 }, - { 0x00008000, { "CBOAT " }, 0 }, - { 0x00008000, { "BBOAT " }, 0 }, - { 0x00008000, { "RCKC " }, 0 }, - { 0x00008000, { "SKYTR " }, 0 }, - { 0x00008000, { "WMMINE " }, 0 }, - { 0x00008000, { "ARRSW2 " }, 0 }, - { 0x00008000, { "TRIKE " }, 0 }, - { 0x00008000, { "STEEP2 " }, 0 }, - { 0x00008000, { "RCR " }, 0 }, - { 0x00008000, { "TRUCK1 " }, 0 }, - { 0x00008000, { "CTCAR " }, 0 }, - { 0x00008000, { "ZLOG " }, 0 }, - { 0x00008000, { "VCR " }, 0 }, - { 0x00008000, { "NRL2 " }, 0 }, - { 0x00008000, { "BMSU " }, 0 }, - { 0x00008000, { "BMFL " }, 0 }, - { 0x00008000, { "CLIFT2 " }, 0 }, - { 0x00008000, { "BMRB " }, 0 }, - { 0x00008000, { "UTCARR " }, 0 }, - { 0x00008000, { "ARRT2 " }, 0 }, - { 0x00008000, { "SLCFO " }, 0 }, - { 0x00008000, { "AML1 " }, 0 } -}; - -// Maps an alternative vehicle to an entry in RCT1DefaultObjectsRides. -static const uint8 RCT1AlternativeVehicleMappings[89] = { - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_STEEL_ROLLER_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_STEEL_ROLLER_COASTER_TRAIN_BACKWARDS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_WOODEN_ROLLER_COASTER_TRAIN - 73, // RCT1_VEHICLE_TYPE_INVERTED_COASTER_TRAIN // Not in RCT2 - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SUSPENDED_SWINGING_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_LADYBIRD_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_STANDUP_ROLLER_COASTER_CARS - 85, // RCT1_VEHICLE_TYPE_SPINNING_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SINGLE_PERSON_SWINGING_CHAIRS - 86, // RCT1_VEHICLE_TYPE_SWANS_PEDAL_BOATS - 87, // RCT1_VEHICLE_TYPE_LARGE_MONORAIL_TRAIN - 88, // RCT1_VEHICLE_TYPE_CANOES - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_ROWING_BOATS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_STEAM_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_WOODEN_MOUSE_CARS - 89, // RCT1_VEHICLE_TYPE_BUMPER_BOATS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_WOODEN_ROLLER_COASTER_TRAIN_BACKWARDS - 90, // RCT1_VEHICLE_TYPE_ROCKET_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_HORSES // Steeplechase - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SPORTSCARS - 91, // RCT1_VEHICLE_TYPE_LYING_DOWN_SWINGING_CARS // Inverted single-rail - 92, // RCT1_VEHICLE_TYPE_WOODEN_MINE_CARS - 93, // RCT1_VEHICLE_TYPE_SUSPENDED_SWINGING_AIRPLANE_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SMALL_MONORAIL_CARS - 94, // RCT1_VEHICLE_TYPE_WATER_TRICYCLES - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_LAUNCHED_FREEFALL_CAR - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_BOBSLEIGH_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_DINGHIES - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_ROTATING_CABIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_MINE_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_CHAIRLIFT_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_CORKSCREW_ROLLER_COASTER_TRAIN - 95, // RCT1_VEHICLE_TYPE_MOTORBIKES - 96, // RCT1_VEHICLE_TYPE_RACING_CARS - 97, // RCT1_VEHICLE_TYPE_TRUCKS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_GO_KARTS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_RAPIDS_BOATS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_LOG_FLUME_BOATS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_DODGEMS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SWINGING_SHIP - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SWINGING_INVERTER_SHIP - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_MERRY_GO_ROUND - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_FERRIS_WHEEL - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SIMULATOR_POD - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_CINEMA_BUILDING - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_TOPSPIN_CAR - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SPACE_RINGS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_REVERSE_FREEFALL_ROLLER_COASTER_CAR - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_VERTICAL_ROLLER_COASTER_CARS - 98, // RCT1_VEHICLE_TYPE_CAT_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_TWIST_ARMS_AND_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_HAUNTED_HOUSE_BUILDING - 99, // RCT1_VEHICLE_TYPE_LOG_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_CIRCUS_TENT - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_GHOST_TRAIN_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_STEEL_TWISTER_ROLLER_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_WOODEN_TWISTER_ROLLER_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_WOODEN_SIDE_FRICTION_CARS - 100, // RCT1_VEHICLE_TYPE_VINTAGE_CARS - 101, // RCT1_VEHICLE_TYPE_STEAM_TRAIN_COVERED_CARS - 102, // RCT1_VEHICLE_TYPE_STAND_UP_STEEL_TWISTER_ROLLER_COASTER_TRAIN - 103, // RCT1_VEHICLE_TYPE_FLOORLESS_STEEL_TWISTER_ROLLER_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_STEEL_MOUSE_CARS - 104, // RCT1_VEHICLE_TYPE_CHAIRLIFT_CARS_ALTERNATIVE - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SUSPENDED_MONORAIL_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_HELICOPTER_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_VIRGINIA_REEL_TUBS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_REVERSER_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_GOLFERS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_RIVER_RIDE_BOATS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_FLYING_ROLLER_COASTER_TRAIN - 105, // RCT1_VEHICLE_TYPE_NON_LOOPING_STEEL_TWISTER_ROLLER_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_HEARTLINE_TWISTER_CARS - 106, // RCT1_VEHICLE_TYPE_HEARTLINE_TWISTER_CARS_REVERSED - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_RESERVED - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_ROTODROP_CAR - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_FLYING_SAUCERS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_CROOKED_HOUSE_BUILDING - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_BICYCLES - 107, // RCT1_VEHICLE_TYPE_HYPERCOASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_4_ACROSS_INVERTED_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_WATER_COASTER_BOATS - 108, // RCT1_VEHICLE_TYPE_FACEOFF_CARS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_JET_SKIS - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_RAFT_BOATS - 109, // RCT1_VEHICLE_TYPE_AMERICAN_STYLE_STEAM_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_AIR_POWERED_COASTER_TRAIN - USE_DEFAULT_VEHICLE, // RCT1_VEHICLE_TYPE_SUSPENDED_WILD_MOUSE_CARS // Inverted Hairpin in RCT2 - USE_DEFAULT_VEHICLE // RCT1_VEHICLE_TYPE_ENTERPRISE_WHEEL -}; - -// rct2: 0x0098BD0E -static const rct_object_entry RCT1DefaultObjectsSmallScenery[] = { - { 0x00000081, { "TL0 " }, 0 }, - { 0x00000081, { "TL1 " }, 0 }, - { 0x00000081, { "TL2 " }, 0 }, - { 0x00000081, { "TL3 " }, 0 }, - { 0x00000081, { "TM0 " }, 0 }, - { 0x00000081, { "TM1 " }, 0 }, - { 0x00000081, { "TM2 " }, 0 }, - { 0x00000081, { "TM3 " }, 0 }, - { 0x00000081, { "TS0 " }, 0 }, - { 0x00000081, { "TS1 " }, 0 }, - { 0x00000081, { "TS2 " }, 0 }, - { 0x00000081, { "TS3 " }, 0 }, - { 0x00000081, { "TS4 " }, 0 }, - { 0x00000081, { "TS5 " }, 0 }, - { 0x00000081, { "TS6 " }, 0 }, - { 0x00000081, { "TIC " }, 0 }, - { 0x00000081, { "TLC " }, 0 }, - { 0x00000081, { "TMC " }, 0 }, - { 0x00000081, { "TMP " }, 0 }, - { 0x00000081, { "TITC " }, 0 }, - { 0x00000081, { "TGHC " }, 0 }, - { 0x00000081, { "TAC " }, 0 }, - { 0x00000081, { "TGHC2 " }, 0 }, - { 0x00000081, { "TCJ " }, 0 }, - { 0x00000081, { "TMBJ " }, 0 }, - { 0x00000081, { "TCF " }, 0 }, - { 0x00000081, { "TCL " }, 0 }, - { 0x00000081, { "TRF " }, 0 }, - { 0x00000081, { "TRF2 " }, 0 }, - { 0x00000081, { "TEL " }, 0 }, - { 0x00000081, { "TAP " }, 0 }, - { 0x00000081, { "TSP " }, 0 }, - { 0x00000081, { "TMZP " }, 0 }, - { 0x00000081, { "TCRP " }, 0 }, - { 0x00000081, { "TBP " }, 0 }, - { 0x00000081, { "TLP " }, 0 }, - { 0x00000081, { "TWP " }, 0 }, - { 0x00000081, { "TAS " }, 0 }, - { 0x00000081, { "TMG " }, 0 }, - { 0x00000081, { "TWW " }, 0 }, - { 0x00000081, { "TSB " }, 0 }, - { 0x00000081, { "TVL " }, 0 }, - { 0x00000081, { "TCT " }, 0 }, - { 0x00000081, { "TEF " }, 0 }, - { 0x00000081, { "TAL " }, 0 }, - { 0x00000081, { "TSQ " }, 0 }, - { 0x00000081, { "THT " }, 0 }, - { 0x00000081, { "TCB " }, 0 }, - { 0x00000081, { "TDM " }, 0 }, - { 0x00000081, { "TSD " }, 0 }, - { 0x00000081, { "TGS " }, 0 }, - { 0x00000081, { "TUS " }, 0 }, - { 0x00000081, { "TH1 " }, 0 }, - { 0x00000081, { "TBC " }, 0 }, - { 0x00000081, { "TH2 " }, 0 }, - { 0x00000081, { "TPM " }, 0 }, - { 0x00000081, { "TSC " }, 0 }, - { 0x00000081, { "TG1 " }, 0 }, - { 0x00000081, { "TWF " }, 0 }, - { 0x00000081, { "TSH0 " }, 0 }, - { 0x00000081, { "TSH1 " }, 0 }, - { 0x00000081, { "TSH2 " }, 0 }, - { 0x00000081, { "TSH3 " }, 0 }, - { 0x00000081, { "TSH4 " }, 0 }, - { 0x00000081, { "TSH5 " }, 0 }, - { 0x00000081, { "TG2 " }, 0 }, - { 0x00000081, { "TG3 " }, 0 }, - { 0x00000081, { "TG4 " }, 0 }, - { 0x00000081, { "TG5 " }, 0 }, - { 0x00000081, { "TG6 " }, 0 }, - { 0x00000081, { "TG7 " }, 0 }, - { 0x00000081, { "TG8 " }, 0 }, - { 0x00000081, { "TG9 " }, 0 }, - { 0x00000081, { "TG10 " }, 0 }, - { 0x00000081, { "TG11 " }, 0 }, - { 0x00000081, { "TG12 " }, 0 }, - { 0x00000081, { "TG13 " }, 0 }, - { 0x00000081, { "TG14 " }, 0 }, - { 0x00000081, { "TT1 " }, 0 }, - { 0x00000081, { "TDF " }, 0 }, - { 0x00000081, { "TSH " }, 0 }, - { 0x00000081, { "THRS " }, 0 }, - { 0x00000081, { "TSTD " }, 0 }, - { 0x00000081, { "TRMS " }, 0 }, - { 0x00000081, { "TRWS " }, 0 }, - { 0x00000081, { "TRC " }, 0 }, - { 0x00000081, { "TQF " }, 0 }, - { 0x00000081, { "TES1 " }, 0 }, - { 0x00000081, { "TEN " }, 0 }, - { 0x00000081, { "TERS " }, 0 }, - { 0x00000081, { "TERB " }, 0 }, - { 0x00000081, { "TEP " }, 0 }, - { 0x00000081, { "TST1 " }, 0 }, - { 0x00000081, { "TST2 " }, 0 }, - { 0x00000081, { "TMS1 " }, 0 }, - { 0x00000081, { "TAS1 " }, 0 }, - { 0x00000081, { "TAS2 " }, 0 }, - { 0x00000081, { "TAS3 " }, 0 }, - { 0x00000081, { "TST3 " }, 0 }, - { 0x00000081, { "TST4 " }, 0 }, - { 0x00000081, { "TST5 " }, 0 }, - { 0x00000081, { "TAS4 " }, 0 }, - { 0x00000081, { "TCY " }, 0 }, - { 0x00000081, { "TBW " }, 0 }, - { 0x00000081, { "TBR1 " }, 0 }, - { 0x00000081, { "TBR2 " }, 0 }, - { 0x00000081, { "TML " }, 0 }, - { 0x00000081, { "TMW " }, 0 }, - { 0x00000081, { "TBR3 " }, 0 }, - { 0x00000081, { "TBR4 " }, 0 }, - { 0x00000081, { "TMJ " }, 0 }, - { 0x00000081, { "TBR " }, 0 }, - { 0x00000081, { "TMO1 " }, 0 }, - { 0x00000081, { "TMO2 " }, 0 }, - { 0x00000081, { "TMO3 " }, 0 }, - { 0x00000081, { "TMO4 " }, 0 }, - { 0x00000081, { "TMO5 " }, 0 }, - { 0x00000081, { "TWH1 " }, 0 }, - { 0x00000081, { "TWH2 " }, 0 }, - { 0x00000081, { "TNS " }, 0 }, - { 0x00000081, { "TP1 " }, 0 }, - { 0x00000081, { "TP2 " }, 0 }, - { 0x00000081, { "TK1 " }, 0 }, - { 0x00000081, { "TK2 " }, 0 }, - { 0x00000081, { "TR1 " }, 0 }, - { 0x00000081, { "TR2 " }, 0 }, - { 0x00000081, { "TQ1 " }, 0 }, - { 0x00000081, { "TQ2 " }, 0 }, - { 0x00000081, { "TWN " }, 0 }, - { 0x00000081, { "TCE " }, 0 }, - { 0x00000081, { "TCO " }, 0 }, - { 0x00000081, { "THL " }, 0 }, - { 0x00000081, { "TCC " }, 0 }, - { 0x00000081, { "TB1 " }, 0 }, - { 0x00000081, { "TB2 " }, 0 }, - { 0x00000081, { "TK3 " }, 0 }, - { 0x00000081, { "TK4 " }, 0 }, - { 0x00000081, { "TBN " }, 0 }, - { 0x00000081, { "TBN1 " }, 0 }, - { 0x00000081, { "TDT1 " }, 0 }, - { 0x00000081, { "TDT2 " }, 0 }, - { 0x00000081, { "TDT3 " }, 0 }, - { 0x00000081, { "TMM1 " }, 0 }, - { 0x00000081, { "TMM2 " }, 0 }, - { 0x00000081, { "TMM3 " }, 0 }, - { 0x00000081, { "TGS1 " }, 0 }, - { 0x00000081, { "TGS2 " }, 0 }, - { 0x00000081, { "TGS3 " }, 0 }, - { 0x00000081, { "TGS4 " }, 0 }, - { 0x00000081, { "TDN4 " }, 0 }, - { 0x00000081, { "TDN5 " }, 0 }, - { 0x00000081, { "TJT1 " }, 0 }, - { 0x00000081, { "TJT2 " }, 0 }, - { 0x00000081, { "TJB1 " }, 0 }, - { 0x00000081, { "TTF " }, 0 }, - { 0x00000081, { "TF1 " }, 0 }, - { 0x00000081, { "TF2 " }, 0 }, - { 0x00000081, { "TGE1 " }, 0 }, - { 0x00000081, { "TJT3 " }, 0 }, - { 0x00000081, { "TJT4 " }, 0 }, - { 0x00000081, { "TJP1 " }, 0 }, - { 0x00000081, { "TJB2 " }, 0 }, - { 0x00000081, { "TGE2 " }, 0 }, - { 0x00000081, { "TJT5 " }, 0 }, - { 0x00000081, { "TJB3 " }, 0 }, - { 0x00000081, { "TJB4 " }, 0 }, - { 0x00000081, { "TJT6 " }, 0 }, - { 0x00000081, { "TJP2 " }, 0 }, - { 0x00000081, { "TGE3 " }, 0 }, - { 0x00000081, { "TCK " }, 0 }, - { 0x00000081, { "TGE4 " }, 0 }, - { 0x00000081, { "TGE5 " }, 0 }, - { 0x00000081, { "TG15 " }, 0 }, - { 0x00000081, { "TG16 " }, 0 }, - { 0x00000081, { "TG17 " }, 0 }, - { 0x00000081, { "TG18 " }, 0 }, - { 0x00000081, { "TG19 " }, 0 }, - { 0x00000081, { "TG20 " }, 0 }, - { 0x00000081, { "TG21 " }, 0 }, - { 0x00000081, { "TSM " }, 0 }, - { 0x00000081, { "TIG " }, 0 }, - { 0x00000081, { "TCFS " }, 0 }, - { 0x00000081, { "TRFS " }, 0 }, - { 0x00000081, { "TRF3 " }, 0 }, - { 0x00000081, { "TNSS " }, 0 }, - { 0x00000081, { "TCT1 " }, 0 }, - { 0x00000081, { "TCT2 " }, 0 }, - { 0x00000081, { "TSF1 " }, 0 }, - { 0x00000081, { "TSF2 " }, 0 }, - { 0x00000081, { "TSF3 " }, 0 }, - { 0x00000081, { "TCN " }, 0 }, - { 0x00000081, { "TTG " }, 0 }, - { 0x00000081, { "TSNC " }, 0 }, - { 0x00000081, { "TSNB " }, 0 }, - { 0x00000081, { "TSCP " }, 0 }, - { 0x00000081, { "TCD " }, 0 }, - { 0x00000081, { "TSG " }, 0 }, - { 0x00000081, { "TSK " }, 0 }, - { 0x00000081, { "TGH1 " }, 0 }, - { 0x00000081, { "TGH2 " }, 0 }, - { 0x00000081, { "TSMP " }, 0 }, - { 0x00000081, { "TJF " }, 0 }, - { 0x00000081, { "TLY " }, 0 }, - { 0x00000081, { "TGC1 " }, 0 }, - { 0x00000081, { "TGC2 " }, 0 }, - { 0x00000081, { "TGG " }, 0 }, - { 0x00000081, { "TSPH " }, 0 }, - { 0x00000081, { "TOH1 " }, 0 }, - { 0x00000081, { "TOH2 " }, 0 }, - { 0x00000081, { "TOT1 " }, 0 }, - { 0x00000081, { "TOT2 " }, 0 }, - { 0x00000081, { "TOS " }, 0 }, - { 0x00000081, { "TOT3 " }, 0 }, - { 0x00000081, { "TOT4 " }, 0 }, - { 0x00000081, { "TSC2 " }, 0 }, - { 0x00000081, { "TSP1 " }, 0 }, - { 0x00000081, { "TOH3 " }, 0 }, - { 0x00000081, { "TSP2 " }, 0 }, - { 0x00000081, { "ROMROOF1" }, 0 }, - { 0x00000081, { "GEOROOF1" }, 0 }, - { 0x00000081, { "TNTROOF1" }, 0 }, - { 0x00000081, { "JNGROOF1" }, 0 }, - { 0x00000081, { "MINROOF1" }, 0 }, - { 0x00000081, { "ROMROOF2" }, 0 }, - { 0x00000081, { "GEOROOF2" }, 0 }, - { 0x00000081, { "PAGROOF1" }, 0 }, - { 0x00000081, { "SPCROOF1" }, 0 }, - { 0x00000081, { "ROOF1 " }, 0 }, - { 0x00000081, { "ROOF2 " }, 0 }, - { 0x00000081, { "ROOF3 " }, 0 }, - { 0x00000081, { "ROOF4 " }, 0 }, - { 0x00000081, { "ROOF5 " }, 0 }, - { 0x00000081, { "ROOF6 " }, 0 }, - { 0x00000081, { "ROOF7 " }, 0 }, - { 0x00000081, { "ROOF8 " }, 0 }, - { 0x00000081, { "ROOF9 " }, 0 }, - { 0x00000081, { "ROOF10 " }, 0 }, - { 0x00000081, { "ROOF11 " }, 0 }, - { 0x00000081, { "ROOF12 " }, 0 }, - { 0x00000081, { "ROOF13 " }, 0 }, - { 0x00000081, { "ROOF14 " }, 0 }, - { 0x00000081, { "IGROOF " }, 0 }, - { 0x00000081, { "CORROOF " }, 0 }, - { 0x00000081, { "CORROOF2" }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsLargeScenery[] = { - { 0x00000082, { "SCOL " }, 0 }, - { 0x00000082, { "SHS1 " }, 0 }, - { 0x00000082, { "SSPX " }, 0 }, - { 0x00000082, { "SHS2 " }, 0 }, - { 0x00000082, { "SCLN " }, 0 }, - { 0x00000082, { "SMH1 " }, 0 }, - { 0x00000082, { "SMH2 " }, 0 }, - { 0x00000082, { "SVLC " }, 0 }, - { 0x00000082, { "SPYR " }, 0 }, - { 0x00000082, { "SMN1 " }, 0 }, - { 0x00000082, { "SMB " }, 0 }, - { 0x00000082, { "SSK1 " }, 0 }, - { 0x00000082, { "SDN1 " }, 0 }, - { 0x00000082, { "SDN2 " }, 0 }, - { 0x00000082, { "SDN3 " }, 0 }, - { 0x00000082, { "SIP " }, 0 }, - { 0x00000082, { "STB1 " }, 0 }, - { 0x00000082, { "STB2 " }, 0 }, - { 0x00000082, { "STG1 " }, 0 }, - { 0x00000082, { "STG2 " }, 0 }, - { 0x00000082, { "SCT " }, 0 }, - { 0x00000082, { "SOH1 " }, 0 }, - { 0x00000082, { "SOH2 " }, 0 }, - { 0x00000082, { "SOH3 " }, 0 }, - { 0x00000082, { "SGP " }, 0 }, - { 0x00000082, { "SSR " }, 0 }, - { 0x00000082, { "STH " }, 0 }, - { 0x00000082, { "SAH " }, 0 }, - { 0x00000082, { "SPS " }, 0 }, - { 0x00000082, { "SPG " }, 0 }, - { 0x00000082, { "SOB " }, 0 }, - { 0x00000082, { "SAH2 " }, 0 }, - { 0x00000082, { "SST " }, 0 }, - { 0x00000082, { "SSH " }, 0 }, - { 0x00000082, { "SAH3 " }, 0 }, - { 0x00000082, { "SSIG1 " }, 0 }, - { 0x00000082, { "SSIG2 " }, 0 }, - { 0x00000082, { "SSIG3 " }, 0 }, - { 0x00000082, { "SSIG4 " }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsWall[] = { - { 0x00000083, { "WMF " }, 0 }, - { 0x00000083, { "WMFG " }, 0 }, - { 0x00000083, { "WRW " }, 0 }, - { 0x00000083, { "WEW " }, 0 }, - { 0x00000083, { "WHG " }, 0 }, - { 0x00000083, { "WHGG " }, 0 }, - { 0x00000083, { "WCW1 " }, 0 }, - { 0x00000083, { "WCW2 " }, 0 }, - { 0x00000083, { "WSW " }, 0 }, - { 0x00000083, { "WSWG " }, 0 }, - { 0x00000083, { "WMW " }, 0 }, - { 0x00000083, { "WALLGL16" }, 0 }, - { 0x00000083, { "WFW1 " }, 0 }, - { 0x00000083, { "WFWG " }, 0 }, - { 0x00000083, { "WPW1 " }, 0 }, - { 0x00000083, { "WPW2 " }, 0 }, - { 0x00000083, { "WPF " }, 0 }, - { 0x00000083, { "WPFG " }, 0 }, - { 0x00000083, { "WWTW " }, 0 }, - { 0x00000083, { "WMWW " }, 0 }, - { 0x00000083, { "WSW1 " }, 0 }, - { 0x00000083, { "WSW2 " }, 0 }, - { 0x00000083, { "WGW2 " }, 0 }, - { 0x00000083, { "WBW " }, 0 }, - { 0x00000083, { "WBR1 " }, 0 }, - { 0x00000083, { "WBRG " }, 0 }, - { 0x00000083, { "WALLCFAR" }, 0 }, // Slot taken by white wooden fence in RCT1 - { 0x00000083, { "WALLPOST" }, 0 }, // Slot taken by red wooden fence in RCT1 - { 0x00000083, { "WBR2 " }, 0 }, - { 0x00000083, { "WBR3 " }, 0 }, - { 0x00000083, { "WPW3 " }, 0 }, - { 0x00000083, { "WJF " }, 0 }, - { 0x00000083, { "WCH " }, 0 }, - { 0x00000083, { "WCHG " }, 0 }, - { 0x00000083, { "WC1 " }, 0 }, - { 0x00000083, { "WC2 " }, 0 }, - { 0x00000083, { "WC3 " }, 0 }, - { 0x00000083, { "WC4 " }, 0 }, - { 0x00000083, { "WC5 " }, 0 }, - { 0x00000083, { "WC6 " }, 0 }, - { 0x00000083, { "WC7 " }, 0 }, - { 0x00000083, { "WC8 " }, 0 }, - { 0x00000083, { "WC9 " }, 0 }, - { 0x00000083, { "WC10 " }, 0 }, - { 0x00000083, { "WC11 " }, 0 }, - { 0x00000083, { "WC12 " }, 0 }, - { 0x00000083, { "WC13 " }, 0 }, - { 0x00000083, { "WC14 " }, 0 }, - { 0x00000083, { "WC15 " }, 0 }, - { 0x00000083, { "WC16 " }, 0 }, - { 0x00000083, { "WC17 " }, 0 }, - { 0x00000083, { "WC18 " }, 0 }, - { 0x00000083, { "WALLBRDR" }, 0 }, - { 0x00000083, { "WALLBR32" }, 0 }, - { 0x00000083, { "WALLBR16" }, 0 }, - { 0x00000083, { "WALLBR8 " }, 0 }, - { 0x00000083, { "WALLCF8 " }, 0 }, - { 0x00000083, { "WALLCF16" }, 0 }, - { 0x00000083, { "WALLCF32" }, 0 }, - { 0x00000083, { "WALLBB8 " }, 0 }, - { 0x00000083, { "WALLBB16" }, 0 }, - { 0x00000083, { "WALLBB32" }, 0 }, - { 0x00000083, { "WALLRS8 " }, 0 }, - { 0x00000083, { "WALLRS16" }, 0 }, - { 0x00000083, { "WALLRS32" }, 0 }, - { 0x00000083, { "WALLCB8 " }, 0 }, - { 0x00000083, { "WALLCB16" }, 0 }, - { 0x00000083, { "WALLCB32" }, 0 }, - { 0x00000083, { "WALLGL8 " }, 0 }, - { 0x00000083, { "WALLGL32" }, 0 }, - { 0x00000083, { "WALLWD8 " }, 0 }, - { 0x00000083, { "WALLWD16" }, 0 }, - { 0x00000083, { "WALLWD32" }, 0 }, - { 0x00000083, { "WALLTN32" }, 0 }, - { 0x00000083, { "WALLJN32" }, 0 }, - { 0x00000083, { "WALLMN32" }, 0 }, - { 0x00000083, { "WALLSP32" }, 0 }, - { 0x00000083, { "WALLPG32" }, 0 }, - { 0x00000083, { "WALLU132" }, 0 }, - { 0x00000083, { "WALLU232" }, 0 }, - { 0x00000083, { "WALLCZ32" }, 0 }, - { 0x00000083, { "WALLCW32" }, 0 }, - { 0x00000083, { "WALLCY32" }, 0 }, - { 0x00000083, { "WALLCX32" }, 0 }, - { 0x00000083, { "WBR1A " }, 0 }, - { 0x00000083, { "WBR2A " }, 0 }, - { 0x00000083, { "WRWA " }, 0 }, - { 0x00000083, { "WWTWA " }, 0 }, - { 0x00000083, { "WALLIG16" }, 0 }, - { 0x00000083, { "WALLIG24" }, 0 }, - { 0x00000083, { "WALLCO16" }, 0 }, - { 0x00000083, { "WALLCFDR" }, 0 }, - { 0x00000083, { "WALLCBDR" }, 0 }, - { 0x00000083, { "WALLBRWN" }, 0 }, - { 0x00000083, { "WALLCFWN" }, 0 }, - { 0x00000083, { "WALLCBWN" }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsBanner[] = { - { 0x00000084, { "BN1 " }, 0 }, - { 0x00000084, { "BN2 " }, 0 }, - { 0x00000084, { "BN3 " }, 0 }, - { 0x00000084, { "BN4 " }, 0 }, - { 0x00000084, { "BN5 " }, 0 }, - { 0x00000084, { "BN6 " }, 0 }, - { 0x00000084, { "BN7 " }, 0 }, - { 0x00000084, { "BN8 " }, 0 }, - { 0x00000084, { "BN9 " }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsPath[] = { - { 0x00000085, { "TARMAC " }, 0 }, - { 0x00000085, { "TARMACB " }, 0 }, - { 0x00000085, { "PATHSPCE" }, 0 }, - { 0x00000085, { "PATHDIRT" }, 0 }, - { 0x00000085, { "ROAD " }, 0 }, - { 0x00000085, { "PATHCRZY" }, 0 }, - { 0x00000085, { "PATHASH " }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsPathBits[] = { - { 0x00000086, { "LAMP1 " }, 0 }, - { 0x00000086, { "LAMP2 " }, 0 }, - { 0x00000086, { "LITTER1 " }, 0 }, - { 0x00000086, { "BENCH1 " }, 0 }, - { 0x00000086, { "JUMPFNT1" }, 0 }, - { 0x00000086, { "LAMP3 " }, 0 }, - { 0x00000086, { "LAMP4 " }, 0 }, - { 0x00000086, { "JUMPSNW1" }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsSceneryGroup[] = { - { 0x00000087, { "SCGTREES" }, 0 }, - { 0x00000087, { "SCGPATHX" }, 0 }, - { 0x00000087, { "SCGSHRUB" }, 0 }, - { 0x00000087, { "SCGGARDN" }, 0 }, - { 0x00000087, { "SCGFENCE" }, 0 }, - { 0x00000087, { "SCGWALLS" }, 0 }, - - { 0x00000087, { "SCGMINE " }, 0 }, // RCT1_SCENERY_THEME_MINE_THEME - { 0x00000087, { "SCGCLASS" }, 0 }, // RCT1_SCENERY_THEME_CLASSICAL_ROMAN - { 0x00000087, { "SCGEGYPT" }, 0 }, // RCT1_SCENERY_THEME_EGYPTIAN - { 0x00000087, { "SCGMART " }, 0 }, // RCT1_SCENERY_THEME_MARTIAN - { 0x00000087, { "SCGWOND " }, 0 }, // RCT1_SCENERY_THEME_TOYLAND - { 0x00000087, { "SCGJURAS" }, 0 }, // RCT1_SCENERY_THEME_JURASSIC - { 0x00000087, { "SCGSPOOK" }, 0 }, // RCT1_SCENERY_THEME_GRAVEYARD - { 0x00000087, { "SCGJUNGL" }, 0 }, // RCT1_SCENERY_THEME_JUNGLE - { 0x00000087, { "SCGABSTR" }, 0 }, // RCT1_SCENERY_THEME_ABSTRACT - { 0x00000087, { "SCGSNOW " }, 0 }, // RCT1_SCENERY_THEME_SNOW_ICE - { 0x00000087, { "SCGMEDIE" }, 0 }, // RCT1_SCENERY_THEME_MEDIEVAL - { 0x00000087, { "SCGSPACE" }, 0 }, // RCT1_SCENERY_THEME_SPACE - { 0x00000087, { "SCGHALLO" }, 0 }, // RCT1_SCENERY_THEME_CREEPY - - // Not enough space to fit these last two themes (think about doing dynamic list) - // { 0x00000087, { "SCGURBAN" }, 0 }, // RCT1_SCENERY_THEME_URBAN - // { 0x00000087, { "SCGORIEN" }, 0 }, // RCT1_SCENERY_THEME_PAGODA -}; - -static const rct_object_entry RCT1DefaultObjectsParkEntrance[] = { - { 0x00000088, { "PKENT1 " }, 0 } -}; - -static const rct_object_entry RCT1DefaultObjectsWater[] = { - { 0x00000089, { "WTRCYAN " }, 0 }, - { 0x00000089, { "WTRORNG " }, 0 } -}; - -static const RCT1DefaultObjectsGroup RCT1DefaultObjects[10] = { - { RCT1DefaultObjectsRides, countof(RCT1DefaultObjectsRides) }, - { RCT1DefaultObjectsSmallScenery, countof(RCT1DefaultObjectsSmallScenery) }, - { RCT1DefaultObjectsLargeScenery, countof(RCT1DefaultObjectsLargeScenery) }, - { RCT1DefaultObjectsWall, countof(RCT1DefaultObjectsWall) }, - { RCT1DefaultObjectsBanner, countof(RCT1DefaultObjectsBanner) }, - { RCT1DefaultObjectsPath, countof(RCT1DefaultObjectsPath) }, - { RCT1DefaultObjectsPathBits, countof(RCT1DefaultObjectsPathBits) }, - { RCT1DefaultObjectsSceneryGroup, countof(RCT1DefaultObjectsSceneryGroup) }, - { RCT1DefaultObjectsParkEntrance, countof(RCT1DefaultObjectsParkEntrance) }, - { RCT1DefaultObjectsWater, countof(RCT1DefaultObjectsWater) } -}; - -// Keep these in the same order as gVehicleHierarchies -const char *SpiralRCObjectOrder[] = { "SPDRCR "}; -const char *StandupRCObjectOrder[] = { "TOGST "}; -const char *SuspendedSWRCObjectOrder[] = { "ARRSW1 ", "VEKVAMP ", "ARRSW2 "}; -const char *InvertedRCObjectOrder[] = { "NEMT "}; -const char *JuniorCoasterObjectOrder[] = { "ZLDB ", "ZLOG "}; -const char *MiniatureRailwayObjectOrder[] = { "NRL ", "NRL2 ", "AML1 ", "TRAM1 "}; -const char *MonorailObjectOrder[] = { "MONO1 ", "MONO2 ", "MONO3 "}; -const char *MiniSuspendedRCObjectOrder[] = { "BATFL ", "SKYTR "}; -const char *BoatRideObjectOrder[] = { "RBOAT ", "BBOAT ", "CBOAT ", "SWANS ", "TRIKE ","JSKI "}; -const char *WoodenWMObjectOrder[] = { "WMOUSE ", "WMMINE "}; -const char *SteeplechaseObjectOrder[] = { "STEEP1 ", "STEEP2 ", "SBOX "}; -const char *CarRideObjectOrder[] = { "SPCAR ", "RCR ", "TRUCK1 ", "VCR ", "CTCAR "}; -const char *LaunchedFFObjectOrder[] = { "SSC1 "}; -const char *BobsleighRCObjectOrder[] = { "BOB1 ", "INTBOB "}; -const char *ObservationTowerObjectOrder[] = { "OBS1 ", "OBS2 "}; -const char *LoopingRCObjectOrder[] = { "SCHT1 "}; -const char *DinghySlideObjectOrder[] = { "DING1 "}; -const char *MineTrainRCObjectOrder[] = { "AMT1 "}; -const char *ChairliftObjectOrder[] = { "CLIFT1 ", "CLIFT2 "}; -const char *CorkscrewRCObjectOrder[] = { "ARRT1 ", "ARRT2 "}; -const char *GoKartsObjectOrder[] = { "KART1 "}; -const char *LogFlumeObjectOrder[] = { "LFB1 "}; -const char *RiverRapidsObjectOrder[] = { "RAPBOAT "}; -const char *ReverseFreefallRCObjectOrder[] = { "REVF1 "}; -const char *LiftObjectOrder[] = { "LIFT1 "}; -const char *VerticalDropRCObjectOrder[] = { "BMVD "}; -const char *GhostTrainObjectOrder[] = { "GTC ", "HMCAR "}; -const char *TwisterRCObjectOrder[] = { "BMSD ", "BMSU ", "BMFL ", "BMRB ", "GOLTR "}; -const char *WoodenRCObjectOrder[] = { "PTCT1 ", "MFT ", "PTCT2 "}; -const char *SideFrictionRCObjectOrder[] = { "SFRIC1 "}; -const char *SteelWildMouseObjectOrder[] = { "SMC1 ", "SMC2 ", "WMSPIN "}; -const char *MultiDimensionRCObjectOrder[] = { "ARRX "}; -const char *FlyingRCObjectOrder[] = { "BMAIR "}; -const char *VirginiaReelRCObjectOrder[] = { "VREEL "}; -const char *SplashBoatsObjectOrder[] = { "SPBOAT "}; -const char *MiniHelicoptersObjectOrder[] = { "HELICAR "}; -const char *LayDownRCObjectOrder[] = { "VEKST "}; -const char *SuspendedMonorailObjectOrder[] = { "SMONO "}; -const char *ReverserRCObjectOrder[] = { "REVCAR "}; -const char *HeartlineTwisterObjectOrder[] = { "UTCAR ", "UTCARR "}; -const char *GigaRCObjectOrder[] = { "INTST "}; -const char *RotoDropObjectOrder[] = { "GDROP1 "}; -const char *MonorailCyclesObjectOrder[] = { "MONBK "}; -const char *CompactInvertedRCObjectOrder[] = { "SLCT ", "SLCFO ", "VEKDV "}; -const char *WaterRCObjectOrder[] = { "CSTBOAT "}; -const char *AirPoweredRCObjectOrder[] = { "THCAR "}; -const char *InvertedHairpinRCObjectOrder[] = { "IVMC1 "}; -const char *SubmarineRideObjectOrder[] = { "SUBMAR "}; -const char *RiverRaftsObjectOrder[] = { "RFTBOAT "}; -const char *InvertedImpulseRCObjectOrder[] = { "INTINV "}; -const char *MiniRCObjectOrder[] = { "WCATC ", "RCKC ", "JSTAR1 "}; -const char *MineRideRCObjectOrder[] = { "PMT1 "}; -const char *LIMLaunchedRCObjectOrder[] = { "PREMT1 "}; - -typedef struct { - const char **entries; - int count; -} RCT1VehicleHierarchiesGroup; - -RCT1VehicleHierarchiesGroup gVehicleHierarchies[0x60] = { - { SpiralRCObjectOrder, countof(SpiralRCObjectOrder) }, // 0 Spiral Roller coaster - { StandupRCObjectOrder, countof(StandupRCObjectOrder) }, // 1 Stand Up Coaster - { SuspendedSWRCObjectOrder, countof(SuspendedSWRCObjectOrder) }, // 2 Suspended Swinging - { InvertedRCObjectOrder, countof(InvertedRCObjectOrder) }, // 3 Inverted - { JuniorCoasterObjectOrder, countof(JuniorCoasterObjectOrder) }, // 4 Junior RC / Steel Mini Coaster - { MiniatureRailwayObjectOrder, countof(MiniatureRailwayObjectOrder) }, // 5 Mini Railroad - { MonorailObjectOrder, countof(MonorailObjectOrder) }, // 6 Monorail - { MiniSuspendedRCObjectOrder, countof(MiniSuspendedRCObjectOrder) }, // 7 Mini Suspended Coaster - { BoatRideObjectOrder, countof(BoatRideObjectOrder) }, // 8 Boat ride - { WoodenWMObjectOrder, countof(WoodenWMObjectOrder) }, // 9 Wooden Wild Mine/Mouse - { SteeplechaseObjectOrder, countof(SteeplechaseObjectOrder) }, // a Steeplechase/Motorbike/Soap Box Derby - { CarRideObjectOrder, countof(CarRideObjectOrder) }, // b Car Ride - { LaunchedFFObjectOrder, countof(LaunchedFFObjectOrder) }, // c Launched Freefall - { BobsleighRCObjectOrder, countof(BobsleighRCObjectOrder) }, // d Bobsleigh Coaster - { ObservationTowerObjectOrder, countof(ObservationTowerObjectOrder) }, // e Observation Tower - { LoopingRCObjectOrder, countof(LoopingRCObjectOrder) }, // f Looping Roller Coaster - { DinghySlideObjectOrder, countof(DinghySlideObjectOrder) }, // 10 Dinghy Slide - { MineTrainRCObjectOrder, countof(MineTrainRCObjectOrder) }, // 11 Mine Train Coaster - { ChairliftObjectOrder, countof(ChairliftObjectOrder) }, // 12 Chairlift - { CorkscrewRCObjectOrder, countof(CorkscrewRCObjectOrder) }, // 13 Corkscrew Roller Coaster - { NULL, 0 }, // 14 Maze, N/A - { NULL, 0 }, // 15 Spiral Slide, N/A - { GoKartsObjectOrder, countof(GoKartsObjectOrder) }, // 16 Go Karts - { LogFlumeObjectOrder, countof(LogFlumeObjectOrder) }, // 17 Log Flume - { RiverRapidsObjectOrder, countof(RiverRapidsObjectOrder) }, // 18 River Rapids - { NULL, 0 }, // 19 Dodgems, N/A - { NULL, 0 }, // 1a Pirate Ship, N/A - { NULL, 0 }, // 1b Swinging Inverter Ship, N/A - { NULL, 0 }, // 1c Food Stall, N/A - { NULL, 0 }, // 1d (none), N/A - { NULL, 0 }, // 1e Drink Stall, N/A - { NULL, 0 }, // 1f (none), N/A - { NULL, 0 }, // 20 Shop (all types), N/A - { NULL, 0 }, // 21 Merry Go Round, N/A - { NULL, 0 }, // 22 Balloon Stall (maybe), N/A - { NULL, 0 }, // 23 Information Kiosk, N/A - { NULL, 0 }, // 24 Bathroom, N/A - { NULL, 0 }, // 25 Ferris Wheel, N/A - { NULL, 0 }, // 26 Motion Simulator, N/A - { NULL, 0 }, // 27 3D Cinema, N/A - { NULL, 0 }, // 28 Top Spin, N/A - { NULL, 0 }, // 29 Space Rings, N/A - { ReverseFreefallRCObjectOrder, countof(ReverseFreefallRCObjectOrder) }, // 2a Reverse Freefall Coaster - { LiftObjectOrder, countof(LiftObjectOrder) }, // 2b Lift - { VerticalDropRCObjectOrder, countof(VerticalDropRCObjectOrder) }, // 2c Vertical Drop Roller Coaster - { NULL, 0 }, // 2d ATM, N/A - { NULL, 0 }, // 2e Twist, N/A - { NULL, 0 }, // 2f Haunted House, N/A - { NULL, 0 }, // 30 First Aid, N/A - { NULL, 0 }, // 31 Circus Show, N/A - { GhostTrainObjectOrder, countof(GhostTrainObjectOrder) }, // 32 Ghost Train - { TwisterRCObjectOrder, countof(TwisterRCObjectOrder) }, // 33 Twister Roller Coaster - { WoodenRCObjectOrder, countof(WoodenRCObjectOrder) }, // 34 Wooden Roller Coaster - { SideFrictionRCObjectOrder, countof(SideFrictionRCObjectOrder) }, // 35 Side-Friction Roller Coaster - { SteelWildMouseObjectOrder, countof(SteelWildMouseObjectOrder) }, // 36 Steel Wild Mouse - { MultiDimensionRCObjectOrder, countof(MultiDimensionRCObjectOrder) }, // 37 Multi Dimension Coaster - { NULL, 0 }, // 38 (none), N/A - { FlyingRCObjectOrder, countof(FlyingRCObjectOrder) }, // 39 Flying Roller Coaster - { NULL, 0 }, // 3a (none), N/A - { VirginiaReelRCObjectOrder, countof(VirginiaReelRCObjectOrder) }, // 3b Virginia Reel - { SplashBoatsObjectOrder, countof(SplashBoatsObjectOrder) }, // 3c Splash Boats - { MiniHelicoptersObjectOrder, countof(MiniHelicoptersObjectOrder) }, // 3d Mini Helicopters - { LayDownRCObjectOrder, countof(LayDownRCObjectOrder) }, // 3e Lay-down Roller Coaster - { SuspendedMonorailObjectOrder, countof(SuspendedMonorailObjectOrder) }, // 3f Suspended Monorail - { NULL, 0 }, // 40 (none), N/A - { ReverserRCObjectOrder, countof(ReverserRCObjectOrder) }, // 41 Reverser Roller Coaster - { HeartlineTwisterObjectOrder, countof(HeartlineTwisterObjectOrder) }, // 42 Heartline Twister Roller Coaster - { NULL, 0 }, // 43 Mini Golf, N/A - { GigaRCObjectOrder, countof(GigaRCObjectOrder) }, // 44 Giga Coaster - { RotoDropObjectOrder, countof(RotoDropObjectOrder) }, // 45 Roto-Drop - { NULL, 0 }, // 46 Flying Saucers, N/A - { NULL, 0 }, // 47 Crooked House, N/A - { MonorailCyclesObjectOrder, countof(MonorailCyclesObjectOrder) }, // 48 Monorail Cycles - { CompactInvertedRCObjectOrder, countof(CompactInvertedRCObjectOrder) }, // 49 Compact Inverted Coaster - { WaterRCObjectOrder, countof(WaterRCObjectOrder) }, // 4a Water Coaster - { AirPoweredRCObjectOrder, countof(AirPoweredRCObjectOrder) }, // 4b Air Powered Vertical Coaster - { InvertedHairpinRCObjectOrder, countof(InvertedHairpinRCObjectOrder) }, // 4c Inverted Hairpin Coaster - { NULL, 0 }, // 4d Magic Carpet, N/A - { SubmarineRideObjectOrder, countof(SubmarineRideObjectOrder) }, // 4e Submarine Ride - { RiverRaftsObjectOrder, countof(RiverRaftsObjectOrder) }, // 4f River Rafts - { NULL, 0 }, // 50 (none), N/A - { NULL, 0 }, // 51 Enterprise, N/A - { NULL, 0 }, // 52 (none), N/A - { NULL, 0 }, // 53 (none), N/A - { NULL, 0 }, // 54 (none), N/A - { NULL, 0 }, // 55 (none), N/A - { InvertedImpulseRCObjectOrder, countof(InvertedImpulseRCObjectOrder) }, // 56 Inverted Impulse Coaster - { MiniRCObjectOrder, countof(MiniRCObjectOrder) }, // 57 Mini Roller Coaster - { MineRideRCObjectOrder, countof(MineRideRCObjectOrder) }, // 58 Mine Ride - { NULL, 0 }, // 59 Unknown Ride - { LIMLaunchedRCObjectOrder, countof(LIMLaunchedRCObjectOrder) }, // 60 LIM Launched Roller Coaster -}; - -const uint8 gRideCategories[0x60] = { - 2, // Spiral Roller coaster - 2, // Stand Up Coaster - 2, // Suspended Swinging - 2, // Inverted - 2, // Steel Mini Coaster - 0, // Mini Railroad - 0, // Monorail - 2, // Mini Suspended Coaster - 4, // Boat ride - 2, // Wooden Wild Mine/Mouse - 2, // Steeplechase/Motorbike/Soap Box Derby - 1, // Car Ride - 3, // Launched Freefall - 2, // Bobsleigh Coaster - 1, // Observation Tower - 2, // Looping Roller Coaster - 4, // Dinghy Slide - 2, // Mine Train Coaster - 0, // Chairlift - 2, // Corkscrew Roller Coaster - 1, // Maze - 1, // Spiral Slide - 3, // Go Karts - 4, // Log Flume - 4, // River Rapids - 1, // Dodgems - 3, // Pirate Ship - 3, // Swinging Inverter Ship - 5, // Food Stall - 255, // (none) - 5, // Drink Stall - 255, // (none) - 5, // Shop (all types) - 1, // Merry Go Round - 5, // Balloon Stall (maybe) - 5, // Information Kiosk - 5, // Bathroom - 1, // Ferris Wheel - 3, // Motion Simulator - 3, // 3D Cinema - 3, // Top Spin - 1, // Space Rings - 2, // Reverse Freefall Coaster - 0, // Elevator - 2, // Vertical Drop Roller Coaster - 5, // ATM - 3, // Twist - 1, // Haunted House - 5, // First Aid - 1, // Circus Show - 1, // Ghost Train - 2, // Twister Roller Coaster - 2, // Wooden Roller Coaster - 2, // Side-Friction Roller Coaster - 2, // Wild Mouse - 2, // Multi Dimension Coaster - 255, // (none) - 2, // Flying Roller Coaster - 255, // (none) - 2, // Virginia Reel - 4, // Splash Boats - 1, // Mini Helicopters - 2, // Lay-down Roller Coaster - 0, // Suspended Monorail - 255, // (none) - 2, // Reverser Roller Coaster - 2, // Heartline Twister Roller Coaster - 1, // Mini Golf - 2, // Giga Coaster - 3, // Roto-Drop - 1, // Flying Saucers - 1, // Crooked House - 1, // Monorail Cycles - 2, // Compact Inverted Coaster - 2, // Water Coaster - 2, // Air Powered Vertical Coaster - 2, // Inverted Hairpin Coaster - 3, // Magic Carpet - 4, // Submarine Ride - 4, // River Rafts - 255, // (none) - 3, // Enterprise - 255, // (none) - 255, // (none) - 255, // (none) - 255, // (none) - 2, // Inverted Impulse Coaster - 2, // Mini Roller Coaster - 2, // Mine Ride - 255, //59 Unknown Ride - 2 // LIM Launched Roller Coaster -}; - -/* This function keeps a list of the preferred vehicle for every generic track type, out of the available vehicle types in the current game. - It determines which picture is shown on the new ride tab and which train type is selected by default.*/ -bool vehicleIsHigherInHierarchy(int track_type, char *currentVehicleName, char *comparedVehicleName) -{ - if(currentVehicleName==NULL || comparedVehicleName==NULL || gVehicleHierarchies[track_type].entries==NULL) { + if (!gConfigInterface.select_by_track_type) { return false; } - int currentVehicleHierarchy; - int comparedVehicleHierarchy; - - currentVehicleHierarchy=255; - comparedVehicleHierarchy=255; - - for(int i = 0; i < gVehicleHierarchies[track_type].count; i++) { - if(gVehicleHierarchies[track_type].entries[i]==NULL) - continue; - - if(strcmp(comparedVehicleName,gVehicleHierarchies[track_type].entries[i])==0) - comparedVehicleHierarchy=i; - - if(strcmp(currentVehicleName,gVehicleHierarchies[track_type].entries[i])==0) - currentVehicleHierarchy=i; - } - - if(comparedVehicleHierarchyride_type[j], RIDE_TYPE_FLAG_FLAT_RIDE)) - remove_flag=false; - if(ride->ride_type[j]==RIDE_TYPE_MAZE || ride->ride_type[j]==RIDE_TYPE_MINI_GOLF) - remove_flag=false; + bool remove_flag = true; + for (int j = 0; j < 3; j++) { + if (ride_type_has_flag(rideEntry->ride_type[j], RIDE_TYPE_FLAG_FLAT_RIDE)) { + remove_flag = false; + } + if (rideEntry->ride_type[j] == RIDE_TYPE_MAZE || rideEntry->ride_type[j] == RIDE_TYPE_MINI_GOLF) { + remove_flag = false; + } } return remove_flag; } -const uint8 RCT1SceneryGroupConvertTable[] = { - 255, // RCT1_SCENERY_THEME_GENERAL - 6, // RCT1_SCENERY_THEME_MINE_THEME - 7, // RCT1_SCENERY_THEME_CLASSICAL_ROMAN - 8, // RCT1_SCENERY_THEME_EGYPTIAN - 9, // RCT1_SCENERY_THEME_MARTIAN - 255, // RCT1_SCENERY_THEME_JUMPING_FOUNTAINS - 10, // RCT1_SCENERY_THEME_WONDERLAND - 11, // RCT1_SCENERY_THEME_JURASSIC - 12, // RCT1_SCENERY_THEME_SPOOKY - 13, // RCT1_SCENERY_THEME_JUNGLE - 14, // RCT1_SCENERY_THEME_ABSTRACT - 255, // RCT1_SCENERY_THEME_GARDEN_CLOCK - 15, // RCT1_SCENERY_THEME_SNOW_ICE - 16, // RCT1_SCENERY_THEME_MEDIEVAL - 17, // RCT1_SCENERY_THEME_SPACE - 18, // RCT1_SCENERY_THEME_CREEPY - 255, // RCT1_SCENERY_THEME_URBAN - 255 // RCT1_SCENERY_THEME_PAGODA +const uint8 gRideCategories[] = { + 2, // Spiral Roller coaster + 2, // Stand Up Coaster + 2, // Suspended Swinging + 2, // Inverted + 2, // Steel Mini Coaster + 0, // Mini Railroad + 0, // Monorail + 2, // Mini Suspended Coaster + 4, // Boat ride + 2, // Wooden Wild Mine/Mouse + 2, // Steeplechase/Motorbike/Soap Box Derby + 1, // Car Ride + 3, // Launched Freefall + 2, // Bobsleigh Coaster + 1, // Observation Tower + 2, // Looping Roller Coaster + 4, // Dinghy Slide + 2, // Mine Train Coaster + 0, // Chairlift + 2, // Corkscrew Roller Coaster + 1, // Maze + 1, // Spiral Slide + 3, // Go Karts + 4, // Log Flume + 4, // River Rapids + 1, // Dodgems + 3, // Pirate Ship + 3, // Swinging Inverter Ship + 5, // Food Stall + 255, // (none) + 5, // Drink Stall + 255, // (none) + 5, // Shop (all types) + 1, // Merry Go Round + 5, // Balloon Stall (maybe) + 5, // Information Kiosk + 5, // Bathroom + 1, // Ferris Wheel + 3, // Motion Simulator + 3, // 3D Cinema + 3, // Top Spin + 1, // Space Rings + 2, // Reverse Freefall Coaster + 0, // Elevator + 2, // Vertical Drop Roller Coaster + 5, // ATM + 3, // Twist + 1, // Haunted House + 5, // First Aid + 1, // Circus Show + 1, // Ghost Train + 2, // Twister Roller Coaster + 2, // Wooden Roller Coaster + 2, // Side-Friction Roller Coaster + 2, // Wild Mouse + 2, // Multi Dimension Coaster + 255, // (none) + 2, // Flying Roller Coaster + 255, // (none) + 2, // Virginia Reel + 4, // Splash Boats + 1, // Mini Helicopters + 2, // Lay-down Roller Coaster + 0, // Suspended Monorail + 255, // (none) + 2, // Reverser Roller Coaster + 2, // Heartline Twister Roller Coaster + 1, // Mini Golf + 2, // Giga Coaster + 3, // Roto-Drop + 1, // Flying Saucers + 1, // Crooked House + 1, // Monorail Cycles + 2, // Compact Inverted Coaster + 2, // Water Coaster + 2, // Air Powered Vertical Coaster + 2, // Inverted Hairpin Coaster + 3, // Magic Carpet + 4, // Submarine Ride + 4, // River Rafts + 255, // (none) + 3, // Enterprise + 255, // (none) + 255, // (none) + 255, // (none) + 255, // (none) + 2, // Inverted Impulse Coaster + 2, // Mini Roller Coaster + 2, // Mine Ride + 255, //59 Unknown Ride + 2 // LIM Launched Roller Coaster }; - -#pragma endregion - -#pragma region RCT1 Scenario / Saved Game Import - -#include "audio/audio.h" -#include "localisation/date.h" -#include "peep/staff.h" - -static void rct1_import_s4_properly(rct1_s4 *s4); - -static const uint8 RCT1RideTypeConversionTable[] = { - RIDE_TYPE_WOODEN_ROLLER_COASTER, - RIDE_TYPE_STAND_UP_ROLLER_COASTER, - RIDE_TYPE_SUSPENDED_SWINGING_COASTER, - RIDE_TYPE_INVERTED_ROLLER_COASTER, - RIDE_TYPE_JUNIOR_ROLLER_COASTER, - RIDE_TYPE_MINIATURE_RAILWAY, - RIDE_TYPE_MONORAIL, - RIDE_TYPE_MINI_SUSPENDED_COASTER, - RIDE_TYPE_BOAT_RIDE, - RIDE_TYPE_WOODEN_WILD_MOUSE, - RIDE_TYPE_STEEPLECHASE, - RIDE_TYPE_CAR_RIDE, - RIDE_TYPE_LAUNCHED_FREEFALL, - RIDE_TYPE_BOBSLEIGH_COASTER, - RIDE_TYPE_OBSERVATION_TOWER, - RIDE_TYPE_LOOPING_ROLLER_COASTER, - RIDE_TYPE_DINGHY_SLIDE, - RIDE_TYPE_MINE_TRAIN_COASTER, - RIDE_TYPE_CHAIRLIFT, - RIDE_TYPE_CORKSCREW_ROLLER_COASTER, - RIDE_TYPE_MAZE, - RIDE_TYPE_SPIRAL_SLIDE, - RIDE_TYPE_GO_KARTS, - RIDE_TYPE_LOG_FLUME, - RIDE_TYPE_RIVER_RAPIDS, - RIDE_TYPE_DODGEMS, - RIDE_TYPE_PIRATE_SHIP, - RIDE_TYPE_SWINGING_INVERTER_SHIP, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_DRINK_STALL, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_SHOP, - RIDE_TYPE_MERRY_GO_ROUND, - RIDE_TYPE_SHOP, - RIDE_TYPE_INFORMATION_KIOSK, - RIDE_TYPE_TOILETS, - RIDE_TYPE_FERRIS_WHEEL, - RIDE_TYPE_MOTION_SIMULATOR, - RIDE_TYPE_3D_CINEMA, - RIDE_TYPE_TOP_SPIN, - RIDE_TYPE_SPACE_RINGS, - RIDE_TYPE_REVERSE_FREEFALL_COASTER, - RIDE_TYPE_SHOP, - RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_TWIST, - RIDE_TYPE_HAUNTED_HOUSE, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_CIRCUS_SHOW, - RIDE_TYPE_GHOST_TRAIN, - RIDE_TYPE_TWISTER_ROLLER_COASTER, - RIDE_TYPE_WOODEN_ROLLER_COASTER, - RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER, - RIDE_TYPE_WILD_MOUSE, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_SHOP, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_VIRGINIA_REEL, - RIDE_TYPE_SPLASH_BOATS, - RIDE_TYPE_MINI_HELICOPTERS, - RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, - RIDE_TYPE_SUSPENDED_MONORAIL, - RIDE_TYPE_NULL, - RIDE_TYPE_REVERSER_ROLLER_COASTER, - RIDE_TYPE_HEARTLINE_TWISTER_COASTER, - RIDE_TYPE_MINI_GOLF, - RIDE_TYPE_NULL, - RIDE_TYPE_ROTO_DROP, - RIDE_TYPE_FLYING_SAUCERS, - RIDE_TYPE_CROOKED_HOUSE, - RIDE_TYPE_MONORAIL_CYCLES, - RIDE_TYPE_COMPACT_INVERTED_COASTER, - RIDE_TYPE_WATER_COASTER, - RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER, - RIDE_TYPE_INVERTED_HAIRPIN_COASTER, - RIDE_TYPE_BOAT_RIDE, - RIDE_TYPE_SHOP, - RIDE_TYPE_RIVER_RAFTS, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_ENTERPRISE, - RIDE_TYPE_DRINK_STALL, - RIDE_TYPE_FOOD_STALL, - RIDE_TYPE_DRINK_STALL -}; - -static int rct1_get_sc_number(const char *path) -{ - const char *filename = path_get_filename(path); - if (tolower(filename[0]) == 's' && tolower(filename[1]) == 'c') { - char digitBuffer[8]; - char *dst = digitBuffer; - const char *src = filename + 2; - for (int i = 0; i < 7 && *src != '.'; i++) { - *dst++ = *src++; - } - *dst++ = 0; - if (digitBuffer[0] == '0' && digitBuffer[1] == 0) { - return 0; - } else { - int digits = atoi(digitBuffer); - return digits == 0 ? -1 : digits; - } - } else { - return -1; - } -} - -static void rct1_import_map_elements(rct1_s4 *s4) -{ - memcpy(gMapElements, s4->map_elements, 0xC000 * sizeof(rct_map_element)); - rct1_clear_extra_tile_entries(); - rct1_fix_colours(); - rct1_fix_z(); - rct1_fix_paths(); - rct1_fix_walls(); - rct1_fix_banners(s4); - rct1_fix_terrain(); - rct1_fix_entrance_positions(); - - rct1_ride *ride; - rct_map_element *mapElement; - for (int y = 0; y < 256; y++) { - for (int x = 0; x < 256; x++) { - // restartTile: - mapElement = map_get_first_element_at(x, y); - do { - switch (map_element_get_type(mapElement)) { - case MAP_ELEMENT_TYPE_TRACK: - ride = &s4->rides[mapElement->properties.track.ride_index]; - break; - case MAP_ELEMENT_TYPE_ENTRANCE: - break; - } - } while (!map_element_is_last_for_tile(mapElement++)); - } - } -} - -static void rct1_import_ride(rct1_s4 *s4, rct_ride *dst, rct1_ride *src) -{ - int gameVersion = sawyercoding_detect_rct1_version(s4->game_version) & FILE_VERSION_MASK; - - rct_ride_entry *rideEntry; - - memset(dst, 0, sizeof(rct_ride)); - - dst->type = RCT1RideTypeConversionTable[src->type]; - - // Make sure the right vehicle is chosen. - // https://github.com/OpenRCT2/OpenRCT2/wiki/RCT1-ride-and-vehicle-types-and-their-RCT2-equivalents - if (RCT1AlternativeVehicleMappings[src->vehicle_type] != USE_DEFAULT_VEHICLE) - dst->subtype = RCT1AlternativeVehicleMappings[src->vehicle_type]; - else - dst->subtype = src->type; - - rideEntry = get_ride_entry(dst->subtype); - - // Ride name - dst->name = 0; - if (is_user_string_id(src->name)) { - const char *rideName = s4->string_table[(src->name - 0x8000) % 1024]; - if (rideName[0] != 0) { - rct_string_id rideNameStringId = user_string_allocate(4, rideName); - if (rideNameStringId != 0) { - dst->name = rideNameStringId; - } - } - } - if (dst->name == 0) { - dst->name = 1; - - uint16 *args = (uint16*)&dst->name_arguments; - args[0] = 2 + dst->type; - args[1] = src->name_argument_number; - } - - // - dst->status = RIDE_STATUS_CLOSED; - - // Flags - if (src->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) - dst->lifecycle_flags |= RIDE_LIFECYCLE_ON_RIDE_PHOTO; - if (src->lifecycle_flags & RIDE_LIFECYCLE_MUSIC) - dst->lifecycle_flags |= RIDE_LIFECYCLE_MUSIC; - if (src->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) - dst->lifecycle_flags |= RIDE_LIFECYCLE_INDESTRUCTIBLE; - if (src->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) - dst->lifecycle_flags |= RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; - - // Station - dst->overall_view = src->overall_view; - for (int i = 0; i < 4; i++) { - dst->station_starts[i] = src->station_starts[i]; - dst->station_heights[i] = src->station_height[i] / 2; - dst->station_length[i] = src->station_length[i]; - dst->station_depart[i] = src->station_light[i]; - dst->train_at_station[i] = 0xFF; // Use src->station_depart[i] when we import with guests and vehicles intact - dst->entrances[i] = src->entrance[i]; - dst->exits[i] = src->exit[i]; - dst->queue_time[i] = src->queue_time[i]; - dst->last_peep_in_queue[i] = 0xFFFF; - } - dst->num_stations = src->num_stations; - - for (int i = 0; i < 32; i++) { - dst->vehicles[i] = 0xFFFF; - } - dst->num_vehicles = src->num_trains; - dst->num_cars_per_train = src->num_cars_per_train + rideEntry->zero_cars; - dst->proposed_num_vehicles = src->num_trains; - dst->max_trains = 32; - dst->proposed_num_cars_per_train = src->num_cars_per_train + rideEntry->zero_cars; - - // Operation - dst->depart_flags = src->depart_flags; - dst->min_waiting_time = src->min_waiting_time; - dst->max_waiting_time = src->max_waiting_time; - dst->operation_option = src->operation_option; - dst->num_circuits = 1; - dst->min_max_cars_per_train = (rideEntry->min_cars_in_train << 4) | rideEntry->max_cars_in_train; - dst->lift_hill_speed = 5; // RCT1 used 5mph / 8 km/h for every lift hill - - if (gameVersion == FILE_VERSION_RCT1) // Original RCT had no music settings, take default style - dst->music = RCT2_ADDRESS(0x0097D4F4, uint8)[dst->type * 8]; - else - dst->music = src->music; - - if (src->operating_mode == RCT1_RIDE_MODE_POWERED_LAUNCH) // Launched rides never passed through the station in RCT1. - dst->mode = RIDE_MODE_POWERED_LAUNCH; - else - dst->mode = src->operating_mode; - - // Colours - dst->colour_scheme_type = src->colour_scheme; - if (gameVersion == FILE_VERSION_RCT1) { - dst->track_colour_main[0] = RCT1ColourConversionTable[src->track_primary_colour]; - dst->track_colour_additional[0] = RCT1ColourConversionTable[src->track_secondary_colour]; - dst->track_colour_supports[0] = RCT1ColourConversionTable[src->track_support_colour]; - } else { - for (int i = 0; i < 4; i++) { - dst->track_colour_main[i] = RCT1ColourConversionTable[src->track_colour_main[i]]; - dst->track_colour_additional[i] = RCT1ColourConversionTable[src->track_colour_additional[i]]; - dst->track_colour_supports[i] = RCT1ColourConversionTable[src->track_colour_supports[i]]; - } - // Entrance styles were introduced with AA. They correspond directly with those in RCT2. - dst->entrance_style = src->entrance_style; - } - - - if(gameVersion < FILE_VERSION_RCT1_LL && dst->type == RIDE_TYPE_MERRY_GO_ROUND) { - // The merry-go-round in pre-LL versions was always yellow with red - dst->vehicle_colours[0].body_colour = COLOUR_YELLOW; - dst->vehicle_colours[0].trim_colour = COLOUR_BRIGHT_RED; - } else { - for (int i = 0; i < 12; i++) { - dst->vehicle_colours[i].body_colour = RCT1ColourConversionTable[src->vehicle_colours[i].body]; - dst->vehicle_colours[i].trim_colour = RCT1ColourConversionTable[src->vehicle_colours[i].trim]; - } - } - - // Maintenance - dst->build_date = src->build_date; - dst->inspection_interval = src->inspection_interval; - dst->last_inspection = src->last_inspection; - dst->reliability = src->reliability; - dst->unreliability_factor = src->unreliability_factor; - dst->breakdown_reason = src->breakdown_reason; - - // Finance - dst->upkeep_cost = src->upkeep_cost; - dst->price = src->price; - dst->income_per_hour = src->income_per_hour; - - dst->value = src->value; - dst->satisfaction = 255; - dst->satisfaction_time_out = 0; - dst->satisfaction_next = 0; - dst->popularity = src->popularity; - dst->popularity_next = src->popularity_next; - dst->popularity_time_out = src->popularity_time_out; - - dst->music_tune_id = 255; - dst->measurement_index = 255; - dst->excitement = (ride_rating)-1; -} - -static uint8 rct1_convert_vehicle_to_ride_entry_index(uint8 rct1RideType, uint8 vehicle) -{ - uint8 rideEntryIndex = rct1RideType; - if (vehicle < countof(RCT1AlternativeVehicleMappings)) { - vehicle = RCT1AlternativeVehicleMappings[vehicle]; - if (vehicle != USE_DEFAULT_VEHICLE) { - rideEntryIndex = vehicle; - } - } - return rideEntryIndex; -} - -static bool _rct1ResearchRideEntryUsed[128]; -static bool _rct1ResearchRideTypeUsed[128]; - -static void rct1_research_insert_vehicle(const rct1_research_item *researchItem, bool researched) -{ - uint8 rct1RideType = researchItem->related_ride; - uint8 vehicle = researchItem->item; - - uint8 rideEntryIndex = rct1_convert_vehicle_to_ride_entry_index(rct1RideType, vehicle); - if (!_rct1ResearchRideEntryUsed[rideEntryIndex]) { - _rct1ResearchRideEntryUsed[rideEntryIndex] = true; - research_insert_ride_entry(rideEntryIndex, researched); - } -} - -/** - * In RollerCoaster Tycoon 1 the research was divided up into scenery themes, - * rides, vehicles for rides and special track pieces for rides. Currently - * OpenRCT2 does not support researching of special track pieces and whether - * vehicles are research-able depends on the vehicle object. - * - * TODO We might probably want to sort the researched items by the prefered - * RCT1 order so the right image shows in the new ride window. This is - * only relevant if RCT1 ride sorting is turned off. - */ -static void rct1_import_research_list(const rct1_s4 *s4) -{ - int maxResearchItems = countof(s4->research_items); - const rct1_research_item *researchItems = s4->research_items; - - // Loopy Landscapes stores research items in a different place - int gameVersion = sawyercoding_detect_rct1_version(s4->game_version) & FILE_VERSION_MASK; - if (gameVersion == FILE_VERSION_RCT1_LL) { - maxResearchItems = countof(s4->research_items_LL); - researchItems = s4->research_items_LL; - } - - // Initialise the "seen" tables - memset(_rct1ResearchRideEntryUsed, 0, sizeof(_rct1ResearchRideEntryUsed)); - memset(_rct1ResearchRideTypeUsed, 0, sizeof(_rct1ResearchRideTypeUsed)); - - // The first six scenery groups are always available - for (int i = 0; i < 6; i++) { - research_insert_scenery_group_entry(i, true); - } - - bool researched = true; - for (int i = 0; i < maxResearchItems; i++) { - const rct1_research_item *researchItem = &researchItems[i]; - if (researchItem->item == RCT1_RESEARCH_END_AVAILABLE) { - researched = false; - } else if (researchItem->item == RCT1_RESEARCH_END_RESEARCHABLE || researchItem->item == RCT1_RESEARCH_END) { - break; - } - - switch (researchItem->category) { - case RCT1_RESEARCH_CATEGORY_THEME: - { - uint8 rct1SceneryTheme = researchItem->item; - uint8 sceneryGroupEntryIndex = RCT1SceneryGroupConvertTable[rct1SceneryTheme]; - if (sceneryGroupEntryIndex != 255) { - research_insert_scenery_group_entry(sceneryGroupEntryIndex, researched); - } - break; - } - case RCT1_RESEARCH_CATEGORY_RIDE: - { - uint8 rct1RideType = researchItem->item; - uint8 rideEntryIndex = rct1RideType; - rct_ride_entry *rideEntry = get_ride_entry(rideEntryIndex); - - // Add all vehicles for this ride type that are researched or before this research item - uint32 numVehicles = 0; - for (int j = 0; j < maxResearchItems; j++) { - const rct1_research_item *researchItem2 = &researchItems[j]; - if (researchItem2->item == RCT1_RESEARCH_END_AVAILABLE) { - break; - } - - if (researchItem->category == RCT1_RESEARCH_CATEGORY_VEHICLE && - researchItem->related_ride == rct1RideType - ) { - // Only add the vehicles that were listed before this ride, otherwise we might - // change the research order - if (j < i) { - rct1_research_insert_vehicle(researchItem, researched); - } - numVehicles++; - } - } - - if (numVehicles == 0) { - // No vehicles found so just add the default for this ride - if (!_rct1ResearchRideEntryUsed[rideEntryIndex]) { - _rct1ResearchRideEntryUsed[rideEntryIndex] = true; - research_insert_ride_entry(rideEntryIndex, researched); - } - } - break; - } - case RCT1_RESEARCH_CATEGORY_VEHICLE: - // Only add vehicle if the related ride has been seen, this to make sure that vehicles - // are researched only after the ride has been researched - if (_rct1ResearchRideTypeUsed[researchItem->related_ride]) { - rct1_research_insert_vehicle(researchItem, researched); - } - break; - case RCT1_RESEARCH_CATEGORY_SPECIAL: - // Not supported - break; - } - } - - research_remove_non_separate_vehicle_types(); -} - -static void rct1_import_s4_properly(rct1_s4 *s4) -{ - int mapSize = s4->map_size == 0 ? 128 : s4->map_size; - - audio_pause_sounds(); - audio_unpause_sounds(); - object_unload_all(); - map_init(mapSize); - banner_init(); - reset_park_entrances(); - user_string_clear_all(); - reset_sprite_list(); - ride_init_all(); - window_guest_list_init_vars_a(); - staff_reset_modes(); - park_init(); - finance_init(); - date_reset(); - window_guest_list_init_vars_b(); - window_staff_list_init_vars(); - RCT2_GLOBAL(0x0141F570, uint8) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; - window_new_ride_init_vars(); - RCT2_GLOBAL(0x0141F571, uint8) = 4; - news_item_init_queue(); - - rct_string_id stringId; - - rct1_load_default_objects(); - reset_loaded_objects(); - - // Fix object availability - research_reset_items(); - rct1_import_research_list(s4); - - // Map elements - rct1_import_map_elements(s4); - - // Rides - for (int i = 0; i < MAX_RIDES; i++) { - if (s4->rides[i].type != RIDE_TYPE_NULL) { - rct1_import_ride(s4, get_ride(i), &s4->rides[i]); - } - } - - // Peep spawns - for (int i = 0; i < 2; i++) { - gPeepSpawns[i] = s4->peep_spawn[i]; - } - - // Map animations - rct_map_animation *s4Animations = (rct_map_animation*)s4->map_animations; - for (int i = 0; i < 1000; i++) { - gAnimatedObjects[i] = s4Animations[i]; - gAnimatedObjects[i].baseZ /= 2; - } - RCT2_GLOBAL(0x0138B580, uint16) = s4->num_map_animations; - - // Finance - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, uint32) = ENCRYPT_MONEY(s4->cash); - RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = s4->park_entrance_fee; - - // Park name - const char *parkName = s4->scenario_name; - if (is_user_string_id((rct_string_id)s4->park_name_string_index)) { - const char *userString = s4->string_table[(s4->park_name_string_index - 0x8000) % 1024]; - if (userString[0] != 0) { - parkName = userString; - } - } - stringId = user_string_allocate(4, parkName); - if (stringId != 0) { - RCT2_GLOBAL(RCT2_ADDRESS_PARK_NAME, rct_string_id) = stringId; - RCT2_GLOBAL(RCT2_ADDRESS_PARK_NAME_ARGS, uint32) = 0; - } - - // Park flags - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = s4->park_flags; - - // Clear cheat detection flag (unused anyway) - RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_ANTI_CHEAT_DEPRECATED; - - // Scenario name - rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; - strcpy(s6Info->name, s4->scenario_name); - strcpy(s6Info->details, ""); - - // Scenario objective - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) = s4->scenario_objective_type; - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8) = s4->scenario_objective_years; - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_CURRENCY, uint32) = s4->scenario_objective_currency; - RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16) = s4->scenario_objective_num_guests; - - // Restore view - RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, uint16) = s4->view_x; - RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, uint16) = s4->view_y; - RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint8) = s4->view_zoom; - RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION + 1, uint8) = s4->view_rotation; -} - -#pragma endregion diff --git a/src/rct1.h b/src/rct1.h index ba6d370664..39fb4768b7 100644 --- a/src/rct1.h +++ b/src/rct1.h @@ -717,18 +717,18 @@ enum { RCT1_SCENARIO_FLAG_19 = 1 << 19, }; -extern const uint8 RCT1ColourConversionTable[32]; - extern const uint8 gRideCategories[0x60]; bool rct1_read_sc4(const char *path, rct1_s4 *s4); bool rct1_read_sv4(const char *path, rct1_s4 *s4); void rct1_import_s4(rct1_s4 *s4); void rct1_fix_landscape(); -bool vehicleIsHigherInHierarchy(int track_type, char *currentVehicleName, char *comparedVehicleName); -bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *ride); +int vehicle_preference_compare(uint8 rideType, const char * a, const char * b); +bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry); bool rct1_load_saved_game(const char *path); bool rct1_load_scenario(const char *path); +colour_t rct1_get_colour(colour_t colour); + #endif diff --git a/src/rct1/S4Importer.cpp b/src/rct1/S4Importer.cpp index b0228bcd14..52a0a3d776 100644 --- a/src/rct1/S4Importer.cpp +++ b/src/rct1/S4Importer.cpp @@ -70,6 +70,8 @@ void S4Importer::Import() ImportScenarioNameDetails(); ImportScenarioObjective(); ImportSavedView(); + + game_convert_strings_to_utf8(); } void S4Importer::Initialise() @@ -1508,51 +1510,68 @@ const char * S4Importer::GetUserString(rct_string_id stringId) // C -> C++ transfer ///////////////////////////////////////// extern "C" -bool rct1_load_saved_game(const utf8 * path) { - bool result; + bool rct1_load_saved_game(const utf8 * path) + { + bool result; - auto s4Importer = new S4Importer(); - try - { - s4Importer->LoadSavedGame(path); - s4Importer->Import(); - result = true; + auto s4Importer = new S4Importer(); + try + { + s4Importer->LoadSavedGame(path); + s4Importer->Import(); + result = true; + } catch (Exception ex) + { + result = false; + } + delete s4Importer; + return result; } - catch (Exception ex) + + bool rct1_load_scenario(const utf8 * path) { - result = false; + bool result; + + auto s4Importer = new S4Importer(); + try + { + s4Importer->LoadScenario(path); + s4Importer->Import(); + result = true; + } catch (Exception ex) + { + result = false; + } + delete s4Importer; + return result; } - delete s4Importer; - - if (result) + + colour_t rct1_get_colour(colour_t colour) { - game_load_init(); + return RCT1::GetColour(colour); + } + + /** + * This function keeps a list of the preferred vehicle for every generic track + * type, out of the available vehicle types in the current game. It determines + * which picture is shown on the new ride tab and which train type is selected + * by default. + */ + int vehicle_preference_compare(uint8 rideType, const char * a, const char * b) + { + List rideEntryOrder = RCT1::GetPreferedRideEntryOrder(rideType); + for (const char * object : rideEntryOrder) + { + if (String::Equals(object, a, true)) + { + return -1; + } + if (String::Equals(object, b, true)) + { + return 1; + } + } + return 0; } - return result; -} - -extern "C" -bool rct1_load_scenario(const utf8 * path) -{ - bool result; - - auto s4Importer = new S4Importer(); - try - { - s4Importer->LoadScenario(path); - s4Importer->Import(); - result = true; - } - catch (Exception ex) - { - result = false; - } - delete s4Importer; - - if (result) - { - scenario_begin(); - } - return result; } diff --git a/src/rct1/import.h b/src/rct1/import.h index ff8f52bf49..ca84dc3ba2 100644 --- a/src/rct1/import.h +++ b/src/rct1/import.h @@ -24,4 +24,6 @@ namespace RCT1 const char * GetSceneryGroupObject(uint8 sceneryGroupType); const List GetSceneryObjects(uint8 sceneryType); + + const List GetPreferedRideEntryOrder(uint8 rideType); } diff --git a/src/rct2.c b/src/rct2.c index 7fbeb00839..c1d274873c 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -368,9 +368,13 @@ bool rct2_open_file(const char *path) // TODO track design install return true; } else if (_stricmp(extension, "sv4") == 0) { - rct1_load_saved_game(path); + if (rct1_load_saved_game(path)) { + game_load_init(); + } } else if (_stricmp(extension, "sc4") == 0) { - rct1_load_scenario(path); + if (rct1_load_scenario(path)) { + scenario_begin(); + } } return false; diff --git a/src/ride/track.c b/src/ride/track.c index f933df43a1..19cf1890a1 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -616,12 +616,12 @@ rct_track_td6* load_track_design(const char *path) // Unsure why it is 67 edi = (uint8*)&track_design->vehicle_colours; for (i = 0; i < 67; i++, edi++) - *edi = RCT1ColourConversionTable[*edi]; + *edi = rct1_get_colour(*edi); // Edit the colours to use the new versions edi = (uint8*)&track_design->track_spine_colour; for (i = 0; i < 12; i++, edi++) - *edi = RCT1ColourConversionTable[*edi]; + *edi = rct1_get_colour(*edi); // Highest drop height is 1bit = 3/4 a meter in td6 // Highest drop height is 1bit = 1/3 a meter in td4 diff --git a/src/windows/new_ride.c b/src/windows/new_ride.c index 4410bad6cf..ea38244d8f 100644 --- a/src/windows/new_ride.c +++ b/src/windows/new_ride.c @@ -334,17 +334,15 @@ static void window_new_ride_populate_list() continue; // Skip if the vehicle isn't the preferred vehicle for this generic track type - if(gConfigInterface.select_by_track_type && (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry))) { - if(strcmp(preferredVehicleName," \0")==0) { - strcpy(preferredVehicleName,rideEntryName); - preferredVehicleName[8]=0; - } - else { - if(vehicleIsHigherInHierarchy(rideType,preferredVehicleName,rideEntryName)) { - strcpy(preferredVehicleName,rideEntryName); - preferredVehicleName[8]=0; - } - else { + if (gConfigInterface.select_by_track_type && (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry))) { + if (strcmp(preferredVehicleName, " \0") == 0) { + strcpy(preferredVehicleName, rideEntryName); + preferredVehicleName[8] = 0; + } else { + if (vehicle_preference_compare(rideType, preferredVehicleName, rideEntryName) == 1) { + strcpy(preferredVehicleName, rideEntryName); + preferredVehicleName[8] = 0; + } else { continue; } }