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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user