Fix import of S4 and S6

This commit is contained in:
Ted John 2018-05-21 19:06:21 +01:00
parent 96a0a22cd1
commit 6af0cb2b88
8 changed files with 33 additions and 65 deletions

View file

@ -559,7 +559,7 @@ namespace OpenRCT2
try
{
auto result = parkImporter->LoadFromStream(stream, info.Type == FILE_TYPE::SCENARIO, false, path.c_str());
// _objectManager->LoadObjects(result.RequiredObjects.data(), result.RequiredObjects.size());
_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());

View file

@ -80,7 +80,7 @@ namespace ParkImporter
bool ExtensionIsScenario(const std::string &extension);
}
class ObjectLoadException : std::exception
class ObjectLoadException : public std::exception
{
public:
std::vector<rct_object_entry> const MissingObjects;
@ -91,7 +91,7 @@ public:
}
};
class UnsupportedRCTCFlagException : std::exception
class UnsupportedRCTCFlagException : public std::exception
{
public:
uint8 const Flag;

View file

@ -135,7 +135,7 @@ public:
{
// Find all the required objects
bool missingObjects;
auto requiredObjects = GetRequiredObjects(entries, &missingObjects);
auto requiredObjects = GetRequiredObjects(entries, count, &missingObjects);
if (missingObjects)
{
return false;
@ -482,11 +482,11 @@ private:
return invalidEntries;
}
std::vector<const ObjectRepositoryItem *> GetRequiredObjects(const rct_object_entry * entries, bool * missingObjects)
std::vector<const ObjectRepositoryItem *> GetRequiredObjects(const rct_object_entry * entries, size_t count, bool * missingObjects)
{
std::vector<const ObjectRepositoryItem *> requiredObjects;
*missingObjects = false;
for (sint32 i = 0; i < OBJECT_ENTRY_COUNT; i++)
for (sint32 i = 0; i < count; i++)
{
const rct_object_entry * entry = &entries[i];
const ObjectRepositoryItem * ori = nullptr;

View file

@ -177,7 +177,7 @@ public:
bool skipObjectCheck,
const utf8 * path) override
{
_s4 = ReadAndDecodeS4(stream, isScenario);
_s4 = *ReadAndDecodeS4(stream, isScenario);
_s4Path = path;
// Only determine what objects we required to import this saved game
@ -298,9 +298,9 @@ public:
}
private:
rct1_s4 ReadAndDecodeS4(IStream * stream, bool isScenario)
std::unique_ptr<rct1_s4> ReadAndDecodeS4(IStream * stream, bool isScenario)
{
rct1_s4 s4;
auto s4 = std::make_unique<rct1_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);
@ -319,7 +319,7 @@ private:
if (decodedSize == sizeof(rct1_s4))
{
std::memcpy(&s4, decodedData.get(), sizeof(rct1_s4));
std::memcpy(s4.get(), decodedData.get(), sizeof(rct1_s4));
return s4;
}
else

View file

@ -55,13 +55,6 @@
#include "../world/Sprite.h"
#include "../world/Surface.h"
class ObjectLoadException : public std::runtime_error
{
public:
ObjectLoadException() : std::runtime_error("Unable to load objects.") { }
explicit ObjectLoadException(const std::string &message) : std::runtime_error(message) { }
};
/**
* Class to import RollerCoaster Tycoon 2 scenarios (*.SC6) and saved games (*.SV6).
*/
@ -147,7 +140,7 @@ public:
if (_s6.header.classic_flag == 0xf)
{
return ParkLoadResult::CreateUnsupportedRCTCflag(_s6.header.classic_flag);
throw UnsupportedRCTCFlagException(_s6.header.classic_flag);
}
// Read packed objects
@ -179,15 +172,9 @@ public:
chunkReader.ReadChunk(&_s6.next_free_tile_element_pointer_index, 3048816);
}
auto missingObjects = _objectManager->GetInvalidObjects(_s6.objects);
if (!missingObjects.empty())
{
return ParkLoadResult::CreateMissingObjects(missingObjects);
}
_s6Path = path;
return ParkLoadResult::CreateOK();
return ParkLoadResult(std::vector<rct_object_entry>(std::begin(_s6.objects), std::end(_s6.objects)));
}
bool GetDetails(scenario_index_entry * dst) override
@ -452,10 +439,11 @@ public:
// pad_13CE778
// Fix and set dynamic variables
if (!_objectManager->LoadObjects(_s6.objects, OBJECT_ENTRY_COUNT))
{
throw ObjectLoadException();
}
// TODO objects should already be loaded
// if (!_objectManager->LoadObjects(_s6.objects, OBJECT_ENTRY_COUNT))
// {
// throw ObjectLoadException();
// }
map_strip_ghost_flag_from_elements();
map_update_tile_pointers();
game_convert_strings_to_utf8();
@ -893,47 +881,33 @@ void load_from_sv6(const char * path)
* rct2: 0x00676053
* scenario (ebx)
*/
ParkLoadResult * load_from_sc6(const char * path)
void load_from_sc6(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->LoadScenario(path));
if (result->Error == PARK_LOAD_ERROR_OK)
{
s6Importer->Import();
game_fix_save_vars();
sprite_position_tween_reset();
}
auto result = s6Importer->LoadScenario(path);
s6Importer->Import();
game_fix_save_vars();
sprite_position_tween_reset();
return;
}
catch (const ObjectLoadException &)
catch (const ObjectLoadException&)
{
gErrorType = ERROR_TYPE_FILE_LOAD;
gErrorStringId = STR_GAME_SAVE_FAILED;
}
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;
gScreenAge = 0;
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
}

View file

@ -385,7 +385,7 @@ extern uint32 gLastAutoSaveUpdate;
extern char gScenarioFileName[260];
ParkLoadResult * load_from_sc6(const char *path);
void load_from_sc6(const char *path);
void scenario_begin();
void scenario_update();

View file

@ -29,11 +29,7 @@ TEST(MultiLaunchTest, all)
bool initialised = context->Initialise();
ASSERT_TRUE(initialised);
ParkLoadResult * plr = load_from_sv6(path.c_str());
ASSERT_EQ(ParkLoadResult_GetError(plr), PARK_LOAD_ERROR_OK);
ParkLoadResult_Delete(plr);
load_from_sv6(path.c_str());
game_load_init();
// Check ride count to check load was successful

View file

@ -21,9 +21,7 @@ protected:
bool initialised = _context->Initialise();
ASSERT_TRUE(initialised);
ParkLoadResult * plr = load_from_sv6(parkPath.c_str());
ASSERT_EQ(ParkLoadResult_GetError(plr), PARK_LOAD_ERROR_OK);
ParkLoadResult_Delete(plr);
load_from_sv6(parkPath.c_str());
game_load_init();
SUCCEED();
}