mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
prepare unpacking objects
This commit is contained in:
@@ -132,7 +132,7 @@ int write_object_file(SDL_RWops *rw, rct_object_entry* entry)
|
||||
*
|
||||
* rct2: 0x006AA2B7
|
||||
*/
|
||||
int object_load_packed(SDL_RWops* rw)
|
||||
int object_load_packed_old(SDL_RWops* rw)
|
||||
{
|
||||
object_unload_all();
|
||||
|
||||
|
||||
@@ -33,10 +33,12 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../config.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../object.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../scenario.h"
|
||||
#include "../util/sawyercoding.h"
|
||||
}
|
||||
|
||||
constexpr uint16 OBJECT_REPOSITORY_VERSION = 6;
|
||||
@@ -139,6 +141,36 @@ public:
|
||||
return object;
|
||||
}
|
||||
|
||||
void AddObject(const rct_object_entry * objectEntry, const void * data, size_t dataSize) override
|
||||
{
|
||||
char objectName[9] = { 0 };
|
||||
Memory::Copy(objectName, objectEntry->name, 8);
|
||||
|
||||
int realChecksum = object_calculate_checksum(objectEntry, (const uint8 *)data, (int)dataSize);
|
||||
if (realChecksum != objectEntry->checksum)
|
||||
{
|
||||
log_error("Checksum mismatch from packed object: %.8s", objectName);
|
||||
if (!gConfigGeneral.allow_loading_with_incorrect_checksum)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
utf8 path[MAX_PATH];
|
||||
GetPathForNewObject(path, sizeof(path), objectName);
|
||||
|
||||
Console::WriteLine("Adding object: [%s]", objectName);
|
||||
try
|
||||
{
|
||||
SaveObject(path, objectEntry, data, dataSize);
|
||||
ScanObject(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console::WriteLine("Failed saving object: [%s] to '%s'.", objectName, path);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ClearItems()
|
||||
{
|
||||
@@ -374,6 +406,50 @@ private:
|
||||
item->ThemeObjects = nullptr;
|
||||
}
|
||||
|
||||
static void SaveObject(const utf8 * path, const rct_object_entry * entry, const void * data, size_t dataSize)
|
||||
{
|
||||
// TODO
|
||||
// auto fs = FileStream(path, FILE_MODE_WRITE);
|
||||
// fs.Write(entry, sizeof(entry));
|
||||
}
|
||||
|
||||
static void GetPathForNewObject(utf8 * buffer, size_t bufferSize, const char * name)
|
||||
{
|
||||
char normalisedName[9] = { 0 };
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (name[i] != ' ')
|
||||
{
|
||||
normalisedName[i] = toupper(name[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalisedName[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
substitute_path(buffer, gRCT2AddressObjectDataPath, normalisedName);
|
||||
char * lastCh = buffer + strlen(buffer);
|
||||
strcat(buffer, ".DAT");
|
||||
|
||||
for (; platform_file_exists(buffer);)
|
||||
{
|
||||
for (char * ch = lastCh - 1; ; ch--)
|
||||
{
|
||||
if (*ch == '\\')
|
||||
{
|
||||
substitute_path(buffer, gRCT2AddressObjectDataPath, "00000000.DAT");
|
||||
break;
|
||||
}
|
||||
if (*ch < '0') *ch = '0';
|
||||
else if (*ch == '9') *ch = 'A';
|
||||
else if (*ch == 'Z') *ch = '0';
|
||||
else (*ch)++;
|
||||
if (*ch != '0') break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void GetRepositoryPath(utf8 * buffer, size_t bufferSize)
|
||||
{
|
||||
platform_get_user_directory(buffer, nullptr);
|
||||
@@ -539,4 +615,31 @@ extern "C"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int object_load_packed(SDL_RWops * rw)
|
||||
{
|
||||
rct_object_entry entry;
|
||||
SDL_RWread(rw, &entry, 16, 1);
|
||||
|
||||
uint8 * chunk = Memory::Allocate<uint8>(0x600000);
|
||||
if (chunk == nullptr)
|
||||
{
|
||||
log_error("Failed to allocate buffer for packed object.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 chunkSize = sawyercoding_read_chunk(rw, chunk);
|
||||
chunk = Memory::Reallocate(chunk, chunkSize);
|
||||
if (chunk == nullptr)
|
||||
{
|
||||
log_error("Failed to reallocate buffer for packed object.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IObjectRepository * objRepo = GetObjectRepository();
|
||||
objRepo->AddObject(&entry, chunk, chunkSize);
|
||||
|
||||
Memory::Free(chunk);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ interface IObjectRepository
|
||||
virtual const ObjectRepositoryItem * FindObject(const utf8 * name) abstract;
|
||||
virtual const ObjectRepositoryItem * FindObject(const rct_object_entry * objectEntry) abstract;
|
||||
virtual Object * LoadObject(const rct_object_entry * objectEntry) abstract;
|
||||
virtual void AddObject(const rct_object_entry * objectEntry,
|
||||
const void * data,
|
||||
size_t dataSize) abstract;
|
||||
};
|
||||
|
||||
IObjectRepository * GetObjectRepository();
|
||||
|
||||
Reference in New Issue
Block a user