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:
@@ -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
|
||||
|
||||
34
src/editor.c
34
src/editor.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
44
src/game.c
44
src/game.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
242
src/object.c
242
src/object.c
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -738,7 +738,7 @@ void load_track_scenery_objects(){
|
||||
scenery_entry += sizeof(rct_track_scenery);
|
||||
}
|
||||
|
||||
sub_6A9FC0();
|
||||
reset_loaded_objects();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user