mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-20 13:33:02 +01:00
clean up scenario list
This commit is contained in:
@@ -73,6 +73,7 @@
|
||||
<ClCompile Include="..\src\ride.c" />
|
||||
<ClCompile Include="..\src\sawyercoding.c" />
|
||||
<ClCompile Include="..\src\scenario.c" />
|
||||
<ClCompile Include="..\src\scenario_list.c" />
|
||||
<ClCompile Include="..\src\screenshot.c" />
|
||||
<ClCompile Include="..\src\string_ids.c" />
|
||||
<ClCompile Include="..\src\title.c" />
|
||||
|
||||
@@ -296,10 +296,13 @@
|
||||
<ClCompile Include="..\src\window_map.c">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\scenario_list.c">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\openrct2.exe">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
233
src/scenario.c
233
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
226
src/scenario_list.c
Normal file
226
src/scenario_list.c
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#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;
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user