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"
|
||||
}
|
||||
|
||||
constexpr uint16 OBJECT_REPOSITORY_VERSION = 7;
|
||||
constexpr uint16 OBJECT_REPOSITORY_VERSION = 8;
|
||||
|
||||
struct ObjectRepositoryHeader
|
||||
{
|
||||
|
@ -155,14 +155,11 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Object * LoadObject(const rct_object_entry * objectEntry) override
|
||||
Object * LoadObject(const ObjectRepositoryItem * ori) override
|
||||
{
|
||||
Object * object = nullptr;
|
||||
const ObjectRepositoryItem * item = FindObject(objectEntry);
|
||||
if (item != nullptr)
|
||||
{
|
||||
object = ObjectFactory::CreateObjectFromLegacyFile(item->Path);
|
||||
}
|
||||
Guard::ArgumentNotNull(ori);
|
||||
|
||||
Object * object = ObjectFactory::CreateObjectFromLegacyFile(ori->Path);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -388,9 +385,7 @@ private:
|
|||
|
||||
item.ObjectEntry = stream->ReadValue<rct_object_entry>();
|
||||
item.Path = stream->ReadString();
|
||||
item.NumImages = stream->ReadValue<uint32>();
|
||||
item.Name = stream->ReadString();
|
||||
item.ChunkSize = stream->ReadValue<size_t>();
|
||||
|
||||
switch (item.ObjectEntry.flags & 0x0F) {
|
||||
case OBJECT_TYPE_RIDE:
|
||||
|
@ -420,9 +415,7 @@ private:
|
|||
{
|
||||
stream->WriteValue(item.ObjectEntry);
|
||||
stream->WriteString(item.Path);
|
||||
stream->WriteValue(item.NumImages);
|
||||
stream->WriteString(item.Name);
|
||||
stream->WriteValue(item.ChunkSize);
|
||||
|
||||
switch (item.ObjectEntry.flags & 0x0F) {
|
||||
case OBJECT_TYPE_RIDE:
|
||||
|
@ -597,15 +590,25 @@ extern "C"
|
|||
|
||||
bool object_load_chunk(int groupIndex, const rct_object_entry * entry, int * outGroupIndex)
|
||||
{
|
||||
IObjectRepository * objRepo = GetObjectRepository();
|
||||
Object * object = objRepo->LoadObject(entry);
|
||||
IObjectRepository * objectRepository = GetObjectRepository();
|
||||
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)
|
||||
{
|
||||
utf8 objName[9] = { 0 };
|
||||
Memory::Copy(objName, entry->name, 8);
|
||||
Console::Error::WriteFormat("[%s]: Object not found or could not be loaded.", objName);
|
||||
Memory::Copy(objName, ori->ObjectEntry.name, 8);
|
||||
Console::Error::WriteFormat("[%s]: Object could not be loaded.", objName);
|
||||
Console::Error::WriteLine();
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8 objectType = object->GetObjectType();
|
||||
|
@ -618,7 +621,7 @@ extern "C"
|
|||
{
|
||||
log_error("Object Load failed due to too many objects of a certain type.");
|
||||
delete object;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -635,7 +638,50 @@ extern "C"
|
|||
int loadedObjectIndex = GetObjectEntryIndex(objectType, groupIndex);
|
||||
delete _loadedObjects[loadedObjectIndex];
|
||||
_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()
|
||||
|
@ -655,9 +701,17 @@ extern "C"
|
|||
|
||||
void * object_repository_load_object(const rct_object_entry * objectEntry)
|
||||
{
|
||||
Object * object = nullptr;
|
||||
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();
|
||||
}
|
||||
}
|
||||
return (void *)object;
|
||||
}
|
||||
|
||||
|
@ -730,8 +784,11 @@ extern "C"
|
|||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((stexObjectEntry->flags & 0xFF) != 255)
|
||||
{
|
||||
IObjectRepository * objRepo = GetObjectRepository();
|
||||
Object * object = objRepo->LoadObject(stexObjectEntry);
|
||||
IObjectRepository * objectRepository = GetObjectRepository();
|
||||
const ObjectRepositoryItem * ori = objectRepository->FindObject(stexObjectEntry);
|
||||
if (ori != nullptr)
|
||||
{
|
||||
Object * object = objectRepository->LoadObject(ori);
|
||||
if (object != nullptr)
|
||||
{
|
||||
StexObject * stexObject = static_cast<StexObject*>(object);
|
||||
|
@ -746,6 +803,7 @@ extern "C"
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int object_load_packed(SDL_RWops * rw)
|
||||
{
|
||||
|
|
|
@ -27,33 +27,36 @@ extern "C"
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
class Object;
|
||||
#else
|
||||
typedef struct Object Object;
|
||||
#endif
|
||||
|
||||
typedef struct ObjectRepositoryItem
|
||||
{
|
||||
rct_object_entry ObjectEntry;
|
||||
utf8 * Path;
|
||||
uint32 NumImages;
|
||||
utf8 * Name;
|
||||
size_t ChunkSize;
|
||||
Object * LoadedObject;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16 NumThemeObjects;
|
||||
rct_object_entry * ThemeObjects;
|
||||
};
|
||||
struct
|
||||
{
|
||||
uint8 RideFlags;
|
||||
uint8 RideCategory[2];
|
||||
uint8 RideType[3];
|
||||
};
|
||||
struct
|
||||
{
|
||||
uint16 NumThemeObjects;
|
||||
rct_object_entry * ThemeObjects;
|
||||
};
|
||||
};
|
||||
} ObjectRepositoryItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class Object;
|
||||
|
||||
interface IObjectRepository
|
||||
{
|
||||
virtual ~IObjectRepository() { }
|
||||
|
@ -63,7 +66,7 @@ interface IObjectRepository
|
|||
virtual const ObjectRepositoryItem * FindObject(const utf8 * name) 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,
|
||||
const void * data,
|
||||
size_t dataSize) abstract;
|
||||
|
|
|
@ -187,44 +187,6 @@ bool object_read_and_load_entries(SDL_RWops* rw)
|
|||
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
|
||||
|
|
|
@ -114,16 +114,9 @@ void S6Importer::LoadSavedGame(SDL_RWops *rw)
|
|||
|
||||
// Read packed objects
|
||||
// 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++)
|
||||
{
|
||||
j += object_load_packed(rw);
|
||||
}
|
||||
if (j > 0)
|
||||
{
|
||||
object_list_load();
|
||||
}
|
||||
object_load_packed(rw);
|
||||
}
|
||||
|
||||
sawyercoding_read_chunk_safe(rw, &_s6.objects, sizeof(_s6.objects));
|
||||
|
@ -144,16 +137,9 @@ void S6Importer::LoadScenario(SDL_RWops *rw)
|
|||
|
||||
// Read packed objects
|
||||
// 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++)
|
||||
{
|
||||
j += object_load_packed(rw);
|
||||
}
|
||||
if (j > 0)
|
||||
{
|
||||
object_list_load();
|
||||
}
|
||||
object_load_packed(rw);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
visible_list_dispose();
|
||||
w->selected_list_item = -1;
|
||||
_listItems = malloc(numObjects * sizeof(list_item));
|
||||
_numListItems = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue