mirror of https://github.com/OpenRCT2/OpenRCT2.git
prepare for better object loading
This commit is contained in:
parent
4e259920b1
commit
e8635c1307
|
@ -44,7 +44,7 @@ extern "C"
|
||||||
#include "../util/sawyercoding.h"
|
#include "../util/sawyercoding.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint16 OBJECT_REPOSITORY_VERSION = 7;
|
constexpr uint16 OBJECT_REPOSITORY_VERSION = 8;
|
||||||
|
|
||||||
struct ObjectRepositoryHeader
|
struct ObjectRepositoryHeader
|
||||||
{
|
{
|
||||||
|
@ -155,14 +155,11 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object * LoadObject(const rct_object_entry * objectEntry) override
|
Object * LoadObject(const ObjectRepositoryItem * ori) override
|
||||||
{
|
{
|
||||||
Object * object = nullptr;
|
Guard::ArgumentNotNull(ori);
|
||||||
const ObjectRepositoryItem * item = FindObject(objectEntry);
|
|
||||||
if (item != nullptr)
|
Object * object = ObjectFactory::CreateObjectFromLegacyFile(ori->Path);
|
||||||
{
|
|
||||||
object = ObjectFactory::CreateObjectFromLegacyFile(item->Path);
|
|
||||||
}
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,9 +385,7 @@ private:
|
||||||
|
|
||||||
item.ObjectEntry = stream->ReadValue<rct_object_entry>();
|
item.ObjectEntry = stream->ReadValue<rct_object_entry>();
|
||||||
item.Path = stream->ReadString();
|
item.Path = stream->ReadString();
|
||||||
item.NumImages = stream->ReadValue<uint32>();
|
|
||||||
item.Name = stream->ReadString();
|
item.Name = stream->ReadString();
|
||||||
item.ChunkSize = stream->ReadValue<size_t>();
|
|
||||||
|
|
||||||
switch (item.ObjectEntry.flags & 0x0F) {
|
switch (item.ObjectEntry.flags & 0x0F) {
|
||||||
case OBJECT_TYPE_RIDE:
|
case OBJECT_TYPE_RIDE:
|
||||||
|
@ -420,9 +415,7 @@ private:
|
||||||
{
|
{
|
||||||
stream->WriteValue(item.ObjectEntry);
|
stream->WriteValue(item.ObjectEntry);
|
||||||
stream->WriteString(item.Path);
|
stream->WriteString(item.Path);
|
||||||
stream->WriteValue(item.NumImages);
|
|
||||||
stream->WriteString(item.Name);
|
stream->WriteString(item.Name);
|
||||||
stream->WriteValue(item.ChunkSize);
|
|
||||||
|
|
||||||
switch (item.ObjectEntry.flags & 0x0F) {
|
switch (item.ObjectEntry.flags & 0x0F) {
|
||||||
case OBJECT_TYPE_RIDE:
|
case OBJECT_TYPE_RIDE:
|
||||||
|
@ -597,15 +590,25 @@ extern "C"
|
||||||
|
|
||||||
bool object_load_chunk(int groupIndex, const rct_object_entry * entry, int * outGroupIndex)
|
bool object_load_chunk(int groupIndex, const rct_object_entry * entry, int * outGroupIndex)
|
||||||
{
|
{
|
||||||
IObjectRepository * objRepo = GetObjectRepository();
|
IObjectRepository * objectRepository = GetObjectRepository();
|
||||||
Object * object = objRepo->LoadObject(entry);
|
const ObjectRepositoryItem * ori = objectRepository->FindObject(entry);
|
||||||
|
if (ori == nullptr)
|
||||||
|
{
|
||||||
|
utf8 objName[9] = { 0 };
|
||||||
|
Memory::Copy(objName, ori->ObjectEntry.name, 8);
|
||||||
|
Console::Error::WriteFormat("[%s]: Object not found.", objName);
|
||||||
|
Console::Error::WriteLine();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object * object = objectRepository->LoadObject(ori);
|
||||||
if (object == nullptr)
|
if (object == nullptr)
|
||||||
{
|
{
|
||||||
utf8 objName[9] = { 0 };
|
utf8 objName[9] = { 0 };
|
||||||
Memory::Copy(objName, entry->name, 8);
|
Memory::Copy(objName, ori->ObjectEntry.name, 8);
|
||||||
Console::Error::WriteFormat("[%s]: Object not found or could not be loaded.", objName);
|
Console::Error::WriteFormat("[%s]: Object could not be loaded.", objName);
|
||||||
Console::Error::WriteLine();
|
Console::Error::WriteLine();
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 objectType = object->GetObjectType();
|
uint8 objectType = object->GetObjectType();
|
||||||
|
@ -618,7 +621,7 @@ extern "C"
|
||||||
{
|
{
|
||||||
log_error("Object Load failed due to too many objects of a certain type.");
|
log_error("Object Load failed due to too many objects of a certain type.");
|
||||||
delete object;
|
delete object;
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -635,7 +638,50 @@ extern "C"
|
||||||
int loadedObjectIndex = GetObjectEntryIndex(objectType, groupIndex);
|
int loadedObjectIndex = GetObjectEntryIndex(objectType, groupIndex);
|
||||||
delete _loadedObjects[loadedObjectIndex];
|
delete _loadedObjects[loadedObjectIndex];
|
||||||
_loadedObjects[loadedObjectIndex] = object;
|
_loadedObjects[loadedObjectIndex] = object;
|
||||||
return 1;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool object_load_entries(rct_object_entry * entries)
|
||||||
|
{
|
||||||
|
log_verbose("loading required objects");
|
||||||
|
|
||||||
|
object_unload_all();
|
||||||
|
|
||||||
|
bool loadFailed = false;
|
||||||
|
|
||||||
|
// Load each object
|
||||||
|
for (int i = 0; i < OBJECT_ENTRY_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (check_object_entry(&entries[i]))
|
||||||
|
{
|
||||||
|
// Get entry group index
|
||||||
|
int entryGroupIndex = i;
|
||||||
|
for (int j = 0; j < OBJECT_ENTRY_GROUP_COUNT; j++)
|
||||||
|
{
|
||||||
|
if (entryGroupIndex < object_entry_group_counts[j])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
entryGroupIndex -= object_entry_group_counts[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the obect
|
||||||
|
if (!object_load_chunk(entryGroupIndex, &entries[i], NULL)) {
|
||||||
|
// log_error("failed to load entry: %.8s", entries[i].name);
|
||||||
|
// memcpy(gCommonFormatArgs, &entries[i], sizeof(rct_object_entry));
|
||||||
|
loadFailed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadFailed)
|
||||||
|
{
|
||||||
|
object_unload_all();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_verbose("finished loading required objects");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_loaded_objects()
|
void reset_loaded_objects()
|
||||||
|
@ -655,9 +701,17 @@ extern "C"
|
||||||
|
|
||||||
void * object_repository_load_object(const rct_object_entry * objectEntry)
|
void * object_repository_load_object(const rct_object_entry * objectEntry)
|
||||||
{
|
{
|
||||||
|
Object * object = nullptr;
|
||||||
IObjectRepository * objRepository = GetObjectRepository();
|
IObjectRepository * objRepository = GetObjectRepository();
|
||||||
Object * object = objRepository->LoadObject(objectEntry);
|
const ObjectRepositoryItem * ori = objRepository->FindObject(objectEntry);
|
||||||
|
if (ori != nullptr)
|
||||||
|
{
|
||||||
|
object = objRepository->LoadObject(ori);
|
||||||
|
if (object != nullptr)
|
||||||
|
{
|
||||||
object->Load();
|
object->Load();
|
||||||
|
}
|
||||||
|
}
|
||||||
return (void *)object;
|
return (void *)object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,8 +784,11 @@ extern "C"
|
||||||
// Checks for a scenario string object (possibly for localisation)
|
// Checks for a scenario string object (possibly for localisation)
|
||||||
if ((stexObjectEntry->flags & 0xFF) != 255)
|
if ((stexObjectEntry->flags & 0xFF) != 255)
|
||||||
{
|
{
|
||||||
IObjectRepository * objRepo = GetObjectRepository();
|
IObjectRepository * objectRepository = GetObjectRepository();
|
||||||
Object * object = objRepo->LoadObject(stexObjectEntry);
|
const ObjectRepositoryItem * ori = objectRepository->FindObject(stexObjectEntry);
|
||||||
|
if (ori != nullptr)
|
||||||
|
{
|
||||||
|
Object * object = objectRepository->LoadObject(ori);
|
||||||
if (object != nullptr)
|
if (object != nullptr)
|
||||||
{
|
{
|
||||||
StexObject * stexObject = static_cast<StexObject*>(object);
|
StexObject * stexObject = static_cast<StexObject*>(object);
|
||||||
|
@ -746,6 +803,7 @@ extern "C"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int object_load_packed(SDL_RWops * rw)
|
int object_load_packed(SDL_RWops * rw)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,33 +27,36 @@ extern "C"
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
class Object;
|
||||||
|
#else
|
||||||
|
typedef struct Object Object;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct ObjectRepositoryItem
|
typedef struct ObjectRepositoryItem
|
||||||
{
|
{
|
||||||
rct_object_entry ObjectEntry;
|
rct_object_entry ObjectEntry;
|
||||||
utf8 * Path;
|
utf8 * Path;
|
||||||
uint32 NumImages;
|
|
||||||
utf8 * Name;
|
utf8 * Name;
|
||||||
size_t ChunkSize;
|
Object * LoadedObject;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16 NumThemeObjects;
|
|
||||||
rct_object_entry * ThemeObjects;
|
|
||||||
};
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8 RideFlags;
|
uint8 RideFlags;
|
||||||
uint8 RideCategory[2];
|
uint8 RideCategory[2];
|
||||||
uint8 RideType[3];
|
uint8 RideType[3];
|
||||||
};
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16 NumThemeObjects;
|
||||||
|
rct_object_entry * ThemeObjects;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} ObjectRepositoryItem;
|
} ObjectRepositoryItem;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
class Object;
|
|
||||||
|
|
||||||
interface IObjectRepository
|
interface IObjectRepository
|
||||||
{
|
{
|
||||||
virtual ~IObjectRepository() { }
|
virtual ~IObjectRepository() { }
|
||||||
|
@ -63,7 +66,7 @@ interface IObjectRepository
|
||||||
virtual const ObjectRepositoryItem * FindObject(const utf8 * name) const abstract;
|
virtual const ObjectRepositoryItem * FindObject(const utf8 * name) const abstract;
|
||||||
virtual const ObjectRepositoryItem * FindObject(const rct_object_entry * objectEntry) const abstract;
|
virtual const ObjectRepositoryItem * FindObject(const rct_object_entry * objectEntry) const abstract;
|
||||||
|
|
||||||
virtual Object * LoadObject(const rct_object_entry * objectEntry) abstract;
|
virtual Object * LoadObject(const ObjectRepositoryItem * ori) abstract;
|
||||||
virtual void AddObject(const rct_object_entry * objectEntry,
|
virtual void AddObject(const rct_object_entry * objectEntry,
|
||||||
const void * data,
|
const void * data,
|
||||||
size_t dataSize) abstract;
|
size_t dataSize) abstract;
|
||||||
|
|
|
@ -187,44 +187,6 @@ bool object_read_and_load_entries(SDL_RWops* rw)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool object_load_entries(rct_object_entry* entries)
|
|
||||||
{
|
|
||||||
log_verbose("loading required objects");
|
|
||||||
|
|
||||||
object_unload_all();
|
|
||||||
|
|
||||||
bool loadFailed = false;
|
|
||||||
// Load each object
|
|
||||||
for (int i = 0; i < OBJECT_ENTRY_COUNT; i++) {
|
|
||||||
if (!check_object_entry(&entries[i])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get entry group index
|
|
||||||
int entryGroupIndex = i;
|
|
||||||
for (int j = 0; j < countof(object_entry_group_counts); j++) {
|
|
||||||
if (entryGroupIndex < object_entry_group_counts[j])
|
|
||||||
break;
|
|
||||||
entryGroupIndex -= object_entry_group_counts[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the obect
|
|
||||||
if (!object_load_chunk(entryGroupIndex, &entries[i], NULL)) {
|
|
||||||
// log_error("failed to load entry: %.8s", entries[i].name);
|
|
||||||
// memcpy(gCommonFormatArgs, &entries[i], sizeof(rct_object_entry));
|
|
||||||
loadFailed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadFailed) {
|
|
||||||
object_unload_all();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_verbose("finished loading required objects");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x006A9DA2
|
* rct2: 0x006A9DA2
|
||||||
|
|
|
@ -114,16 +114,9 @@ void S6Importer::LoadSavedGame(SDL_RWops *rw)
|
||||||
|
|
||||||
// Read packed objects
|
// Read packed objects
|
||||||
// TODO try to contain this more and not store objects until later
|
// TODO try to contain this more and not store objects until later
|
||||||
if (_s6.header.num_packed_objects > 0) {
|
|
||||||
int j = 0;
|
|
||||||
for (uint16 i = 0; i < _s6.header.num_packed_objects; i++)
|
for (uint16 i = 0; i < _s6.header.num_packed_objects; i++)
|
||||||
{
|
{
|
||||||
j += object_load_packed(rw);
|
object_load_packed(rw);
|
||||||
}
|
|
||||||
if (j > 0)
|
|
||||||
{
|
|
||||||
object_list_load();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sawyercoding_read_chunk_safe(rw, &_s6.objects, sizeof(_s6.objects));
|
sawyercoding_read_chunk_safe(rw, &_s6.objects, sizeof(_s6.objects));
|
||||||
|
@ -144,16 +137,9 @@ void S6Importer::LoadScenario(SDL_RWops *rw)
|
||||||
|
|
||||||
// Read packed objects
|
// Read packed objects
|
||||||
// TODO try to contain this more and not store objects until later
|
// TODO try to contain this more and not store objects until later
|
||||||
if (_s6.header.num_packed_objects > 0) {
|
|
||||||
int j = 0;
|
|
||||||
for (uint16 i = 0; i < _s6.header.num_packed_objects; i++)
|
for (uint16 i = 0; i < _s6.header.num_packed_objects; i++)
|
||||||
{
|
{
|
||||||
j += object_load_packed(rw);
|
object_load_packed(rw);
|
||||||
}
|
|
||||||
if (j > 0)
|
|
||||||
{
|
|
||||||
object_list_load();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sawyercoding_read_chunk_safe(rw, &_s6.objects, sizeof(_s6.objects));
|
sawyercoding_read_chunk_safe(rw, &_s6.objects, sizeof(_s6.objects));
|
||||||
|
|
|
@ -347,6 +347,7 @@ static void visible_list_refresh(rct_window *w)
|
||||||
int numObjects = (int)object_repository_get_items_count();
|
int numObjects = (int)object_repository_get_items_count();
|
||||||
|
|
||||||
visible_list_dispose();
|
visible_list_dispose();
|
||||||
|
w->selected_list_item = -1;
|
||||||
_listItems = malloc(numObjects * sizeof(list_item));
|
_listItems = malloc(numObjects * sizeof(list_item));
|
||||||
_numListItems = 0;
|
_numListItems = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue