mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor load park result
Use a C++ struct and pass that to C.
This commit is contained in:
parent
d75295b027
commit
ddb96ec267
|
@ -21,6 +21,65 @@
|
||||||
#include "object/ObjectRepository.h"
|
#include "object/ObjectRepository.h"
|
||||||
#include "ParkImporter.h"
|
#include "ParkImporter.h"
|
||||||
|
|
||||||
|
ParkLoadResult::ParkLoadResult(PARK_LOAD_ERROR error)
|
||||||
|
: Error(error)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ParkLoadResult::ParkLoadResult(PARK_LOAD_ERROR error, const std::vector<rct_object_entry> &missingObjects)
|
||||||
|
: Error(error),
|
||||||
|
MissingObjects(missingObjects)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ParkLoadResult ParkLoadResult::CreateOK()
|
||||||
|
{
|
||||||
|
return ParkLoadResult(PARK_LOAD_ERROR::PARK_LOAD_ERROR_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParkLoadResult ParkLoadResult::CreateInvalidExtension()
|
||||||
|
{
|
||||||
|
return ParkLoadResult(PARK_LOAD_ERROR::PARK_LOAD_ERROR_INVALID_EXTENSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParkLoadResult ParkLoadResult::CreateMissingObjects(const std::vector<rct_object_entry> &missingObjects)
|
||||||
|
{
|
||||||
|
return ParkLoadResult(PARK_LOAD_ERROR::PARK_LOAD_ERROR_MISSING_OBJECTS, missingObjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParkLoadResult ParkLoadResult::CreateUnknown()
|
||||||
|
{
|
||||||
|
return ParkLoadResult(PARK_LOAD_ERROR::PARK_LOAD_ERROR_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
PARK_LOAD_ERROR ParkLoadResult_GetError(const ParkLoadResult * t)
|
||||||
|
{
|
||||||
|
return t->Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ParkLoadResult_GetMissingObjectsCount(const ParkLoadResult * t)
|
||||||
|
{
|
||||||
|
return t->MissingObjects.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rct_object_entry * ParkLoadResult_GetMissingObjects(const ParkLoadResult * t)
|
||||||
|
{
|
||||||
|
return t->MissingObjects.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParkLoadResult_Delete(ParkLoadResult * t)
|
||||||
|
{
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParkLoadResult * ParkLoadResult_CreateInvalidExtension()
|
||||||
|
{
|
||||||
|
return new ParkLoadResult(ParkLoadResult::CreateInvalidExtension());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace ParkImporter
|
namespace ParkImporter
|
||||||
{
|
{
|
||||||
IParkImporter * Create(const std::string &hintPath)
|
IParkImporter * Create(const std::string &hintPath)
|
||||||
|
|
|
@ -22,20 +22,45 @@
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
#include "park_load_result_types.h"
|
#include "object.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum PARK_LOAD_ERROR
|
||||||
|
{
|
||||||
|
PARK_LOAD_ERROR_OK,
|
||||||
|
PARK_LOAD_ERROR_MISSING_OBJECTS,
|
||||||
|
PARK_LOAD_ERROR_INVALID_EXTENSION,
|
||||||
|
PARK_LOAD_ERROR_UNKNOWN = 255
|
||||||
|
} PARK_LOAD_ERROR;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "scenario/ScenarioRepository.h"
|
#include "scenario/ScenarioRepository.h"
|
||||||
|
|
||||||
interface IObjectManager;
|
interface IObjectManager;
|
||||||
interface IObjectRepository;
|
interface IObjectRepository;
|
||||||
interface IStream;
|
interface IStream;
|
||||||
|
|
||||||
|
struct ParkLoadResult final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const PARK_LOAD_ERROR Error;
|
||||||
|
const std::vector<rct_object_entry> MissingObjects;
|
||||||
|
|
||||||
|
static ParkLoadResult CreateOK();
|
||||||
|
static ParkLoadResult CreateInvalidExtension();
|
||||||
|
static ParkLoadResult CreateMissingObjects(const std::vector<rct_object_entry> &missingObjects);
|
||||||
|
static ParkLoadResult CreateUnknown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ParkLoadResult(PARK_LOAD_ERROR error);
|
||||||
|
ParkLoadResult(PARK_LOAD_ERROR error, const std::vector<rct_object_entry> &missingObjects);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to import scenarios and saved games.
|
* Interface to import scenarios and saved games.
|
||||||
*/
|
*/
|
||||||
|
@ -43,10 +68,12 @@ interface IParkImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IParkImporter() = default;
|
virtual ~IParkImporter() = default;
|
||||||
virtual park_load_result * Load(const utf8 * path) abstract;
|
|
||||||
virtual park_load_result * LoadSavedGame(const utf8 * path, bool skipObjectCheck = false) abstract;
|
virtual ParkLoadResult Load(const utf8 * path) abstract;
|
||||||
virtual park_load_result * LoadScenario(const utf8 * path, bool skipObjectCheck = false) abstract;
|
virtual ParkLoadResult LoadSavedGame(const utf8 * path, bool skipObjectCheck = false) abstract;
|
||||||
virtual park_load_result * LoadFromStream(IStream * stream, bool isScenario, bool skipObjectCheck = false) abstract;
|
virtual ParkLoadResult LoadScenario(const utf8 * path, bool skipObjectCheck = false) abstract;
|
||||||
|
virtual ParkLoadResult LoadFromStream(IStream * stream, bool isScenario, bool skipObjectCheck = false) abstract;
|
||||||
|
|
||||||
virtual void Import() abstract;
|
virtual void Import() abstract;
|
||||||
virtual bool GetDetails(scenario_index_entry * dst) abstract;
|
virtual bool GetDetails(scenario_index_entry * dst) abstract;
|
||||||
};
|
};
|
||||||
|
@ -61,6 +88,10 @@ namespace ParkImporter
|
||||||
bool ExtensionIsScenario(const std::string &extension);
|
bool ExtensionIsScenario(const std::string &extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef struct ParkLoadResult ParkLoadResult;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -70,6 +101,11 @@ extern "C"
|
||||||
void park_importer_load_from_stream(void * stream, const utf8 * hintPath);
|
void park_importer_load_from_stream(void * stream, const utf8 * hintPath);
|
||||||
bool park_importer_extension_is_scenario(const utf8 * extension);
|
bool park_importer_extension_is_scenario(const utf8 * extension);
|
||||||
|
|
||||||
|
PARK_LOAD_ERROR ParkLoadResult_GetError(const ParkLoadResult * t);
|
||||||
|
size_t ParkLoadResult_GetMissingObjectsCount(const ParkLoadResult * t);
|
||||||
|
const rct_object_entry * ParkLoadResult_GetMissingObjects(const ParkLoadResult * t);
|
||||||
|
void ParkLoadResult_Delete(ParkLoadResult * t);
|
||||||
|
ParkLoadResult * ParkLoadResult_CreateInvalidExtension();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "rct1.h"
|
#include "rct1.h"
|
||||||
#include "ride/ride.h"
|
#include "ride/ride.h"
|
||||||
|
#include "ParkImporter.h"
|
||||||
#include "scenario/scenario.h"
|
#include "scenario/scenario.h"
|
||||||
#include "util/sawyercoding.h"
|
#include "util/sawyercoding.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
@ -261,16 +262,18 @@ static sint32 editor_load_landscape_from_sc4(const char *path)
|
||||||
*/
|
*/
|
||||||
static sint32 editor_read_s6(const char *path)
|
static sint32 editor_read_s6(const char *path)
|
||||||
{
|
{
|
||||||
park_load_result* loadResult = { 0 };
|
ParkLoadResult * loadResult = NULL;
|
||||||
const char *extension = path_get_extension(path);
|
const char *extension = path_get_extension(path);
|
||||||
if (_stricmp(extension, ".sc6") == 0) {
|
if (_stricmp(extension, ".sc6") == 0) {
|
||||||
loadResult = scenario_load(path);
|
loadResult = scenario_load(path);
|
||||||
} else if (_stricmp(extension, ".sv6") == 0) {
|
} else if (_stricmp(extension, ".sv6") == 0) {
|
||||||
loadResult = game_load_sv6_path(path);
|
loadResult = game_load_sv6_path(path);
|
||||||
}
|
}
|
||||||
if (loadResult->error != PARK_LOAD_ERROR_NONE) {
|
if (ParkLoadResult_GetError(loadResult) != PARK_LOAD_ERROR_OK) {
|
||||||
|
ParkLoadResult_Delete(loadResult);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
ParkLoadResult_Delete(loadResult);
|
||||||
|
|
||||||
editor_clear_map_for_editing(true);
|
editor_clear_map_for_editing(true);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "OpenRCT2.h"
|
#include "OpenRCT2.h"
|
||||||
|
#include "ParkImporter.h"
|
||||||
#include "peep/peep.h"
|
#include "peep/peep.h"
|
||||||
#include "peep/staff.h"
|
#include "peep/staff.h"
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
@ -1094,15 +1095,16 @@ bool game_load_save(const utf8 *path)
|
||||||
safe_strcpy(gScenarioSavePath, path, MAX_PATH);
|
safe_strcpy(gScenarioSavePath, path, MAX_PATH);
|
||||||
|
|
||||||
uint32 extension_type = get_file_extension_type(path);
|
uint32 extension_type = get_file_extension_type(path);
|
||||||
park_load_result* result = {0};
|
ParkLoadResult * result = NULL;
|
||||||
bool load_success = false;
|
bool load_success = false;
|
||||||
if (extension_type == FILE_EXTENSION_SV6) {
|
if (extension_type == FILE_EXTENSION_SV6) {
|
||||||
result = game_load_sv6_path(path);
|
result = game_load_sv6_path(path);
|
||||||
load_success = (result->error == PARK_LOAD_ERROR_NONE);
|
load_success = (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_OK);
|
||||||
if (load_success)
|
if (load_success)
|
||||||
gFirstTimeSaving = false;
|
gFirstTimeSaving = false;
|
||||||
} else if (extension_type == FILE_EXTENSION_SV4) {
|
} else if (extension_type == FILE_EXTENSION_SV4) {
|
||||||
load_success = rct1_load_saved_game(path);
|
result = rct1_load_saved_game(path);
|
||||||
|
load_success = (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_OK);
|
||||||
if (load_success)
|
if (load_success)
|
||||||
gFirstTimeSaving = true;
|
gFirstTimeSaving = true;
|
||||||
}
|
}
|
||||||
|
@ -1126,20 +1128,20 @@ bool game_load_save(const utf8 *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_park_load_failure(park_load_result* result, const utf8* path)
|
void handle_park_load_failure(const ParkLoadResult * result, const utf8 * path)
|
||||||
{
|
{
|
||||||
if (result->error == PARK_LOAD_ERROR_BAD_OBJECTS)
|
if (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_MISSING_OBJECTS)
|
||||||
{
|
{
|
||||||
// The path needs to be duplicated as it's a const here
|
// The path needs to be duplicated as it's a const here
|
||||||
// which the window function doesn't like
|
// which the window function doesn't like
|
||||||
window_object_load_error_open(strndup(path, strnlen(path, MAX_PATH)), result->object_validity);
|
window_object_load_error_open(strndup(path, strnlen(path, MAX_PATH)),
|
||||||
}
|
ParkLoadResult_GetMissingObjectsCount(result),
|
||||||
else if (result->error != PARK_LOAD_ERROR_NONE) {
|
ParkLoadResult_GetMissingObjects(result));
|
||||||
|
} else if (ParkLoadResult_GetError(result) != PARK_LOAD_ERROR_OK) {
|
||||||
// If loading the SV6 or SV4 failed for a reason other than invalid objects
|
// If loading the SV6 or SV4 failed for a reason other than invalid objects
|
||||||
// the current park state will be corrupted so just go back to the title screen.
|
// the current park state will be corrupted so just go back to the title screen.
|
||||||
title_load();
|
title_load();
|
||||||
}
|
}
|
||||||
SafeFree(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_load_init()
|
void game_load_init()
|
||||||
|
@ -1378,7 +1380,6 @@ void rct2_exit()
|
||||||
|
|
||||||
bool game_load_save_or_scenario(const utf8 * path)
|
bool game_load_save_or_scenario(const utf8 * path)
|
||||||
{
|
{
|
||||||
park_load_result* result;
|
|
||||||
uint32 extension = get_file_extension_type(path);
|
uint32 extension = get_file_extension_type(path);
|
||||||
switch (extension) {
|
switch (extension) {
|
||||||
case FILE_EXTENSION_SV4:
|
case FILE_EXTENSION_SV4:
|
||||||
|
@ -1386,8 +1387,12 @@ bool game_load_save_or_scenario(const utf8 * path)
|
||||||
return game_load_save(path);
|
return game_load_save(path);
|
||||||
case FILE_EXTENSION_SC4:
|
case FILE_EXTENSION_SC4:
|
||||||
case FILE_EXTENSION_SC6:
|
case FILE_EXTENSION_SC6:
|
||||||
result = scenario_load_and_play_from_path(path);
|
{
|
||||||
return (result->error == PARK_LOAD_ERROR_NONE);
|
ParkLoadResult * result = scenario_load_and_play_from_path(path);
|
||||||
|
bool success = (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_OK);
|
||||||
|
ParkLoadResult_Delete(result);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "rct2/addresses.h"
|
#include "rct2/addresses.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "scenario/scenario.h"
|
#include "scenario/scenario.h"
|
||||||
#include "park_load_result_types.h"
|
|
||||||
|
|
||||||
enum GAME_COMMAND {
|
enum GAME_COMMAND {
|
||||||
GAME_COMMAND_SET_RIDE_APPEARANCE,
|
GAME_COMMAND_SET_RIDE_APPEARANCE,
|
||||||
|
@ -171,7 +170,7 @@ sint32 game_do_command_p(sint32 command, sint32 *eax, sint32 *ebx, sint32 *ecx,
|
||||||
void game_log_multiplayer_command(int command, int *eax, int* ebx, int* ecx, int* edx, int* edi, int* ebp);
|
void game_log_multiplayer_command(int command, int *eax, int* ebx, int* ecx, int* edx, int* edi, int* ebp);
|
||||||
|
|
||||||
void game_load_or_quit_no_save_prompt();
|
void game_load_or_quit_no_save_prompt();
|
||||||
park_load_result * game_load_sv6_path(const char * path);
|
ParkLoadResult * game_load_sv6_path(const char * path);
|
||||||
bool game_load_save(const utf8 *path);
|
bool game_load_save(const utf8 *path);
|
||||||
void game_load_init();
|
void game_load_init();
|
||||||
void game_pause_toggle(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
void game_pause_toggle(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||||
|
@ -180,7 +179,7 @@ bool game_is_paused();
|
||||||
bool game_is_not_paused();
|
bool game_is_not_paused();
|
||||||
void save_game();
|
void save_game();
|
||||||
void save_game_as();
|
void save_game_as();
|
||||||
void handle_park_load_failure(park_load_result* result, const utf8* path);
|
void handle_park_load_failure(const ParkLoadResult * result, const utf8 * path);
|
||||||
void rct2_exit();
|
void rct2_exit();
|
||||||
void rct2_exit_reason(rct_string_id title, rct_string_id body);
|
void rct2_exit_reason(rct_string_id title, rct_string_id body);
|
||||||
void game_autosave();
|
void game_autosave();
|
||||||
|
|
|
@ -767,7 +767,7 @@ rct_window *window_mapgen_open();
|
||||||
rct_window *window_loadsave_open(sint32 type, char *defaultName);
|
rct_window *window_loadsave_open(sint32 type, char *defaultName);
|
||||||
rct_window *window_changelog_open();
|
rct_window *window_changelog_open();
|
||||||
void window_debug_paint_open();
|
void window_debug_paint_open();
|
||||||
rct_window *window_object_load_error_open(utf8* path, object_validity_result* result);
|
rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects, const rct_object_entry * missingObjects);
|
||||||
|
|
||||||
rct_window * window_editor_main_open();
|
rct_window * window_editor_main_open();
|
||||||
void window_editor_bottom_toolbar_open();
|
void window_editor_bottom_toolbar_open();
|
||||||
|
|
|
@ -447,10 +447,10 @@ private:
|
||||||
return duplicate;
|
return duplicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_validity_result* GetInvalidObjects(const rct_object_entry * entries) override
|
std::vector<rct_object_entry> GetInvalidObjects(const rct_object_entry * entries) override
|
||||||
{
|
{
|
||||||
uint16 invalidObjectCount = 0;
|
std::vector<rct_object_entry> invalidEntries;
|
||||||
rct_object_entry * * invalidEntries = Memory::AllocateArray<rct_object_entry *>(OBJECT_ENTRY_COUNT);
|
invalidEntries.reserve(OBJECT_ENTRY_COUNT);
|
||||||
for (sint32 i = 0; i < OBJECT_ENTRY_COUNT; i++)
|
for (sint32 i = 0; i < OBJECT_ENTRY_COUNT; i++)
|
||||||
{
|
{
|
||||||
const rct_object_entry * entry = &entries[i];
|
const rct_object_entry * entry = &entries[i];
|
||||||
|
@ -460,7 +460,7 @@ private:
|
||||||
ori = _objectRepository->FindObject(entry);
|
ori = _objectRepository->FindObject(entry);
|
||||||
if (ori == nullptr)
|
if (ori == nullptr)
|
||||||
{
|
{
|
||||||
invalidEntries[invalidObjectCount++] = DuplicateObjectEntry(entry);
|
invalidEntries.push_back(*entry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -471,16 +471,14 @@ private:
|
||||||
loadedObject = _objectRepository->LoadObject(ori);
|
loadedObject = _objectRepository->LoadObject(ori);
|
||||||
if (loadedObject == nullptr)
|
if (loadedObject == nullptr)
|
||||||
{
|
{
|
||||||
invalidEntries[invalidObjectCount++] = DuplicateObjectEntry(entry);
|
invalidEntries.push_back(*entry);
|
||||||
}
|
}
|
||||||
|
delete loadedObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object_validity_result* result = Memory::Allocate<object_validity_result>(sizeof(object_validity_result));
|
return invalidEntries;
|
||||||
result->invalid_object_count = invalidObjectCount;
|
|
||||||
result->invalid_objects = invalidEntries;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetRequiredObjects(const rct_object_entry * entries,
|
bool GetRequiredObjects(const rct_object_entry * entries,
|
||||||
|
|
|
@ -27,7 +27,6 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
#include "../park_load_result_types.h"
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,10 +41,10 @@ interface IObjectManager
|
||||||
{
|
{
|
||||||
virtual ~IObjectManager() { }
|
virtual ~IObjectManager() { }
|
||||||
|
|
||||||
virtual Object * GetLoadedObject(size_t index) abstract;
|
virtual Object * GetLoadedObject(size_t index) abstract;
|
||||||
virtual Object * GetLoadedObject(const rct_object_entry * entry) abstract;
|
virtual Object * GetLoadedObject(const rct_object_entry * entry) abstract;
|
||||||
virtual uint8 GetLoadedObjectEntryIndex(const Object * object) abstract;
|
virtual uint8 GetLoadedObjectEntryIndex(const Object * object) abstract;
|
||||||
virtual object_validity_result* GetInvalidObjects(const rct_object_entry * entries) abstract;
|
virtual std::vector<rct_object_entry> GetInvalidObjects(const rct_object_entry * entries) abstract;
|
||||||
|
|
||||||
virtual Object * LoadObject(const rct_object_entry * entry) abstract;
|
virtual Object * LoadObject(const rct_object_entry * entry) abstract;
|
||||||
virtual bool LoadObjects(const rct_object_entry * entries, size_t count) abstract;
|
virtual bool LoadObjects(const rct_object_entry * entries, size_t count) abstract;
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
|
|
||||||
/*****************************************************************************
|
|
||||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
||||||
*
|
|
||||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
|
||||||
* For more information, visit https://github.com/OpenRCT2/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.
|
|
||||||
*
|
|
||||||
* A full copy of the GNU General Public License can be found in licence.txt
|
|
||||||
*****************************************************************************/
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#ifndef _PARK_LOAD_RESULT_H_
|
|
||||||
#define _PARK_LOAD_RESULT_H_
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
|
|
||||||
enum PARK_LOAD_ERROR {
|
|
||||||
PARK_LOAD_ERROR_NONE,
|
|
||||||
PARK_LOAD_ERROR_BAD_OBJECTS,
|
|
||||||
PARK_LOAD_ERROR_INVALID_EXTENSION,
|
|
||||||
PARK_LOAD_ERROR_UNKNOWN = 255
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct object_validity_result
|
|
||||||
{
|
|
||||||
uint16 invalid_object_count;
|
|
||||||
rct_object_entry * * invalid_objects;
|
|
||||||
|
|
||||||
} object_validity_result;
|
|
||||||
|
|
||||||
typedef struct park_load_result {
|
|
||||||
uint8 error;
|
|
||||||
object_validity_result* object_validity;
|
|
||||||
} park_load_result;
|
|
||||||
#endif
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "management/award.h"
|
#include "management/award.h"
|
||||||
#include "management/news_item.h"
|
#include "management/news_item.h"
|
||||||
#include "management/research.h"
|
#include "management/research.h"
|
||||||
#include "park_load_result_types.h"
|
|
||||||
#include "rct12.h"
|
#include "rct12.h"
|
||||||
#include "rct2.h"
|
#include "rct2.h"
|
||||||
#include "ride/ride.h"
|
#include "ride/ride.h"
|
||||||
|
@ -35,6 +34,8 @@
|
||||||
#define RCT1_MAX_RIDES_IN_PARK 128
|
#define RCT1_MAX_RIDES_IN_PARK 128
|
||||||
#define RCT1_RESEARCH_FLAGS_SEPARATOR 0xFF
|
#define RCT1_RESEARCH_FLAGS_SEPARATOR 0xFF
|
||||||
|
|
||||||
|
typedef struct ParkLoadResult ParkLoadResult;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
typedef struct rct1_entrance {
|
typedef struct rct1_entrance {
|
||||||
uint16 x;
|
uint16 x;
|
||||||
|
@ -1210,8 +1211,8 @@ extern const uint8 gRideCategories[RIDE_TYPE_COUNT];
|
||||||
sint32 vehicle_preference_compare(uint8 rideType, const char * a, const char * b);
|
sint32 vehicle_preference_compare(uint8 rideType, const char * a, const char * b);
|
||||||
bool rideTypeShouldLoseSeparateFlag(const rct_ride_entry *rideEntry);
|
bool rideTypeShouldLoseSeparateFlag(const rct_ride_entry *rideEntry);
|
||||||
|
|
||||||
park_load_result * rct1_load_saved_game(const char *path);
|
ParkLoadResult * rct1_load_saved_game(const char *path);
|
||||||
park_load_result * rct1_load_scenario(const char *path);
|
ParkLoadResult * rct1_load_scenario(const char *path);
|
||||||
|
|
||||||
colour_t rct1_get_colour(colour_t colour);
|
colour_t rct1_get_colour(colour_t colour);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "../core/Path.hpp"
|
#include "../core/Path.hpp"
|
||||||
#include "../core/String.hpp"
|
#include "../core/String.hpp"
|
||||||
#include "../core/Util.hpp"
|
#include "../core/Util.hpp"
|
||||||
|
#include "../object/Object.h"
|
||||||
#include "../object/ObjectManager.h"
|
#include "../object/ObjectManager.h"
|
||||||
#include "../object/ObjectRepository.h"
|
#include "../object/ObjectRepository.h"
|
||||||
#include "../ParkImporter.h"
|
#include "../ParkImporter.h"
|
||||||
|
@ -126,7 +127,7 @@ private:
|
||||||
uint8 _researchRideTypeUsed[128];
|
uint8 _researchRideTypeUsed[128];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
park_load_result* Load(const utf8 * path) override
|
ParkLoadResult Load(const utf8 * path) override
|
||||||
{
|
{
|
||||||
const utf8 * extension = Path::GetExtension(path);
|
const utf8 * extension = Path::GetExtension(path);
|
||||||
if (String::Equals(extension, ".sc4", true))
|
if (String::Equals(extension, ".sc4", true))
|
||||||
|
@ -143,27 +144,24 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* LoadSavedGame(const utf8 * path, bool skipObjectCheck = false) override
|
ParkLoadResult LoadSavedGame(const utf8 * path, bool skipObjectCheck = false) override
|
||||||
{
|
{
|
||||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||||
park_load_result* result = LoadFromStream(&fs, false, skipObjectCheck);
|
auto result = LoadFromStream(&fs, false, skipObjectCheck);
|
||||||
_s4Path = path;
|
_s4Path = path;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* LoadScenario(const utf8 * path, bool skipObjectCheck = false) override
|
ParkLoadResult LoadScenario(const utf8 * path, bool skipObjectCheck = false) override
|
||||||
{
|
{
|
||||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||||
park_load_result* result = LoadFromStream(&fs, true, skipObjectCheck);
|
auto result = LoadFromStream(&fs, true, skipObjectCheck);
|
||||||
_s4Path = path;
|
_s4Path = path;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* LoadFromStream(IStream * stream, bool isScenario, bool skipObjectCheck = false) override
|
ParkLoadResult LoadFromStream(IStream * stream, bool isScenario, bool skipObjectCheck = false) override
|
||||||
{
|
{
|
||||||
park_load_result* result = Memory::Allocate<park_load_result>(sizeof(park_load_result));
|
|
||||||
result->error = PARK_LOAD_ERROR_NONE;
|
|
||||||
|
|
||||||
size_t dataSize = stream->GetLength() - stream->GetPosition();
|
size_t dataSize = stream->GetLength() - stream->GetPosition();
|
||||||
std::unique_ptr<uint8> data = std::unique_ptr<uint8>(stream->ReadArray<uint8>(dataSize));
|
std::unique_ptr<uint8> data = std::unique_ptr<uint8>(stream->ReadArray<uint8>(dataSize));
|
||||||
std::unique_ptr<uint8> decodedData = std::unique_ptr<uint8>(Memory::Allocate<uint8>(sizeof(rct1_s4)));
|
std::unique_ptr<uint8> decodedData = std::unique_ptr<uint8>(Memory::Allocate<uint8>(sizeof(rct1_s4)));
|
||||||
|
@ -188,12 +186,11 @@ public:
|
||||||
{
|
{
|
||||||
InitialiseEntryMaps();
|
InitialiseEntryMaps();
|
||||||
CreateAvailableObjectMappings();
|
CreateAvailableObjectMappings();
|
||||||
object_validity_result* object_result = GetInvalidObjects();
|
|
||||||
|
|
||||||
result->object_validity = object_result;
|
auto missingObjects = GetInvalidObjects();
|
||||||
if (object_result->invalid_object_count > 0)
|
if (missingObjects.size() > 0)
|
||||||
{
|
{
|
||||||
result->error = PARK_LOAD_ERROR_BAD_OBJECTS;
|
return ParkLoadResult::CreateMissingObjects(missingObjects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +198,7 @@ public:
|
||||||
{
|
{
|
||||||
throw Exception("Unable to decode park.");
|
throw Exception("Unable to decode park.");
|
||||||
}
|
}
|
||||||
return result;
|
return ParkLoadResult::CreateOK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Import() override
|
void Import() override
|
||||||
|
@ -1751,22 +1748,16 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_validity_result* GetInvalidObjects()
|
std::vector<rct_object_entry> GetInvalidObjects()
|
||||||
{
|
{
|
||||||
object_validity_result* result = Memory::Allocate<object_validity_result>(sizeof(object_validity_result));
|
std::vector<rct_object_entry> missingObjects;
|
||||||
uint16 invalidObjectCount = 0;
|
GetInvalidObjects(OBJECT_TYPE_RIDE, _rideEntries.GetEntries(), missingObjects);
|
||||||
rct_object_entry * * invalidEntries = Memory::AllocateArray<rct_object_entry *>(OBJECT_ENTRY_COUNT);
|
GetInvalidObjects(OBJECT_TYPE_SMALL_SCENERY, _smallSceneryEntries.GetEntries(), missingObjects);
|
||||||
|
GetInvalidObjects(OBJECT_TYPE_LARGE_SCENERY, _largeSceneryEntries.GetEntries(), missingObjects);
|
||||||
result->invalid_object_count = invalidObjectCount;
|
GetInvalidObjects(OBJECT_TYPE_WALLS, _wallEntries.GetEntries(), missingObjects);
|
||||||
result->invalid_objects = invalidEntries;
|
GetInvalidObjects(OBJECT_TYPE_PATHS, _pathEntries.GetEntries(), missingObjects);
|
||||||
|
GetInvalidObjects(OBJECT_TYPE_PATH_BITS, _pathAdditionEntries.GetEntries(), missingObjects);
|
||||||
GetInvalidObjects(OBJECT_TYPE_RIDE, _rideEntries.GetEntries(), *result);
|
GetInvalidObjects(OBJECT_TYPE_SCENERY_SETS, _sceneryGroupEntries.GetEntries(), missingObjects);
|
||||||
GetInvalidObjects(OBJECT_TYPE_SMALL_SCENERY, _smallSceneryEntries.GetEntries(), *result);
|
|
||||||
GetInvalidObjects(OBJECT_TYPE_LARGE_SCENERY, _largeSceneryEntries.GetEntries(), *result);
|
|
||||||
GetInvalidObjects(OBJECT_TYPE_WALLS, _wallEntries.GetEntries(), *result);
|
|
||||||
GetInvalidObjects(OBJECT_TYPE_PATHS, _pathEntries.GetEntries(), *result);
|
|
||||||
GetInvalidObjects(OBJECT_TYPE_PATH_BITS, _pathAdditionEntries.GetEntries(), *result);
|
|
||||||
GetInvalidObjects(OBJECT_TYPE_SCENERY_SETS, _sceneryGroupEntries.GetEntries(), *result);
|
|
||||||
GetInvalidObjects(OBJECT_TYPE_BANNERS, std::vector<const char *>({
|
GetInvalidObjects(OBJECT_TYPE_BANNERS, std::vector<const char *>({
|
||||||
"BN1 ",
|
"BN1 ",
|
||||||
"BN2 ",
|
"BN2 ",
|
||||||
|
@ -1777,14 +1768,13 @@ private:
|
||||||
"BN7 ",
|
"BN7 ",
|
||||||
"BN8 ",
|
"BN8 ",
|
||||||
"BN9 "
|
"BN9 "
|
||||||
}), *result);
|
}), missingObjects);
|
||||||
GetInvalidObjects(OBJECT_TYPE_PARK_ENTRANCE, std::vector<const char *>({ "PKENT1 " }), *result);
|
GetInvalidObjects(OBJECT_TYPE_PARK_ENTRANCE, std::vector<const char *>({ "PKENT1 " }), missingObjects);
|
||||||
GetInvalidObjects(OBJECT_TYPE_WATER, _waterEntry.GetEntries(), *result);
|
GetInvalidObjects(OBJECT_TYPE_WATER, _waterEntry.GetEntries(), missingObjects);
|
||||||
|
return missingObjects;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetInvalidObjects(uint8 objectType, const std::vector<const char *> &entries, object_validity_result &result)
|
void GetInvalidObjects(uint8 objectType, const std::vector<const char *> &entries, std::vector<rct_object_entry> &missingObjects)
|
||||||
{
|
{
|
||||||
IObjectRepository * objectRepository = GetObjectRepository();
|
IObjectRepository * objectRepository = GetObjectRepository();
|
||||||
for (const char * objectName : entries)
|
for (const char * objectName : entries)
|
||||||
|
@ -1794,26 +1784,19 @@ private:
|
||||||
Memory::Copy(entry.name, objectName, 8);
|
Memory::Copy(entry.name, objectName, 8);
|
||||||
entry.checksum = 0;
|
entry.checksum = 0;
|
||||||
|
|
||||||
const ObjectRepositoryItem * ori = nullptr;
|
const ObjectRepositoryItem * ori = objectRepository->FindObject(&entry);
|
||||||
ori = objectRepository->FindObject(&entry);
|
|
||||||
if (ori == nullptr)
|
if (ori == nullptr)
|
||||||
{
|
{
|
||||||
rct_object_entry * invalid_entry = Memory::Allocate<rct_object_entry>(sizeof(rct_object_entry));
|
missingObjects.push_back(entry);
|
||||||
invalid_entry->flags = entry.flags;
|
|
||||||
Memory::Copy(invalid_entry->name, objectName, 8);
|
|
||||||
result.invalid_objects[result.invalid_object_count++] = invalid_entry;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Object * object = objectRepository->LoadObject(ori);
|
Object * object = objectRepository->LoadObject(ori);
|
||||||
if (object == nullptr && objectType != OBJECT_TYPE_SCENERY_SETS)
|
if (object == nullptr && objectType != OBJECT_TYPE_SCENERY_SETS)
|
||||||
{
|
{
|
||||||
rct_object_entry * invalid_entry = Memory::Allocate<rct_object_entry>(sizeof(rct_object_entry));
|
missingObjects.push_back(entry);
|
||||||
invalid_entry->flags = entry.flags;
|
|
||||||
Memory::Copy(invalid_entry->name, objectName, 8);
|
|
||||||
result.invalid_objects[result.invalid_object_count++] = invalid_entry;
|
|
||||||
}
|
}
|
||||||
SafeFree(object);
|
delete object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2661,46 +2644,43 @@ IParkImporter * ParkImporter::CreateS4()
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
park_load_result* rct1_load_saved_game(const utf8 * path)
|
ParkLoadResult * rct1_load_saved_game(const utf8 * path)
|
||||||
{
|
{
|
||||||
park_load_result* result = {};
|
ParkLoadResult * result = nullptr;
|
||||||
|
auto s4Importer = std::make_unique<S4Importer>();
|
||||||
auto s4Importer = new S4Importer();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = s4Importer->LoadSavedGame(path);
|
result = new ParkLoadResult(s4Importer->LoadSavedGame(path));
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE)
|
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||||
{
|
{
|
||||||
s4Importer->Import();
|
s4Importer->Import();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const Exception &)
|
|
||||||
{
|
|
||||||
result = {};
|
|
||||||
result->error = PARK_LOAD_ERROR_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
delete s4Importer;
|
catch (const Exception &)
|
||||||
|
{
|
||||||
|
delete result;
|
||||||
|
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* rct1_load_scenario(const utf8 * path)
|
ParkLoadResult * rct1_load_scenario(const utf8 * path)
|
||||||
{
|
{
|
||||||
park_load_result* result = {};
|
ParkLoadResult * result = nullptr;
|
||||||
|
auto s4Importer = std::make_unique<S4Importer>();
|
||||||
auto s4Importer = new S4Importer();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = s4Importer->LoadSavedGame(path);
|
result = new ParkLoadResult(s4Importer->LoadSavedGame(path));
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE)
|
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||||
{
|
{
|
||||||
s4Importer->Import();
|
s4Importer->Import();
|
||||||
}
|
}
|
||||||
} catch (const Exception &)
|
|
||||||
{
|
|
||||||
result = {};
|
|
||||||
result->error = PARK_LOAD_ERROR_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
delete s4Importer;
|
catch (const Exception &)
|
||||||
|
{
|
||||||
|
delete result;
|
||||||
|
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "object/ObjectManager.h"
|
#include "object/ObjectManager.h"
|
||||||
#include "OpenRCT2.h"
|
#include "OpenRCT2.h"
|
||||||
|
#include "ParkImporter.h"
|
||||||
#include "peep/staff.h"
|
#include "peep/staff.h"
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "rct1.h"
|
#include "rct1.h"
|
||||||
|
@ -339,12 +340,13 @@ bool rct2_open_file(const char *path)
|
||||||
}
|
}
|
||||||
} else if (_stricmp(extension, "sc6") == 0) {
|
} else if (_stricmp(extension, "sc6") == 0) {
|
||||||
// TODO scenario install
|
// TODO scenario install
|
||||||
park_load_result *result = scenario_load_and_play_from_path(path);
|
ParkLoadResult * result = scenario_load_and_play_from_path(path);
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE) {
|
if (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_OK) {
|
||||||
|
ParkLoadResult_Delete(result);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
handle_park_load_failure(result, path);
|
handle_park_load_failure(result, path);
|
||||||
|
ParkLoadResult_Delete(result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (_stricmp(extension, "td6") == 0 || _stricmp(extension, "td4") == 0) {
|
} else if (_stricmp(extension, "td6") == 0 || _stricmp(extension, "td4") == 0) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
Memory::Set(&_s6, 0, sizeof(_s6));
|
Memory::Set(&_s6, 0, sizeof(_s6));
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* Load(const utf8 * path) override
|
ParkLoadResult Load(const utf8 * path) override
|
||||||
{
|
{
|
||||||
const utf8 * extension = Path::GetExtension(path);
|
const utf8 * extension = Path::GetExtension(path);
|
||||||
if (String::Equals(extension, ".sc6", true))
|
if (String::Equals(extension, ".sc6", true))
|
||||||
|
@ -98,29 +98,24 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* LoadSavedGame(const utf8 * path, bool skipObjectCheck = false) override
|
ParkLoadResult LoadSavedGame(const utf8 * path, bool skipObjectCheck = false) override
|
||||||
{
|
{
|
||||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||||
park_load_result* result = LoadFromStream(&fs, false, skipObjectCheck);
|
auto result = LoadFromStream(&fs, false, skipObjectCheck);
|
||||||
_s6Path = path;
|
_s6Path = path;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* LoadScenario(const utf8 * path, bool skipObjectCheck = false) override
|
ParkLoadResult LoadScenario(const utf8 * path, bool skipObjectCheck = false) override
|
||||||
{
|
{
|
||||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||||
park_load_result* result = LoadFromStream(&fs, true, skipObjectCheck);
|
auto result = LoadFromStream(&fs, true, skipObjectCheck);
|
||||||
_s6Path = path;
|
_s6Path = path;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
park_load_result* LoadFromStream(IStream * stream, bool isScenario, bool skipObjectCheck = false) override
|
ParkLoadResult LoadFromStream(IStream * stream, bool isScenario, bool skipObjectCheck = false) override
|
||||||
{
|
{
|
||||||
park_load_result* result = Memory::Allocate<park_load_result>(sizeof(park_load_result));
|
|
||||||
result->error = PARK_LOAD_ERROR_UNKNOWN;
|
|
||||||
|
|
||||||
if (isScenario && !gConfigGeneral.allow_loading_with_incorrect_checksum && !SawyerEncoding::ValidateChecksum(stream))
|
if (isScenario && !gConfigGeneral.allow_loading_with_incorrect_checksum && !SawyerEncoding::ValidateChecksum(stream))
|
||||||
{
|
{
|
||||||
throw IOException("Invalid checksum.");
|
throw IOException("Invalid checksum.");
|
||||||
|
@ -175,18 +170,12 @@ public:
|
||||||
chunkReader.ReadChunk(&_s6.next_free_map_element_pointer_index, 3048816);
|
chunkReader.ReadChunk(&_s6.next_free_map_element_pointer_index, 3048816);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_validity_result* object_result = _objectManager->GetInvalidObjects(_s6.objects);
|
auto missingObjects = _objectManager->GetInvalidObjects(_s6.objects);
|
||||||
|
if (missingObjects.size() > 0)
|
||||||
result->object_validity = object_result;
|
|
||||||
if (object_result->invalid_object_count > 0)
|
|
||||||
{
|
{
|
||||||
result->error = PARK_LOAD_ERROR_BAD_OBJECTS;
|
return ParkLoadResult::CreateMissingObjects(missingObjects);
|
||||||
}
|
}
|
||||||
else
|
return ParkLoadResult::CreateOK();
|
||||||
{
|
|
||||||
result->error = PARK_LOAD_ERROR_NONE;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetDetails(scenario_index_entry * dst) override
|
bool GetDetails(scenario_index_entry * dst) override
|
||||||
|
@ -439,17 +428,17 @@ IParkImporter * ParkImporter::CreateS6(IObjectRepository * objectRepository, IOb
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
park_load_result* game_load_sv6_path(const char * path)
|
ParkLoadResult * game_load_sv6_path(const char * path)
|
||||||
{
|
{
|
||||||
park_load_result* result = {};
|
ParkLoadResult * result = nullptr;
|
||||||
auto s6Importer = new S6Importer(GetObjectRepository(), GetObjectManager());
|
auto s6Importer = new S6Importer(GetObjectRepository(), GetObjectManager());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = s6Importer->LoadSavedGame(path);
|
result = new ParkLoadResult(s6Importer->LoadSavedGame(path));
|
||||||
|
|
||||||
// We mustn't import if there's something
|
// We mustn't import if there's something
|
||||||
// wrong with the park data
|
// wrong with the park data
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE)
|
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||||
{
|
{
|
||||||
s6Importer->Import();
|
s6Importer->Import();
|
||||||
|
|
||||||
|
@ -474,7 +463,11 @@ extern "C"
|
||||||
}
|
}
|
||||||
delete s6Importer;
|
delete s6Importer;
|
||||||
|
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE)
|
if (result == nullptr)
|
||||||
|
{
|
||||||
|
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||||
|
}
|
||||||
|
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||||
{
|
{
|
||||||
gScreenAge = 0;
|
gScreenAge = 0;
|
||||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||||
|
@ -487,14 +480,14 @@ extern "C"
|
||||||
* rct2: 0x00676053
|
* rct2: 0x00676053
|
||||||
* scenario (ebx)
|
* scenario (ebx)
|
||||||
*/
|
*/
|
||||||
park_load_result* scenario_load(const char * path)
|
ParkLoadResult * scenario_load(const char * path)
|
||||||
{
|
{
|
||||||
park_load_result* result = {};
|
ParkLoadResult * result = nullptr;
|
||||||
auto s6Importer = new S6Importer(GetObjectRepository(), GetObjectManager());
|
auto s6Importer = new S6Importer(GetObjectRepository(), GetObjectManager());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = s6Importer->LoadScenario(path);
|
result = new ParkLoadResult(s6Importer->LoadScenario(path));
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE)
|
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||||
{
|
{
|
||||||
s6Importer->Import();
|
s6Importer->Import();
|
||||||
|
|
||||||
|
@ -518,7 +511,12 @@ extern "C"
|
||||||
gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
||||||
}
|
}
|
||||||
delete s6Importer;
|
delete s6Importer;
|
||||||
if (result->error != PARK_LOAD_ERROR_NONE)
|
|
||||||
|
if (result == nullptr)
|
||||||
|
{
|
||||||
|
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||||
|
}
|
||||||
|
if (result->Error != PARK_LOAD_ERROR_OK)
|
||||||
{
|
{
|
||||||
gScreenAge = 0;
|
gScreenAge = 0;
|
||||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
#include "../object_list.h"
|
#include "../object_list.h"
|
||||||
#include "../OpenRCT2.h"
|
#include "../OpenRCT2.h"
|
||||||
|
#include "../ParkImporter.h"
|
||||||
#include "../peep/staff.h"
|
#include "../peep/staff.h"
|
||||||
#include "../platform/platform.h"
|
#include "../platform/platform.h"
|
||||||
#include "../rct1.h"
|
#include "../rct1.h"
|
||||||
|
@ -88,28 +89,24 @@ money32 gScenarioCompanyValueRecord;
|
||||||
static sint32 scenario_create_ducks();
|
static sint32 scenario_create_ducks();
|
||||||
static void scenario_objective_check();
|
static void scenario_objective_check();
|
||||||
|
|
||||||
park_load_result* scenario_load_and_play_from_path(const char *path)
|
ParkLoadResult * scenario_load_and_play_from_path(const char * path)
|
||||||
{
|
{
|
||||||
window_close_construction_windows();
|
window_close_construction_windows();
|
||||||
|
|
||||||
uint32 extension = get_file_extension_type(path);
|
uint32 extension = get_file_extension_type(path);
|
||||||
park_load_result* result = malloc(sizeof(park_load_result));
|
ParkLoadResult * result = NULL;
|
||||||
if (extension == FILE_EXTENSION_SC6) {
|
if (extension == FILE_EXTENSION_SC6) {
|
||||||
result = scenario_load(path);
|
result = scenario_load(path);
|
||||||
if (result->error != PARK_LOAD_ERROR_NONE)
|
if (ParkLoadResult_GetError(result) != PARK_LOAD_ERROR_OK) {
|
||||||
{
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
} else if (extension == FILE_EXTENSION_SC4) {
|
||||||
else if (extension == FILE_EXTENSION_SC4) {
|
|
||||||
result = rct1_load_scenario(path);
|
result = rct1_load_scenario(path);
|
||||||
if (result->error != PARK_LOAD_ERROR_NONE)
|
if (ParkLoadResult_GetError(result) != PARK_LOAD_ERROR_OK) {
|
||||||
{
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
result = ParkLoadResult_CreateInvalidExtension();
|
||||||
result->error = PARK_LOAD_ERROR_INVALID_EXTENSION;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "../management/finance.h"
|
#include "../management/finance.h"
|
||||||
#include "../management/research.h"
|
#include "../management/research.h"
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
#include "../park_load_result_types.h"
|
|
||||||
#include "../rct12.h"
|
#include "../rct12.h"
|
||||||
#include "../rct2.h"
|
#include "../rct2.h"
|
||||||
#include "../rct2/addresses.h"
|
#include "../rct2/addresses.h"
|
||||||
|
@ -32,6 +31,8 @@
|
||||||
#include "../world/map_animation.h"
|
#include "../world/map_animation.h"
|
||||||
#include "../world/sprite.h"
|
#include "../world/sprite.h"
|
||||||
|
|
||||||
|
typedef struct ParkLoadResult ParkLoadResult;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
/**
|
/**
|
||||||
* SV6/SC6 header chunk
|
* SV6/SC6 header chunk
|
||||||
|
@ -390,8 +391,8 @@ extern uint32 gLastAutoSaveUpdate;
|
||||||
|
|
||||||
extern const char *_scenarioFileName;
|
extern const char *_scenarioFileName;
|
||||||
|
|
||||||
park_load_result *scenario_load(const char *path);
|
ParkLoadResult * scenario_load(const char *path);
|
||||||
park_load_result *scenario_load_and_play_from_path(const char *path);
|
ParkLoadResult * scenario_load_and_play_from_path(const char *path);
|
||||||
void scenario_begin();
|
void scenario_begin();
|
||||||
void scenario_update();
|
void scenario_update();
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
#include "../park_load_result_types.h"
|
|
||||||
|
|
||||||
sint32 squaredmetres_to_squaredfeet(sint32 squaredMetres);
|
sint32 squaredmetres_to_squaredfeet(sint32 squaredMetres);
|
||||||
sint32 metres_to_feet(sint32 metres);
|
sint32 metres_to_feet(sint32 metres);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
#include "../platform/platform.h"
|
#include "../platform/platform.h"
|
||||||
#include "../sprites.h"
|
#include "../sprites.h"
|
||||||
#include "../util/util.h"
|
|
||||||
|
|
||||||
enum WINDOW_OBJECT_LOAD_ERROR_WIDGET_IDX {
|
enum WINDOW_OBJECT_LOAD_ERROR_WIDGET_IDX {
|
||||||
WIDX_BACKGROUND,
|
WIDX_BACKGROUND,
|
||||||
|
@ -91,7 +90,7 @@ static rct_window_event_list window_object_load_error_events = {
|
||||||
window_object_load_error_scrollpaint
|
window_object_load_error_scrollpaint
|
||||||
};
|
};
|
||||||
|
|
||||||
rct_object_entry * * invalid_entries = NULL;
|
rct_object_entry * invalid_entries = NULL;
|
||||||
sint32 highlighted_index = -1;
|
sint32 highlighted_index = -1;
|
||||||
utf8* file_path = NULL;
|
utf8* file_path = NULL;
|
||||||
|
|
||||||
|
@ -168,20 +167,20 @@ static utf8* combine_object_names(rct_window *w)
|
||||||
for (uint16 i = 0; i < w->no_list_items; i++) {
|
for (uint16 i = 0; i < w->no_list_items; i++) {
|
||||||
cur_len += (8 + line_sep_len);
|
cur_len += (8 + line_sep_len);
|
||||||
assert(cur_len < buffer_len);
|
assert(cur_len < buffer_len);
|
||||||
strncat(buffer, invalid_entries[i]->name, 8);
|
strncat(buffer, invalid_entries[i].name, 8);
|
||||||
strncat(buffer, PLATFORM_NEWLINE, line_sep_len);
|
strncat(buffer, PLATFORM_NEWLINE, line_sep_len);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
rct_window *window_object_load_error_open(utf8* path, object_validity_result* result)
|
rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects, const rct_object_entry * missingObjects)
|
||||||
{
|
{
|
||||||
rct_window* window;
|
size_t missingObjectsSize = numMissingObjects * sizeof(rct_object_entry);
|
||||||
|
invalid_entries = malloc(missingObjectsSize);
|
||||||
invalid_entries = result->invalid_objects;
|
memcpy(invalid_entries, missingObjects, missingObjectsSize);
|
||||||
|
|
||||||
// Check if window is already open
|
// Check if window is already open
|
||||||
window = window_bring_to_front_by_class(WC_OBJECT_LOAD_ERROR);
|
rct_window * window = window_bring_to_front_by_class(WC_OBJECT_LOAD_ERROR);
|
||||||
if (window == NULL) {
|
if (window == NULL) {
|
||||||
window = window_create_centred(
|
window = window_create_centred(
|
||||||
WW,
|
WW,
|
||||||
|
@ -201,7 +200,7 @@ rct_window *window_object_load_error_open(utf8* path, object_validity_result* re
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh list items and path
|
// Refresh list items and path
|
||||||
window->no_list_items = result->invalid_object_count;
|
window->no_list_items = (uint16)numMissingObjects;
|
||||||
file_path = path;
|
file_path = path;
|
||||||
|
|
||||||
window_invalidate(window);
|
window_invalidate(window);
|
||||||
|
@ -232,7 +231,7 @@ static void window_object_load_error_mouseup(rct_window *w, rct_widgetindex widg
|
||||||
break;
|
break;
|
||||||
case WIDX_COPY_CURRENT:
|
case WIDX_COPY_CURRENT:
|
||||||
if (w->selected_list_item > -1) {
|
if (w->selected_list_item > -1) {
|
||||||
selected_name = strndup(invalid_entries[w->selected_list_item]->name, 8);
|
selected_name = strndup(invalid_entries[w->selected_list_item].name, 8);
|
||||||
platform_place_string_on_clipboard(selected_name);
|
platform_place_string_on_clipboard(selected_name);
|
||||||
SafeFree(selected_name);
|
SafeFree(selected_name);
|
||||||
}
|
}
|
||||||
|
@ -296,7 +295,6 @@ static void window_object_load_error_paint(rct_window *w, rct_drawpixelinfo *dpi
|
||||||
|
|
||||||
static void window_object_load_error_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
|
static void window_object_load_error_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
|
||||||
{
|
{
|
||||||
|
|
||||||
gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, ColourMapA[w->colours[1]].mid_light);
|
gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, ColourMapA[w->colours[1]].mid_light);
|
||||||
const sint32 list_width = w->widgets[WIDX_SCROLL].right - w->widgets[WIDX_SCROLL].left;
|
const sint32 list_width = w->widgets[WIDX_SCROLL].right - w->widgets[WIDX_SCROLL].left;
|
||||||
|
|
||||||
|
@ -317,12 +315,10 @@ static void window_object_load_error_scrollpaint(rct_window *w, rct_drawpixelinf
|
||||||
gfx_fill_rect(dpi, 0, y, list_width, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].lighter | 0x1000000);
|
gfx_fill_rect(dpi, 0, y, list_width, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].lighter | 0x1000000);
|
||||||
|
|
||||||
// Draw the actual object entry's name...
|
// Draw the actual object entry's name...
|
||||||
gfx_draw_string(dpi, strndup(invalid_entries[i]->name, 8), COLOUR_DARK_GREEN, 5, y);
|
gfx_draw_string(dpi, strndup(invalid_entries[i].name, 8), COLOUR_DARK_GREEN, 5, y);
|
||||||
|
|
||||||
// ... and type
|
// ... and type
|
||||||
rct_string_id type = get_object_type_string(invalid_entries[i]);
|
rct_string_id type = get_object_type_string(&invalid_entries[i]);
|
||||||
gfx_draw_string_left(dpi, type, NULL, COLOUR_DARK_GREEN, (WW - 5) / 3 + 1, y);
|
gfx_draw_string_left(dpi, type, NULL, COLOUR_DARK_GREEN, (WW - 5) / 3 + 1, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "../interface/window.h"
|
#include "../interface/window.h"
|
||||||
#include "../localisation/localisation.h"
|
#include "../localisation/localisation.h"
|
||||||
#include "../network/network.h"
|
#include "../network/network.h"
|
||||||
|
#include "../ParkImporter.h"
|
||||||
#include "../platform/platform.h"
|
#include "../platform/platform.h"
|
||||||
#include "../sprites.h"
|
#include "../sprites.h"
|
||||||
#include "../title/TitleScreen.h"
|
#include "../title/TitleScreen.h"
|
||||||
|
@ -165,14 +166,14 @@ static void window_server_start_close(rct_window *w)
|
||||||
|
|
||||||
static void window_server_start_scenarioselect_callback(const utf8 *path)
|
static void window_server_start_scenarioselect_callback(const utf8 *path)
|
||||||
{
|
{
|
||||||
park_load_result* result;
|
|
||||||
network_set_password(_password);
|
network_set_password(_password);
|
||||||
result = scenario_load_and_play_from_path(path);
|
ParkLoadResult * result = scenario_load_and_play_from_path(path);
|
||||||
if (result->error == PARK_LOAD_ERROR_NONE) {
|
if (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_OK) {
|
||||||
network_begin_server(gConfigNetwork.default_port, gConfigNetwork.listen_address);
|
network_begin_server(gConfigNetwork.default_port, gConfigNetwork.listen_address);
|
||||||
} else {
|
} else {
|
||||||
handle_park_load_failure(result, path);
|
handle_park_load_failure(result, path);
|
||||||
}
|
}
|
||||||
|
ParkLoadResult_Delete(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_server_start_loadsave_callback(sint32 result, const utf8 * path)
|
static void window_server_start_loadsave_callback(sint32 result, const utf8 * path)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "../interface/widget.h"
|
#include "../interface/widget.h"
|
||||||
#include "../interface/window.h"
|
#include "../interface/window.h"
|
||||||
#include "../localisation/localisation.h"
|
#include "../localisation/localisation.h"
|
||||||
|
#include "../ParkImporter.h"
|
||||||
#include "../sprites.h"
|
#include "../sprites.h"
|
||||||
#include "../title/TitleScreen.h"
|
#include "../title/TitleScreen.h"
|
||||||
#include "../util/util.h"
|
#include "../util/util.h"
|
||||||
|
@ -129,8 +130,9 @@ void window_title_menu_open()
|
||||||
|
|
||||||
static void window_title_menu_scenarioselect_callback(const utf8 *path)
|
static void window_title_menu_scenarioselect_callback(const utf8 *path)
|
||||||
{
|
{
|
||||||
park_load_result *result = scenario_load_and_play_from_path(path);
|
ParkLoadResult * result = scenario_load_and_play_from_path(path);
|
||||||
handle_park_load_failure(result, path);
|
handle_park_load_failure(result, path);
|
||||||
|
ParkLoadResult_Delete(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_title_menu_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
static void window_title_menu_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "../localisation/localisation.h"
|
#include "../localisation/localisation.h"
|
||||||
#include "../network/network.h"
|
#include "../network/network.h"
|
||||||
#include "../network/twitch.h"
|
#include "../network/twitch.h"
|
||||||
|
#include "../ParkImporter.h"
|
||||||
#include "../peep/staff.h"
|
#include "../peep/staff.h"
|
||||||
#include "../scenario/scenario.h"
|
#include "../scenario/scenario.h"
|
||||||
#include "../sprites.h"
|
#include "../sprites.h"
|
||||||
|
@ -519,8 +520,9 @@ static void window_top_toolbar_mousedown(rct_widgetindex widgetIndex, rct_window
|
||||||
|
|
||||||
static void window_top_toolbar_scenarioselect_callback(const utf8 *path)
|
static void window_top_toolbar_scenarioselect_callback(const utf8 *path)
|
||||||
{
|
{
|
||||||
park_load_result *result = scenario_load_and_play_from_path(path);
|
ParkLoadResult * result = scenario_load_and_play_from_path(path);
|
||||||
handle_park_load_failure(result, path);
|
handle_park_load_failure(result, path);
|
||||||
|
ParkLoadResult_Delete(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue