1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-16 11:33:03 +01:00

Merge pull request #901 from duncanspumpkin/refactor

Refactor of Object Functions
This commit is contained in:
Ted John
2015-03-07 14:03:53 +00:00
18 changed files with 306 additions and 239 deletions

View File

@@ -126,15 +126,31 @@
#define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319
// 0 = none, 255 = load file, 254 = anything else
#define RCT2_ADDRESS_ERROR_TYPE 0x009AC31B
#define RCT2_ADDRESS_ERROR_STRING_ID 0x009AC31C
#define RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS 0x009AC861
#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 +235,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 +270,11 @@
#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
// 1 if custom objects installed, 0 otherwise
#define RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED 0x00F42BDA
#define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC
#define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908

View File

@@ -152,10 +152,11 @@ 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();
reset_loaded_objects();
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
s6Info->name[0] = 0;
@@ -463,7 +464,7 @@ static void sub_6A2B62()
object_unload_all();
RCT2_CALLPROC_EBPSAFE(0x0069F53D);
sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();
RCT2_CALLPROC_EBPSAFE(0x006A2730);
RCT2_CALLPROC_EBPSAFE(0x006A2956);
RCT2_CALLPROC_EBPSAFE(0x006A29B9);
@@ -587,8 +588,8 @@ static int editor_load_landscape_from_sv4(const char *path)
// Open file
fp = fopen(path, "rb");
if (fp == NULL) {
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = 3011;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011;
return 0;
}
@@ -614,8 +615,8 @@ static int editor_load_landscape_from_sc4(const char *path)
// Open file
fp = fopen(path, "rb");
if (fp == NULL) {
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = 3011;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011;
return 0;
}
@@ -758,8 +759,8 @@ static int editor_read_s6(const char *path)
if (file != NULL) {
if (!sawyercoding_validate_checksum(file)) {
fclose(file);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
log_error("failed to load scenario, invalid checksum");
return 0;
@@ -835,7 +836,7 @@ static int editor_read_s6(const char *path)
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
map_update_tile_pointers();
map_remove_all_rides();
@@ -911,9 +912,10 @@ 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);
sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
rct_stex_entry* stex = g_stexEntries[0];
if ((int)stex != 0xFFFFFFFF) {
object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]);
reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
s6Info->name[0] = 0;
@@ -961,8 +963,8 @@ static int editor_read_s6(const char *path)
}
log_error("failed to find scenario file.");
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
}

View File

