1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-19 21:13:05 +01:00

Use streams for SV6 export

This commit is contained in:
Ted John
2017-02-05 15:45:23 +00:00
parent 0dcab94411
commit 2518362112
17 changed files with 344 additions and 275 deletions

View File

@@ -32,6 +32,7 @@
#include "../core/String.hpp"
#include "../PlatformEnvironment.h"
#include "../rct12/SawyerChunkReader.h"
#include "../rct12/SawyerChunkWriter.h"
#include "../scenario/ScenarioRepository.h"
#include "Object.h"
#include "ObjectFactory.h"
@@ -224,7 +225,7 @@ public:
}
}
bool TryExportPackedObject(IStream * stream) override
void ExportPackedObject(IStream * stream) override
{
auto chunkReader = SawyerChunkReader(stream);
@@ -240,7 +241,25 @@ public:
std::shared_ptr<SawyerChunk> chunk = chunkReader.ReadChunk();
AddObject(&entry, chunk->GetData(), chunk->GetLength());
}
return true;
}
void WritePackedObjects(IStream * stream, std::vector<const ObjectRepositoryItem *> &objects) override
{
log_verbose("packing %u objects", objects.size());
for (const auto &object : objects)
{
Guard::ArgumentNotNull(object);
log_verbose("exporting object %.8s", object->ObjectEntry.name);
if (IsObjectCustom(object))
{
WritePackedObject(stream, &object->ObjectEntry);
}
else
{
log_warning("Refusing to pack vanilla/expansion object \"%s\"", object->ObjectEntry.name);
}
}
}
private:
@@ -648,6 +667,30 @@ private:
String::Append(buffer, bufferSize, ".DAT");
}
}
void WritePackedObject(IStream * stream, const rct_object_entry * entry)
{
const ObjectRepositoryItem * item = FindObject(entry);
if (item == nullptr)
{
throw Exception(String::StdFormat("Unable to find object '%.8s'", entry->name));
}
// Read object data from file
auto fs = FileStream(item->Path, FILE_MODE_OPEN);
auto fileEntry = fs.ReadValue<rct_object_entry>();
if (!object_entry_compare(entry, &fileEntry))
{
throw Exception("Header found in object file does not match object to pack.");
}
auto chunkReader = SawyerChunkReader(&fs);
auto chunk = chunkReader.ReadChunk();
// Write object data to stream
auto chunkWriter = SawyerChunkWriter(stream);
stream->WriteValue(*entry);
chunkWriter.WriteChunk(chunk.get());
}
};
static std::unique_ptr<ObjectRepository> _objectRepository;
@@ -663,6 +706,14 @@ IObjectRepository * GetObjectRepository()
return _objectRepository.get();
}
bool IsObjectCustom(const ObjectRepositoryItem * object)
{
Guard::ArgumentNotNull(object);
// Validate the object is not one from base game or expansion pack
return !(object->ObjectEntry.flags & 0xF0);
}
extern "C"
{
rct_object_entry * object_list_find(rct_object_entry * entry)
@@ -755,45 +806,6 @@ extern "C"
}
}
bool object_saved_packed(SDL_RWops * rw, const rct_object_entry * entry)
{
IObjectRepository * objectRepository = GetObjectRepository();
const ObjectRepositoryItem * item = objectRepository->FindObject(entry);
if (item == nullptr)
{
return false;
}
auto fs = FileStream(item->Path, FILE_MODE_OPEN);
rct_object_entry fileEntry = fs.ReadValue<rct_object_entry>();
if (!object_entry_compare(entry, &fileEntry))
{
return false;
}
sawyercoding_chunk_header chunkHeader = fs.ReadValue<sawyercoding_chunk_header>();
uint8 * chunkData = fs.ReadArray<uint8>(chunkHeader.length);
if (SDL_RWwrite(rw, entry, sizeof(rct_object_entry), 1) != 1)
{
Memory::Free(chunkData);
return false;
}
if (SDL_RWwrite(rw, &chunkHeader, sizeof(sawyercoding_chunk_header), 1) != 1)
{
Memory::Free(chunkData);
return false;
}
if (SDL_RWwrite(rw, chunkData, chunkHeader.length, 1) != 1)
{
Memory::Free(chunkData);
return false;
}
Memory::Free(chunkData);
return true;
}
size_t object_repository_get_items_count()
{
IObjectRepository * objectRepository = GetObjectRepository();