mirror of https://github.com/OpenRCT2/OpenRCT2.git
More refactoring of object.c
This commit is contained in:
parent
e7db42f0fe
commit
ddcf766fea
|
@ -130,11 +130,23 @@
|
|||
|
||||
#define RCT2_ADDRESS_RIDE_ENTRIES 0x009ACFA4
|
||||
|
||||
|
||||
|
||||
#define RCT2_ADDRESS_SMALL_SCENERY_ENTRIES 0x009AD1A4
|
||||
#define RCT2_ADDRESS_LARGE_SCENERY_ENTRIES 0x009AD594
|
||||
#define RCT2_ADDRESS_WALL_SCENERY_ENTRIES 0x009AD794
|
||||
#define RCT2_ADDRESS_BANNER_SCENERY_ENTRIES 0x009AD994
|
||||
#define RCT2_ADDRESS_PATH_TYPES 0x009ADA14
|
||||
#define RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES 0x009ADA54
|
||||
#define RCT2_ADDRESS_SCENERY_SET_ENTRIES 0x009ADA90
|
||||
|
||||
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
|
||||
#define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC
|
||||
|
||||
#define RCT2_ADDRESS_TOTAL_NO_IMAGES 0x009ADAF0
|
||||
|
||||
#define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK 0x009ADAF8
|
||||
|
||||
|
||||
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
|
||||
|
||||
#define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288
|
||||
|
@ -219,15 +231,6 @@
|
|||
|
||||
#define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28
|
||||
|
||||
#define RCT2_ADDRESS_PATH_TYPES 0x009ADA14
|
||||
|
||||
#define RCT2_ADDRESS_SMALL_SCENERY_ENTRIES 0x009AD1A4
|
||||
#define RCT2_ADDRESS_LARGE_SCENERY_ENTRIES 0x009AD594
|
||||
#define RCT2_ADDRESS_WALL_SCENERY_ENTRIES 0x009AD794
|
||||
#define RCT2_ADDRESS_BANNER_SCENERY_ENTRIES 0x009AD994
|
||||
#define RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES 0x009ADA54
|
||||
#define RCT2_ADDRESS_SCENERY_SET_ENTRIES 0x009ADA90
|
||||
|
||||
//Every pixel changed by rain is stored.
|
||||
//32bit (pixel_offset 24 bit)(pixel_colour 8 bit)
|
||||
//Use the rainPixels[] global in drawing.c from now on
|
||||
|
@ -263,6 +266,8 @@
|
|||
#define RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID 0x00F42BBC
|
||||
#define RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER 0x00F42BC0
|
||||
|
||||
#define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT 0x00F42BC8
|
||||
|
||||
#define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC
|
||||
|
||||
#define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908
|
||||
|
|
10
src/editor.c
10
src/editor.c
|
@ -152,8 +152,9 @@ void editor_convert_save_to_scenario()
|
|||
s6Info->objective_arg_3 = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, sint16);
|
||||
climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8));
|
||||
|
||||
if (RCT2_GLOBAL(0x009ADAE4, uint32) != 0xFFFFFFFF) {
|
||||
object_unload(0, (rct_object_entry_extended*)0x00F4287C);
|
||||
rct_stex_entry* stex = g_stexEntries[0];
|
||||
if ((int)stex != 0xFFFFFFFF) {
|
||||
object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]);
|
||||
//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
|
||||
sub_6A9FC0();
|
||||
|
||||
|
@ -911,8 +912,9 @@ static int editor_read_s6(const char *path)
|
|||
|
||||
climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8));
|
||||
|
||||
if (RCT2_GLOBAL(0x009ADAE4, uint32) != 0xFFFFFFFF) {
|
||||
object_unload(0, (rct_object_entry_extended*)0x00F4287C);
|
||||
rct_stex_entry* stex = g_stexEntries[0];
|
||||
if ((int)stex != 0xFFFFFFFF) {
|
||||
object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]);
|
||||
sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
|
||||
|
||||
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
|
||||
|
|
230
src/object.c
230
src/object.c
|
@ -175,12 +175,14 @@ int object_load(int groupIndex, rct_object_entry *entry, int* chunkSize)
|
|||
* ebx : file
|
||||
* ebp : entry
|
||||
*/
|
||||
int sub_6A9F42(FILE *file, rct_object_entry* entry){
|
||||
int write_object_file(FILE *file, rct_object_entry* entry){
|
||||
uint8 entryGroupIndex = 0, type = 0;
|
||||
uint8* chunk = 0;
|
||||
|
||||
if (!find_object_in_entry_group(entry, &type, &entryGroupIndex))return 0;
|
||||
|
||||
chunk = object_entry_groups[type].chunks[entryGroupIndex];
|
||||
|
||||
object_paint(type, 1, entryGroupIndex, type, 0, (int)chunk, 0, 0);
|
||||
|
||||
rct_object_entry_extended* installed_entry = &object_entry_groups[type].entries[entryGroupIndex];
|
||||
|
@ -211,35 +213,39 @@ int object_load_packed(FILE *file)
|
|||
{
|
||||
object_unload_all();
|
||||
|
||||
rct_object_entry* entry = RCT2_ADDRESS(0xF42B84, rct_object_entry);
|
||||
rct_object_entry entry;
|
||||
|
||||
fread((void*)entry, 16, 1, file);
|
||||
fread(&entry, 16, 1, file);
|
||||
|
||||
uint8* chunk = rct2_malloc(0x600000);
|
||||
uint32 chunkSize = sawyercoding_read_chunk(file, chunk);
|
||||
chunk = rct2_realloc(chunk, chunkSize);
|
||||
|
||||
if (chunk == NULL){
|
||||
log_error("Failed to allocate memory for packed object.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (object_calculate_checksum(entry, chunk, chunkSize) != entry->checksum){
|
||||
if (object_calculate_checksum(&entry, chunk, chunkSize) != entry.checksum){
|
||||
log_error("Checksum missmatch from packed object: %.8s", entry.name);
|
||||
rct2_free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (object_paint(entry->flags & 0x0F, 2, 0, entry->flags & 0x0F, 0, (int)chunk, 0, 0)) {
|
||||
int type = entry.flags & 0x0F;
|
||||
|
||||
if (object_paint(type, 2, 0, type, 0, (int)chunk, 0, 0)) {
|
||||
log_error("Packed object failed paint test.");
|
||||
rct2_free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) >= 0x4726E){
|
||||
log_error("Packed object has too many images.");
|
||||
rct2_free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int type = entry->flags & 0x0F;
|
||||
|
||||
// ecx
|
||||
int entryGroupIndex = 0;
|
||||
|
||||
for (; entryGroupIndex < object_entry_group_counts[type]; entryGroupIndex++){
|
||||
|
@ -249,21 +255,24 @@ int object_load_packed(FILE *file)
|
|||
}
|
||||
|
||||
if (entryGroupIndex == object_entry_group_counts[type]){
|
||||
// This should never occur. Objects are not loaded before installing a
|
||||
// packed object. So there is only one object loaded at this point.
|
||||
log_error("Too many objects of the same type loaded.");
|
||||
rct2_free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copy the entry into the relevant entry group.
|
||||
object_entry_groups[type].chunks[entryGroupIndex] = chunk;
|
||||
rct_object_entry_extended* edx = &object_entry_groups[type].entries[entryGroupIndex];
|
||||
memcpy(edx, (int*)entry, sizeof(rct_object_entry));
|
||||
edx->chunk_size = chunkSize;
|
||||
rct_object_entry_extended* extended_entry = &object_entry_groups[type].entries[entryGroupIndex];
|
||||
memcpy(extended_entry, &entry, sizeof(rct_object_entry));
|
||||
extended_entry->chunk_size = chunkSize;
|
||||
|
||||
//esi
|
||||
// Ensure the entry does not already exist.
|
||||
rct_object_entry *installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)){
|
||||
for (uint32 i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); ++i){
|
||||
if (object_entry_compare(entry, installedObject)){
|
||||
if (object_entry_compare(&entry, installedObject)){
|
||||
object_unload_all();
|
||||
return 0;
|
||||
}
|
||||
|
@ -271,24 +280,23 @@ int object_load_packed(FILE *file)
|
|||
}
|
||||
}
|
||||
|
||||
//Installing new data
|
||||
//format_string(0x141ED68, 3163, 0);
|
||||
//Code for updating progress bar removed.
|
||||
|
||||
// Convert the entry name to a upper case path name
|
||||
char path[260];
|
||||
char objectPath[13] = { 0 };
|
||||
char objectPath[9] = { 0 };
|
||||
for (int i = 0; i < 8; ++i){
|
||||
if (entry->name[i] != ' ')
|
||||
objectPath[i] = toupper(entry->name[i]);
|
||||
if (entry.name[i] != ' ')
|
||||
objectPath[i] = toupper(entry.name[i]);
|
||||
else
|
||||
objectPath[i] = '\0';
|
||||
}
|
||||
|
||||
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath);
|
||||
// Require pointer to start of filename
|
||||
char* last_char = path + strlen(path);
|
||||
strcat(path, ".DAT");
|
||||
|
||||
//
|
||||
// Check that file does not exist
|
||||
// Adjust filename if it does.
|
||||
for (; platform_file_exists(path);){
|
||||
for (char* curr_char = last_char - 1;; --curr_char){
|
||||
if (*curr_char == '\\'){
|
||||
|
@ -304,30 +312,19 @@ int object_load_packed(FILE *file)
|
|||
}
|
||||
}
|
||||
|
||||
// Removed progress bar code
|
||||
|
||||
// The following section cannot be finished until 6A9F42 is finished
|
||||
// Run the game once with vanila rct2 to not reach this part of code.
|
||||
log_verbose("Function might not be finished.");
|
||||
// Actually write the object to the file
|
||||
FILE* obj_file = fopen(path, "wb");
|
||||
if (obj_file){
|
||||
// Removed progress bar code
|
||||
sub_6A9F42(obj_file, entry);
|
||||
uint8 result = write_object_file(obj_file, &entry);
|
||||
|
||||
fclose(obj_file);
|
||||
// Removed progress bar code
|
||||
object_unload_all();
|
||||
// Removed progress bar code
|
||||
return 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
else{
|
||||
object_unload_all();
|
||||
return 0;
|
||||
}
|
||||
//create file
|
||||
//6aa48C
|
||||
int eax = 1;//, ebx = 0, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0;
|
||||
//RCT2_CALLFUNC_X(0x006AA2B7, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return 1;
|
||||
|
||||
object_unload_all();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,6 +338,7 @@ void object_unload(int groupIndex, rct_object_entry_extended *entry)
|
|||
|
||||
int object_entry_compare(const rct_object_entry *a, const rct_object_entry *b)
|
||||
{
|
||||
// If an official object don't bother checking checksum
|
||||
if (a->flags & 0xF0) {
|
||||
if ((a->flags & 0x0F) != (b->flags & 0x0F))
|
||||
return 0;
|
||||
|
@ -1501,73 +1499,89 @@ int object_get_scenario_text(rct_object_entry *entry)
|
|||
{
|
||||
// RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry); return;
|
||||
|
||||
int i;
|
||||
rct_object_entry *installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
|
||||
for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32); i++) {
|
||||
if (object_entry_compare(installedObject, entry)) {
|
||||
char path[260];
|
||||
char *objectPath = (char*)installedObject + 16;
|
||||
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath);
|
||||
|
||||
rct_object_entry openedEntry;
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (file != NULL) {
|
||||
fread(&openedEntry, sizeof(rct_object_entry), 1, file);
|
||||
if (object_entry_compare(&openedEntry, entry)) {
|
||||
|
||||
// Get chunk size
|
||||
char *pos = (char*)installedObject + 16;
|
||||
// Skip file name
|
||||
while (*pos++);
|
||||
|
||||
// Read chunk
|
||||
int chunkSize = *((uint32*)pos);
|
||||
char *chunk;
|
||||
if (chunkSize == 0xFFFFFFFF) {
|
||||
chunk = malloc(0x600000);
|
||||
chunkSize = sawyercoding_read_chunk(file, chunk);
|
||||
chunk = realloc(chunk, chunkSize);
|
||||
}
|
||||
else {
|
||||
chunk = malloc(chunkSize);
|
||||
sawyercoding_read_chunk(file, chunk);
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
// Calculate and check checksum
|
||||
if (object_calculate_checksum(&openedEntry, chunk, chunkSize) != openedEntry.checksum) {
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 2;
|
||||
free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (object_paint(openedEntry.flags & 0x0F, 2, 0, 0, 0, (int)chunk, 0, 0)) {
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 3;
|
||||
free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int total_no_images = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32);
|
||||
// This is being changed to force the images to be loaded into a different
|
||||
// image id.
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0x726E;
|
||||
RCT2_GLOBAL(0x009ADAF8, uint32) = (int)chunk;
|
||||
*((rct_object_entry*)0x00F42BC8) = openedEntry;
|
||||
|
||||
RCT2_GLOBAL(0x009ADAFC, uint8) = 255;
|
||||
RCT2_GLOBAL(0x009ADAFD, uint8) = 1;
|
||||
object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0);
|
||||
RCT2_GLOBAL(0x009ADAFC, uint8) = 0;
|
||||
RCT2_GLOBAL(0x009ADAFD, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = total_no_images;
|
||||
return 1;
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
installedObject = object_get_next(installedObject);
|
||||
installedObject = object_list_find(entry);
|
||||
|
||||
if (installedObject == NULL){
|
||||
log_error("Object not found: %.8s", entry->name);
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char path[260];
|
||||
char *objectPath = (char*)installedObject + 16;
|
||||
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath);
|
||||
|
||||
rct_object_entry openedEntry;
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (file != NULL) {
|
||||
fread(&openedEntry, sizeof(rct_object_entry), 1, file);
|
||||
if (object_entry_compare(&openedEntry, entry)) {
|
||||
|
||||
// Skip over the object entry
|
||||
char *pos = (char*)installedObject + sizeof(rct_object_entry);
|
||||
// Skip file name
|
||||
while (*pos++);
|
||||
|
||||
// Read chunk
|
||||
int chunkSize = *((uint32*)pos);
|
||||
|
||||
char *chunk;
|
||||
if (chunkSize == 0xFFFFFFFF) {
|
||||
chunk = malloc(0x600000);
|
||||
chunkSize = sawyercoding_read_chunk(file, chunk);
|
||||
chunk = realloc(chunk, chunkSize);
|
||||
}
|
||||
else {
|
||||
chunk = malloc(chunkSize);
|
||||
sawyercoding_read_chunk(file, chunk);
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
// Calculate and check checksum
|
||||
if (object_calculate_checksum(&openedEntry, chunk, chunkSize) != openedEntry.checksum) {
|
||||
log_error("Opened object failed calculated checksum.");
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 2;
|
||||
free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (object_paint(openedEntry.flags & 0x0F, 2, 0, 0, 0, (int)chunk, 0, 0)) {
|
||||
// This is impossible for STEX entries to fail.
|
||||
log_error("Opened object failed paitn test.");
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 3;
|
||||
free(chunk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Save the real total images.
|
||||
int total_no_images = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32);
|
||||
|
||||
// This is being changed to force the images to be loaded into a different
|
||||
// image id.
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0x726E;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, uint32) = (int)chunk;
|
||||
// Not used anywhere.
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT, rct_object_entry) = openedEntry;
|
||||
|
||||
// Tell text to be loaded into a different address
|
||||
RCT2_GLOBAL(0x009ADAFC, uint8) = 255;
|
||||
// Not used??
|
||||
RCT2_GLOBAL(0x009ADAFD, uint8) = 1;
|
||||
object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0);
|
||||
// Tell text to be loaded into normal address
|
||||
RCT2_GLOBAL(0x009ADAFC, uint8) = 0;
|
||||
// Not used??
|
||||
RCT2_GLOBAL(0x009ADAFD, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = total_no_images;
|
||||
return 1;
|
||||
}
|
||||
log_error("Opened object didn't match.");
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
log_error("File failed to open.");
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1578,9 +1592,9 @@ int object_get_scenario_text(rct_object_entry *entry)
|
|||
*/
|
||||
void object_free_scenario_text()
|
||||
{
|
||||
if (RCT2_GLOBAL(0x009ADAF8, void*) != NULL) {
|
||||
rct2_free(RCT2_GLOBAL(0x009ADAF8, void*));
|
||||
RCT2_GLOBAL(0x009ADAF8, void*) = NULL;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, void*) != NULL) {
|
||||
rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, void*));
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, void*) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1630,7 +1644,7 @@ char *object_get_name(rct_object_entry *entry)
|
|||
// Skip filename
|
||||
while (*pos++);
|
||||
|
||||
// Skip
|
||||
// Skip no of images
|
||||
pos += 4;
|
||||
|
||||
return pos;
|
||||
|
|
|
@ -86,7 +86,7 @@ int object_entry_compare(const rct_object_entry *a, const rct_object_entry *b);
|
|||
int object_calculate_checksum(const rct_object_entry *entry, const char *data, int dataLength);
|
||||
int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);
|
||||
rct_object_entry *object_get_next(rct_object_entry *entry);
|
||||
int sub_6A9F42(FILE *file, rct_object_entry* entry);
|
||||
int write_object_file(FILE *file, rct_object_entry* entry);
|
||||
void sub_6A9FC0();
|
||||
int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index);
|
||||
|
||||
|
|
|
@ -69,16 +69,16 @@ int object_entry_group_encoding[] = {
|
|||
// 0x98D97C chunk address', 0x98D980 object_entries
|
||||
rct_object_entry_group object_entry_groups[] = {
|
||||
(uint8**)(0x009ACFA4 ), (rct_object_entry_extended*)(0x00F3F03C ), // rides
|
||||
(uint8**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // small scenery
|
||||
(uint8**)(0x009ACFA4 + (380 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (380 * 20)), // large scenery
|
||||
(uint8**)(0x009ACFA4 + (508 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (508 * 20)), // walls
|
||||
(uint8**)(0x009ACFA4 + (636 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (636 * 20)), // banners
|
||||
(uint8**)(0x009ACFA4 + (668 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (668 * 20)), // paths
|
||||
(uint8**)(0x009ACFA4 + (684 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (684 * 20)), // path bits
|
||||
(uint8**)(0x009ACFA4 + (699 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (699 * 20)), // scenery sets
|
||||
(uint8**)(0x009ACFA4 + (718 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (718 * 20)), // park entrance
|
||||
(uint8**)(0x009ACFA4 + (719 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (719 * 20)), // water
|
||||
(uint8**)(0x009ACFA4 + (720 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (720 * 20)) // scenario text
|
||||
(uint8**)(0x009ACFA4 + (128 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (128 * 20)), // small scenery 0x009AD1A4, 0xF2FA3C
|
||||
(uint8**)(0x009ACFA4 + (380 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (380 * 20)), // large scenery 0x009AD594, 0xF40DEC
|
||||
(uint8**)(0x009ACFA4 + (508 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (508 * 20)), // walls 0x009AD794, 0xF417EC
|
||||
(uint8**)(0x009ACFA4 + (636 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (636 * 20)), // banners 0x009AD994, 0xF421EC
|
||||
(uint8**)(0x009ACFA4 + (668 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (668 * 20)), // paths 0x009ADA14, 0xF4246C
|
||||
(uint8**)(0x009ACFA4 + (684 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (684 * 20)), // path bits 0x009ADA54, 0xF425AC
|
||||
(uint8**)(0x009ACFA4 + (699 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (699 * 20)), // scenery sets 0x009ADA90, 0xF426D8
|
||||
(uint8**)(0x009ACFA4 + (718 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (718 * 20)), // park entrance 0x009ADADC, 0xF42854
|
||||
(uint8**)(0x009ACFA4 + (719 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (719 * 20)), // water 0x009ADAE0, 0xF42868
|
||||
(uint8**)(0x009ACFA4 + (720 * 4)), (rct_object_entry_extended*)(0x00F3F03C + (720 * 20)) // scenario text 0x009ADAE4, 0xF4287C
|
||||
};
|
||||
|
||||
static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int fileDateModifiedChecksum);
|
||||
|
|
|
@ -69,10 +69,10 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in
|
|||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((info->entry.flags & 0xFF) != 255) {
|
||||
if (object_get_scenario_text(&info->entry)) {
|
||||
int ebp = RCT2_GLOBAL(0x009ADAF8, uint32);
|
||||
format_string(info->name, RCT2_GLOBAL(ebp, sint16), NULL);
|
||||
format_string(info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
|
||||
RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8);
|
||||
rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
|
||||
format_string(info->name, stex_entry->scenario_name, NULL);
|
||||
format_string(info->details, stex_entry->details, NULL);
|
||||
RCT2_GLOBAL(0x009AA00C, uint8) = stex_entry->var_06;
|
||||
object_free_scenario_text();
|
||||
}
|
||||
}
|
||||
|
@ -274,11 +274,10 @@ int scenario_load_and_play_from_path(const char *path)
|
|||
strcpy((char*)RCT2_ADDRESS_SCENARIO_DETAILS, s6Info->details);
|
||||
strcpy((char*)RCT2_ADDRESS_SCENARIO_NAME, s6Info->name);
|
||||
|
||||
if (RCT2_GLOBAL(0x009ADAE4, sint32) != -1) {
|
||||
char *ebp = RCT2_GLOBAL(0x009ADAE4, char*);
|
||||
|
||||
rct_stex_entry* stex = g_stexEntries[0];
|
||||
if ((int)stex != -1) {
|
||||
//
|
||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, RCT2_GLOBAL(ebp + 2, uint16), 0);
|
||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, stex->park_name, 0);
|
||||
|
||||
// Set park name
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = STR_CANT_RENAME_PARK;
|
||||
|
@ -293,12 +292,12 @@ int scenario_load_and_play_from_path(const char *path)
|
|||
*((int*)(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER + 28)));
|
||||
|
||||
//
|
||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, RCT2_GLOBAL(ebp + 0, uint16), 0);
|
||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, stex->scenario_name, 0);
|
||||
strncpy((char*)RCT2_ADDRESS_SCENARIO_NAME, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, 31);
|
||||
((char*)RCT2_ADDRESS_SCENARIO_NAME)[31] = '\0';
|
||||
|
||||
// Set scenario details
|
||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, RCT2_GLOBAL(ebp + 4, uint16), 0);
|
||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, stex->details, 0);
|
||||
strncpy((char*)RCT2_ADDRESS_SCENARIO_DETAILS, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, 255);
|
||||
((char*)RCT2_ADDRESS_SCENARIO_DETAILS)[255] = '\0';
|
||||
}
|
||||
|
@ -840,11 +839,12 @@ int scenario_prepare_for_save()
|
|||
|
||||
s6Info->entry.flags = 255;
|
||||
|
||||
char *stex = RCT2_GLOBAL(0x009ADAE4, char*);
|
||||
if (stex != (char*)0xFFFFFFFF) {
|
||||
format_string(buffer, RCT2_GLOBAL(stex, uint16), NULL);
|
||||
rct_stex_entry* stex = g_stexEntries[0];
|
||||
if ((int)stex != 0xFFFFFFFF) {
|
||||
format_string(buffer, stex->scenario_name, NULL);
|
||||
strncpy(s6Info->name, buffer, sizeof(s6Info->name));
|
||||
s6Info->entry = *((rct_object_entry*)0x00F4287C);
|
||||
|
||||
memcpy(&s6Info->entry, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0], sizeof(rct_object_entry));
|
||||
}
|
||||
|
||||
if (s6Info->name[0] == 0)
|
||||
|
@ -894,7 +894,7 @@ int scenario_write_packed_objects(FILE *file)
|
|||
if (RCT2_ADDRESS(0x009ACFA4, uint32)[i] == 0xFFFFFFFF || (entry->flags & 0xF0))
|
||||
continue;
|
||||
|
||||
if (!sub_6A9F42(file, (rct_object_entry*)entry))
|
||||
if (!write_object_file(file, (rct_object_entry*)entry))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,11 +84,14 @@ typedef struct {
|
|||
} rct_scenario_basic;
|
||||
|
||||
typedef struct {
|
||||
rct_string_id scenario_name;
|
||||
rct_string_id park_name;
|
||||
rct_string_id details;
|
||||
rct_string_id scenario_name; // 0x00
|
||||
rct_string_id park_name; // 0x02
|
||||
rct_string_id details; // 0x04
|
||||
uint8 var_06;
|
||||
} rct_stex_entry;
|
||||
|
||||
#define g_stexEntries ((rct_stex_entry**)object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].chunks)
|
||||
|
||||
/* This will be useful for backwards compatibility
|
||||
typedef struct {
|
||||
// SC6[0]
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../localisation/localisation.h"
|
||||
#include "../object.h"
|
||||
#include "../ride/track.h"
|
||||
#include "../scenario.h"
|
||||
#include "error.h"
|
||||
|
||||
enum {
|
||||
|
@ -571,7 +572,9 @@ static void window_editor_object_selection_paint()
|
|||
gfx_draw_string_left(dpi, 3164, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, x, y);
|
||||
}
|
||||
|
||||
if (w->selected_list_item == -1 || RCT2_GLOBAL(0x009ADAF8, sint32) == -1)
|
||||
rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
|
||||
|
||||
if (w->selected_list_item == -1 || stex_entry == NULL)
|
||||
return;
|
||||
|
||||
highlightedEntry = (rct_object_entry*)w->var_494;
|
||||
|
@ -581,7 +584,7 @@ static void window_editor_object_selection_paint()
|
|||
widget = &w->widgets[WIDX_PREVIEW];
|
||||
x = w->x + (widget->left + widget->right) / 2 + 1;
|
||||
y = w->y + (widget->top + widget->bottom) / 2 + 1;
|
||||
object_paint(type, 3, type, x, y, 0, (int)dpi, RCT2_GLOBAL(0x009ADAF8, sint32));
|
||||
object_paint(type, 3, type, x, y, 0, (int)dpi, (int)stex_entry);
|
||||
|
||||
// Draw name of object
|
||||
x = w->x + (widget->left + widget->right) / 2 + 1;
|
||||
|
@ -629,7 +632,7 @@ static void window_editor_object_selection_paint()
|
|||
// Draw description of object
|
||||
x = w->x + w->widgets[WIDX_LIST].right + 4;
|
||||
y += 15;
|
||||
object_paint(type, 259, type, x, y, (int)w, (int)dpi, RCT2_GLOBAL(0x009ADAF8, sint32));
|
||||
object_paint(type, 259, type, x, y, (int)w, (int)dpi, (int)stex_entry);
|
||||
|
||||
// Draw object dat name
|
||||
strcpy(stringBuffer, datName);
|
||||
|
|
|
@ -835,7 +835,7 @@ static void window_editor_objective_options_main_invalidate()
|
|||
|
||||
window_get_register(w);
|
||||
|
||||
stex = RCT2_GLOBAL(0x009ADAE4, rct_stex_entry*);
|
||||
stex = g_stexEntries[0];
|
||||
if (stex == (rct_stex_entry*)0xFFFFFFFF)
|
||||
stex = NULL;
|
||||
|
||||
|
@ -920,7 +920,7 @@ static void window_editor_objective_options_main_paint()
|
|||
window_draw_widgets(w, dpi);
|
||||
window_editor_objective_options_draw_tab_images(w, dpi);
|
||||
|
||||
stex = RCT2_GLOBAL(0x009ADAE4, rct_stex_entry*);
|
||||
stex = g_stexEntries[0];
|
||||
if (stex == (rct_stex_entry*)0xFFFFFFFF)
|
||||
stex = NULL;
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ static void window_footpath_dropdown()
|
|||
|
||||
j = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[i];
|
||||
pathType = g_pathTypeEntries[i];
|
||||
if (pathType == (rct_path_type*)-1)
|
||||
continue;
|
||||
if (pathType->flags & flags)
|
||||
|
@ -533,7 +533,7 @@ static void window_footpath_invalidate()
|
|||
|
||||
// Set footpath and queue type button images
|
||||
selectedPath = RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint16);
|
||||
pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[selectedPath];
|
||||
pathType = g_pathTypeEntries[selectedPath];
|
||||
|
||||
int pathImage = 71 + pathType->image;
|
||||
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
||||
|
@ -570,7 +570,7 @@ static void window_footpath_paint()
|
|||
image = RCT2_ADDRESS(0x0098D7E0, uint8)[image];
|
||||
|
||||
selectedPath = RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint16);
|
||||
pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[selectedPath];
|
||||
pathType = g_pathTypeEntries[selectedPath];
|
||||
image += pathType->image;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_TYPE, uint8) != SELECTED_PATH_TYPE_NORMAL)
|
||||
image += 51;
|
||||
|
@ -609,7 +609,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window *w, rct_widget
|
|||
flags = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
pathType = RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_path_type*)[i];
|
||||
pathType = g_pathTypeEntries[i];
|
||||
if (pathType == (rct_path_type*)-1)
|
||||
continue;
|
||||
if (pathType->flags & flags)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "../common.h"
|
||||
#include "../interface/viewport.h"
|
||||
#include "../object.h"
|
||||
|
||||
enum {
|
||||
PROVISIONAL_PATH_FLAG_SHOW_ARROW = (1 << 0)
|
||||
|
@ -36,6 +37,8 @@ typedef struct {
|
|||
uint8 flags; // 0x0B
|
||||
} rct_path_type;
|
||||
|
||||
#define g_pathTypeEntries ((rct_path_type**)object_entry_groups[OBJECT_TYPE_PATHS].chunks)
|
||||
|
||||
void game_command_place_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_remove_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
money32 footpath_place(int type, int x, int y, int z, int slope, int flags);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define _SCENERY_H_
|
||||
|
||||
#include "../common.h"
|
||||
#include "../object.h"
|
||||
|
||||
typedef struct {
|
||||
uint32 flags; // 0x06
|
||||
|
@ -129,12 +130,12 @@ typedef struct {
|
|||
uint32 var_10A;
|
||||
} rct_scenery_set_entry;
|
||||
|
||||
#define g_smallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_SMALL_SCENERY_ENTRIES, rct_scenery_entry*)
|
||||
#define g_largeSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_scenery_entry*)
|
||||
#define g_wallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_WALL_SCENERY_ENTRIES, rct_scenery_entry*)
|
||||
#define g_bannerSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_BANNER_SCENERY_ENTRIES, rct_scenery_entry*)
|
||||
#define g_pathBitSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES, rct_scenery_entry*)
|
||||
#define g_scenerySetEntries RCT2_ADDRESS(RCT2_ADDRESS_SCENERY_SET_ENTRIES, rct_scenery_set_entry*)
|
||||
#define g_smallSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].chunks)
|
||||
#define g_largeSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_LARGE_SCENERY].chunks)
|
||||
#define g_wallSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_WALLS].chunks)
|
||||
#define g_bannerSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_BANNERS].chunks)
|
||||
#define g_pathBitSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_PATH_BITS].chunks)
|
||||
#define g_scenerySetEntries ((rct_scenery_set_entry**)object_entry_groups[OBJECT_TYPE_SCENERY_SETS].chunks)
|
||||
|
||||
void init_scenery();
|
||||
|
||||
|
|
Loading…
Reference in New Issue