diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 9e85fc8eb7..6b3bb9f23a 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -73,6 +73,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index f1bf2f4f96..1d60034e94 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -296,10 +296,13 @@
Windows
+
+ Header Files
+
Resource Files
-
+
\ No newline at end of file
diff --git a/src/addresses.h b/src/addresses.h
index a38e57f6da..bf7e95c7f8 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -44,8 +44,8 @@
#define RCT2_ADDRESS_LAND_TOOL_SIZE 0x009A9800
#define RCT2_ADDRESS_SAVE_PROMPT_MODE 0x009A9802
-#define RCT2_ADDRESS_SCENARIO_LIST 0x009A9FF4
-#define RCT2_ADDRESS_NUM_SCENARIOS 0x009AA008
+// #define RCT2_ADDRESS_SCENARIO_LIST 0x009A9FF4
+// #define RCT2_ADDRESS_NUM_SCENARIOS 0x009AA008
#define RCT2_ADDRESS_APP_PATH 0x009AA214
diff --git a/src/rct2.c b/src/rct2.c
index a8ab8ea254..239a264ac5 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -210,6 +210,14 @@ void rct2_init_directories()
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char), RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char));
}
+void subsitute_path(char *dest, const char *path, const char *filename)
+{
+ while (*path != '*') {
+ *dest++ = *path++;
+ }
+ strcpy(dest, filename);
+}
+
// rct2: 0x00674B42
void rct2_startup_checks()
{
diff --git a/src/rct2.h b/src/rct2.h
index a872cc25fc..64840b4816 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -161,6 +161,7 @@ enum {
};
void rct2_endupdate();
+void subsitute_path(char *dest, const char *path, const char *filename);
char *get_file_path(int pathId);
void get_system_info();
void get_system_time();
diff --git a/src/scenario.c b/src/scenario.c
index 9e4d557af7..4ecb88ca17 100644
--- a/src/scenario.c
+++ b/src/scenario.c
@@ -36,232 +36,11 @@
#include "sprite.h"
#include "viewport.h"
-#define UNINITIALISED_SCENARIO_LIST ((rct_scenario_basic*)-1)
-
-#define RCT2_SCENARIO_LIST RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)
-#define RCT2_NUM_SCENARIOS RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32)
-int _scenarioListSize;
-
-static void scenario_list_add(char *path);
-static void scenario_list_sort();
-static int scenario_list_sort_compare(const void* a, const void* b);
-static void scenario_scores_load();
-static void scenario_scores_save();
-static int scenario_load_basic(char *path);
-
-static void subsitute_path(char *dest, char *path, char *filename)
-{
- while (*path != '*') {
- *dest++ = *path++;
- }
- strcpy(dest, filename);
-}
-
-static rct_scenario_basic *get_scenario_by_filename(char *filename)
-{
- int i;
- for (i = 0; i < RCT2_NUM_SCENARIOS; i++)
- if (strcmp(RCT2_SCENARIO_LIST[i].path, filename) == 0)
- return &(RCT2_SCENARIO_LIST[i]);
-
- return NULL;
-}
-
-/**
- *
- * rct2: 0x006775A8
- */
-void scenario_load_list()
-{
- int i;
- HANDLE hFindFile;
- WIN32_FIND_DATAA findFileData;
-
- // Load scores
- scenario_scores_load();
-
- // Set all scenarios to be invisible
- for (i = 0; i < RCT2_NUM_SCENARIOS; i++)
- RCT2_SCENARIO_LIST[i].flags &= ~SCENARIO_FLAGS_VISIBLE;
-
- // Enumerate through each scenario in the directory
- hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), &findFileData);
- if (hFindFile != INVALID_HANDLE_VALUE) {
- do {
- scenario_list_add(findFileData.cFileName);
- } while (FindNextFile(hFindFile, &findFileData));
- FindClose(hFindFile);
- }
-
- // Sort alphabetically
- scenario_list_sort();
-
- // Save the scores
- scenario_scores_save();
-}
-
-static void scenario_list_add(char *path)
-{
- rct_scenario_basic *scenario;
- rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
-
- // Check if scenario already exists in list, likely if in scores
- scenario = get_scenario_by_filename(path);
- if (scenario != NULL) {
- // Set 0141EF68 to the scenario path
- subsitute_path(
- RCT2_ADDRESS(0x0141EF68, char),
- RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char),
- path
- );
-
- // Load the basic scenario information
- if (!scenario_load_basic(RCT2_ADDRESS(0x0141EF68, char)))
- return;
-
- //
- if (s6Info->var_000 != 255)
- return;
-
- // Update the scenario information
- scenario->flags |= SCENARIO_FLAGS_VISIBLE;
- scenario->category = s6Info->category;
- scenario->objective_type = s6Info->objective_type;
- scenario->objective_arg_1 = s6Info->objective_arg_1;
- scenario->objective_arg_2 = s6Info->objective_arg_2;
- scenario->objective_arg_3 = s6Info->objective_arg_3;
- strcpy(scenario->name, s6Info->name);
- strcpy(scenario->details, s6Info->details);
- return;
- }
-
- // Check if the scenario list buffer has room for another scenario
- if ((RCT2_NUM_SCENARIOS + 1) * (int)sizeof(rct_scenario_basic) > _scenarioListSize) {
- // Allocate more room
- _scenarioListSize += 16 * sizeof(rct_scenario_basic);
- RCT2_SCENARIO_LIST = (rct_scenario_basic*)rct2_realloc(RCT2_SCENARIO_LIST, _scenarioListSize);
- }
-
- // Set 0141EF68 to the scenario path
- subsitute_path(
- RCT2_ADDRESS(0x0141EF68, char),
- RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char),
- path
- );
-
- // Load the scenario information
- if (!scenario_load_basic(RCT2_ADDRESS(0x0141EF68, char)))
- return;
-
- //
- if (s6Info->var_000 != 255)
- return;
-
- // Increment the number of scenarios
- scenario = &RCT2_SCENARIO_LIST[RCT2_NUM_SCENARIOS];
- RCT2_NUM_SCENARIOS++;
-
- // Add this new scenario to the list
- strcpy(scenario->path, path);
- scenario->flags = SCENARIO_FLAGS_VISIBLE;
- if (RCT2_GLOBAL(0x009AA00C, uint8) & 1)
- scenario->flags |= SCENARIO_FLAGS_SIXFLAGS;
- scenario->category = s6Info->category;
- scenario->objective_type = s6Info->objective_type;
- scenario->objective_arg_1 = s6Info->objective_arg_1;
- scenario->objective_arg_2 = s6Info->objective_arg_2;
- scenario->objective_arg_3 = s6Info->objective_arg_3;
- strcpy(scenario->name, s6Info->name);
- strcpy(scenario->details, s6Info->details);
-}
-
-/**
-* Sort the list of scenarios. This used to be an insertion sort which took
-* place as each scenario loaded. It has now been changed to a quicksort which
-* takes place after all the scenarios have been loaded in.
-* rct2: 0x00677C3B
-*/
-static void scenario_list_sort()
-{
- qsort(
- RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*),
- RCT2_NUM_SCENARIOS,
- sizeof(rct_scenario_basic),
- scenario_list_sort_compare
- );
-}
-
-/**
-* Basic scenario information compare function for sorting.
-* rct2: 0x00677C08
-*/
-static int scenario_list_sort_compare(const void* a, const void* b)
-{
- return strcmp(((rct_scenario_basic*)a)->name, ((rct_scenario_basic*)b)->name);
-}
-
-/**
- *
- * rct2: 0x006775A8
- */
-static void scenario_scores_load()
-{
- HANDLE hFile;
- DWORD bytes_read;
-
- // Free scenario list if already allocated
- if (RCT2_SCENARIO_LIST != UNINITIALISED_SCENARIO_LIST) {
- rct2_free(RCT2_SCENARIO_LIST);
- RCT2_SCENARIO_LIST = UNINITIALISED_SCENARIO_LIST;
- }
-
- // Try and load the scores
- hFile = CreateFile(get_file_path(PATH_ID_SCORES), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile != INVALID_HANDLE_VALUE) {
- ReadFile(hFile, (void*)0x009A9FFC, 16, &bytes_read, NULL);
- if (bytes_read == 16) {
- _scenarioListSize = RCT2_NUM_SCENARIOS * sizeof(rct_scenario_basic);
- RCT2_SCENARIO_LIST = (rct_scenario_basic*)rct2_malloc(_scenarioListSize);
- ReadFile(hFile, RCT2_SCENARIO_LIST, _scenarioListSize, &bytes_read, NULL);
- CloseHandle(hFile);
- if (bytes_read == _scenarioListSize)
- return;
- } else {
- CloseHandle(hFile);
- }
- }
-
- // Unable to load scores, allocate some space for a reload
- RCT2_NUM_SCENARIOS = 0;
- _scenarioListSize = 0x4000;
- RCT2_SCENARIO_LIST = (rct_scenario_basic*)rct2_malloc(_scenarioListSize);
-}
-
-/**
- *
- * rct2: 0x00677B50
- */
-static void scenario_scores_save()
-{
- HANDLE hFile;
- DWORD bytes_written;
-
- hFile = CreateFile(get_file_path(PATH_ID_SCORES), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile != INVALID_HANDLE_VALUE) {
- WriteFile(hFile, (void*)0x009A9FFC, 16, &bytes_written, NULL);
- if (RCT2_NUM_SCENARIOS > 0)
- WriteFile(hFile, RCT2_SCENARIO_LIST, RCT2_NUM_SCENARIOS * sizeof(rct_scenario_basic), &bytes_written, NULL);
- CloseHandle(hFile);
- }
-}
-
/**
* Loads only the basic information from a scenario.
* rct2: 0x006761D6
*/
-static int scenario_load_basic(char *path)
+int scenario_load_basic(const char *path)
{
HANDLE hFile;
int _eax;
@@ -281,7 +60,7 @@ static int scenario_load_basic(char *path)
sawyercoding_read_chunk(hFile, (uint8*)s6Info);
CloseHandle(hFile);
RCT2_GLOBAL(0x009AA00C, uint8) = 0;
- if (s6Info->flags != 255) {
+ if ((s6Info->flags & 0xFF) != 255) {
#ifdef _MSC_VER
__asm {
push ebp
@@ -337,7 +116,7 @@ static int scenario_load_basic(char *path)
* rct2: 0x00676053
* scenario (ebx)
*/
-void scenario_load(char *path)
+void scenario_load(const char *path)
{
HANDLE hFile;
int i, j;
@@ -427,7 +206,7 @@ void scenario_load(char *path)
* rct2: 0x00678282
* scenario (ebx)
*/
-void scenario_load_and_play(rct_scenario_basic *scenario)
+void scenario_load_and_play(const rct_scenario_basic *scenario)
{
rct_window *mainWindow;
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
@@ -590,9 +369,9 @@ void scenario_success()
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = current_val;
RCT2_CALLPROC_EBPSAFE(0x0069BE9B); // celebration
- for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32); i++) {
+ for (i = 0; i < gScenarioListCount; i++) {
char *cur_scenario_name = RCT2_ADDRESS(0x135936C, char);
- scenario = &(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)[i]);
+ scenario = &gScenarioList[i];
if (0 == strncmp(cur_scenario_name, scenario->path, 256)){
if (scenario->flags & SCENARIO_FLAGS_COMPLETED && scenario->company_value < current_val)
diff --git a/src/scenario.h b/src/scenario.h
index 1589b7621f..ec47c7f3a1 100644
--- a/src/scenario.h
+++ b/src/scenario.h
@@ -49,10 +49,22 @@ typedef struct {
uint8 pad_00A[0x3E];
char name[64]; // 0x48
char details[256]; // 0x88
- uint8 flags; // 0x188
- uint8 pad_189[0x0F];
+ uint32 flags; // 0x188
+ uint32 pad_18C;
+ uint32 pad_190;
+ uint32 pad_194;
} rct_s6_info;
+/*
+ * Scenario scores file header.
+ * size: 0x10
+ */
+typedef struct {
+ uint32 var_0;
+ uint32 var_4;
+ uint32 var_8;
+ uint32 scenario_count; // 0x0C
+} rct_scenario_scores_header;
/**
* Scenario basic structure, mainly for scenario select
@@ -107,9 +119,16 @@ enum {
OBJECTIVE_MONTHLY_FOOD_INCOME
};
+// Scenario list
+extern int gScenarioListCount;
+extern int gScenarioListCapacity;
+extern rct_scenario_basic *gScenarioList;
+
+int scenario_scores_save();
void scenario_load_list();
-void scenario_load(char *path);
-void scenario_load_and_play(rct_scenario_basic *scenario);
+int scenario_load_basic(const char *path);
+void scenario_load(const char *path);
+void scenario_load_and_play(const rct_scenario_basic *scenario);
void scenario_update();
#endif
diff --git a/src/scenario_list.c b/src/scenario_list.c
new file mode 100644
index 0000000000..c2e7a97df7
--- /dev/null
+++ b/src/scenario_list.c
@@ -0,0 +1,226 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#include
+#include "addresses.h"
+#include "rct2.h"
+#include "scenario.h"
+
+// Scenario list
+int gScenarioListCount = 0;
+int gScenarioListCapacity = 0;
+rct_scenario_basic *gScenarioList = NULL;
+
+static void scenario_list_add(const char *path);
+static void scenario_list_sort();
+static int scenario_list_sort_compare(const void *a, const void *b);
+static int scenario_scores_load();
+
+static rct_scenario_basic *get_scenario_by_filename(const char *filename)
+{
+ int i;
+ for (i = 0; i < gScenarioListCount; i++)
+ if (strcmp(gScenarioList[i].path, filename) == 0)
+ return &gScenarioList[i];
+
+ return NULL;
+}
+
+/**
+ *
+ * rct2: 0x006775A8
+ */
+void scenario_load_list()
+{
+ int i;
+ HANDLE hFindFile;
+ WIN32_FIND_DATAA findFileData;
+
+ // Load scores
+ scenario_scores_load();
+
+ // Set all scenarios to be invisible
+ for (i = 0; i < gScenarioListCount; i++)
+ gScenarioList[i].flags &= ~SCENARIO_FLAGS_VISIBLE;
+
+ // Enumerate through each scenario in the directory
+ hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), &findFileData);
+ if (hFindFile != INVALID_HANDLE_VALUE) {
+ do {
+ scenario_list_add(findFileData.cFileName);
+ } while (FindNextFile(hFindFile, &findFileData));
+ FindClose(hFindFile);
+ }
+
+ // Sort alphabetically
+ scenario_list_sort();
+
+ // Save the scores
+ scenario_scores_save();
+}
+
+static void scenario_list_add(const char *path)
+{
+ char scenarioPath[MAX_PATH];
+ rct_scenario_basic *scenario;
+ rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
+
+ // Get absolute path
+ subsitute_path(scenarioPath, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), path);
+
+ // Load the basic scenario information
+ if (!scenario_load_basic(scenarioPath))
+ return;
+
+ // Ignore scenarios where first header byte is not 255
+ if (s6Info->var_000 != 255)
+ return;
+
+ // Check if scenario already exists in list, likely if in scores
+ scenario = get_scenario_by_filename(path);
+ if (scenario != NULL) {
+ // Update the scenario information
+ scenario->flags |= SCENARIO_FLAGS_VISIBLE;
+ scenario->category = s6Info->category;
+ scenario->objective_type = s6Info->objective_type;
+ scenario->objective_arg_1 = s6Info->objective_arg_1;
+ scenario->objective_arg_2 = s6Info->objective_arg_2;
+ scenario->objective_arg_3 = s6Info->objective_arg_3;
+ strcpy(scenario->name, s6Info->name);
+ strcpy(scenario->details, s6Info->details);
+ } else {
+ // Check if the scenario list buffer has room for another scenario
+ if (gScenarioListCount >= gScenarioListCapacity) {
+ // Allocate more room
+ gScenarioListCapacity += 16;
+ gScenarioList = realloc(gScenarioList, gScenarioListCapacity * sizeof(rct_scenario_basic));
+ }
+
+ // Increment the number of scenarios
+ scenario = &gScenarioList[gScenarioListCount];
+ gScenarioListCount++;
+
+ // Add this new scenario to the list
+ strcpy(scenario->path, path);
+ scenario->flags = SCENARIO_FLAGS_VISIBLE;
+ if (RCT2_GLOBAL(0x009AA00C, uint8) & 1)
+ scenario->flags |= SCENARIO_FLAGS_SIXFLAGS;
+ scenario->category = s6Info->category;
+ scenario->objective_type = s6Info->objective_type;
+ scenario->objective_arg_1 = s6Info->objective_arg_1;
+ scenario->objective_arg_2 = s6Info->objective_arg_2;
+ scenario->objective_arg_3 = s6Info->objective_arg_3;
+ strcpy(scenario->name, s6Info->name);
+ strcpy(scenario->details, s6Info->details);
+ }
+}
+
+/**
+* Sort the list of scenarios. This used to be an insertion sort which took
+* place as each scenario loaded. It has now been changed to a quicksort which
+* takes place after all the scenarios have been loaded in.
+* rct2: 0x00677C3B
+*/
+static void scenario_list_sort()
+{
+ qsort(gScenarioList, gScenarioListCount, sizeof(rct_scenario_basic), scenario_list_sort_compare);
+}
+
+/**
+* Basic scenario information compare function for sorting.
+* rct2: 0x00677C08
+*/
+static int scenario_list_sort_compare(const void *a, const void *b)
+{
+ return strcmp(((rct_scenario_basic*)a)->name, ((rct_scenario_basic*)b)->name);
+}
+
+/**
+ *
+ * rct2: 0x006775A8
+ */
+static int scenario_scores_load()
+{
+ FILE *file;
+
+ // Free scenario list if already allocated
+ if (gScenarioList != NULL) {
+ free(gScenarioList);
+ gScenarioList = NULL;
+ }
+
+ // Try and load the scores file
+ file = fopen(get_file_path(PATH_ID_SCORES), "rb");
+ if (file == NULL) {
+ RCT2_ERROR("Unable to load scenario scores.");
+ return 0;
+ }
+
+ // Load header
+ rct_scenario_scores_header header;
+ if (fread(&header, 16, 1, file) != 1) {
+ fclose(file);
+ RCT2_ERROR("Invalid header in scenario scores file.");
+ return 0;
+ }
+ gScenarioListCount = header.scenario_count;
+
+ // Load scenario information with scores
+ int scenarioListBufferSize = gScenarioListCount * sizeof(rct_scenario_basic);
+ gScenarioListCapacity = gScenarioListCount;
+ gScenarioList = malloc(scenarioListBufferSize);
+ if (fread(gScenarioList, scenarioListBufferSize, 1, file) == 1) {
+ fclose(file);
+ return 1;
+ }
+
+ // Unable to load scores, free scenario list
+ fclose(file);
+ gScenarioListCount = 0;
+ gScenarioListCapacity = 0;
+ free(gScenarioList);
+ gScenarioList = NULL;
+ return 0;
+}
+
+/**
+ *
+ * rct2: 0x00677B50
+ */
+int scenario_scores_save()
+{
+ FILE *file;
+
+ file = fopen(get_file_path(PATH_ID_SCORES), "wb");
+ if (file == NULL) {
+ RCT2_ERROR("Unable to save scenario scores.");
+ return 0;
+ }
+
+ rct_scenario_scores_header header;
+ header.scenario_count = gScenarioListCount;
+
+ fwrite(&header, sizeof(header), 1, file);
+ if (gScenarioListCount > 0)
+ fwrite(gScenarioList, gScenarioListCount * sizeof(rct_scenario_basic), 1, file);
+
+ fclose(file);
+ return 1;
+}
\ No newline at end of file
diff --git a/src/window_title_scenarioselect.c b/src/window_title_scenarioselect.c
index 021490dc81..8f0f34329b 100644
--- a/src/window_title_scenarioselect.c
+++ b/src/window_title_scenarioselect.c
@@ -147,8 +147,8 @@ static void window_scenarioselect_init_tabs()
rct_scenario_basic* scenario;
show_pages = 0;
- for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32); i++) {
- scenario = &(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)[i]);
+ for (i = 0; i < gScenarioListCount; i++) {
+ scenario = &gScenarioList[i];
if (scenario->flags & SCENARIO_FLAGS_VISIBLE)
show_pages |= 1 << scenario->category;
}
@@ -233,8 +233,8 @@ static void window_scenarioselect_scrollgetsize()
height = 0;
- for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32); i++) {
- scenario = &(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)[i]);
+ for (i = 0; i < gScenarioListCount; i++) {
+ scenario = &gScenarioList[i];
if (scenario->category != w->selected_tab)
continue;
if (scenario->flags & SCENARIO_FLAGS_VISIBLE)
@@ -281,8 +281,8 @@ static void window_scenarioselect_scrollmousedown()
#endif
- for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32); i++) {
- scenario = &(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)[i]);
+ for (i = 0; i < gScenarioListCount; i++) {
+ scenario = &gScenarioList[i];
if (scenario->category != w->selected_tab)
continue;
if (!(scenario->flags & SCENARIO_FLAGS_VISIBLE))
@@ -325,8 +325,8 @@ static void window_scenarioselect_scrollmouseover()
selected = NULL;
- for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32); i++) {
- scenario = &(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)[i]);
+ for (i = 0; i < gScenarioListCount; i++) {
+ scenario = &gScenarioList[i];
if (scenario->category != w->selected_tab)
continue;
if (!(scenario->flags & SCENARIO_FLAGS_VISIBLE))
@@ -458,8 +458,8 @@ static void window_scenarioselect_scrollpaint()
gfx_clear(dpi, colour);
y = 0;
- for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_NUM_SCENARIOS, sint32); i++) {
- scenario = &(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_LIST, rct_scenario_basic*)[i]);
+ for (i = 0; i < gScenarioListCount; i++) {
+ scenario = &gScenarioList[i];
if (scenario->category != w->selected_tab)
continue;
if (!(scenario->flags & SCENARIO_FLAGS_VISIBLE))