More refactoring of object.c

This commit is contained in:
Duncan Frost 2015-03-07 09:44:34 +00:00
parent e7db42f0fe
commit ddcf766fea
12 changed files with 197 additions and 166 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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