mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 19:43:06 +01:00
Use streams for reading parks in S4 importer
This commit is contained in:
@@ -21,62 +21,6 @@
|
||||
#include "util/sawyercoding.h"
|
||||
#include "util/util.h"
|
||||
|
||||
bool rct1_read_sc4(const char *path, rct1_s4 *s4)
|
||||
{
|
||||
uint8 *buffer, *decodedBuffer;
|
||||
size_t length, decodedLength;
|
||||
bool success;
|
||||
|
||||
if (!readentirefile(path, (void**)&buffer, &length)) {
|
||||
gErrorType = ERROR_TYPE_FILE_LOAD;
|
||||
gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sint32 fileType = sawyercoding_detect_file_type(buffer, length);
|
||||
|
||||
decodedBuffer = malloc(sizeof(rct1_s4));
|
||||
decodedLength = (fileType & FILE_VERSION_MASK) == FILE_VERSION_RCT1 ?
|
||||
sawyercoding_decode_sv4(buffer, decodedBuffer, length, sizeof(rct1_s4)) :
|
||||
sawyercoding_decode_sc4(buffer, decodedBuffer, length, sizeof(rct1_s4));
|
||||
if (decodedLength == sizeof(rct1_s4)) {
|
||||
memcpy(s4, decodedBuffer, sizeof(rct1_s4));
|
||||
success = true;
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
free(decodedBuffer);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool rct1_read_sv4(const char *path, rct1_s4 *s4)
|
||||
{
|
||||
uint8 *buffer, *decodedBuffer;
|
||||
size_t length, decodedLength;
|
||||
bool success;
|
||||
|
||||
if (!readentirefile(path, (void**)&buffer, &length)) {
|
||||
gErrorType = ERROR_TYPE_FILE_LOAD;
|
||||
gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
decodedBuffer = malloc(sizeof(rct1_s4));
|
||||
decodedLength = sawyercoding_decode_sv4(buffer, decodedBuffer, length, sizeof(rct1_s4));
|
||||
if (decodedLength == sizeof(rct1_s4)) {
|
||||
memcpy(s4, decodedBuffer, sizeof(rct1_s4));
|
||||
success = true;
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
free(decodedBuffer);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool rideTypeShouldLoseSeparateFlag(const rct_ride_entry *rideEntry)
|
||||
{
|
||||
if (!gConfigInterface.select_by_track_type) {
|
||||
|
||||
@@ -1189,10 +1189,6 @@ enum {
|
||||
|
||||
extern const uint8 gRideCategories[0x60];
|
||||
|
||||
bool rct1_read_sc4(const char *path, rct1_s4 *s4);
|
||||
bool rct1_read_sv4(const char *path, rct1_s4 *s4);
|
||||
void rct1_import_s4(rct1_s4 *s4);
|
||||
void rct1_fix_landscape();
|
||||
sint32 vehicle_preference_compare(uint8 rideType, const char * a, const char * b);
|
||||
bool rideTypeShouldLoseSeparateFlag(const rct_ride_entry *rideEntry);
|
||||
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "../core/Collections.hpp"
|
||||
#include "../core/Console.hpp"
|
||||
#include "../core/Exception.hpp"
|
||||
#include "../core/FileStream.hpp"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../core/IStream.hpp"
|
||||
#include "../core/Memory.hpp"
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/String.hpp"
|
||||
@@ -91,9 +94,9 @@ public:
|
||||
class S4Importer final : public IS4Importer
|
||||
{
|
||||
private:
|
||||
const utf8 * _s4Path;
|
||||
rct1_s4 _s4;
|
||||
uint8 _gameVersion;
|
||||
const utf8 * _s4Path = nullptr;
|
||||
rct1_s4 _s4 = { 0 };
|
||||
uint8 _gameVersion = 0;
|
||||
|
||||
// Lists of dynamic object entries
|
||||
EntryList _rideEntries;
|
||||
@@ -120,24 +123,6 @@ private:
|
||||
uint8 _researchRideTypeUsed[128];
|
||||
|
||||
public:
|
||||
void LoadSavedGame(const utf8 * path) override
|
||||
{
|
||||
if (!rct1_read_sv4(path, &_s4))
|
||||
{
|
||||
throw Exception("Unable to load SV4.");
|
||||
}
|
||||
_s4Path = path;
|
||||
}
|
||||
|
||||
void LoadScenario(const utf8 * path) override
|
||||
{
|
||||
if (!rct1_read_sc4(path, &_s4))
|
||||
{
|
||||
throw Exception("Unable to load SC4.");
|
||||
}
|
||||
_s4Path = path;
|
||||
}
|
||||
|
||||
void Load(const utf8 * path) override
|
||||
{
|
||||
const utf8 * extension = Path::GetExtension(path);
|
||||
@@ -155,6 +140,47 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void LoadSavedGame(const utf8 * path) override
|
||||
{
|
||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||
LoadFromStream(&fs, false);
|
||||
_s4Path = path;
|
||||
}
|
||||
|
||||
void LoadScenario(const utf8 * path) override
|
||||
{
|
||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||
LoadFromStream(&fs, true);
|
||||
_s4Path = path;
|
||||
}
|
||||
|
||||
void LoadFromStream(IStream * stream, bool isScenario) override
|
||||
{
|
||||
size_t dataSize = stream->GetLength() - stream->GetPosition();
|
||||
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)));
|
||||
|
||||
size_t decodedSize;
|
||||
if (isScenario)
|
||||
{
|
||||
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))
|
||||
{
|
||||
Memory::Copy<void>(&_s4, decodedData.get(), sizeof(rct1_s4));
|
||||
_s4Path = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception("Unable to decode park.");
|
||||
}
|
||||
}
|
||||
|
||||
void Import() override
|
||||
{
|
||||
Initialise();
|
||||
|
||||
@@ -19,16 +19,19 @@
|
||||
#include "../common.h"
|
||||
#include "../scenario/ScenarioRepository.h"
|
||||
|
||||
interface IStream;
|
||||
|
||||
/**
|
||||
* Interface to import RollerCoaster Tycoon 1 scenarios (*.SC4) and saved games (*.SV4).
|
||||
*/
|
||||
interface IS4Importer
|
||||
{
|
||||
public:
|
||||
virtual ~IS4Importer() { }
|
||||
virtual ~IS4Importer() = default;
|
||||
virtual void Load(const utf8 * path) abstract;
|
||||
virtual void LoadSavedGame(const utf8 * path) abstract;
|
||||
virtual void LoadScenario(const utf8 * path) abstract;
|
||||
virtual void Load(const utf8 * path) abstract;
|
||||
virtual void LoadFromStream(IStream * stream, bool isScenario) abstract;
|
||||
virtual void Import() abstract;
|
||||
virtual bool GetDetails(scenario_index_entry * dst) abstract;
|
||||
};
|
||||
|
||||
@@ -317,12 +317,18 @@ private:
|
||||
// RCT1 scenario
|
||||
bool result = false;
|
||||
IS4Importer * s4Importer = CreateS4Importer();
|
||||
s4Importer->LoadScenario(path.c_str());
|
||||
if (s4Importer->GetDetails(entry))
|
||||
try
|
||||
{
|
||||
s4Importer->LoadScenario(path.c_str());
|
||||
if (s4Importer->GetDetails(entry))
|
||||
{
|
||||
String::Set(entry->path, sizeof(entry->path), path.c_str());
|
||||
entry->timestamp = timestamp;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
String::Set(entry->path, sizeof(entry->path), path.c_str());
|
||||
entry->timestamp = timestamp;
|
||||
result = true;
|
||||
}
|
||||
delete s4Importer;
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user