@@ -298,8 +298,6 @@ void game_update()
void game_logic_update()
{
short stringId, _dx;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32)++;
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, sint32)++;
RCT2_GLOBAL(0x009DEA66, sint16)++;
@@ -329,16 +327,16 @@ void game_logic_update()
// Update windows
window_dispatch_update_all();
if (RCT2_GLOBAL(0x009AC31B, uint8) != 0) {
stringId = STR_UNABLE_TO_LOAD_FILE;
_dx = RCT2_GLOBAL(0x009AC31C, uint16);
if (RCT2_GLOBAL(0x009AC31B, uint8) != 254) {
stringId = RCT2_GLOBAL(0x009AC31C, uint16);
_dx = 0xFFFF;
if (RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) != 0) {
rct_string_id title_text = STR_UNABLE_TO_LOAD_FILE;
rct_string_id body_text = RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16);
if (RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) == 254) {
title_text = RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16);
body_text = 0xFFFF;
}
RCT2_GLOBAL(0x009AC31B, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0;
window_error_open(stringId, _dx);
window_error_open(title_text, body_text);
}
}
@@ -601,7 +599,7 @@ int game_load_save(const char *path)
if (file == NULL) {
log_error("unable to open %s", path);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
}
@@ -611,7 +609,7 @@ int game_load_save(const char *path)
log_error("invalid checksum, %s", path);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
}
@@ -663,7 +661,7 @@ int game_load_save(const char *path)
}
// The rest is the same as in scenario load and play
sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();
map_update_tile_pointers();
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
@@ -811,6 +809,26 @@ void game_autosave()
scenario_save(path, 0x80000000);
}
/**
*
* rct2: 0x006E3838
*/
void rct2_exit_reason(rct_string_id title, rct_string_id body){
// Before this would set a quit message
char exit_title[255];
format_string(exit_title, title, 0);
char exit_body[255];
format_string(exit_body, body, 0);
log_error(exit_title);
log_error(exit_body);
rct2_exit();
}
/**
*
* rct2: 0x006E3879

View File

@@ -21,6 +21,8 @@
#ifndef _GAME_H_
#define _GAME_H_
#include "common.h"
enum GAME_COMMAND {
GAME_COMMAND_0,
GAME_COMMAND_1,
@@ -109,6 +111,7 @@ int game_load_save(const char *path);
void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
char save_game();
void rct2_exit();
void rct2_exit_reason(rct_string_id title, rct_string_id body);
void game_autosave();
#endif

View File

@@ -175,17 +175,19 @@ 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 eax = 0, entryGroupIndex = 0, type = 0, edx = 0, edi = 0, ebp = (int)entry, chunk = 0;
RCT2_CALLFUNC_X(0x6A9DA2, &eax, &entryGroupIndex, &type, &edx, &chunk, &edi, &ebp);
if (eax == 0) return 0;
int write_object_file(FILE *file, rct_object_entry* entry){
uint8 entryGroupIndex = 0, type = 0;
uint8* chunk = 0;
object_paint(type, 1, entryGroupIndex, type, edx, chunk, edi, ebp);
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];
uint8* dst_buffer = malloc(0x600000);
memcpy(dst_buffer, (uint8*)installed_entry, sizeof(rct_object_entry));
memcpy(dst_buffer, installed_entry, sizeof(rct_object_entry));
uint32 size_dst = sizeof(rct_object_entry);
@@ -196,7 +198,7 @@ int sub_6A9F42(FILE *file, rct_object_entry* entry){
chunkHeader.encoding = object_entry_group_encoding[type];
chunkHeader.length = installed_entry->chunk_size;
size_dst += sawyercoding_write_chunk_buffer(dst_buffer + sizeof(rct_object_entry), (uint8*)chunk, chunkHeader);
size_dst += sawyercoding_write_chunk_buffer(dst_buffer + sizeof(rct_object_entry), chunk, chunkHeader);
fwrite(dst_buffer, 1, size_dst, file);
free(dst_buffer);
@@ -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,8 +86,8 @@ 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);
void sub_6A9FC0();
int write_object_file(FILE *file, rct_object_entry* entry);
void reset_loaded_objects();
int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index);
rct_object_entry *object_list_find(rct_object_entry *entry);

View File

@@ -24,6 +24,7 @@
#include "platform/platform.h"
#include "ride/track.h"
#include "util/sawyercoding.h"
#include "game.h"
#define OBJECT_ENTRY_GROUP_COUNT 11
#define OBJECT_ENTRY_COUNT 721
@@ -69,16 +70,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);
@@ -152,10 +153,12 @@ static void object_list_examine()
int i;
rct_object_entry *object;
RCT2_GLOBAL(RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED, uint8) = 0;
object = 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->flags & 0xF0)
RCT2_GLOBAL(0x00F42BDA, uint8) |= 1;
if (!(object->flags & 0xF0))
RCT2_GLOBAL(RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED, uint8) |= 1;
object = object_get_next(object);
}
@@ -165,19 +168,10 @@ static void object_list_examine()
object_list_create_hash_table();
}
/**
*
* rct2: 0x006DED68
*/
void reset_9E32F8()
/* rct2: 0x006A9FC0 */
void reset_loaded_objects()
{
uint8* edi = RCT2_ADDRESS(0x009E32F8, uint8);
memset(edi, 0xFF, 90);
}
void sub_6A9FC0()
{
reset_9E32F8();
reset_type_to_ride_entry_index_map();
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E;
@@ -248,7 +242,7 @@ void object_list_load()
//if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS, uint8) != 0)
// RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS, uint8) = 0;
sub_6A9FC0();
reset_loaded_objects();
// Dispose installed object list
if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) != -1) {
@@ -259,7 +253,8 @@ void object_list_load()
RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_malloc(4096);
if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){
RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0);
log_error("Failed to allocate memory for object list");
rct2_exit_reason(835, 3162);
return;
}
@@ -280,7 +275,8 @@ void object_list_load()
installed_buffer_size += 0x1000;
RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_realloc(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), installed_buffer_size);
if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){
RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0);
log_error("Failed to allocate memory for object list");
rct2_exit_reason(835, 3162);
return;
}
}
@@ -288,22 +284,22 @@ void object_list_load()
char path[MAX_PATH];
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), enumFileInfo.path);
rct_object_entry* entry = RCT2_ADDRESS(0x00F42B74, rct_object_entry);
if (!object_load_entry(path, entry))
rct_object_entry entry;
if (!object_load_entry(path, &entry))
continue;
rct_object_entry* installed_entry = (rct_object_entry*)(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset);
current_item_offset += install_object_entry(entry, installed_entry, enumFileInfo.path);
current_item_offset += install_object_entry(&entry, installed_entry, enumFileInfo.path);
}
platform_enumerate_files_end(enumFileHandle);
}
sub_6A9FC0();
reset_loaded_objects();
object_list_cache_save(fileCount, totalFileSize, fileDateModifiedChecksum, current_item_offset);
//
// Reload track list
ride_list_item ride_list;
ride_list.entry_index = 0xFC;
ride_list.type = 0xFC;
@@ -349,7 +345,7 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file
log_error("Potential mismatch in file numbers. Possible corrupt file. Consider deleting plugin.dat.");
fclose(file);
sub_6A9FC0();
reset_loaded_objects();
object_list_examine();
return 1;
}
@@ -408,15 +404,15 @@ void set_load_objects_fail_reason(){
format_string(string_buffer, 3323, 0); //Missing object data, ID:
RCT2_CALLPROC_X(0x6AB344, 0, 0, 0, 0, 0, (int)string_buffer, 0x13CE952);
RCT2_GLOBAL(0x9AC31B, uint8) = 0xFF;
RCT2_GLOBAL(0x9AC31C, uint16) = 3165;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3165;
return;
}
char* exapansion_name = &RCT2_ADDRESS(RCT2_ADDRESS_EXPANSION_NAMES, char)[128 * expansion];
if (*exapansion_name == '\0'){
RCT2_GLOBAL(0x9AC31B, uint8) = 0xFF;
RCT2_GLOBAL(0x9AC31C, uint16) = 3325;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3325;
return;
}
@@ -424,8 +420,8 @@ void set_load_objects_fail_reason(){
format_string(string_buffer, 3324, 0); // Requires expansion pack
strcat(string_buffer, exapansion_name);
RCT2_GLOBAL(0x9AC31B, uint8) = 0xFF;
RCT2_GLOBAL(0x9AC31C, uint16) = 3165;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3165;
}
/**
@@ -493,7 +489,7 @@ void object_unload_all()
if (object_entry_groups[i].chunks[j] != (uint8*)0xFFFFFFFF)
object_unload(j, &object_entry_groups[i].entries[j]);
sub_6A9FC0();
reset_loaded_objects();
}
@@ -601,7 +597,9 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in
// 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;

View File

@@ -140,6 +140,15 @@ rct_ride_type *ride_get_entry(rct_ride *ride)
return GET_RIDE_ENTRY(ride->subtype);
}
/**
*
* rct2: 0x006DED68
*/
void reset_type_to_ride_entry_index_map(){
uint8* typeToRideEntryIndexMap = RCT2_ADDRESS(0x009E32F8, uint8);
memset(typeToRideEntryIndexMap, 0xFF, 90);
}
uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType)
{
uint8 *typeToRideEntryIndexMap = (uint8*)0x009E32F8;

View File

@@ -674,6 +674,7 @@ track_colour ride_get_track_colour(rct_ride *ride, int colourScheme);
vehicle_colour ride_get_vehicle_colour(rct_ride *ride, int vehicleIndex);
rct_ride_type *ride_get_entry(rct_ride *ride);
uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType);
void reset_type_to_ride_entry_index_map();
void ride_measurement_clear(rct_ride *ride);
void ride_measurements_update();
rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message);

