prepare for better object loading

This commit is contained in:
Ted John 2016-07-03 21:05:18 +01:00
parent 4e259920b1
commit e8635c1307
5 changed files with 108 additions and 98 deletions

View File

@ -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);
object->Load();
const ObjectRepositoryItem * ori = objRepository->FindObject(objectEntry);
if (ori != nullptr)
{
object = objRepository->LoadObject(ori);
if (object != nullptr)
{
object->Load();
}
}
return (void *)object;
}
@ -730,18 +784,22 @@ extern "C"
// Checks for a scenario string object (possibly for localisation)
if ((stexObjectEntry->flags & 0xFF) != 255)
{
IObjectRepository * objRepo = GetObjectRepository();
Object * object = objRepo->LoadObject(stexObjectEntry);
if (object != nullptr)
IObjectRepository * objectRepository = GetObjectRepository();
const ObjectRepositoryItem * ori = objectRepository->FindObject(stexObjectEntry);
if (ori != nullptr)
{
StexObject * stexObject = static_cast<StexObject*>(object);
const utf8 * scenarioName = stexObject->GetScenarioName();
const utf8 * scenarioDetails = stexObject->GetScenarioDetails();
Object * object = objectRepository->LoadObject(ori);
if (object != nullptr)
{
StexObject * stexObject = static_cast<StexObject*>(object);
const utf8 * scenarioName = stexObject->GetScenarioName();
const utf8 * scenarioDetails = stexObject->GetScenarioDetails();
String::Set(scenarioEntry->name, sizeof(scenarioEntry->name), scenarioName);
String::Set(scenarioEntry->details, sizeof(scenarioEntry->details), scenarioDetails);
String::Set(scenarioEntry->name, sizeof(scenarioEntry->name), scenarioName);
String::Set(scenarioEntry->details, sizeof(scenarioEntry->details), scenarioDetails);
delete object;
delete object;
}
}
}
}

View File

@ -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;

View File

@ -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

View File

@ -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();
}
for (uint16 i = 0; i < _s6.header.num_packed_objects; i++)
{
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();
}
for (uint16 i = 0; i < _s6.header.num_packed_objects; i++)
{
object_load_packed(rw);
}
sawyercoding_read_chunk_safe(rw, &_s6.objects, sizeof(_s6.objects));

View File

@ -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;