1
0
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:
Ted John
2017-01-30 22:58:48 +00:00
parent f30a3b315c
commit 2b045ddb9b
5 changed files with 63 additions and 88 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;
};

View File

@@ -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;