mirror of https://github.com/OpenRCT2/OpenRCT2.git
Make start on loading objects only once
This commit is contained in:
parent
633b3e5b92
commit
96a0a22cd1
|
@ -36,8 +36,8 @@
|
|||
#include "core/String.hpp"
|
||||
#include "core/Util.hpp"
|
||||
#include "drawing/IDrawingEngine.h"
|
||||
#include "localisation/Localisation.h"
|
||||
#include "FileClassifier.h"
|
||||
#include "HandleParkLoad.h"
|
||||
#include "network/network.h"
|
||||
#include "object/ObjectManager.h"
|
||||
#include "object/ObjectRepository.h"
|
||||
|
@ -559,52 +559,80 @@ namespace OpenRCT2
|
|||
try
|
||||
{
|
||||
auto result = parkImporter->LoadFromStream(stream, info.Type == FILE_TYPE::SCENARIO, false, path.c_str());
|
||||
if (result.Error == PARK_LOAD_ERROR_OK)
|
||||
// _objectManager->LoadObjects(result.RequiredObjects.data(), result.RequiredObjects.size());
|
||||
parkImporter->Import();
|
||||
String::Set(gScenarioSavePath, Util::CountOf(gScenarioSavePath), path.c_str());
|
||||
String::Set(gCurrentLoadedPath, Util::CountOf(gCurrentLoadedPath), path.c_str());
|
||||
gFirstTimeSaving = true;
|
||||
game_fix_save_vars();
|
||||
sprite_position_tween_reset();
|
||||
gScreenAge = 0;
|
||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||
if (info.Type == FILE_TYPE::SAVED_GAME)
|
||||
{
|
||||
parkImporter->Import();
|
||||
String::Set(gScenarioSavePath, Util::CountOf(gScenarioSavePath), path.c_str());
|
||||
String::Set(gCurrentLoadedPath, Util::CountOf(gCurrentLoadedPath), path.c_str());
|
||||
gFirstTimeSaving = true;
|
||||
game_fix_save_vars();
|
||||
sprite_position_tween_reset();
|
||||
gScreenAge = 0;
|
||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||
if (info.Type == FILE_TYPE::SAVED_GAME)
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||
{
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||
{
|
||||
network_close();
|
||||
}
|
||||
game_load_init();
|
||||
if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||
{
|
||||
network_send_map();
|
||||
}
|
||||
network_close();
|
||||
}
|
||||
else
|
||||
game_load_init();
|
||||
if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||
{
|
||||
scenario_begin();
|
||||
if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||
{
|
||||
network_send_map();
|
||||
}
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||
{
|
||||
network_close();
|
||||
}
|
||||
network_send_map();
|
||||
}
|
||||
// This ensures that the newly loaded save reflects the user's
|
||||
// 'show real names of guests' option, now that it's a global setting
|
||||
peep_update_names(gConfigGeneral.show_real_names_of_guests);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_park_load_failure_with_title_opt(&result, path, loadTitleScreenFirstOnFail);
|
||||
scenario_begin();
|
||||
if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||
{
|
||||
network_send_map();
|
||||
}
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||
{
|
||||
network_close();
|
||||
}
|
||||
}
|
||||
// This ensures that the newly loaded save reflects the user's
|
||||
// 'show real names of guests' option, now that it's a global setting
|
||||
peep_update_names(gConfigGeneral.show_real_names_of_guests);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
catch (const ObjectLoadException& e)
|
||||
{
|
||||
// This option is used when loading parks from the command line
|
||||
// to ensure that the title sequence loads before the window
|
||||
if (loadTitleScreenFirstOnFail)
|
||||
{
|
||||
title_load();
|
||||
}
|
||||
// The path needs to be duplicated as it's a const here
|
||||
// which the window function doesn't like
|
||||
auto intent = Intent(WC_OBJECT_LOAD_ERROR);
|
||||
intent.putExtra(INTENT_EXTRA_PATH, path);
|
||||
intent.putExtra(INTENT_EXTRA_LIST, (void *)e.MissingObjects.data());
|
||||
intent.putExtra(INTENT_EXTRA_LIST_COUNT, (uint32)e.MissingObjects.size());
|
||||
|
||||
auto windowManager = _uiContext->GetWindowManager();
|
||||
windowManager->OpenIntent(&intent);
|
||||
}
|
||||
catch (const UnsupportedRCTCFlagException& e)
|
||||
{
|
||||
// This option is used when loading parks from the command line
|
||||
// to ensure that the title sequence loads before the window
|
||||
if (loadTitleScreenFirstOnFail)
|
||||
{
|
||||
title_load();
|
||||
}
|
||||
|
||||
auto windowManager = _uiContext->GetWindowManager();
|
||||
set_format_arg(0, uint16, e.Flag);
|
||||
windowManager->ShowError(STR_FAILED_TO_LOAD_IMCOMPATIBLE_RCTC_FLAG, STR_NONE);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
// 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.
|
||||
title_load();
|
||||
Console::Error::WriteLine(e.what());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -245,22 +245,15 @@ namespace Editor
|
|||
*/
|
||||
static bool ReadS6(const char * path)
|
||||
{
|
||||
ParkLoadResult * loadResult = nullptr;
|
||||
const char * extension = path_get_extension(path);
|
||||
auto extension = path_get_extension(path);
|
||||
if (_stricmp(extension, ".sc6") == 0)
|
||||
{
|
||||
loadResult = load_from_sc6(path);
|
||||
load_from_sc6(path);
|
||||
}
|
||||
else if (_stricmp(extension, ".sv6") == 0)
|
||||
{
|
||||
loadResult = load_from_sv6(path);
|
||||
load_from_sv6(path);
|
||||
}
|
||||
if (ParkLoadResult_GetError(loadResult) != PARK_LOAD_ERROR_OK)
|
||||
{
|
||||
ParkLoadResult_Delete(loadResult);
|
||||
return false;
|
||||
}
|
||||
ParkLoadResult_Delete(loadResult);
|
||||
|
||||
ClearMapForEditing(true);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "Editor.h"
|
||||
#include "FileClassifier.h"
|
||||
#include "Game.h"
|
||||
#include "HandleParkLoad.h"
|
||||
#include "Input.h"
|
||||
#include "interface/Screenshot.h"
|
||||
#include "interface/Viewport.h"
|
||||
|
@ -1324,50 +1323,6 @@ void game_fix_save_vars()
|
|||
fix_park_entrance_locations();
|
||||
}
|
||||
|
||||
void handle_park_load_failure_with_title_opt(const ParkLoadResult * result, const std::string & path, bool loadTitleFirst)
|
||||
{
|
||||
if (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_MISSING_OBJECTS)
|
||||
{
|
||||
// This option is used when loading parks from the command line
|
||||
// to ensure that the title sequence loads before the window
|
||||
if (loadTitleFirst)
|
||||
{
|
||||
title_load();
|
||||
}
|
||||
// The path needs to be duplicated as it's a const here
|
||||
// which the window function doesn't like
|
||||
auto intent = Intent(WC_OBJECT_LOAD_ERROR);
|
||||
intent.putExtra(INTENT_EXTRA_PATH, path);
|
||||
intent.putExtra(INTENT_EXTRA_LIST, (void *) ParkLoadResult_GetMissingObjects(result));
|
||||
intent.putExtra(INTENT_EXTRA_LIST_COUNT, (uint32) ParkLoadResult_GetMissingObjectsCount(result));
|
||||
context_open_intent(&intent);
|
||||
}
|
||||
else if (ParkLoadResult_GetError(result) == PARK_LOAD_ERROR_UNSUPPORTED_RCTC_FLAG)
|
||||
{
|
||||
// This option is used when loading parks from the command line
|
||||
// to ensure that the title sequence loads before the window
|
||||
if (loadTitleFirst)
|
||||
{
|
||||
title_load();
|
||||
}
|
||||
|
||||
set_format_arg(0, uint16, ParkLoadResult_GetFlag(result));
|
||||
context_show_error(STR_FAILED_TO_LOAD_IMCOMPATIBLE_RCTC_FLAG, STR_NONE);
|
||||
|
||||
}
|
||||
else if (ParkLoadResult_GetError(result) != PARK_LOAD_ERROR_OK)
|
||||
{
|
||||
// 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.
|
||||
title_load();
|
||||
}
|
||||
}
|
||||
|
||||
void handle_park_load_failure(const ParkLoadResult * result, const std::string & path)
|
||||
{
|
||||
handle_park_load_failure_with_title_opt(result, path, false);
|
||||
}
|
||||
|
||||
void game_load_init()
|
||||
{
|
||||
rct_window * mainWindow;
|
||||
|
|
|
@ -172,7 +172,7 @@ sint32 game_do_command_p(uint32 command, sint32 * eax, sint32 * ebx, sint32 * ec
|
|||
void game_log_multiplayer_command(int command, const int * eax, const int * ebx, const int * ecx, int * edx, int * edi, int * ebp);
|
||||
|
||||
void game_load_or_quit_no_save_prompt();
|
||||
ParkLoadResult * load_from_sv6(const char * path);
|
||||
void load_from_sv6(const char * path);
|
||||
void game_load_init();
|
||||
void game_pause_toggle(sint32 * eax, sint32 * ebx, sint32 * ecx, sint32 * edx, sint32 * esi, sint32 * edi, sint32 * ebp);
|
||||
void pause_toggle();
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#pragma region Copyright (c) 2014-2018 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct ParkLoadResult;
|
||||
|
||||
void handle_park_load_failure_with_title_opt(const ParkLoadResult * result, const std::string & path, bool loadTitleFirst);
|
||||
void handle_park_load_failure(const ParkLoadResult * result, const std::string & path);
|
|
@ -22,81 +22,6 @@
|
|||
#include "object/ObjectRepository.h"
|
||||
#include "ParkImporter.h"
|
||||
|
||||
ParkLoadResult::ParkLoadResult(PARK_LOAD_ERROR error)
|
||||
: Error(error),
|
||||
Flag(0)
|
||||
{
|
||||
}
|
||||
|
||||
ParkLoadResult::ParkLoadResult(PARK_LOAD_ERROR error, const std::vector<rct_object_entry> &missingObjects)
|
||||
: Error(error),
|
||||
MissingObjects(missingObjects),
|
||||
Flag(0)
|
||||
{
|
||||
}
|
||||
|
||||
ParkLoadResult::ParkLoadResult(PARK_LOAD_ERROR error, const uint8 flag)
|
||||
: Error(error),
|
||||
Flag(flag)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ParkLoadResult ParkLoadResult::CreateUnsupportedRCTCflag(uint8 classic_flag)
|
||||
{
|
||||
return ParkLoadResult(PARK_LOAD_ERROR::PARK_LOAD_ERROR_UNSUPPORTED_RCTC_FLAG, classic_flag);
|
||||
}
|
||||
|
||||
PARK_LOAD_ERROR ParkLoadResult_GetError(const ParkLoadResult * t)
|
||||
{
|
||||
return t->Error;
|
||||
}
|
||||
|
||||
size_t ParkLoadResult_GetMissingObjectsCount(const ParkLoadResult * t)
|
||||
{
|
||||
return t->MissingObjects.size();
|
||||
}
|
||||
|
||||
uint8 ParkLoadResult_GetFlag(const ParkLoadResult * t)
|
||||
{
|
||||
return t->Flag;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
std::unique_ptr<IParkImporter> Create(const std::string &hintPath)
|
||||
|
|
|
@ -42,20 +42,12 @@ struct scenario_index_entry;
|
|||
struct ParkLoadResult final
|
||||
{
|
||||
public:
|
||||
const PARK_LOAD_ERROR Error;
|
||||
const std::vector<rct_object_entry> MissingObjects;
|
||||
const uint8 Flag;
|
||||
std::vector<rct_object_entry> const RequiredObjects;
|
||||
|
||||
static ParkLoadResult CreateOK();
|
||||
static ParkLoadResult CreateInvalidExtension();
|
||||
static ParkLoadResult CreateMissingObjects(const std::vector<rct_object_entry> &missingObjects);
|
||||
static ParkLoadResult CreateUnknown();
|
||||
static ParkLoadResult CreateUnsupportedRCTCflag(uint8 classic_flag);
|
||||
|
||||
private:
|
||||
explicit ParkLoadResult(PARK_LOAD_ERROR error);
|
||||
ParkLoadResult(PARK_LOAD_ERROR error, const std::vector<rct_object_entry> &missingObjects);
|
||||
ParkLoadResult(PARK_LOAD_ERROR error, const uint8 flag);
|
||||
explicit ParkLoadResult(std::vector<rct_object_entry>&& requiredObjects)
|
||||
: RequiredObjects(requiredObjects)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,6 +80,28 @@ namespace ParkImporter
|
|||
bool ExtensionIsScenario(const std::string &extension);
|
||||
}
|
||||
|
||||
class ObjectLoadException : std::exception
|
||||
{
|
||||
public:
|
||||
std::vector<rct_object_entry> const MissingObjects;
|
||||
|
||||
explicit ObjectLoadException(std::vector<rct_object_entry>&& missingObjects)
|
||||
: MissingObjects(missingObjects)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class UnsupportedRCTCFlagException : std::exception
|
||||
{
|
||||
public:
|
||||
uint8 const Flag;
|
||||
|
||||
explicit UnsupportedRCTCFlagException(uint8 flag)
|
||||
: Flag(flag)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void park_importer_load_from_stream(void * stream, const utf8 * hintPath);
|
||||
bool park_importer_extension_is_scenario(const utf8 * extension);
|
||||
|
||||
|
|
|
@ -57,7 +57,183 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\resources\resource.h" />
|
||||
<ClInclude Include="**\*.h" />
|
||||
<ClInclude Include="actions\GameAction.h" />
|
||||
<ClInclude Include="audio\audio.h" />
|
||||
<ClInclude Include="audio\AudioChannel.h" />
|
||||
<ClInclude Include="audio\AudioContext.h" />
|
||||
<ClInclude Include="audio\AudioMixer.h" />
|
||||
<ClInclude Include="audio\AudioSource.h" />
|
||||
<ClInclude Include="Cheats.h" />
|
||||
<ClInclude Include="CmdlineSprite.h" />
|
||||
<ClInclude Include="common.h" />
|
||||
<ClInclude Include="config\Config.h" />
|
||||
<ClInclude Include="Context.h" />
|
||||
<ClInclude Include="core\DataSerialiser.h" />
|
||||
<ClInclude Include="core\DataSerialiserTraits.h" />
|
||||
<ClInclude Include="core\Endianness.h" />
|
||||
<ClInclude Include="core\File.h" />
|
||||
<ClInclude Include="core\FileScanner.h" />
|
||||
<ClInclude Include="core\Imaging.h" />
|
||||
<ClInclude Include="core\MemoryStream.h" />
|
||||
<ClInclude Include="core\Zip.h" />
|
||||
<ClInclude Include="Date.h" />
|
||||
<ClInclude Include="Diagnostic.h" />
|
||||
<ClInclude Include="drawing\Drawing.h" />
|
||||
<ClInclude Include="drawing\Font.h" />
|
||||
<ClInclude Include="drawing\IDrawingContext.h" />
|
||||
<ClInclude Include="drawing\IDrawingEngine.h" />
|
||||
<ClInclude Include="drawing\ImageImporter.h" />
|
||||
<ClInclude Include="drawing\LightFX.h" />
|
||||
<ClInclude Include="drawing\NewDrawing.h" />
|
||||
<ClInclude Include="drawing\Rain.h" />
|
||||
<ClInclude Include="drawing\Text.h" />
|
||||
<ClInclude Include="drawing\TTF.h" />
|
||||
<ClInclude Include="drawing\X8DrawingEngine.h" />
|
||||
<ClInclude Include="Editor.h" />
|
||||
<ClInclude Include="EditorObjectSelectionSession.h" />
|
||||
<ClInclude Include="FileClassifier.h" />
|
||||
<ClInclude Include="Game.h" />
|
||||
<ClInclude Include="Input.h" />
|
||||
<ClInclude Include="interface\Chat.h" />
|
||||
<ClInclude Include="interface\Colour.h" />
|
||||
<ClInclude Include="interface\Console.h" />
|
||||
<ClInclude Include="interface\Cursors.h" />
|
||||
<ClInclude Include="interface\FontFamilies.h" />
|
||||
<ClInclude Include="interface\Fonts.h" />
|
||||
<ClInclude Include="interface\Screenshot.h" />
|
||||
<ClInclude Include="interface\themes.h" />
|
||||
<ClInclude Include="interface\Viewport.h" />
|
||||
<ClInclude Include="interface\Widget.h" />
|
||||
<ClInclude Include="interface\Window.h" />
|
||||
<ClInclude Include="interface\Window_internal.h" />
|
||||
<ClInclude Include="Intro.h" />
|
||||
<ClInclude Include="localisation\Currency.h" />
|
||||
<ClInclude Include="localisation\Date.h" />
|
||||
<ClInclude Include="localisation\FormatCodes.h" />
|
||||
<ClInclude Include="localisation\Language.h" />
|
||||
<ClInclude Include="localisation\LanguagePack.h" />
|
||||
<ClInclude Include="localisation\Localisation.h" />
|
||||
<ClInclude Include="localisation\LocalisationService.h" />
|
||||
<ClInclude Include="localisation\StringIds.h" />
|
||||
<ClInclude Include="localisation\User.h" />
|
||||
<ClInclude Include="management\Award.h" />
|
||||
<ClInclude Include="management\Finance.h" />
|
||||
<ClInclude Include="management\Marketing.h" />
|
||||
<ClInclude Include="management\NewsItem.h" />
|
||||
<ClInclude Include="management\Research.h" />
|
||||
<ClInclude Include="network\DiscordService.h" />
|
||||
<ClInclude Include="network\http.h" />
|
||||
<ClInclude Include="network\network.h" />
|
||||
<ClInclude Include="network\NetworkAction.h" />
|
||||
<ClInclude Include="network\NetworkConnection.h" />
|
||||
<ClInclude Include="network\NetworkGroup.h" />
|
||||
<ClInclude Include="network\NetworkKey.h" />
|
||||
<ClInclude Include="network\NetworkPacket.h" />
|
||||
<ClInclude Include="network\NetworkPlayer.h" />
|
||||
<ClInclude Include="network\NetworkServerAdvertiser.h" />
|
||||
<ClInclude Include="network\NetworkTypes.h" />
|
||||
<ClInclude Include="network\NetworkUser.h" />
|
||||
<ClInclude Include="network\ServerList.h" />
|
||||
<ClInclude Include="network\TcpSocket.h" />
|
||||
<ClInclude Include="network\twitch.h" />
|
||||
<ClInclude Include="object\BannerObject.h" />
|
||||
<ClInclude Include="object\DefaultObjects.h" />
|
||||
<ClInclude Include="object\EntranceObject.h" />
|
||||
<ClInclude Include="object\FootpathItemObject.h" />
|
||||
<ClInclude Include="object\FootpathObject.h" />
|
||||
<ClInclude Include="object\ImageTable.h" />
|
||||
<ClInclude Include="object\LargeSceneryObject.h" />
|
||||
<ClInclude Include="object\Object.h" />
|
||||
<ClInclude Include="object\ObjectFactory.h" />
|
||||
<ClInclude Include="object\ObjectJsonHelpers.h" />
|
||||
<ClInclude Include="object\ObjectLimits.h" />
|
||||
<ClInclude Include="object\ObjectList.h" />
|
||||
<ClInclude Include="object\ObjectManager.h" />
|
||||
<ClInclude Include="object\ObjectRepository.h" />
|
||||
<ClInclude Include="object\RideObject.h" />
|
||||
<ClInclude Include="object\SceneryGroupObject.h" />
|
||||
<ClInclude Include="object\SceneryObject.h" />
|
||||
<ClInclude Include="object\SmallSceneryObject.h" />
|
||||
<ClInclude Include="object\StexObject.h" />
|
||||
<ClInclude Include="object\StringTable.h" />
|
||||
<ClInclude Include="object\WallObject.h" />
|
||||
<ClInclude Include="object\WaterObject.h" />
|
||||
<ClInclude Include="OpenRCT2.h" />
|
||||
<ClInclude Include="paint\Paint.h" />
|
||||
<ClInclude Include="paint\Painter.h" />
|
||||
<ClInclude Include="paint\sprite\Sprite.h" />
|
||||
<ClInclude Include="paint\Supports.h" />
|
||||
<ClInclude Include="paint\tile_element\Surface.h" />
|
||||
<ClInclude Include="paint\tile_element\TileElement.h" />
|
||||
<ClInclude Include="paint\VirtualFloor.h" />
|
||||
<ClInclude Include="ParkImporter.h" />
|
||||
<ClInclude Include="peep\Peep.h" />
|
||||
<ClInclude Include="peep\Staff.h" />
|
||||
<ClInclude Include="PlatformEnvironment.h" />
|
||||
<ClInclude Include="platform\Crash.h" />
|
||||
<ClInclude Include="platform\platform.h" />
|
||||
<ClInclude Include="platform\Platform2.h" />
|
||||
<ClInclude Include="rct12\RCT12.h" />
|
||||
<ClInclude Include="rct12\SawyerChunk.h" />
|
||||
<ClInclude Include="rct12\SawyerChunkReader.h" />
|
||||
<ClInclude Include="rct12\SawyerChunkWriter.h" />
|
||||
<ClInclude Include="rct12\SawyerEncoding.h" />
|
||||
<ClInclude Include="rct1\RCT1.h" />
|
||||
<ClInclude Include="rct1\Tables.h" />
|
||||
<ClInclude Include="rct2\RCT2.h" />
|
||||
<ClInclude Include="rct2\S6Exporter.h" />
|
||||
<ClInclude Include="ride\CableLift.h" />
|
||||
<ClInclude Include="ride\coaster\BolligerMabillardTrack.h" />
|
||||
<ClInclude Include="ride\coaster\JuniorRollerCoaster.h" />
|
||||
<ClInclude Include="ride\MusicList.h" />
|
||||
<ClInclude Include="ride\Ride.h" />
|
||||
<ClInclude Include="ride\RideData.h" />
|
||||
<ClInclude Include="ride\RideGroupManager.h" />
|
||||
<ClInclude Include="ride\RideRatings.h" />
|
||||
<ClInclude Include="ride\ShopItem.h" />
|
||||
<ClInclude Include="ride\Station.h" />
|
||||
<ClInclude Include="ride\Track.h" />
|
||||
<ClInclude Include="ride\TrackData.h" />
|
||||
<ClInclude Include="ride\TrackDesign.h" />
|
||||
<ClInclude Include="ride\TrackDesignRepository.h" />
|
||||
<ClInclude Include="ride\TrackPaint.h" />
|
||||
<ClInclude Include="ride\Vehicle.h" />
|
||||
<ClInclude Include="ride\VehicleData.h" />
|
||||
<ClInclude Include="ride\VehiclePaint.h" />
|
||||
<ClInclude Include="scenario\Scenario.h" />
|
||||
<ClInclude Include="scenario\ScenarioRepository.h" />
|
||||
<ClInclude Include="scenario\ScenarioSources.h" />
|
||||
<ClInclude Include="sprites.h" />
|
||||
<ClInclude Include="title\TitleScreen.h" />
|
||||
<ClInclude Include="title\TitleSequence.h" />
|
||||
<ClInclude Include="title\TitleSequenceManager.h" />
|
||||
<ClInclude Include="title\TitleSequencePlayer.h" />
|
||||
<ClInclude Include="ui\UiContext.h" />
|
||||
<ClInclude Include="ui\WindowManager.h" />
|
||||
<ClInclude Include="util\SawyerCoding.h" />
|
||||
<ClInclude Include="util\Util.h" />
|
||||
<ClInclude Include="Version.h" />
|
||||
<ClInclude Include="windows\Intent.h" />
|
||||
<ClInclude Include="windows\tile_inspector.h" />
|
||||
<ClInclude Include="world\Banner.h" />
|
||||
<ClInclude Include="world\Climate.h" />
|
||||
<ClInclude Include="world\Entrance.h" />
|
||||
<ClInclude Include="world\Footpath.h" />
|
||||
<ClInclude Include="world\Fountain.h" />
|
||||
<ClInclude Include="world\LargeScenery.h" />
|
||||
<ClInclude Include="world\Map.h" />
|
||||
<ClInclude Include="world\MapAnimation.h" />
|
||||
<ClInclude Include="world\MapGen.h" />
|
||||
<ClInclude Include="world\MapHelpers.h" />
|
||||
<ClInclude Include="world\Park.h" />
|
||||
<ClInclude Include="world\Scenery.h" />
|
||||
<ClInclude Include="world\SmallScenery.h" />
|
||||
<ClInclude Include="world\Sprite.h" />
|
||||
<ClInclude Include="world\Surface.h" />
|
||||
<ClInclude Include="world\TileElement.h" />
|
||||
<ClInclude Include="world\TileInspector.h" />
|
||||
<ClInclude Include="world\Wall.h" />
|
||||
<ClInclude Include="world\Water.h" />
|
||||
<ClInclude Include="**\*.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -67,4 +243,4 @@
|
|||
<Image Include="..\..\resources\logo\icon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -1238,7 +1238,7 @@ enum {
|
|||
RCT1_LANDSCAPE_DOOR_OPEN = 3,
|
||||
};
|
||||
|
||||
ParkLoadResult * load_from_sv4(const char *path);
|
||||
ParkLoadResult * load_from_sc4(const char *path);
|
||||
void load_from_sv4(const char *path);
|
||||
void load_from_sc4(const char *path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
class S4Importer final : public IParkImporter
|
||||
{
|
||||
private:
|
||||
const utf8 * _s4Path = nullptr;
|
||||
std::string _s4Path;
|
||||
rct1_s4 _s4 = { 0 };
|
||||
uint8 _gameVersion = 0;
|
||||
uint8 _parkValueConversionFactor = 0;
|
||||
|
@ -174,51 +174,16 @@ public:
|
|||
|
||||
ParkLoadResult LoadFromStream(IStream * stream,
|
||||
bool isScenario,
|
||||
bool skipObjectCheck = false,
|
||||
const utf8 * path = String::Empty) override
|
||||
bool skipObjectCheck,
|
||||
const utf8 * path) override
|
||||
{
|
||||
size_t dataSize = stream->GetLength() - stream->GetPosition();
|
||||
auto deleter_lambda = [dataSize](uint8 * ptr) { Memory::FreeArray(ptr, dataSize); };
|
||||
auto data = std::unique_ptr<uint8, decltype(deleter_lambda)>(stream->ReadArray<uint8>(dataSize), deleter_lambda);
|
||||
auto decodedData = std::unique_ptr<uint8, decltype(&Memory::Free<uint8>)>(Memory::Allocate<uint8>(sizeof(rct1_s4)), &Memory::Free<uint8>);
|
||||
_s4 = ReadAndDecodeS4(stream, isScenario);
|
||||
_s4Path = path;
|
||||
|
||||
size_t decodedSize;
|
||||
sint32 fileType = sawyercoding_detect_file_type(data.get(), dataSize);
|
||||
if (isScenario && (fileType & FILE_VERSION_MASK) != FILE_VERSION_RCT1)
|
||||
{
|
||||
decodedSize = sawyercoding_decode_sc4(data.get(), decodedData.get(), dataSize, sizeof(rct1_s4));
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedSize = sawyercoding_decode_sv4(data.get(), decodedData.get(), dataSize, sizeof(rct1_s4));
|
||||
}
|
||||
|
||||
if (decodedSize == sizeof(rct1_s4))
|
||||
{
|
||||
std::memcpy(&_s4, decodedData.get(), sizeof(rct1_s4));
|
||||
if (_s4Path)
|
||||
{
|
||||
Memory::Free(_s4Path);
|
||||
}
|
||||
_s4Path = String::Duplicate(path);
|
||||
|
||||
if (!skipObjectCheck)
|
||||
{
|
||||
InitialiseEntryMaps();
|
||||
CreateAvailableObjectMappings();
|
||||
|
||||
auto missingObjects = GetInvalidObjects();
|
||||
if (!missingObjects.empty())
|
||||
{
|
||||
return ParkLoadResult::CreateMissingObjects(missingObjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unable to decode park.");
|
||||
}
|
||||
return ParkLoadResult::CreateOK();
|
||||
// Only determine what objects we required to import this saved game
|
||||
InitialiseEntryMaps();
|
||||
CreateAvailableObjectMappings();
|
||||
return ParkLoadResult(GetRequiredObjects());
|
||||
}
|
||||
|
||||
void Import() override
|
||||
|
@ -333,6 +298,36 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
rct1_s4 ReadAndDecodeS4(IStream * stream, bool isScenario)
|
||||
{
|
||||
rct1_s4 s4;
|
||||
size_t dataSize = stream->GetLength() - stream->GetPosition();
|
||||
auto deleter_lambda = [dataSize](uint8 * ptr) { Memory::FreeArray(ptr, dataSize); };
|
||||
auto data = std::unique_ptr<uint8, decltype(deleter_lambda)>(stream->ReadArray<uint8>(dataSize), deleter_lambda);
|
||||
auto decodedData = std::unique_ptr<uint8, decltype(&Memory::Free<uint8>)>(Memory::Allocate<uint8>(sizeof(rct1_s4)), &Memory::Free<uint8>);
|
||||
|
||||
size_t decodedSize;
|
||||
sint32 fileType = sawyercoding_detect_file_type(data.get(), dataSize);
|
||||
if (isScenario && (fileType & FILE_VERSION_MASK) != FILE_VERSION_RCT1)
|
||||
{
|
||||
decodedSize = sawyercoding_decode_sc4(data.get(), decodedData.get(), dataSize, sizeof(rct1_s4));
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedSize = sawyercoding_decode_sv4(data.get(), decodedData.get(), dataSize, sizeof(rct1_s4));
|
||||
}
|
||||
|
||||
if (decodedSize == sizeof(rct1_s4))
|
||||
{
|
||||
std::memcpy(&s4, decodedData.get(), sizeof(rct1_s4));
|
||||
return s4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unable to decode park.");
|
||||
}
|
||||
}
|
||||
|
||||
void Initialise()
|
||||
{
|
||||
_gameVersion = sawyercoding_detect_rct1_version(_s4.game_version) & FILE_VERSION_MASK;
|
||||
|
@ -1890,17 +1885,34 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<rct_object_entry> GetInvalidObjects()
|
||||
void AppendRequiredObjects(std::vector<rct_object_entry>& entries, uint8 objectType, const EntryList& entryList)
|
||||
{
|
||||
std::vector<rct_object_entry> missingObjects;
|
||||
GetInvalidObjects(OBJECT_TYPE_RIDE, _rideEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_SMALL_SCENERY, _smallSceneryEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_LARGE_SCENERY, _largeSceneryEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_WALLS, _wallEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_PATHS, _pathEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_PATH_BITS, _pathAdditionEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_SCENERY_GROUP, _sceneryGroupEntries.GetEntries(), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_BANNERS, std::vector<const char *>({
|
||||
AppendRequiredObjects(entries, objectType, entryList.GetEntries());
|
||||
}
|
||||
|
||||
void AppendRequiredObjects(std::vector<rct_object_entry>& entries, uint8 objectType, const std::vector<const char *>& objectNames)
|
||||
{
|
||||
for (const auto objectName : objectNames)
|
||||
{
|
||||
rct_object_entry entry{};
|
||||
entry.flags = ((OBJECT_SOURCE_RCT2 << 4) & 0xF0) | (objectType & 0x0F);
|
||||
std::memset(entry.name, ' ', sizeof(entry.name));
|
||||
std::strncpy(entry.name, objectName, sizeof(entry.name));
|
||||
entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<rct_object_entry> GetRequiredObjects()
|
||||
{
|
||||
std::vector<rct_object_entry> result;
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_RIDE, _rideEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_SMALL_SCENERY, _smallSceneryEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_LARGE_SCENERY, _largeSceneryEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_WALLS, _wallEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_PATHS, _pathEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_PATH_BITS, _pathAdditionEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_SCENERY_GROUP, _sceneryGroupEntries);
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_BANNERS, std::vector<const char *>({
|
||||
"BN1 ",
|
||||
"BN2 ",
|
||||
"BN3 ",
|
||||
|
@ -1909,11 +1921,10 @@ private:
|
|||
"BN6 ",
|
||||
"BN7 ",
|
||||
"BN8 ",
|
||||
"BN9 "
|
||||
}), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_PARK_ENTRANCE, std::vector<const char *>({ "PKENT1 " }), missingObjects);
|
||||
GetInvalidObjects(OBJECT_TYPE_WATER, _waterEntry.GetEntries(), missingObjects);
|
||||
return missingObjects;
|
||||
"BN9 " }));
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_PARK_ENTRANCE, std::vector<const char *>({ "PKENT1 " }));
|
||||
AppendRequiredObjects(result, OBJECT_TYPE_WATER, _waterEntry);
|
||||
return result;
|
||||
}
|
||||
|
||||
void GetInvalidObjects(uint8 objectType, const std::vector<const char *> &entries, std::vector<rct_object_entry> &missingObjects)
|
||||
|
@ -2843,44 +2854,20 @@ std::unique_ptr<IParkImporter> ParkImporter::CreateS4()
|
|||
return std::make_unique<S4Importer>();
|
||||
}
|
||||
|
||||
ParkLoadResult * load_from_sv4(const utf8 * path)
|
||||
void load_from_sv4(const utf8 * path)
|
||||
{
|
||||
ParkLoadResult * result = nullptr;
|
||||
auto s4Importer = std::make_unique<S4Importer>();
|
||||
try
|
||||
{
|
||||
result = new ParkLoadResult(s4Importer->LoadSavedGame(path));
|
||||
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||
{
|
||||
s4Importer->Import();
|
||||
}
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
delete result;
|
||||
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||
}
|
||||
return result;
|
||||
auto result = s4Importer->LoadSavedGame(path);
|
||||
// TODO load objects
|
||||
s4Importer->Import();
|
||||
}
|
||||
|
||||
ParkLoadResult * load_from_sc4(const utf8 * path)
|
||||
void load_from_sc4(const utf8 * path)
|
||||
{
|
||||
ParkLoadResult * result = nullptr;
|
||||
auto s4Importer = std::make_unique<S4Importer>();
|
||||
try
|
||||
{
|
||||
result = new ParkLoadResult(s4Importer->LoadScenario(path));
|
||||
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||
{
|
||||
s4Importer->Import();
|
||||
}
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
delete result;
|
||||
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||
}
|
||||
return result;
|
||||
auto result = s4Importer->LoadScenario(path);
|
||||
// TODO load objects
|
||||
s4Importer->Import();
|
||||
}
|
||||
|
||||
static uint8 GetPathType(rct_tile_element * tileElement)
|
||||
|
|
|
@ -857,52 +857,35 @@ std::unique_ptr<IParkImporter> ParkImporter::CreateS6(std::shared_ptr<IObjectRep
|
|||
return std::make_unique<S6Importer>(objectRepository, objectManager);
|
||||
}
|
||||
|
||||
ParkLoadResult * load_from_sv6(const char * path)
|
||||
void load_from_sv6(const char * path)
|
||||
{
|
||||
ParkLoadResult * result = nullptr;
|
||||
auto context = OpenRCT2::GetContext();
|
||||
auto s6Importer = new S6Importer(context->GetObjectRepository(), context->GetObjectManager());
|
||||
auto s6Importer = std::make_unique<S6Importer>(context->GetObjectRepository(), context->GetObjectManager());
|
||||
try
|
||||
{
|
||||
result = new ParkLoadResult(s6Importer->LoadSavedGame(path));
|
||||
|
||||
// We mustn't import if there's something
|
||||
// wrong with the park data
|
||||
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||
{
|
||||
s6Importer->Import();
|
||||
|
||||
game_fix_save_vars();
|
||||
sprite_position_tween_reset();
|
||||
}
|
||||
auto result = s6Importer->LoadSavedGame(path);
|
||||
// TODO load objects
|
||||
s6Importer->Import();
|
||||
game_fix_save_vars();
|
||||
sprite_position_tween_reset();
|
||||
gScreenAge = 0;
|
||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||
}
|
||||
catch (const ObjectLoadException &)
|
||||
catch (const ObjectLoadException&)
|
||||
{
|
||||
gErrorType = ERROR_TYPE_FILE_LOAD;
|
||||
gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
||||
}
|
||||
catch (const IOException &)
|
||||
catch (const IOException&)
|
||||
{
|
||||
gErrorType = ERROR_TYPE_FILE_LOAD;
|
||||
gErrorStringId = STR_GAME_SAVE_FAILED;
|
||||
}
|
||||
catch (const std::exception &)
|
||||
catch (const std::exception&)
|
||||
{
|
||||
gErrorType = ERROR_TYPE_FILE_LOAD;
|
||||
gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
||||
}
|
||||
delete s6Importer;
|
||||
|
||||
if (result == nullptr)
|
||||
{
|
||||
result = new ParkLoadResult(ParkLoadResult::CreateUnknown());
|
||||
}
|
||||
if (result->Error == PARK_LOAD_ERROR_OK)
|
||||
{
|
||||
gScreenAge = 0;
|
||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue