diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 0c16ef28cc..e1983c881a 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -194,6 +194,7 @@ uint32 gfx_object_allocate_images(const rct_g1_element * images, uint32 count) void gfx_object_free_images(uint32 baseImageId, uint32 count) { + _nextImageId = 29294; } /** diff --git a/src/localisation/language.cpp b/src/localisation/language.cpp index 70f357c162..bd87a4b628 100644 --- a/src/localisation/language.cpp +++ b/src/localisation/language.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include #include "LanguagePack.h" extern "C" { @@ -455,17 +456,33 @@ bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_s outStringIds[2] != STR_NONE; } -static rct_string_id _nextObjectStringId = NONSTEX_BASE_STRING_ID; +static bool _availableObjectStringIdsInitialised = false; +static std::stack _availableObjectStringIds; rct_string_id language_allocate_object_string(const utf8 * target) { - rct_string_id stringId = _nextObjectStringId++; + if (!_availableObjectStringIdsInitialised) + { + _availableObjectStringIdsInitialised = true; + for (rct_string_id stringId = NONSTEX_BASE_STRING_ID + MAX_OBJECT_CACHED_STRINGS; stringId >= NONSTEX_BASE_STRING_ID; stringId--) + { + _availableObjectStringIds.push(stringId); + } + } + + rct_string_id stringId = _availableObjectStringIds.top(); + _availableObjectStringIds.pop(); _languageCurrent->SetString(stringId, target); return stringId; } void language_free_object_string(rct_string_id stringId) { + if (_languageCurrent != nullptr) + { + _languageCurrent->SetString(stringId, nullptr); + } + _availableObjectStringIds.push(stringId); } } diff --git a/src/object.c b/src/object.c index 225cf5518f..ae0978962c 100644 --- a/src/object.c +++ b/src/object.c @@ -50,131 +50,6 @@ int object_load_entry(const utf8 *path, rct_object_entry *outEntry) return 1; } -int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSize, const rct_object_entry *installedObject) -{ - uint8 objectType; - rct_object_entry openedEntry; - char path[MAX_PATH]; - SDL_RWops* rw; - - substitute_path(path, gRCT2AddressObjectDataPath, (char*)installedObject + 16); - - log_verbose("loading object, %s", path); - - rw = SDL_RWFromFile(path, "rb"); - if (rw == NULL) - return 0; - - SDL_RWread(rw, &openedEntry, sizeof(rct_object_entry), 1); - if (!object_entry_compare(&openedEntry, entry)) { - SDL_RWclose(rw); - return 0; - } - - // Get chunk size - uint8 *installedObject_pointer = (uint8*)installedObject + 16; - // Skip file name - while (*installedObject_pointer++); - - // Read chunk size - *chunkSize = *((uint32*)installedObject_pointer); - uint8 *chunk; - - if (*chunkSize == 0xFFFFFFFF) { - chunk = (uint8*)malloc(0x600000); - assert(chunk != NULL); - *chunkSize = sawyercoding_read_chunk_with_size(rw, chunk, 0x600000); - chunk = realloc(chunk, *chunkSize); - } - else { - chunk = (uint8*)malloc(*chunkSize); - *chunkSize = sawyercoding_read_chunk_with_size(rw, chunk, *chunkSize); - } - SDL_RWclose(rw); - if (chunk == NULL) { - log_error("Failed to load object from %s of size %d", path, *chunkSize); - return 0; - } - - int calculatedChecksum = object_calculate_checksum(&openedEntry, chunk, *chunkSize); - - // Calculate and check checksum - if (calculatedChecksum != openedEntry.checksum && !gConfigGeneral.allow_loading_with_incorrect_checksum) { - log_error("Object Load failed due to checksum failure: calculated checksum %d, object says %d.", calculatedChecksum, (int)openedEntry.checksum); - free(chunk); - return 0; - - } - - objectType = openedEntry.flags & 0x0F; - - if (!object_test(objectType, chunk)) { - log_error("Object Load failed due to paint failure."); - free(chunk); - return 0; - } - - if (gTotalNoImages >= 0x4726E){ - log_error("Object Load failed due to too many images loaded."); - free(chunk); - return 0; - } - - void** chunk_list = object_entry_groups[objectType].chunks; - if (groupIndex == -1) { - for (groupIndex = 0; chunk_list[groupIndex] != (void*)-1; groupIndex++) { - if (groupIndex + 1 >= object_entry_group_counts[objectType]) { - log_error("Object Load failed due to too many objects of a certain type."); - free(chunk); - return 0; - } - } - } - chunk_list[groupIndex] = chunk; - - rct_object_entry_extended* extended_entry = &object_entry_groups[objectType].entries[groupIndex]; - - memcpy(extended_entry, &openedEntry, sizeof(rct_object_entry)); - extended_entry->chunk_size = *chunkSize; - - gLastLoadedObjectChunkData = chunk; - - if (RCT2_GLOBAL(0x9ADAFD, uint8) != 0) { - object_load(objectType, chunk, groupIndex); - } - return 1; -} - -/** - * - * rct2: 0x006A985D - */ -int object_load_chunk_old(int groupIndex, rct_object_entry *entry, int* chunkSize) -{ - // Alow chunkSize to be null - int tempChunkSize; - if (chunkSize == NULL) - chunkSize = &tempChunkSize; - - RCT2_GLOBAL(0xF42B64, uint32) = groupIndex; - - if (gInstalledObjectsCount == 0) { - log_error("Object Load failed due to no items installed check."); - return 1; - } - - rct_object_entry *installedObject = object_list_find(entry); - if (installedObject == NULL) { - log_error("object not installed"); - return 0; - } - - if (object_load_file(groupIndex, entry, chunkSize, installedObject)) - return 1; - - return 0; -} - /** * * rct2: 0x006a9f42 diff --git a/src/object.h b/src/object.h index 3c9b1a3ea2..8f71595450 100644 --- a/src/object.h +++ b/src/object.h @@ -119,7 +119,6 @@ int object_load_packed(SDL_RWops* rw); void object_unload_all(); int check_object_entry(rct_object_entry *entry); -int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSize, const rct_object_entry *installedObject); int object_load_chunk(int groupIndex, rct_object_entry *entry, int* chunk_size); void object_unload_chunk(rct_object_entry *entry); int object_get_scenario_text(rct_object_entry *entry); diff --git a/src/object/LargeSceneryObject.cpp b/src/object/LargeSceneryObject.cpp index 4eb3ccf754..a3c74c8d1b 100644 --- a/src/object/LargeSceneryObject.cpp +++ b/src/object/LargeSceneryObject.cpp @@ -70,6 +70,8 @@ void LargeSceneryObject::Load() _legacyType.name = language_allocate_object_string(GetName()); _legacyType.image = gfx_object_allocate_images(ImageTable.GetImages(), ImageTable.GetCount()); + _legacyType.large_scenery.tiles = _tiles; + _legacyType.large_scenery.scenery_tab_id = 0xFF; if ((_sceneryTabEntry.flags & 0xFF) != 0xFF) { diff --git a/src/object/ObjectRepository.cpp b/src/object/ObjectRepository.cpp index 91d502522e..78a8132cd8 100644 --- a/src/object/ObjectRepository.cpp +++ b/src/object/ObjectRepository.cpp @@ -102,6 +102,21 @@ public: } } + const ObjectRepositoryItem * FindObject(const utf8 * name) override + { + rct_object_entry entry = { 0 }; + utf8 entryName[9] = { ' ' }; + String::Set(entryName, sizeof(entryName), name); + Memory::Copy(entry.name, entryName, 8); + + auto kvp = _itemMap.find(entry); + if (kvp != _itemMap.end()) + { + return &_items[kvp->second]; + } + return nullptr; + } + const ObjectRepositoryItem * FindObject(const rct_object_entry * objectEntry) override { auto kvp = _itemMap.find(*objectEntry); @@ -384,6 +399,20 @@ int GetObjectEntryIndex(uint8 objectType, uint8 entryIndex) extern "C" { + rct_object_entry * object_list_find(rct_object_entry * entry) + { + IObjectRepository * objRepo = GetObjectRepository(); + const ObjectRepositoryItem * item = objRepo->FindObject(entry); + return (rct_object_entry *)&item->ObjectEntry; + } + + rct_object_entry * object_list_find_by_name(const char * name) + { + IObjectRepository * objRepo = GetObjectRepository(); + const ObjectRepositoryItem * item = objRepo->FindObject(name); + return (rct_object_entry *)&item->ObjectEntry; + } + void object_list_load() { IObjectRepository * objRepo = GetObjectRepository(); diff --git a/src/object/ObjectRepository.h b/src/object/ObjectRepository.h index f64b6e6b86..93b10525a6 100644 --- a/src/object/ObjectRepository.h +++ b/src/object/ObjectRepository.h @@ -52,6 +52,7 @@ interface IObjectRepository { virtual ~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; }; diff --git a/src/object_list.c b/src/object_list.c index 967517e92c..ee9b885528 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -30,18 +30,6 @@ #include "world/scenery.h" #include "world/water.h" -#define PLUGIN_VERSION 4 -#define FILTER_VERSION 1 - -typedef struct rct_plugin_header { - uint16 version; - uint32 total_files; - uint32 total_file_size; - uint32 date_modified_checksum; - uint32 object_list_size; - uint32 object_list_no_items; -} rct_plugin_header; - // 98DA00 int object_entry_group_counts[] = { 128, // rides @@ -102,11 +90,6 @@ const rct_object_entry_group object_entry_groups[] = { (void**)(gStexEntries ), (rct_object_entry_extended*)(0x00F3F03C + (720 * 20)) // scenario text 0x009ADAE4, 0xF4287C }; -static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int fileDateModifiedChecksum); -static int object_list_cache_save(int fileCount, uint64 totalFileSize, int fileDateModifiedChecksum, int currentItemOffset); - -void object_list_create_hash_table(); -static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* installed_entry, const char* path, rct_object_filters* filter); static void load_object_filter(rct_object_entry* entry, uint8* chunk, rct_object_filters* filter); static rct_object_filters *_installedObjectFilters = NULL; @@ -120,82 +103,6 @@ uint32 gNumInstalledCustomObjects; void *gLastLoadedObjectChunkData; -static void get_plugin_path(utf8 *outPath) -{ - platform_get_user_directory(outPath, NULL); - strcat(outPath, "plugin.dat"); -} - -static uintptr_t object_get_length_cached(const rct_object_entry **entryCache, const size_t index) -{ - return (uintptr_t)entryCache[index + 1] - (uintptr_t)entryCache[index]; -} - -static rct_object_entry **_entryCache = NULL; - -static int object_comparator(const void *left, const void *right) -{ - const size_t leftIndex = *(const size_t *)left; - const size_t rightIndex = *(const size_t *)right; - const char *leftName = object_get_name(_entryCache[leftIndex]); - const char *rightName = object_get_name(_entryCache[rightIndex]); - return strcmp(leftName, rightName); -} - -static void object_list_sort() -{ - rct_object_entry **objectBuffer, *newBuffer, *entry, *destEntry; - rct_object_filters *newFilters = NULL, *destFilter = NULL; - int numObjects, bufferSize; - size_t entrySize; - - objectBuffer = &gInstalledObjects; - numObjects = gInstalledObjectsCount; - - - _entryCache = malloc((numObjects + 1)* sizeof(rct_object_entry*)); - size_t *sortLUT = malloc((numObjects + 1) * sizeof(size_t)); - entry = *objectBuffer; - // This loop initialises entry cache, so it doesn't have to be called 17M - // times, but only a few thousand. - int i = 0; - do { - _entryCache[i] = entry; - sortLUT[i] = i; - } while (i++ < numObjects && (entry = object_get_next(entry))); - qsort(sortLUT, numObjects, sizeof(size_t), object_comparator); - - // Get buffer size - bufferSize = (uintptr_t)entry - (uintptr_t)*objectBuffer; - - // Create new buffer - newBuffer = (rct_object_entry*)malloc(bufferSize); - destEntry = newBuffer; - if (_installedObjectFilters) { - newFilters = malloc(numObjects * sizeof(rct_object_filters)); - destFilter = newFilters; - } - - // Copy over sorted objects - for (int i = 0; i < numObjects; i++) { - entrySize = object_get_length_cached((const rct_object_entry **)_entryCache, sortLUT[i]); - memcpy(destEntry, _entryCache[sortLUT[i]], entrySize); - destEntry = (rct_object_entry*)((uintptr_t)destEntry + entrySize); - if (_installedObjectFilters) - destFilter[i] = _installedObjectFilters[sortLUT[i]]; - } - free(_entryCache); - free(sortLUT); - - // Replace old buffer - free(*objectBuffer); - *objectBuffer = newBuffer; - if (_installedObjectFilters) { - free(_installedObjectFilters); - _installedObjectFilters = newFilters; - } -} - static uint32 object_list_count_custom_objects() { uint32 numCustomObjects = 0; @@ -218,264 +125,7 @@ static uint32 object_list_count_custom_objects() static void object_list_examine() { object_list_count_custom_objects(); - object_list_sort(); - object_list_create_hash_table(); -} - -/** - * - * rct2: 0x006A9FC0 - */ -void reset_loaded_objects_old() -{ - reset_type_to_ride_entry_index_map(); - - gTotalNoImages = 0xF26E; - - for (int type = 0; type < 11; ++type){ - for (int j = 0; j < object_entry_group_counts[type]; j++){ - uint8* chunk = object_entry_groups[type].chunks[j]; - if (chunk != (uint8*)-1) - object_load(type, chunk, j); - } - } -} - -static int object_list_query_directory(int *outTotalFiles, uint64 *outTotalFileSize, int *outFileDateModifiedChecksum) -{ - int enumFileHandle, totalFiles, fileDateModifiedChecksum; - uint64 totalFileSize; - file_info enumFileInfo; - - totalFiles = 0; - totalFileSize = 0; - fileDateModifiedChecksum = 0; - - // Enumerate through each object in the directory - enumFileHandle = platform_enumerate_files_begin(gRCT2AddressObjectDataPath); - if (enumFileHandle == INVALID_HANDLE) - return 0; - - while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) { - totalFiles++; - totalFileSize += enumFileInfo.size; - fileDateModifiedChecksum ^= - (uint32)(enumFileInfo.last_modified >> 32) ^ - (uint32)(enumFileInfo.last_modified & 0xFFFFFFFF); - fileDateModifiedChecksum = ror32(fileDateModifiedChecksum, 5); - } - platform_enumerate_files_end(enumFileHandle); - - *outTotalFiles = totalFiles; - *outTotalFileSize = totalFileSize; - *outFileDateModifiedChecksum = fileDateModifiedChecksum; - return 1; -} - -/** - * - * rct2: 0x006A8B40 - */ -void object_list_load_old() -{ - int enumFileHandle, totalFiles, fileDateModifiedChecksum; - uint64 totalFileSize; - file_info enumFileInfo; - - int ok = object_list_query_directory(&totalFiles, &totalFileSize, &fileDateModifiedChecksum); - if (ok != 1) { - return; - } - - // Would move this into cache load, but its used further on - totalFiles = ror32(totalFiles, 24); - totalFiles = (totalFiles & ~0xFF) | 1; - totalFiles = rol32(totalFiles, 24); - - if (object_list_cache_load(totalFiles, totalFileSize, fileDateModifiedChecksum)) { - return; - } - - // Dispose installed object list - reset_loaded_objects(); - SafeFree(gInstalledObjects); - - gInstalledObjectsCount = 0; - gInstalledObjects = (rct_object_entry*)malloc(4096); - if (gInstalledObjects == NULL) { - log_error("Failed to allocate memory for object list"); - rct2_exit_reason(835, 3162); - return; - } - - uint32 fileCount = 0; - uint32 objectCount = 0; - size_t currentEntryOffset = 0; - gNumInstalledRCT2Objects = 0; - - log_verbose("building cache of available objects..."); - - if (_installedObjectFilters) { - free(_installedObjectFilters); - _installedObjectFilters = NULL; - } - - enumFileHandle = platform_enumerate_files_begin(gRCT2AddressObjectDataPath); - if (enumFileHandle != INVALID_HANDLE) { - size_t installedObjectsCapacity = 4096; - while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) { - fileCount++; - - if ((installedObjectsCapacity - currentEntryOffset) <= 2842){ - installedObjectsCapacity += 4096; - gInstalledObjects = (rct_object_entry*)realloc(gInstalledObjects, installedObjectsCapacity); - if (gInstalledObjects == NULL) { - log_error("Failed to allocate memory for object list"); - rct2_exit_reason(835, 3162); - return; - } - } - - char path[MAX_PATH]; - substitute_path(path, gRCT2AddressObjectDataPath, enumFileInfo.path); - - rct_object_entry entry; - if (object_load_entry(path, &entry)) { - _installedObjectFilters = realloc(_installedObjectFilters, sizeof(rct_object_filters) * (objectCount + 1)); - - rct_object_entry *installedEntry = (rct_object_entry*)((size_t)gInstalledObjects + currentEntryOffset); - rct_object_filters filter; - size_t newEntrySize = install_object_entry(&entry, installedEntry, enumFileInfo.path, &filter); - if (newEntrySize != 0) { - _installedObjectFilters[objectCount] = filter; - objectCount++; - currentEntryOffset += newEntrySize; - } - } - } - platform_enumerate_files_end(enumFileHandle); - } - - reset_loaded_objects(); - - object_list_cache_save(fileCount, totalFileSize, fileDateModifiedChecksum, currentEntryOffset); - - // Reload track list - ride_list_item ride_list; - ride_list.entry_index = 0xFC; - ride_list.type = 0xFC; - // track_load_list(ride_list); - - object_list_examine(); -} - -static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int fileDateModifiedChecksum) -{ - char path[MAX_PATH]; - SDL_RWops *file; - rct_plugin_header pluginHeader; - uint32 filterVersion = 0; - - log_verbose("loading object list cache (plugin.dat)"); - - get_plugin_path(path); - file = SDL_RWFromFile(path, "rb"); - if (file == NULL) { - log_verbose("Unable to load %s", path); - return 0; - } - - if (SDL_RWread(file, &pluginHeader, sizeof(rct_plugin_header), 1) == 1) { - // Check if object repository has changed in anyway - if ( - pluginHeader.version == PLUGIN_VERSION && - pluginHeader.total_files == totalFiles && - pluginHeader.total_file_size == totalFileSize && - pluginHeader.date_modified_checksum == fileDateModifiedChecksum - ) { - // Dispose installed object list - SafeFree(gInstalledObjects); - - // Read installed object list - gInstalledObjects = (rct_object_entry*)malloc(pluginHeader.object_list_size); - if (SDL_RWread(file, gInstalledObjects, pluginHeader.object_list_size, 1) == 1) { - gInstalledObjectsCount = pluginHeader.object_list_no_items; - - if (pluginHeader.object_list_no_items != (pluginHeader.total_files & 0xFFFFFF)) - log_error("Potential mismatch in file numbers. Possible corrupt file. Consider deleting plugin.dat."); - - if (SDL_RWread(file, &filterVersion, sizeof(filterVersion), 1) == 1) { - if (filterVersion == FILTER_VERSION) { - if (_installedObjectFilters != NULL) { - free(_installedObjectFilters); - } - _installedObjectFilters = malloc(sizeof(rct_object_filters) * pluginHeader.object_list_no_items); - if (SDL_RWread(file, _installedObjectFilters, sizeof(rct_object_filters) * pluginHeader.object_list_no_items, 1) == 1) { - SDL_RWclose(file); - reset_loaded_objects(); - object_list_examine(); - return 1; - } - } - } - log_info("Filter version updated... updating object list cache"); - } - } - else if (pluginHeader.version != PLUGIN_VERSION) { - log_info("Object list cache version different... updating"); - } - else if (pluginHeader.total_files != totalFiles) { - int fileCount = totalFiles - pluginHeader.total_files; - if (fileCount < 0) { - log_info("%d object removed... updating object list cache", abs(fileCount)); - } else { - log_info("%d object added... updating object list cache", fileCount); - } - } else if (pluginHeader.total_file_size != totalFileSize) { - log_info("Objects files size changed... updating object list cache"); - } else if (pluginHeader.date_modified_checksum != fileDateModifiedChecksum) { - log_info("Objects files have been updated... updating object list cache"); - } - - SDL_RWclose(file); - return 0; - } - - SDL_RWclose(file); - - log_error("loading object list cache failed"); - return 0; -} - -static int object_list_cache_save(int fileCount, uint64 totalFileSize, int fileDateModifiedChecksum, int currentItemOffset) -{ - utf8 path[MAX_PATH]; - SDL_RWops *file; - rct_plugin_header pluginHeader; - uint32 filterVersion = FILTER_VERSION; - - log_verbose("saving object list cache (plugin.dat)"); - - pluginHeader.version = PLUGIN_VERSION; - pluginHeader.total_files = fileCount | 0x01000000; - pluginHeader.total_file_size = (uint32)totalFileSize; - pluginHeader.date_modified_checksum = fileDateModifiedChecksum; - pluginHeader.object_list_size = currentItemOffset; - pluginHeader.object_list_no_items = gInstalledObjectsCount; - - get_plugin_path(path); - file = SDL_RWFromFile(path,"wb"); - if (file == NULL) { - log_error("Failed to save %s", path); - return 0; - } - - SDL_RWwrite(file, &pluginHeader, sizeof(rct_plugin_header), 1); - SDL_RWwrite(file, gInstalledObjects, pluginHeader.object_list_size, 1); - SDL_RWwrite(file, &filterVersion, sizeof(filterVersion), 1); - SDL_RWwrite(file, _installedObjectFilters, sizeof(rct_object_filters) * gInstalledObjectsCount, 1); - SDL_RWclose(file); - return 1; + // object_list_sort(); } int check_object_entry(rct_object_entry *entry) @@ -610,72 +260,6 @@ bool object_load_entries(rct_object_entry* entries) return true; } - - -/** - * - * rct2: 0x006A9CE8 - */ -void object_unload_all_old() -{ - int i, j; - - for (i = 0; i < OBJECT_ENTRY_GROUP_COUNT; i++) - for (j = 0; j < object_entry_group_counts[i]; j++) - if (object_entry_groups[i].chunks[j] != (uint8*)0xFFFFFFFF) - object_unload_chunk((rct_object_entry*)&object_entry_groups[i].entries[j]); - - reset_loaded_objects(); -} - - - -uint32 _installedObjectHashTableSize; -rct_object_entry ** _installedObjectHashTable = NULL; - -uint32 _installedObjectHashTableCollisions; - -uint32 object_get_hash_code(rct_object_entry *object) -{ - uint32 hash = 5381; - for (int i = 0; i < 8; i++) - hash = ((hash << 5) + hash) + object->name[i]; - - return hash; -} - -void object_list_create_hash_table() -{ - rct_object_entry *installedObject; - int numInstalledObjects = gInstalledObjectsCount; - - if (_installedObjectHashTable != NULL) - free(_installedObjectHashTable); - - _installedObjectHashTableSize = max(8192, numInstalledObjects * 4); - _installedObjectHashTable = calloc(_installedObjectHashTableSize, sizeof(rct_object_entry*)); - _installedObjectHashTableCollisions = 0; - - installedObject = gInstalledObjects; - for (int i = 0; i < numInstalledObjects; i++) { - uint32 hash = object_get_hash_code(installedObject); - uint32 index = hash % _installedObjectHashTableSize; - - // Find empty slot - while (_installedObjectHashTable[index] != NULL) { - _installedObjectHashTableCollisions++; - index++; - if (index >= _installedObjectHashTableSize) index = 0; - } - - // Set hash table slot - _installedObjectHashTable[index] = installedObject; - - // Next installed object - installedObject = object_get_next(installedObject); - } -} - /** * * rct2: 0x006A9DA2 @@ -701,41 +285,6 @@ int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8 return 1; } -rct_object_entry *object_list_find_by_name(const char * name) -{ - rct_object_entry entry; - memcpy(entry.name, name, 8); - - uint32 hash = object_get_hash_code(&entry); - uint32 index = hash % _installedObjectHashTableSize; - - while (_installedObjectHashTable[index] != NULL) { - if (memcmp(_installedObjectHashTable[index]->name, entry.name, 8) == 0) - return _installedObjectHashTable[index]; - - index++; - if (index >= _installedObjectHashTableSize) index = 0; - } - - return NULL; -} - -rct_object_entry *object_list_find(rct_object_entry *entry) -{ - uint32 hash = object_get_hash_code(entry); - uint32 index = hash % _installedObjectHashTableSize; - - while (_installedObjectHashTable[index] != NULL) { - if (object_entry_compare( _installedObjectHashTable[index], entry)) - return _installedObjectHashTable[index]; - - index++; - if (index >= _installedObjectHashTableSize) index = 0; - } - - return NULL; -} - rct_string_id object_get_name_string_id(rct_object_entry *entry, const void *chunk) { int objectType = entry->flags & 0x0F; @@ -763,111 +312,6 @@ rct_string_id object_get_name_string_id(rct_object_entry *entry, const void *chu } } -/** - * Installs an object_entry at the desired installed_entry address - * Returns the size of the new entry. Will return 0 on failure. - */ -static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* installed_entry, const char* path, rct_object_filters* filter){ - uint8* installed_entry_pointer = (uint8*) installed_entry; - - /** Copy all known information into the install entry **/ - memcpy(installed_entry_pointer, entry, sizeof(rct_object_entry)); - installed_entry_pointer += sizeof(rct_object_entry); - - strcpy((char *)installed_entry_pointer, path); - while (*installed_entry_pointer++); - - // Chunk size is set to unknown - *((sint32*)installed_entry_pointer) = -1; - // No unknown objects set to 0 - *(installed_entry_pointer + 4) = 0; - // No theme objects set to 0 - *((sint32*)(installed_entry_pointer + 5)) = 0; - *((uint16*)(installed_entry_pointer + 9)) = 0; - *((uint32*)(installed_entry_pointer + 11)) = 0; - - gTotalNoImages = 0xF26E; - - gInstalledObjectsCount++; - - // This is a variable used by object_load to decide if it should - // use object_paint on the entry. - RCT2_GLOBAL(0x009ADAFD, uint8) = 1; - - // Probably used by object paint. - RCT2_GLOBAL(0x009ADAF4, uint32) = 0xF42BDB; - - /** Use object_load_file to fill in missing chunk information **/ - int chunk_size; - if (!object_load_file(-1, entry, &chunk_size, installed_entry)){ - log_error("Object Load File failed. Potentially corrupt file: %.8s", entry->name); - RCT2_GLOBAL(0x009ADAF4, sint32) = -1; - RCT2_GLOBAL(0x009ADAFD, uint8) = 0; - gInstalledObjectsCount--; - return 0; - } - - // See above note - RCT2_GLOBAL(0x009ADAF4, sint32) = -1; - RCT2_GLOBAL(0x009ADAFD, uint8) = 0; - - if ((entry->flags & 0xF0) == 0x80) { - gNumInstalledRCT2Objects++; - if (gNumInstalledRCT2Objects > 772){ - log_error("Incorrect number of vanilla RCT2 objects."); - gNumInstalledRCT2Objects--; - gInstalledObjectsCount--; - object_unload_chunk(entry); - return 0; - } - } - *((sint32*)installed_entry_pointer) = chunk_size; - installed_entry_pointer += 4; - - uint8* chunk = (uint8*)gLastLoadedObjectChunkData; // Loaded in object_load - - load_object_filter(entry, chunk, filter); - - // Always extract only the vehicle type, since the track type is always displayed in the left column, to prevent duplicate track names. - rct_string_id nameStringId = object_get_name_string_id(entry, chunk); - if (nameStringId == STR_NONE) { - nameStringId = (rct_string_id)RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID, uint32); - } - - strcpy((char *)installed_entry_pointer, language_get_string(nameStringId)); - while (*installed_entry_pointer++); - - // This is deceptive. Due to setting the total no images earlier to 0xF26E - // this is actually the no_images in this entry. - *((uint32*)installed_entry_pointer) = gTotalNoImages - 0xF26E; - installed_entry_pointer += 4; - - uint8* esi = RCT2_ADDRESS(0x00F42BDB, uint8); - uint8 num_unk_objects = *esi++; - *installed_entry_pointer++ = num_unk_objects; - if (num_unk_objects > 0) { - memcpy(installed_entry_pointer, esi, num_unk_objects * sizeof(rct_object_entry)); - installed_entry_pointer += num_unk_objects * sizeof(rct_object_entry); - esi += num_unk_objects * sizeof(rct_object_entry); - } - - uint8 no_theme_objects = *esi++; - *installed_entry_pointer++ = no_theme_objects; - if (no_theme_objects > 0) { - memcpy(installed_entry_pointer, esi, no_theme_objects * sizeof(rct_object_entry)); - installed_entry_pointer += no_theme_objects * sizeof(rct_object_entry); - } - - *((uint32*)installed_entry_pointer) = RCT2_GLOBAL(0x00F433DD, uint32); - installed_entry_pointer += 4; - - uint32 size_of_object = installed_entry_pointer - (uint8*)installed_entry; - - object_unload_chunk(entry); - - return size_of_object; -} - static void load_object_filter(rct_object_entry* entry, uint8* chunk, rct_object_filters* filter) { rct_ride_entry *rideType;