View File

@@ -738,7 +738,7 @@ void load_track_scenery_objects(){
scenery_entry += sizeof(rct_track_scenery);
}
sub_6A9FC0();
reset_loaded_objects();
}
/**

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();
}
}
@@ -82,8 +82,8 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in
}
log_error("invalid scenario, %s", path);
// RCT2_GLOBAL(0x009AC31B, sint8) = -1;
// RCT2_GLOBAL(0x009AC31C, sint16) = 3011;
// RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, sint8) = -1;
// RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, sint16) = 3011;
return 0;
}
@@ -105,8 +105,8 @@ int scenario_load(const char *path)
if (file != NULL) {
if (!sawyercoding_validate_checksum(file)) {
fclose(file);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
log_error("failed to load scenario, invalid checksum");
return 0;
@@ -172,7 +172,7 @@ int scenario_load(const char *path)
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
sub_6A9FC0();
reset_loaded_objects();
map_update_tile_pointers();
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
return 1;
@@ -182,8 +182,8 @@ int scenario_load(const char *path)
}
log_error("failed to find scenario file.");
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
}
@@ -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;
}
@@ -1133,7 +1133,7 @@ int scenario_save(char *path, int flags)
fclose(file);
if (!(flags & 0x80000000))
sub_6A9FC0();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, uint16) = 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 {
@@ -251,7 +252,7 @@ static void window_editor_object_selection_close()
RCT2_CALLPROC_EBPSAFE(0x6ABB66);
editor_load_selected_objects();
sub_6A9FC0();
reset_loaded_objects();
object_free_scenario_text();
RCT2_CALLPROC_EBPSAFE(0x6AB316);
RCT2_CALLPROC_EBPSAFE(0x685675);
@@ -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

@@ -803,7 +803,7 @@ static void window_options_invalidate()
w->disabled_widgets |= (1ULL << WIDX_REAL_NAME_CHECKBOX);
// save plugin data checkbox: visible or not
if (RCT2_GLOBAL(0x00F42BDA, uint8) == 1)
if (RCT2_GLOBAL(RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED, uint8) == 1)
window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_EMPTY;
else
window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_CHECKBOX;

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