diff --git a/openrct2.vcxproj b/openrct2.vcxproj index e104ee19a7..019cc6419d 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -264,7 +264,7 @@ - + diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters index eee82ee7c2..2e1f69fbca 100644 --- a/openrct2.vcxproj.filters +++ b/openrct2.vcxproj.filters @@ -561,6 +561,9 @@ Source + + Source + @@ -845,6 +848,5 @@ Source - \ No newline at end of file diff --git a/src/scenario.h b/src/scenario.h index b547d1269a..d5ba798073 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -484,4 +484,7 @@ void scenario_success(); void scenario_success_submit_name(const char *name); void scenario_autosave_check(); +bool scenario_get_index_and_source(const utf8 *name, scenario_source *source, sint32 *index); +void scenario_normalise_name(utf8 *name); + #endif diff --git a/src/scenario_list.c b/src/scenario_list.c index a3b6e86b3a..ed7e7d747c 100644 --- a/src/scenario_list.c +++ b/src/scenario_list.c @@ -23,7 +23,6 @@ #include "platform/platform.h" #include "util/util.h" #include "scenario.h" -#include "scenario_sources.h" // Scenario list int gScenarioListCount = 0; @@ -39,9 +38,6 @@ static void scenario_list_add(const char *path); static void scenario_list_sort(); static int scenario_list_sort_by_name(const void *a, const void *b); static int scenario_list_sort_by_index(const void *a, const void *b); -static sint32 get_scenario_index(utf8 *name); -static void normalise_scenario_name(utf8 *name); -static scenario_source source_by_index(sint32 index); static bool scenario_scores_load(); static bool scenario_scores_legacy_load(); @@ -135,11 +131,14 @@ static void scenario_list_add(const utf8 *path) safe_strncpy(newEntry->details, s6Info.details, sizeof(newEntry->details)); // Normalise the name to make the scenario as recognisable as possible. - normalise_scenario_name(newEntry->name); + scenario_normalise_name(newEntry->name); // Look up and store information regarding the origins of this scenario. - newEntry->source_index = get_scenario_index(newEntry->name); - newEntry->source_game = source_by_index(newEntry->source_index); + scenario_source source; + sint32 index; + scenario_get_index_and_source(newEntry->name, &source, &index); + newEntry->source_index = index; + newEntry->source_game = source; } void scenario_list_dispose() @@ -182,63 +181,6 @@ static int scenario_list_sort_by_index(const void *a, const void *b) return entryA->source_index - entryB->source_index; } -static sint32 get_scenario_index(utf8 *name) -{ - for (sint32 i = 0; i < NUM_ORIGINAL_SCENARIOS; i++) { - if (_strcmpi(original_scenario_names[i], name) == 0) { - return i; - } - } - return -1; -} - -static void normalise_scenario_name(utf8 *name) -{ - size_t nameLength = strlen(name); - - // Strip "RCT(1|2)? *" prefix off scenario names. - if (nameLength >= 3 && (name[0] == 'R' && name[1] == 'C' && name[2] == 'T')) { - if (nameLength >= 4 && (name[3] == '1' || name[3] == '2')) { - log_verbose("Stripping RCT/1/2 from name: %s", name); - safe_strncpy(name, name + 4, 64); - } else { - safe_strncpy(name, name + 3, 64); - } - - safe_strtrimleft(name, name, 64); - } - - // American scenario titles should be converted to British name - // Don't worry, names will be translated using language packs later - for (int i = 0; i < NUM_ALIASES; i++) { - if (strcmp(scenario_aliases[(i * 2) + 1], name) == 0) { - log_verbose("Found alias: %s; will treat as: %s", name, scenario_aliases[i * 2]); - safe_strncpy(name, scenario_aliases[i * 2], 64); - } - } -} - -static scenario_source source_by_index(sint32 index) -{ - if (index >= SCENARIO_SOURCE_RCT1_INDEX && index < SCENARIO_SOURCE_RCT1_AA_INDEX) { - return SCENARIO_SOURCE_RCT1; - } else if (index >= SCENARIO_SOURCE_RCT1_AA_INDEX && index < SCENARIO_SOURCE_RCT1_LL_INDEX) { - return SCENARIO_SOURCE_RCT1_AA; - } else if (index >= SCENARIO_SOURCE_RCT1_LL_INDEX && index < SCENARIO_SOURCE_RCT2_INDEX) { - return SCENARIO_SOURCE_RCT1_LL; - } else if (index >= SCENARIO_SOURCE_RCT2_INDEX && index < SCENARIO_SOURCE_RCT2_WW_INDEX) { - return SCENARIO_SOURCE_RCT2; - } else if (index >= SCENARIO_SOURCE_RCT2_WW_INDEX && index < SCENARIO_SOURCE_RCT2_TT_INDEX) { - return SCENARIO_SOURCE_RCT2_WW; - } else if (index >= SCENARIO_SOURCE_RCT2_TT_INDEX && index < SCENARIO_SOURCE_REAL_INDEX) { - return SCENARIO_SOURCE_RCT2_TT; - } else if (index >= SCENARIO_SOURCE_REAL_INDEX && index < NUM_ORIGINAL_SCENARIOS) { - return SCENARIO_SOURCE_REAL; - } else { - return SCENARIO_SOURCE_OTHER; - } -} - scenario_index_entry *scenario_list_find_by_path(const utf8 *path) { for (int i = 0; i < gScenarioListCount; i++) { diff --git a/src/scenario_sources.c b/src/scenario_sources.c new file mode 100644 index 0000000000..66c140e1ed --- /dev/null +++ b/src/scenario_sources.c @@ -0,0 +1,248 @@ +#include "scenario.h" +#include "util/util.h" + +typedef struct { + const utf8 *original; + const utf8 *alternative; +} scenario_alias; + +const scenario_alias ScenarioAliases[] = { + { "Katie's Dreamland", "Katie's World" }, + { "Pokey Park", "Dinky Park" }, + { "White Water Park", "Aqua Park" }, + { "Mystic Mountain", "Mothball Mountain" }, + { "Paradise Pier", "Big Pier" }, + { "Paradise Pier 2", "Big Pier 2" }, +}; + +// RCT +const utf8 * const ScenarioTitlesRCT1[] = { + "Forest Frontiers", + "Dynamite Dunes", + "Leafy Lake", + "Diamond Heights", + "Evergreen Gardens", + "Bumbly Beach", + "Trinity Islands", + "Katie's Dreamland", + "Pokey Park", + "White Water Park", + "Millennium Mines", + "Karts & Coasters", + "Mel's World", + "Mystic Mountain", + "Pacific Pyramids", + "Crumbly Woods", + "Paradise Pier", + "Lightning Peaks", + "Ivory Towers", + "Rainbow Valley", + "Thunder Rock", + "Mega Park", +}; + +// RCT: Added Attractions +const utf8 * const ScenarioTitlesRCT1AA[] = { + "Whispering Cliffs", + "Three Monkeys Park", + "Canary Mines", + "Barony Bridge", + "Funtopia", + "Haunted Harbor", + "Fun Fortress", + "Future World", + "Gentle Glen", + "Jolly Jungle", + "Hydro Hills", + "Sprightly Park", + "Magic Quarters", + "Fruit Farm", + "Butterfly Dam", + "Coaster Canyon", + "Thunderstorm Park", + "Harmonic Hills", + "Roman Village", + "Swamp Cove", + "Adrenaline Heights", + "Utopia", + "Rotting Heights", + "Fiasco Forest", + "Pickle Park", + "Giggle Downs", + "Mineral Park", + "Coaster Crazy", + "Urban Park", + "Geoffrey Gardens", +}; + +// RCT: Loopy Landscapes +const utf8 * const ScenarioTitlesRCT1LL[] = { + "Iceberg Islands", + "Volcania", + "Arid Heights", + "Razor Rocks", + "Crater Lake", + "Vertigo Views", + "Paradise Pier 2", + "Dragon's Cove", + "Good Knight Park", + "Wacky Warren", + "Grand Glacier", + "Crazy Craters", + "Dusty Desert", + "Woodworm Park", + "Icarus Park", + "Sunny Swamps", + "Frightmare Hills", + "Thunder Rocks", + "Octagon Park", + "Pleasure Island", + "Icicle Worlds", + "Tiny Towers", + "Southern Sands", + "Nevermore Park", + "Pacifica", + "Urban Jungle", + "Terror Town", + "Megaworld Park", + "Venus Ponds", + "Micro Park", +}; + +// RCT2 +const utf8 * const ScenarioTitlesRCT2[] = { + "Crazy Castle", + "Electric Fields", + "Factory Capers", + "Amity Airfield", + "Botany Breakers", + "Bumbly Bazaar", + "Dusty Greens", + "Fungus Woods", + "Gravity Gardens", + "Infernal Views", + "Alpine Adventures", + "Extreme Heights", + "Ghost Town", + "Lucky Lake", + "Rainbow Summit", +}; + +// RCT2: Wacky Worlds +const utf8 * const ScenarioTitlesRCT2WW[] = { + "Africa - Victoria Falls", + "Asia - Great Wall of China Tourism Enhancement", + "North America - Grand Canyon", + "South America - Rio Carnival", + "Africa - African Diamond Mine", + "Asia - Maharaja Palace", + "Australasia - Ayers Rock", + "Europe - European Cultural Festival", + "North America - Rollercoaster Heaven", + "South America - Inca Lost City", + "Africa - Oasis", + "Antarctic - Ecological Salvage", + "Asia - Japanese Coastal Reclaim", + "Australasia - Fun at the Beach", + "Europe - Renovation", + "N. America - Extreme Hawaiian Island", + "South America - Rain Forest Plateau", +}; + +// RCT2: Time Twister +const utf8 * const ScenarioTitlesRCT2TT[] = { + "Dark Age - Robin Hood", + "Prehistoric - After the Asteroid", + "Roaring Twenties - Prison Island", + "Rock 'n' Roll - Flower Power", + "Dark Age - Castle", + "Future - First Encounters", + "Mythological - Animatronic Film Set", + "Prehistoric - Jurassic Safari", + "Roaring Twenties - Schneider Cup", + "Future - Future World", + "Mythological - Cradle of Civilisation", + "Prehistoric - Stone Age", + "Roaring Twenties - Skyscrapers", + "Rock 'n' Roll - Rock 'n' Roll", +}; + +// Real parks +const utf8 * const ScenarioTitlesRealParks[] = { + "Alton Towers", + "Heide-Park", + "Blackpool Pleasure Beach", + "Six Flags Belgium", + "Six Flags Great Adventure", + "Six Flags Holland", + "Six Flags Magic Mountain", + "Six Flags over Texas", +}; + +// Other parks +const utf8 * const ScenarioTitlesRCT2BuildYourOwnParks[] = { + "Build your own Six Flags Belgium", + "Build your own Six Flags Great Adventure", + "Build your own Six Flags Holland", + "Build your own Six Flags Magic Mountain", + "Build your own Six Flags Park", + "Build your own Six Flags over Texas", +}; + +const struct { + int count; + const utf8 * const * titles; +} ScenarioTitlesBySource[] = { + { countof(ScenarioTitlesRCT1), ScenarioTitlesRCT1 }, + { countof(ScenarioTitlesRCT1AA), ScenarioTitlesRCT1AA }, + { countof(ScenarioTitlesRCT1LL), ScenarioTitlesRCT1LL }, + { countof(ScenarioTitlesRCT2), ScenarioTitlesRCT2 }, + { countof(ScenarioTitlesRCT2WW), ScenarioTitlesRCT2WW }, + { countof(ScenarioTitlesRCT2TT), ScenarioTitlesRCT2TT }, + { countof(ScenarioTitlesRealParks), ScenarioTitlesRealParks }, +}; + +bool scenario_get_index_and_source(const utf8 *name, scenario_source *source, sint32 *index) +{ + sint32 currentIndex = 0; + for (int i = 0; i < countof(ScenarioTitlesBySource); i++) { + for (int j = 0; j < ScenarioTitlesBySource[i].count; j++) { + if (_strcmpi(name, ScenarioTitlesBySource[i].titles[j]) == 0) { + *source = (scenario_source)i; + *index = currentIndex; + return true; + } + currentIndex++; + } + } + + *source = SCENARIO_SOURCE_OTHER; + *index = -1; + return false; +} + +void scenario_normalise_name(utf8 *name) +{ + size_t nameLength = strlen(name); + + // Strip "RCT(1|2)? *" prefix off scenario names. + if (nameLength >= 3 && (name[0] == 'R' && name[1] == 'C' && name[2] == 'T')) { + if (nameLength >= 4 && (name[3] == '1' || name[3] == '2')) { + log_verbose("Stripping RCT/1/2 from name: %s", name); + safe_strncpy(name, name + 4, 64); + } else { + safe_strncpy(name, name + 3, 64); + } + + safe_strtrimleft(name, name, 64); + } + + // American scenario titles should be converted to British name + // Don't worry, names will be translated using language packs later + for (int i = 0; i < countof(ScenarioAliases); i++) { + if (strcmp(ScenarioAliases[i].alternative, name) == 0) { + log_verbose("Found alias: %s; will treat as: %s", name, ScenarioAliases[i].original); + safe_strncpy(name, ScenarioAliases[i].original, 64); + } + } +} diff --git a/src/scenario_sources.h b/src/scenario_sources.h deleted file mode 100644 index 78efee823a..0000000000 --- a/src/scenario_sources.h +++ /dev/null @@ -1,171 +0,0 @@ -#define NUM_ORIGINAL_SCENARIOS 136 -#define NUM_ALIASES 6 - -#define SCENARIO_SOURCE_RCT1_INDEX 0 -#define SCENARIO_SOURCE_RCT1_AA_INDEX 22 -#define SCENARIO_SOURCE_RCT1_LL_INDEX 52 -#define SCENARIO_SOURCE_RCT2_INDEX 82 -#define SCENARIO_SOURCE_RCT2_WW_INDEX 97 -#define SCENARIO_SOURCE_RCT2_TT_INDEX 114 -#define SCENARIO_SOURCE_REAL_INDEX 128 - -const char * const scenario_aliases[NUM_ALIASES * 2] = { - "Katie's Dreamland", "Katie's World", - "Pokey Park", "Dinky Park", - "White Water Park", "Aqua Park", - "Mystic Mountain", "Mothball Mountain", - "Paradise Pier", "Big Pier", - "Paradise Pier 2", "Big Pier 2", -}; - -const char * const original_scenario_names[NUM_ORIGINAL_SCENARIOS] = { - // RCT - "Forest Frontiers", - "Dynamite Dunes", - "Leafy Lake", - "Diamond Heights", - "Evergreen Gardens", - "Bumbly Beach", - "Trinity Islands", - "Katie's Dreamland", - "Pokey Park", - "White Water Park", - "Millennium Mines", - "Karts & Coasters", - "Mel's World", - "Mystic Mountain", - "Pacific Pyramids", - "Crumbly Woods", - "Paradise Pier", - "Lightning Peaks", - "Ivory Towers", - "Rainbow Valley", - "Thunder Rock", - "Mega Park", - - // RCT: Added Attractions - "Whispering Cliffs", - "Three Monkeys Park", - "Canary Mines", - "Barony Bridge", - "Funtopia", - "Haunted Harbor", - "Fun Fortress", - "Future World", - "Gentle Glen", - "Jolly Jungle", - "Hydro Hills", - "Sprightly Park", - "Magic Quarters", - "Fruit Farm", - "Butterfly Dam", - "Coaster Canyon", - "Thunderstorm Park", - "Harmonic Hills", - "Roman Village", - "Swamp Cove", - "Adrenaline Heights", - "Utopia Park", - "Rotting Heights", - "Fiasco Forest", - "Pickle Park", - "Giggle Downs", - "Mineral Park", - "Coaster Crazy", - "Urban Park", - "Geoffrey Gardens", - - // RCT: Loopy Landscapes - "Iceberg Islands", - "Volcania", - "Arid Heights", - "Razor Rocks", - "Crater Lake", - "Vertigo Views", - "Paradise Pier 2", - "Dragon's Cove", - "Good Knight Park", - "Wacky Warren", - "Grand Glacier", - "Crazy Craters", - "Dusty Desert", - "Woodworm Park", - "Icarus Park", - "Sunny Swamps", - "Frightmare Hills", - "Thunder Rocks", - "Octagon Park", - "Pleasure Island", - "Icicle Worlds", - "Tiny Towers", - "Southern Sands", - "Nevermore Park", - "Pacifica", - "Urban Jungle", - "Terror Town", - "Megaworld Park", - "Venus Ponds", - "Micro Park", - - // RCT2 - "Crazy Castle", - "Electric Fields", - "Factory Capers", - "Amity Airfield", - "Botany Breakers", - "Bumbly Bazaar", - "Dusty Greens", - "Fungus Woods", - "Gravity Gardens", - "Infernal Views", - "Alpine Adventures", - "Extreme Heights", - "Ghost Town", - "Lucky Lake", - "Rainbow Summit", - - // RCT2: Wacky Worlds - "Africa - Victoria Falls", - "Asia - Great Wall of China Tourism Enhancement", - "North America - Grand Canyon", - "South America - Rio Carnival", - "Africa - African Diamond Mine", - "Asia - Maharaja Palace", - "Australasia - Ayers Rock", - "Europe - European Cultural Festival", - "North America - Rollercoaster Heaven", - "South America - Inca Lost City", - "Africa - Oasis", - "Antarctic - Ecological Salvage", - "Asia - Japanese Coastal Reclaim", - "Australasia - Fun at the Beach", - "Europe - Renovation", - "N. America - Extreme Hawaiian Island", - "South America - Rain Forest Plateau", - - // RCT2: Time Twister - "Dark Age - Robin Hood", - "Prehistoric - After the Asteroid", - "Roaring Twenties - Prison Island", - "Rock 'n' Roll - Flower Power", - "Dark Age - Castle", - "Future - First Encounters", - "Mythological - Animatronic Film Set", - "Prehistoric - Jurassic Safari", - "Roaring Twenties - Schneider Cup", - "Future - Future World", - "Mythological - Cradle of Civilisation", - "Prehistoric - Stone Age", - "Roaring Twenties - Skyscrapers", - "Rock 'n' Roll - Rock 'n' Roll", - - // Real parks - "Alton Towers", - "Heide-Park", - "Blackpool Pleasure Beach", - "Six Flags Belgium", - "Six Flags Great Adventure", - "Six Flags Holland", - "Six Flags Magic Mountain", - "Six Flags over Texas" -}; diff --git a/src/windows/title_scenarioselect.c b/src/windows/title_scenarioselect.c index c754a293e6..208b4ae989 100644 --- a/src/windows/title_scenarioselect.c +++ b/src/windows/title_scenarioselect.c @@ -505,12 +505,12 @@ static void initialise_list_items(rct_window *w) // Category heading rct_string_id headingStringId = STR_NONE; if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) { - if (currentHeading != scenario->category) { + if (w->selected_tab != 6 && currentHeading != scenario->category) { currentHeading = scenario->category; headingStringId = STR_BEGINNER_PARKS + currentHeading; } } else { - if (currentHeading != scenario->source_game) { + if (w->selected_tab < 3 && currentHeading != scenario->source_game) { currentHeading = scenario->source_game; headingStringId = STR_SCENARIO_CATEGORY_RCT1 + currentHeading; }