From 8a6eec0236fe787f4ff421e8032f713dfc0c5b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 17 Jun 2016 15:38:22 +0200 Subject: [PATCH 01/17] Try loading objects for x86-64 --- src/object.c | 548 ++++++++++++++++++++++++++++++++++++++-------- src/object.h | 2 +- src/object_list.c | 3 +- src/ride/ride.c | 1 + 4 files changed, 464 insertions(+), 90 deletions(-) diff --git a/src/object.c b/src/object.c index ddeff1e4bb..9f8b14479a 100644 --- a/src/object.c +++ b/src/object.c @@ -128,6 +128,11 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi } } } + + if (RCT2_GLOBAL(0x9ADAFD, uint8) != 0) { + chunk = object_load(objectType, chunk, groupIndex, chunkSize); + } + chunk_list[groupIndex] = chunk; rct_object_entry_extended* extended_entry = &object_entry_groups[objectType].entries[groupIndex]; @@ -137,9 +142,6 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi gLastLoadedObjectChunkData = chunk; - if (RCT2_GLOBAL(0x9ADAFD, uint8) != 0) { - object_load(objectType, chunk, groupIndex); - } return 1; } @@ -477,10 +479,25 @@ int object_chunk_load_image_directory(uint8_t** chunk) return image_start_no; } -typedef bool (*object_load_func)(void *objectEntry, uint32 entryIndex); -typedef void (*object_unload_func)(void *objectEntry); -typedef bool (*object_test_func)(void *objectEntry); -typedef void (*object_paint_func)(void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y); +/** + * object_load_func will receive the struct as it is stored in a file, this + * means 32bit pointers. On non-32bit platforms it's supposed to upconvert + * structure to native pointer types and return pointer to newly allocated + * space. It should not be the same pointer as input. + * + * object_unload_func will receive a pointer to the structure created with + * object_load_func, i.e. with native pointer types + * + * object_test_func will receive a pointer to the struct as it is stored in a + * file. + * + * object_paint_func and object_paint_func will receive structs with native + * pointer types. + */ +typedef uint8* (*object_load_func)(void *objectEntry, uint32 entryIndex, int *chunkSize); +typedef void (*object_unload_func)(void *objectEntry); +typedef bool (*object_test_func)(void *objectEntry); +typedef void (*object_paint_func)(void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y); typedef rct_string_id (*object_desc_func)(void *objectEntry); /** @@ -498,12 +515,115 @@ typedef struct object_type_vtable { // Ride (rct2: 0x006E6E2A) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_ride_load(void *objectEntry, uint32 entryIndex) +/** + * Ride type vehicle structure. + * size: 0x65 + */ +typedef struct { + uint16 rotation_frame_mask; // 0x00 , 0x1A + uint8 var_02; // 0x02 , 0x1C + uint8 var_03; // 0x03 , 0x1D + uint32 spacing; // 0x04 , 0x1E + uint16 car_friction; // 0x08 , 0x22 + sint8 tab_height; // 0x0A , 0x24 + uint8 num_seats; // 0x0B , 0x25 + uint16 sprite_flags; // 0x0C , 0x26 + uint8 sprite_width; // 0x0E , 0x28 + uint8 sprite_height_negative; // 0x0F , 0x29 + uint8 sprite_height_positive; // 0x10 , 0x2A + uint8 var_11; // 0x11 , 0x2B + uint16 flags_a; // 0x12 , 0x2C + uint16 flags_b; // 0x14 , 0x2E + uint16 var_16; // 0x16 , 0x30 + uint32 base_image_id; // 0x18 , 0x32 + uint32 var_1C; // 0x1C , 0x36 + uint32 var_20; // 0x20 , 0x3A + uint32 var_24; // 0x24 , 0x3E + uint32 var_28; // 0x28 , 0x42 + uint32 var_2C; // 0x2C , 0x46 + uint32 var_30; // 0x30 , 0x4A + uint32 var_34; // 0x34 , 0x4E + uint32 var_38; // 0x38 , 0x52 + uint32 var_3C; // 0x3C , 0x56 + uint32 var_40; // 0x40 , 0x5A + uint32 var_44; // 0x44 , 0x5E + uint32 var_48; // 0x48 , 0x62 + uint32 var_4C; // 0x4C , 0x66 + uint32 no_vehicle_images; // 0x50 , 0x6A + uint8 no_seating_rows; // 0x54 , 0x6E + uint8 spinning_inertia; // 0x55 , 0x6F + uint8 spinning_friction; // 0x56 , 0x70 + uint8 friction_sound_id; // 0x57 , 0x71 + uint8 var_58; // 0x58 , 0x72 + uint8 sound_range; // 0x59 , 0x73 + uint8 var_5A; // 0x5A , 0x74 + uint8 powered_acceleration; // 0x5B , 0x75 + uint8 powered_max_speed; // 0x5C , 0x76 + uint8 car_visual; // 0x5D , 0x77 + uint8 pad_5E; + uint8 draw_order; + uint8 special_frames; // 0x60 , 0x7A + uint32 peep_loading_positions; // 0x61 , 0x7B note: uint32 +} rct_ride_entry_vehicle_32bit; + +/** + * Ride type structure. + * size: unknown + */ +typedef struct { + rct_string_id name; // 0x000 + rct_string_id description; // 0x002 + uint32 images_offset; // 0x004 + uint32 flags; // 0x008 + uint8 ride_type[3]; // 0x00C + uint8 min_cars_in_train; // 0x00F + uint8 max_cars_in_train; // 0x010 + uint8 cars_per_flat_ride; // 0x011 + // Number of cars that can't hold passengers + uint8 zero_cars; // 0x012 + // The index to the vehicle type displayed in + // the vehicle tab. + uint8 tab_vehicle; // 0x013 + uint8 default_vehicle; // 0x014 + // Convert from first - fourth vehicle to + // vehicle structure + uint8 front_vehicle; // 0x015 + uint8 second_vehicle; // 0x016 + uint8 rear_vehicle; // 0x017 + uint8 third_vehicle; // 0x018 + uint8 pad_019; + rct_ride_entry_vehicle_32bit vehicles[4]; // 0x1A note: 32bit! + uint32 vehicle_preset_list; // 0x1AE note: uint32! + sint8 excitement_multipler; // 0x1B2 + sint8 intensity_multipler; // 0x1B3 + sint8 nausea_multipler; // 0x1B4 + uint8 max_height; // 0x1B5 + union { + uint64 enabledTrackPieces; // 0x1B6 + struct { + uint32 enabledTrackPiecesA; // 0x1B6 + uint32 enabledTrackPiecesB; // 0x1BA + }; + }; + uint8 category[2]; // 0x1BE + uint8 shop_item; // 0x1C0 + uint8 shop_item_secondary; // 0x1C1 +} rct_ride_entry_32bit; + +static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { - rct_ride_entry *rideEntry = (rct_ride_entry*)objectEntry; + rct_ride_entry_32bit *rideEntry = (rct_ride_entry_32bit*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_ride_entry_32bit)); + const size_t extendedDataSize = *chunkSize - sizeof(rct_ride_entry_32bit); + *chunkSize = *chunkSize + sizeof(rct_ride_entry) - sizeof(rct_ride_entry_32bit); + assert(*chunkSize > 0); + rct_ride_entry* outRideEntry = malloc(*chunkSize); + assert(outRideEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outRideEntry + sizeof(rct_ride_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); + log_warning("loading ride %p", objectEntry); // After rideEntry is 3 string tables - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_ride_entry)); rideEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 0); rideEntry->description = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 1); @@ -513,7 +633,7 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex) } object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 2); - rideEntry->vehicle_preset_list = (vehicle_colour_preset_list*)extendedEntryData; + outRideEntry->vehicle_preset_list = (vehicle_colour_preset_list*)extendedEntryData; // If Unknown struct size is 0xFF then there are 32 3 byte structures uint8 unknown_size = *extendedEntryData++; @@ -537,12 +657,13 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex) } int images_offset = object_chunk_load_image_directory(&extendedEntryData); - rideEntry->images_offset = images_offset; + outRideEntry->images_offset = images_offset; int cur_vehicle_images_offset = images_offset + 3; for (int i = 0; i < 4; i++) { - rct_ride_entry_vehicle* vehicleEntry = &rideEntry->vehicles[i]; + rct_ride_entry_vehicle_32bit* vehicleEntry = &rideEntry->vehicles[i]; + rct_ride_entry_vehicle* outVehicleEntry = &outRideEntry->vehicles[i]; if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT) { int al = 1; @@ -708,12 +829,58 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex) set_vehicle_type_image_max_sizes(vehicleEntry, num_images); } + // Copy the vehicle entry over to new one + outVehicleEntry->rotation_frame_mask = vehicleEntry->rotation_frame_mask; + outVehicleEntry->var_02 = vehicleEntry->var_02; + outVehicleEntry->var_03 = vehicleEntry->var_03; + outVehicleEntry->spacing = vehicleEntry->spacing; + outVehicleEntry->car_friction = vehicleEntry->car_friction; + outVehicleEntry->tab_height = vehicleEntry->tab_height; + outVehicleEntry->num_seats = vehicleEntry->num_seats; + outVehicleEntry->sprite_flags = vehicleEntry->sprite_flags; + outVehicleEntry->sprite_width = vehicleEntry->sprite_width; + outVehicleEntry->sprite_height_negative = vehicleEntry->sprite_height_negative; + outVehicleEntry->sprite_height_positive = vehicleEntry->sprite_height_positive; + outVehicleEntry->var_11 = vehicleEntry->var_11; + outVehicleEntry->flags_a = vehicleEntry->flags_a; + outVehicleEntry->flags_b = vehicleEntry->flags_b; + outVehicleEntry->var_16 = vehicleEntry->var_16; + outVehicleEntry->base_image_id = vehicleEntry->base_image_id; + outVehicleEntry->var_1C = vehicleEntry->var_1C; + outVehicleEntry->var_20 = vehicleEntry->var_20; + outVehicleEntry->var_24 = vehicleEntry->var_24; + outVehicleEntry->var_28 = vehicleEntry->var_28; + outVehicleEntry->var_2C = vehicleEntry->var_2C; + outVehicleEntry->var_30 = vehicleEntry->var_30; + outVehicleEntry->var_34 = vehicleEntry->var_34; + outVehicleEntry->var_38 = vehicleEntry->var_38; + outVehicleEntry->var_3C = vehicleEntry->var_3C; + outVehicleEntry->var_40 = vehicleEntry->var_40; + outVehicleEntry->var_44 = vehicleEntry->var_44; + outVehicleEntry->var_48 = vehicleEntry->var_48; + outVehicleEntry->var_4C = vehicleEntry->var_4C; + outVehicleEntry->no_vehicle_images = vehicleEntry->no_vehicle_images; + outVehicleEntry->no_seating_rows = vehicleEntry->no_seating_rows; + outVehicleEntry->spinning_inertia = vehicleEntry->spinning_inertia; + outVehicleEntry->spinning_friction = vehicleEntry->spinning_friction; + outVehicleEntry->friction_sound_id = vehicleEntry->friction_sound_id; + outVehicleEntry->var_58 = vehicleEntry->var_58; + outVehicleEntry->sound_range = vehicleEntry->sound_range; + outVehicleEntry->var_5A = vehicleEntry->var_5A; + outVehicleEntry->powered_acceleration = vehicleEntry->powered_acceleration; + outVehicleEntry->powered_max_speed = vehicleEntry->powered_max_speed; + outVehicleEntry->car_visual = vehicleEntry->car_visual; + outVehicleEntry->pad_5E = vehicleEntry->pad_5E; + outVehicleEntry->draw_order = vehicleEntry->draw_order; + outVehicleEntry->special_frames = vehicleEntry->special_frames; + sint8 no_positions = *peep_loading_positions++; if (no_positions == -1) { // The no_positions is 16 bit skip over peep_loading_positions += 2; } - vehicleEntry->peep_loading_positions = peep_loading_positions; + // not set for original entry + outVehicleEntry->peep_loading_positions = peep_loading_positions; } } @@ -743,8 +910,9 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex) } // 0x6DEBAA - if (RCT2_GLOBAL(0x9ADAF4, sint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } int di = rideEntry->ride_type[0] | (rideEntry->ride_type[1] << 8) | (rideEntry->ride_type[2] << 16); @@ -754,7 +922,38 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex) } RCT2_GLOBAL(0xF433DD, uint32) = di; - return true; + + outRideEntry->name = rideEntry->name; + outRideEntry->description = rideEntry->description; + outRideEntry->images_offset = rideEntry->images_offset; + outRideEntry->flags = rideEntry->flags; + outRideEntry->ride_type[0] = rideEntry->ride_type[0]; + outRideEntry->ride_type[1] = rideEntry->ride_type[1]; + outRideEntry->ride_type[2] = rideEntry->ride_type[2]; + outRideEntry->min_cars_in_train = rideEntry->min_cars_in_train; + outRideEntry->max_cars_in_train = rideEntry->max_cars_in_train; + outRideEntry->cars_per_flat_ride = rideEntry->cars_per_flat_ride; + outRideEntry->zero_cars = rideEntry->zero_cars; + outRideEntry->tab_vehicle = rideEntry->tab_vehicle; + outRideEntry->default_vehicle = rideEntry->default_vehicle; + outRideEntry->front_vehicle = rideEntry->front_vehicle; + outRideEntry->second_vehicle = rideEntry->second_vehicle; + outRideEntry->rear_vehicle = rideEntry->rear_vehicle; + outRideEntry->third_vehicle = rideEntry->third_vehicle; + outRideEntry->pad_019 = rideEntry->pad_019; + // 0x1a vehicles already set + // 0a1ae vehicle_preset_list already set + outRideEntry->excitement_multipler = rideEntry->excitement_multipler; + outRideEntry->intensity_multipler = rideEntry->intensity_multipler; + outRideEntry->nausea_multipler = rideEntry->nausea_multipler; + outRideEntry->max_height = rideEntry->max_height; + outRideEntry->enabledTrackPieces = rideEntry->enabledTrackPieces; + outRideEntry->category[0] = rideEntry->category[0]; + outRideEntry->category[1] = rideEntry->category[1]; + outRideEntry->shop_item = rideEntry->shop_item; + outRideEntry->shop_item_secondary = rideEntry->shop_item_secondary; + + return outRideEntry; } static void object_type_ride_unload(void *objectEntry) @@ -799,7 +998,8 @@ static void object_type_ride_unload(void *objectEntry) static bool object_type_ride_test(void *objectEntry) { - rct_ride_entry* rideEntry = (rct_ride_entry*)objectEntry; + log_warning("testing ride"); + rct_ride_entry_32bit* rideEntry = (rct_ride_entry_32bit*)objectEntry; if (rideEntry->excitement_multipler > 75) return false; if (rideEntry->intensity_multipler > 75) return false; if (rideEntry->nausea_multipler > 75) return false; @@ -808,7 +1008,7 @@ static bool object_type_ride_test(void *objectEntry) static void object_type_ride_paint(void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y) { - rct_ride_entry *rideEntry = (rct_ride_entry*)objectEntry; + rct_ride_entry_32bit *rideEntry = (rct_ride_entry_32bit*)objectEntry; int imageId = rideEntry->images_offset; if (rideEntry->ride_type[0] == 0xFF) { imageId++; @@ -821,7 +1021,7 @@ static void object_type_ride_paint(void *objectEntry, rct_drawpixelinfo *dpi, si static rct_string_id object_type_ride_desc(void *objectEntry) { - rct_ride_entry *rideEntry = (rct_ride_entry*)objectEntry; + rct_ride_entry_32bit *rideEntry = (rct_ride_entry_32bit*)objectEntry; // Get description rct_string_id stringId = rideEntry->description; @@ -850,10 +1050,52 @@ static const object_type_vtable object_type_ride_vtable[] = { // Small Scenery (rct2: 0x006E3466) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_small_scenery_load(void *objectEntry, uint32 entryIndex) +typedef struct { + uint8 tool_id; // 0x06 + uint8 flags; // 0x07 + sint16 price; // 0x08 + sint16 removal_price; // 0x0A + uint32 tiles; // 0x0C note: 32bit! + uint8 scenery_tab_id; // 0x10 + uint8 var_11; + uint32 text; + uint32 text_image; +} rct_large_scenery_entry_32bit; + +typedef struct { + uint32 flags; // 0x06 + uint8 height; // 0x0A + uint8 tool_id; // 0x0B + sint16 price; // 0x0C + sint16 removal_price; // 0x0E + uint32 var_10; // note: uint32! + uint8 pad_14[0x06]; + uint8 scenery_tab_id; // 0x1A +} rct_small_scenery_entry_32bit; + +typedef struct { + rct_string_id name; // 0x00 + uint32 image; // 0x02 + union { + rct_small_scenery_entry_32bit small_scenery; + rct_large_scenery_entry_32bit large_scenery; + rct_wall_scenery_entry wall; + rct_path_bit_scenery_entry path_bit; + rct_banner_scenery_entry banner; + }; +} rct_scenery_entry_32bit; + +static uint8* object_type_small_scenery_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { - rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + (size_t)0x1C); + rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x1C); + const size_t extendedDataSize = *chunkSize - 0x1C; + *chunkSize = *chunkSize + sizeof(rct_scenery_entry) - 0x1C; + assert(*chunkSize > 0); + rct_scenery_entry* outSceneryEntry = malloc(*chunkSize); + assert(outSceneryEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outSceneryEntry + sizeof(rct_scenery_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_SMALL_SCENERY, entryIndex, 0); sceneryEntry->small_scenery.scenery_tab_id = 0xFF; @@ -866,22 +1108,36 @@ static bool object_type_small_scenery_load(void *objectEntry, uint32 entryIndex) extendedEntryData += sizeof(rct_object_entry); if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG16){ - sceneryEntry->small_scenery.var_10 = (uint32)extendedEntryData; + outSceneryEntry->small_scenery.var_10 = (uintptr_t)extendedEntryData; while (*++extendedEntryData != 0xFF); extendedEntryData++; + } else { + outSceneryEntry->small_scenery.var_10 = sceneryEntry->small_scenery.var_10; } sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } + outSceneryEntry->name = sceneryEntry->name; + outSceneryEntry->image = sceneryEntry->image; + outSceneryEntry->small_scenery.flags = sceneryEntry->small_scenery.flags; + outSceneryEntry->small_scenery.height = sceneryEntry->small_scenery.height; + outSceneryEntry->small_scenery.tool_id = sceneryEntry->small_scenery.tool_id; + outSceneryEntry->small_scenery.price = sceneryEntry->small_scenery.price; + outSceneryEntry->small_scenery.removal_price = sceneryEntry->small_scenery.removal_price; + // var10 already set + // pad_14 not needed set + outSceneryEntry->small_scenery.scenery_tab_id = sceneryEntry->small_scenery.scenery_tab_id; + return true; } static void object_type_small_scenery_unload(void *objectEntry) { - rct_scenery_entry *sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit *sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; sceneryEntry->name = 0; sceneryEntry->image = 0; sceneryEntry->small_scenery.var_10 = 0; @@ -890,7 +1146,7 @@ static void object_type_small_scenery_unload(void *objectEntry) static bool object_type_small_scenery_test(void *objectEntry) { - rct_scenery_entry *sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit *sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; if (sceneryEntry->small_scenery.price <= 0) return false; if (sceneryEntry->small_scenery.removal_price > 0) return true; @@ -903,7 +1159,7 @@ static bool object_type_small_scenery_test(void *objectEntry) static void object_type_small_scenery_paint(void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y) { - rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; rct_drawpixelinfo clipDPI; if (!clip_drawpixelinfo(&clipDPI, dpi, x - 56, y - 56, 112, 112)) { return; @@ -962,10 +1218,17 @@ static const object_type_vtable object_type_small_scenery_vtable[] = { // Large Scenery (rct2: 0x006B92A7) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex) +static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { - rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + (size_t)0x1A); + rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x1A); + const size_t extendedDataSize = *chunkSize - 0x1A; + *chunkSize = *chunkSize + sizeof(rct_scenery_entry) - 0x1A; + assert(*chunkSize > 0); + rct_scenery_entry* outSceneryEntry = malloc(*chunkSize); + assert(outSceneryEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outSceneryEntry + sizeof(rct_scenery_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_LARGE_SCENERY, entryIndex, 0); sceneryEntry->large_scenery.scenery_tab_id = 0xFF; @@ -976,13 +1239,13 @@ static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex) } } - extendedEntryData += sizeof(rct_object_entry); + extendedEntryData += sizeof(rct_scenery_entry_32bit); if (sceneryEntry->large_scenery.flags & (1 << 2)) { - sceneryEntry->large_scenery.text = (rct_large_scenery_text*)extendedEntryData; + outSceneryEntry->large_scenery.text = (rct_large_scenery_text*)extendedEntryData; extendedEntryData += 1038; } - sceneryEntry->large_scenery.tiles = (rct_large_scenery_tile*)extendedEntryData; + outSceneryEntry->large_scenery.tiles = (rct_large_scenery_tile*)extendedEntryData; // skip over large scenery tiles while (*((uint16*)extendedEntryData) != 0xFFFF){ @@ -995,7 +1258,7 @@ static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex) if (sceneryEntry->large_scenery.flags & (1 << 2)){ sceneryEntry->large_scenery.text_image = imageId; - uint8* edx = (uint8*)sceneryEntry->large_scenery.text; + uint8* edx = (uint8*)outSceneryEntry->large_scenery.text; if (!(edx[0xC] & 1)) { imageId += edx[0xD] * 4; } else{ @@ -1003,10 +1266,21 @@ static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex) } } sceneryEntry->image = imageId; - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } + outSceneryEntry->large_scenery.tool_id = sceneryEntry->large_scenery.tool_id; + outSceneryEntry->large_scenery.flags = sceneryEntry->large_scenery.flags; + outSceneryEntry->large_scenery.price = sceneryEntry->large_scenery.price; + outSceneryEntry->large_scenery.removal_price = sceneryEntry->large_scenery.removal_price; + // 0x0a tiles is a pointer, already set + outSceneryEntry->large_scenery.scenery_tab_id = sceneryEntry->large_scenery.scenery_tab_id; + outSceneryEntry->large_scenery.var_11 = sceneryEntry->large_scenery.var_11; + // var_12 is a pointer, already set + outSceneryEntry->large_scenery.text_image = sceneryEntry->large_scenery.text_image; + return true; } @@ -1023,7 +1297,7 @@ static void object_type_large_scenery_unload(void *objectEntry) static bool object_type_large_scenery_test(void *objectEntry) { - rct_scenery_entry *sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit *sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; if (sceneryEntry->large_scenery.price <= 0) return false; if (sceneryEntry->large_scenery.removal_price > 0) return true; @@ -1059,10 +1333,17 @@ static const object_type_vtable object_type_large_scenery_vtable[] = { // Wall (rct2: 0x006E5A25) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_wall_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_wall_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { - rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + (size_t)0x0E); + rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x0E); + const size_t extendedDataSize = *chunkSize - 0x0E; + *chunkSize = *chunkSize + sizeof(rct_scenery_entry) - 0x0E; + assert(*chunkSize > 0); + rct_scenery_entry* outSceneryEntry = malloc(*chunkSize); + assert(outSceneryEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outSceneryEntry + sizeof(rct_scenery_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_WALLS, entryIndex, 0); sceneryEntry->wall.scenery_tab_id = 0xFF; @@ -1076,11 +1357,22 @@ static bool object_type_wall_load(void *objectEntry, uint32 entryIndex) extendedEntryData += sizeof(rct_object_entry); sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } - return true; + outSceneryEntry->name = sceneryEntry->name; + outSceneryEntry->image = sceneryEntry->image; + outSceneryEntry->wall.tool_id = sceneryEntry->wall.tool_id; + outSceneryEntry->wall.flags = sceneryEntry->wall.flags; + outSceneryEntry->wall.height = sceneryEntry->wall.height; + outSceneryEntry->wall.flags2 = sceneryEntry->wall.flags2; + outSceneryEntry->wall.price = sceneryEntry->wall.price; + outSceneryEntry->wall.scenery_tab_id = sceneryEntry->wall.scenery_tab_id; + outSceneryEntry->wall.var_0D = sceneryEntry->wall.var_0D; + + return outSceneryEntry; } @@ -1094,7 +1386,7 @@ static void object_type_wall_unload(void *objectEntry) static bool object_type_wall_test(void *objectEntry) { - rct_scenery_entry *sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit *sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; if (sceneryEntry->wall.price <= 0) return false; return true; } @@ -1143,10 +1435,17 @@ static const object_type_vtable object_type_wall_vtable[] = { // Banner (rct2: 0x006BA84E) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_banner_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_banner_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { - rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + (size_t)0x0C); + rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x0C); + const size_t extendedDataSize = *chunkSize - 0x0C; + *chunkSize = *chunkSize + sizeof(rct_scenery_entry) - 0x0C; + assert(*chunkSize > 0); + rct_scenery_entry* outSceneryEntry = malloc(*chunkSize); + assert(outSceneryEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outSceneryEntry + sizeof(rct_scenery_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_BANNERS, entryIndex, 0); sceneryEntry->banner.scenery_tab_id = 0xFF; @@ -1160,11 +1459,18 @@ static bool object_type_banner_load(void *objectEntry, uint32 entryIndex) extendedEntryData += sizeof(rct_object_entry); sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } + outSceneryEntry->name = sceneryEntry->name; + outSceneryEntry->image = sceneryEntry->image; + outSceneryEntry->banner.scrolling_mode = sceneryEntry->banner.scrolling_mode; + outSceneryEntry->banner.flags = sceneryEntry->banner.flags; + outSceneryEntry->banner.price = sceneryEntry->banner.price; + outSceneryEntry->banner.scenery_tab_id = sceneryEntry->banner.scenery_tab_id; - return true; + return outSceneryEntry; } static void object_type_banner_unload(void *objectEntry) @@ -1177,7 +1483,7 @@ static void object_type_banner_unload(void *objectEntry) static bool object_type_banner_test(void *objectEntry) { - rct_scenery_entry *sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit *sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; if (sceneryEntry->banner.price <= 0) return false; return true; } @@ -1208,10 +1514,17 @@ static const object_type_vtable object_type_banner_vtable[] = { // Path (rct2: 0x006A8621) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_path_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_path_load(void *objectEntry, uint32 entryIndex) { rct_footpath_entry *pathEntry = (rct_footpath_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + (size_t)0x0E); + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x0E); + const size_t extendedDataSize = *chunkSize - 0x0E; + *chunkSize = *chunkSize + sizeof(rct_footpath_entry) - 0x0E; + assert(*chunkSize > 0); + rct_footpath_entry* outPathEntry = malloc(*chunkSize); + assert(outPathEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outPathEntry + sizeof(rct_footpath_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); pathEntry->string_idx = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PATHS, entryIndex, 0); @@ -1219,11 +1532,15 @@ static bool object_type_path_load(void *objectEntry, uint32 entryIndex) pathEntry->image = imageId; pathEntry->bridge_image = imageId + 109; - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } - return true; + // rct_path_Type has no pointer, its size does not change, safe to memcpy + memcpy(outPathEntry, pathEntry, sizeof(rct_path_type)); + + return outPathEntry; } static void object_type_path_unload(void *objectEntry) @@ -1265,10 +1582,17 @@ static const object_type_vtable object_type_path_vtable[] = { // Path Item (rct2: 0x006A86E2) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_path_bit_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_path_bit_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { - rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + (size_t)0x0E); + rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x0E); + const size_t extendedDataSize = *chunkSize - 0x0E; + *chunkSize = *chunkSize + sizeof(rct_scenery_entry) - 0x0E; + assert(*chunkSize > 0); + rct_scenery_entry* outSceneryEntry = malloc(*chunkSize); + assert(outSceneryEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outSceneryEntry + sizeof(rct_scenery_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PATH_BITS, entryIndex, 0); sceneryEntry->path_bit.scenery_tab_id = 0xFF; @@ -1282,11 +1606,20 @@ static bool object_type_path_bit_load(void *objectEntry, uint32 entryIndex) extendedEntryData += sizeof(rct_object_entry); sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } - return true; + outSceneryEntry->name = sceneryEntry->name; + outSceneryEntry->image = sceneryEntry->image; + outSceneryEntry->path_bit.var_06 = sceneryEntry->path_bit.var_06; + outSceneryEntry->path_bit.pad_08 = sceneryEntry->path_bit.pad_08; + outSceneryEntry->path_bit.tool_id = sceneryEntry->path_bit.tool_id; + outSceneryEntry->path_bit.price = sceneryEntry->path_bit.price; + outSceneryEntry->path_bit.scenery_tab_id = sceneryEntry->path_bit.scenery_tab_id; + + return outSceneryEntry; } static void object_type_path_bit_unload(void *objectEntry) @@ -1299,7 +1632,7 @@ static void object_type_path_bit_unload(void *objectEntry) static bool object_type_path_bit_test(void *objectEntry) { - rct_scenery_entry *sceneryEntry = (rct_scenery_entry*)objectEntry; + rct_scenery_entry_32bit *sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; if (sceneryEntry->path_bit.price <= 0) return false; return true; } @@ -1327,15 +1660,22 @@ static const object_type_vtable object_type_path_bit_vtable[] = { // Scenery Set (rct2: 0x006B93AA) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_scenery_set_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_scenery_set_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { rct_scenery_set_entry *scenerySetEntry = (rct_scenery_set_entry*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_set_entry)); + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_set_entry)); + const size_t extendedDataSize = *chunkSize - sizeof(rct_scenery_set_entry); + *chunkSize = *chunkSize + sizeof(rct_scenery_set_entry) - sizeof(rct_scenery_set_entry); + assert(*chunkSize > 0); + rct_scenery_set_entry* outSceneryEntry = malloc(*chunkSize); + assert(outSceneryEntry != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outSceneryEntry + sizeof(rct_scenery_set_entry)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); scenerySetEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_SCENERY_SETS, entryIndex, 0); rct_object_entry *entryObjects = NULL; - uint8 *eax = RCT2_GLOBAL(0x9ADAF4, uint8*); + uint32 eax = RCT2_GLOBAL(0x9ADAF4, uint32); if ((uint32)eax != 0xFFFFFFFF){ *((uint16*)eax) = 0; entryObjects = (rct_object_entry*)(eax + 2); @@ -1350,7 +1690,7 @@ static bool object_type_scenery_set_load(void *objectEntry, uint32 entryIndex) if (entryObjects != NULL){ memcpy(entryObjects, extendedEntryData, sizeof(rct_object_entry)); entryObjects++; - (*(eax + 1))++; + (*((uint8*)(eax + 1)))++; } uint8 entry_type; uint8 entry_index = 0; @@ -1382,7 +1722,9 @@ static bool object_type_scenery_set_load(void *objectEntry, uint32 entryIndex) extendedEntryData++; scenerySetEntry->image = object_chunk_load_image_directory(&extendedEntryData); - return true; + memcpy(outSceneryEntry, scenerySetEntry, sizeof(rct_scenery_set_entry)); + + return outSceneryEntry; } static void object_type_scenery_set_unload(void *objectEntry) @@ -1424,19 +1766,29 @@ static const object_type_vtable object_type_scenery_set_vtable[] = { // Park Entrance (rct2: 0x00666E42) /////////////////////////////////////////////////////////////////////////////// -bool object_type_park_entrance_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_park_entrance_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { rct_entrance_type *entranceType = (rct_entrance_type*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_entrance_type)); + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_entrance_type)); + const size_t extendedDataSize = *chunkSize - sizeof(rct_entrance_type); + *chunkSize = *chunkSize + sizeof(rct_entrance_type) - sizeof(rct_entrance_type); + assert(*chunkSize > 0); + rct_entrance_type* outEntranceType = malloc(*chunkSize); + assert(outEntranceType != NULL); + uint8 *extendedEntryData = (uint8*)((size_t)outEntranceType + sizeof(rct_entrance_type)); + memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); entranceType->string_idx = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PARK_ENTRANCE, entryIndex, 0); entranceType->image_id = object_chunk_load_image_directory(&extendedEntryData); - if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } - return true; + memcpy(outEntranceType, entranceType, sizeof(rct_entrance_type)); + + return outEntranceType; } static void object_type_park_entrance_unload(void *objectEntry) @@ -1483,11 +1835,18 @@ static const object_type_vtable object_type_park_entrance_vtable[] = { // Water (rct2: 0x006E6E2A) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_water_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_water_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { rct_water_type *waterEntry = (rct_water_type*)objectEntry; + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_water_type)); + const size_t extendedDataSize = *chunkSize - sizeof(rct_water_type); + *chunkSize = *chunkSize + sizeof(rct_water_type) - sizeof(rct_water_type); + assert(*chunkSize > 0); + rct_water_type* outWaterEntry = malloc(*chunkSize); + assert(outWaterEntry != NULL); + uint8 *pStringTable = (uint8*)((size_t)outWaterEntry + sizeof(rct_water_type)); + memcpy(pStringTable, origExtendedEntryData, extendedDataSize); - uint8 *pStringTable = (uint8*)((size_t)objectEntry + sizeof(rct_water_type)); waterEntry->string_idx = object_get_localised_text(&pStringTable, OBJECT_TYPE_WATER, entryIndex, 0); int imageId = object_chunk_load_image_directory(&pStringTable); @@ -1495,8 +1854,9 @@ static bool object_type_water_load(void *objectEntry, uint32 entryIndex) waterEntry->var_06 = imageId + 1; waterEntry->var_0A = imageId + 4; - if (RCT2_GLOBAL(0x009ADAF4, uint32) != 0xFFFFFFFF) { - *RCT2_GLOBAL(0x009ADAF4, uint16*) = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } if (RCT2_GLOBAL(0x009ADAFD, uint8) == 0) { @@ -1504,7 +1864,9 @@ static bool object_type_water_load(void *objectEntry, uint32 entryIndex) gfx_invalidate_screen(); } - return true; + memcpy(outWaterEntry, waterEntry, sizeof(rct_water_type)); + + return outWaterEntry; } static void object_type_water_unload(void *objectEntry) @@ -1544,20 +1906,30 @@ static const object_type_vtable object_type_water_vtable[] = { // Stex (rct2: 0x0066B355) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_stex_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_stex_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { rct_stex_entry *stexEntry = (rct_stex_entry*)objectEntry; - uint8 *stringTable = (uint8*)((size_t)objectEntry + (size_t)0x08); + const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x08); + const size_t extendedDataSize = *chunkSize - 0x08; + *chunkSize = *chunkSize + sizeof(rct_stex_entry) - 0x08; + assert(*chunkSize > 0); + rct_stex_entry* outStexEntry = malloc(*chunkSize); + assert(outStexEntry != NULL); + uint8 *stringTable = (uint8*)((size_t)outStexEntry + sizeof(rct_stex_entry)); + memcpy(stringTable, origExtendedEntryData, extendedDataSize); stexEntry->scenario_name = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 0); stexEntry->park_name = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 1); stexEntry->details = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 2); - if (RCT2_GLOBAL(0x9ADAF4, int) != -1) { - RCT2_GLOBAL(0x9ADAF4, uint16*)[0] = 0; + uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if ((uint32)some_pointer != 0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; } - return true; + memcpy(outStexEntry, stexEntry, sizeof(rct_stex_entry)); + + return outStexEntry; } static void object_type_stex_unload(void *objectEntry) @@ -1609,11 +1981,11 @@ static const object_type_vtable * const object_type_vtables[] = { object_type_stex_vtable }; -bool object_load(int type, void *objectEntry, uint32 entryIndex) +uint8* object_load(int type, void *objectEntry, uint32 entryIndex, int *chunkSize) { assert(type >= OBJECT_TYPE_RIDE && type <= OBJECT_TYPE_SCENARIO_TEXT); const object_type_vtable *vtable = object_type_vtables[type]; - return vtable->load(objectEntry, entryIndex) ? 0 : 1; + return vtable->load(objectEntry, entryIndex, chunkSize); } void object_unload(int type, void *objectEntry) @@ -1708,6 +2080,7 @@ int object_get_scenario_text(rct_object_entry *entry) // This is being changed to force the images to be loaded into a different // image id. + chunk = object_load(openedEntry.flags & 0x0F, chunk, 0, &chunkSize); RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0x726E; gStexTempChunk = (rct_stex_entry*)chunk; // Not used anywhere. @@ -1718,7 +2091,6 @@ int object_get_scenario_text(rct_object_entry *entry) memcpy(gTempObjectLoadName, openedEntry.name, 8); // Not used?? RCT2_GLOBAL(0x009ADAFD, uint8) = 1; - object_load(openedEntry.flags & 0x0F, chunk, 0); // Tell text to be loaded into normal address RCT2_GLOBAL(0x009ADAFC, uint8) = 0; // Not used?? diff --git a/src/object.h b/src/object.h index c991489913..b7f7c97bd1 100644 --- a/src/object.h +++ b/src/object.h @@ -139,7 +139,7 @@ char *object_get_name(rct_object_entry *entry); rct_object_filters *get_object_filter(int index); -bool object_load(int type, void *objectEntry, uint32 entryIndex); +uint8* object_load(int type, void *objectEntry, uint32 entryIndex, int *chunkSize); void object_unload(int type, void *objectEntry); bool object_test(int type, void *objectEntry); void object_paint(int type, void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y); diff --git a/src/object_list.c b/src/object_list.c index 7bb7455fa3..f527a04cfe 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -229,6 +229,7 @@ static void object_list_examine() */ void reset_loaded_objects() { + return; reset_type_to_ride_entry_index_map(); RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E; @@ -237,7 +238,7 @@ void reset_loaded_objects() for (int j = 0; j < object_entry_group_counts[type]; j++){ uint8* chunk = object_entry_groups[type].chunks[j]; if (chunk != (uint8*)-1) - object_load(type, chunk, j); + object_load(type, chunk, j, NULL); } } } diff --git a/src/ride/ride.c b/src/ride/ride.c index f5318b8a68..17db2226ba 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -31,6 +31,7 @@ #include "../management/news_item.h" #include "../network/network.h" #include "../object_list.h" +#include "../openrct2.h" #include "../peep/peep.h" #include "../peep/staff.h" #include "../rct1.h" From 340997b365c712d47eeb4934379f0d0efc01efb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 1 May 2016 14:55:50 +0200 Subject: [PATCH 02/17] Add new function to object vtable: reset For use when an object has to be recreated based on already-existing copy in memory with pointers of native length. --- src/object.c | 647 +++++++++++++++++++++++++++++++++++++++++++--- src/object.h | 1 + src/object_list.c | 3 +- src/ride/ride.c | 6 +- 4 files changed, 610 insertions(+), 47 deletions(-) diff --git a/src/object.c b/src/object.c index 9f8b14479a..9f8731fbe7 100644 --- a/src/object.c +++ b/src/object.c @@ -499,16 +499,18 @@ typedef void (*object_unload_func)(void *objectEntry); typedef bool (*object_test_func)(void *objectEntry); typedef void (*object_paint_func)(void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y); typedef rct_string_id (*object_desc_func)(void *objectEntry); +typedef void (*object_reset_func)(void *objectEntry, uint32 entryIndex); /** * Represents addresses for virtual object functions. */ typedef struct object_type_vtable { - object_load_func load; + object_load_func load; object_unload_func unload; - object_test_func test; - object_paint_func paint; - object_desc_func desc; + object_test_func test; + object_paint_func paint; + object_desc_func desc; + object_reset_func reset; } object_type_vtable; /////////////////////////////////////////////////////////////////////////////// @@ -519,7 +521,7 @@ typedef struct object_type_vtable { * Ride type vehicle structure. * size: 0x65 */ -typedef struct { +typedef struct rct_ride_entry_vehicle_32bit { uint16 rotation_frame_mask; // 0x00 , 0x1A uint8 var_02; // 0x02 , 0x1C uint8 var_03; // 0x03 , 0x1D @@ -570,7 +572,7 @@ typedef struct { * Ride type structure. * size: unknown */ -typedef struct { +typedef struct rct_ride_entry_32bit { rct_string_id name; // 0x000 rct_string_id description; // 0x002 uint32 images_offset; // 0x004 @@ -910,8 +912,8 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c } // 0x6DEBAA - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1038,19 +1040,278 @@ static rct_string_id object_type_ride_desc(void *objectEntry) return stringId; } +static void object_type_ride_reset(void *objectEntry, uint32 entryIndex) +{ + rct_ride_entry *rideEntry = (rct_ride_entry*)objectEntry; + + // After rideEntry is 3 string tables + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_ride_entry)); + rideEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 0); + rideEntry->description = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 1); + + //TODO: Move to its own function when ride construction window is merged. + if (gConfigInterface.select_by_track_type) { + rideEntry->enabledTrackPieces = 0xFFFFFFFFFFFFFFFF; + } + + object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 2); + rideEntry->vehicle_preset_list = (vehicle_colour_preset_list*)extendedEntryData; + + // If Unknown struct size is 0xFF then there are 32 3 byte structures + uint8 unknown_size = *extendedEntryData++; + if (unknown_size != 0xFF) { + extendedEntryData += unknown_size * 3; + } else { + extendedEntryData += 0x60; + } + + sint8 *peep_loading_positions = (sint8*)extendedEntryData; + // Peep loading positions variable size + // 4 different vehicle subtypes are available + for (int i = 0; i < 4; i++){ + uint16 no_peep_positions = *extendedEntryData++; + // If no_peep_positions is 0xFF then no_peep_positions is a word + if (no_peep_positions == 0xFF) { + no_peep_positions = *((uint16*)extendedEntryData); + extendedEntryData += 2; + } + extendedEntryData += no_peep_positions; + } + + int images_offset = object_chunk_load_image_directory(&extendedEntryData); + rideEntry->images_offset = images_offset; + + int cur_vehicle_images_offset = images_offset + 3; + + for (int i = 0; i < 4; i++) { + rct_ride_entry_vehicle* vehicleEntry = &rideEntry->vehicles[i]; + + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT) { + int al = 1; + if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SWINGING) { + al = 13; + if ((vehicleEntry->flags_b & (VEHICLE_ENTRY_FLAG_B_5 | VEHICLE_ENTRY_FLAG_B_11)) != (VEHICLE_ENTRY_FLAG_B_5 | VEHICLE_ENTRY_FLAG_B_11)) { + al = 7; + if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_5)) { + if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_11)) { + al = 5; + if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_9) { + al = 3; + } + } + } + } + } + vehicleEntry->var_03 = al; + // 0x6DE90B + + al = 0x20; + if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_14)) { + al = 1; + if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_7) { + if (vehicleEntry->var_11 != 6) { + al = 2; + if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_7)) { + al = 4; + } + } + } + } + if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_12) { + al = vehicleEntry->special_frames; + } + vehicleEntry->var_02 = al; + // 0x6DE946 + + vehicleEntry->var_16 = vehicleEntry->var_02 * vehicleEntry->var_03; + vehicleEntry->base_image_id = cur_vehicle_images_offset; + int image_index = vehicleEntry->base_image_id; + + if (vehicleEntry->car_visual != VEHICLE_VISUAL_RIVER_RAPIDS) { + int b = vehicleEntry->var_16 * 32; + + if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_11) b /= 2; + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_15) b /= 8; + + image_index += b; + + // Incline 25 + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) { + vehicleEntry->var_20 = image_index; + b = vehicleEntry->var_16 * 72; + if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_14) + b = vehicleEntry->var_16 * 16; + + image_index += b; + } + + // Incline 60 + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES) { + vehicleEntry->var_24 = image_index; + b = vehicleEntry->var_16 * 80; + image_index += b; + } + + // Verticle + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) { + vehicleEntry->var_28 = image_index; + b = vehicleEntry->var_16 * 116; + image_index += b; + } + + // Unknown + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) { + vehicleEntry->var_2C = image_index; + b = vehicleEntry->var_16 * 24; + image_index += b; + } + + // Bank + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) { + vehicleEntry->var_30 = image_index; + b = vehicleEntry->var_16 * 80; + image_index += b; + } + + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) { + vehicleEntry->var_34 = image_index; + b = vehicleEntry->var_16 * 40; + image_index += b; + } + + // Track half? Up/Down + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) { + vehicleEntry->var_38 = image_index; + b = vehicleEntry->var_16 * 128; + image_index += b; + } + + // Unknown + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) { + vehicleEntry->var_3C = image_index; + b = vehicleEntry->var_16 * 16; + image_index += b; + } + + // Unknown + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) { + vehicleEntry->var_40 = image_index; + b = vehicleEntry->var_16 * 16; + image_index += b; + } + + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) { + vehicleEntry->var_44 = image_index; + b = vehicleEntry->var_16 * 128; + image_index += b; + } + + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) { + vehicleEntry->var_48 = image_index; + b = vehicleEntry->var_16 * 16; + image_index += b; + } + + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_CORKSCREWS) { + vehicleEntry->var_4C = image_index; + b = vehicleEntry->var_16 * 80; + image_index += b; + } + + // Unknown + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) { + vehicleEntry->var_1C = image_index; + b = vehicleEntry->var_16 * 12; + image_index += b; + } + + if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_14) { + // Same offset as above??? + vehicleEntry->var_4C = image_index; + b = vehicleEntry->var_16 * 32; + image_index += b; + } + } else { + image_index += vehicleEntry->var_16 * 36; + } + // No vehicle images + vehicleEntry->no_vehicle_images = image_index - cur_vehicle_images_offset; + + // Move the offset over this vehicles images. Including peeps + cur_vehicle_images_offset = image_index + vehicleEntry->no_seating_rows * vehicleEntry->no_vehicle_images; + // 0x6DEB0D + + if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_10)) { + int num_images = cur_vehicle_images_offset - vehicleEntry->base_image_id; + if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_13) { + num_images *= 2; + } + + set_vehicle_type_image_max_sizes(vehicleEntry, num_images); + } + + sint8 no_positions = *peep_loading_positions++; + if (no_positions == -1) { + // The no_positions is 16 bit skip over + peep_loading_positions += 2; + } + vehicleEntry->peep_loading_positions = peep_loading_positions; + } + } + + // 0x6DEB71 + if (RCT2_GLOBAL(0x9ADAFD, uint8) == 0) { + for (int i = 0; i < 3; i++) { + int dl = rideEntry->ride_type[i]; + if (dl == 0xFF) { + continue; + } + + uint8 *typeToRideEntryIndexMap = RCT2_ADDRESS(0x009E32F8, uint8); + while (dl >= 0) { + if (*typeToRideEntryIndexMap++ == 0xFF) { + dl--; + } + } + + typeToRideEntryIndexMap--; + uint8 previous_entry = entryIndex; + while (typeToRideEntryIndexMap < RCT2_ADDRESS(0x9E34E4, uint8)){ + uint8 backup_entry = *typeToRideEntryIndexMap; + *typeToRideEntryIndexMap++ = previous_entry; + previous_entry = backup_entry; + } + } + } + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } + + int di = rideEntry->ride_type[0] | (rideEntry->ride_type[1] << 8) | (rideEntry->ride_type[2] << 16); + + if ((rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) && !rideTypeShouldLoseSeparateFlag(rideEntry)) { + di |= 0x1000000; + } + + RCT2_GLOBAL(0xF433DD, uint32) = di; +} + static const object_type_vtable object_type_ride_vtable[] = { object_type_ride_load, object_type_ride_unload, object_type_ride_test, object_type_ride_paint, - object_type_ride_desc + object_type_ride_desc, + object_type_ride_reset, }; /////////////////////////////////////////////////////////////////////////////// // Small Scenery (rct2: 0x006E3466) /////////////////////////////////////////////////////////////////////////////// -typedef struct { +typedef struct rct_large_scenery_entry_32bit { uint8 tool_id; // 0x06 uint8 flags; // 0x07 sint16 price; // 0x08 @@ -1062,7 +1323,7 @@ typedef struct { uint32 text_image; } rct_large_scenery_entry_32bit; -typedef struct { +typedef struct rct_small_scenery_entry_32bit { uint32 flags; // 0x06 uint8 height; // 0x0A uint8 tool_id; // 0x0B @@ -1073,7 +1334,7 @@ typedef struct { uint8 scenery_tab_id; // 0x1A } rct_small_scenery_entry_32bit; -typedef struct { +typedef struct rct_scenery_entry_32bit { rct_string_id name; // 0x00 uint32 image; // 0x02 union { @@ -1116,8 +1377,8 @@ static uint8* object_type_small_scenery_load(void *objectEntry, uint32 entryInde } sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1206,14 +1467,44 @@ static rct_string_id object_type_small_scenery_desc(void *objectEntry) return STR_NONE; } +static void object_type_small_scenery_reset(void *objectEntry, uint32 entryIndex) +{ + rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_entry)); + + sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_SMALL_SCENERY, entryIndex, 0); + sceneryEntry->small_scenery.scenery_tab_id = 0xFF; + if (*extendedEntryData != 0xFF) { + uint8 entry_type, entry_index; + if (find_object_in_entry_group((rct_object_entry*)extendedEntryData, &entry_type, &entry_index)) { + sceneryEntry->small_scenery.scenery_tab_id = entry_index; + } + } + + extendedEntryData += sizeof(rct_object_entry); + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG16){ + sceneryEntry->small_scenery.var_10 = (uintptr_t)extendedEntryData; + while (*++extendedEntryData != 0xFF); + extendedEntryData++; + } + + sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_small_scenery_vtable[] = { object_type_small_scenery_load, object_type_small_scenery_unload, object_type_small_scenery_test, object_type_small_scenery_paint, - object_type_small_scenery_desc + object_type_small_scenery_desc, + object_type_small_scenery_reset, }; + /////////////////////////////////////////////////////////////////////////////// // Large Scenery (rct2: 0x006B92A7) /////////////////////////////////////////////////////////////////////////////// @@ -1266,8 +1557,8 @@ static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex, } } sceneryEntry->image = imageId; - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1321,12 +1612,60 @@ static rct_string_id object_type_large_scenery_desc(void *objectEntry) return STR_NONE; } +static void object_type_large_scenery_reset(void *objectEntry, uint32 entryIndex) +{ + rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_entry)); + + sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_LARGE_SCENERY, entryIndex, 0); + sceneryEntry->large_scenery.scenery_tab_id = 0xFF; + if (*extendedEntryData != 0xFF) { + uint8 entry_type, entry_index; + if (find_object_in_entry_group((rct_object_entry*)extendedEntryData, &entry_type, &entry_index)) { + sceneryEntry->large_scenery.scenery_tab_id = entry_index; + } + } + + extendedEntryData += sizeof(rct_object_entry); + if (sceneryEntry->large_scenery.flags & (1 << 2)) { + sceneryEntry->large_scenery.var_12 = (uintptr_t)extendedEntryData; + extendedEntryData += 1038; + } + + sceneryEntry->large_scenery.tiles = (rct_large_scenery_tile*)extendedEntryData; + + // skip over large scenery tiles + while (*((uint16*)extendedEntryData) != 0xFFFF){ + extendedEntryData += sizeof(rct_large_scenery_tile); + } + + extendedEntryData += 2; + + int imageId = object_chunk_load_image_directory(&extendedEntryData); + if (sceneryEntry->large_scenery.flags & (1 << 2)){ + sceneryEntry->large_scenery.var_16 = imageId; + + uint8* edx = (uint8*)sceneryEntry->large_scenery.var_12; + if (!(edx[0xC] & 1)) { + imageId += edx[0xD] * 4; + } else{ + imageId += edx[0xD] * 2; + } + } + sceneryEntry->image = imageId; + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_large_scenery_vtable[] = { object_type_large_scenery_load, object_type_large_scenery_unload, object_type_large_scenery_test, object_type_large_scenery_paint, - object_type_large_scenery_desc + object_type_large_scenery_desc, + object_type_large_scenery_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1357,8 +1696,8 @@ static uint8* object_type_wall_load(void *objectEntry, uint32 entryIndex, int *c extendedEntryData += sizeof(rct_object_entry); sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1423,12 +1762,36 @@ static rct_string_id object_type_wall_desc(void *objectEntry) return STR_NONE; } +static void object_type_wall_reset(void *objectEntry, uint32 entryIndex) +{ + rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_entry)); + + sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_WALLS, entryIndex, 0); + sceneryEntry->wall.scenery_tab_id = 0xFF; + if (*extendedEntryData != 0xFF){ + uint8 entry_type, entry_index; + if (find_object_in_entry_group((rct_object_entry*)extendedEntryData, &entry_type, &entry_index)) { + sceneryEntry->wall.scenery_tab_id = entry_index; + } + } + + extendedEntryData += sizeof(rct_object_entry); + sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_wall_vtable[] = { object_type_wall_load, object_type_wall_unload, object_type_wall_test, object_type_wall_paint, - object_type_wall_desc + object_type_wall_desc, + object_type_wall_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1459,8 +1822,8 @@ static uint8* object_type_banner_load(void *objectEntry, uint32 entryIndex, int extendedEntryData += sizeof(rct_object_entry); sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } outSceneryEntry->name = sceneryEntry->name; @@ -1502,12 +1865,36 @@ static rct_string_id object_type_banner_desc(void *objectEntry) return STR_NONE; } +static void object_type_banner_reset(void *objectEntry, uint32 entryIndex) +{ + rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_entry)); + + sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_BANNERS, entryIndex, 0); + sceneryEntry->banner.scenery_tab_id = 0xFF; + if (*extendedEntryData != 0xFF){ + uint8 entry_type, entry_index; + if (find_object_in_entry_group((rct_object_entry*)extendedEntryData, &entry_type, &entry_index)){ + sceneryEntry->banner.scenery_tab_id = entry_index; + } + } + + extendedEntryData += sizeof(rct_object_entry); + sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_banner_vtable[] = { object_type_banner_load, object_type_banner_unload, object_type_banner_test, object_type_banner_paint, - object_type_banner_desc + object_type_banner_desc, + object_type_banner_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1532,8 +1919,8 @@ static uint8* object_type_path_load(void *objectEntry, uint32 entryIndex) pathEntry->image = imageId; pathEntry->bridge_image = imageId + 109; - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1570,12 +1957,44 @@ static rct_string_id object_type_path_desc(void *objectEntry) return STR_NONE; } +static void object_type_path_reset(void *objectEntry, uint32 entryIndex) +{ + rct_path_type *pathEntry = (rct_path_type*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_path_type)); + + pathEntry->string_idx = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PATHS, entryIndex, 0); + + int imageId = object_chunk_load_image_directory(&extendedEntryData); + pathEntry->image = imageId; + pathEntry->bridge_image = imageId + 109; + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } + + gFootpathSelectedId = 0; + // Set the default path for when opening footpath window + for (int i = 0; i < object_entry_group_counts[OBJECT_TYPE_PATHS]; i++) { + rct_path_type *pathEntry2 = (rct_path_type*)object_entry_groups[OBJECT_TYPE_PATHS].chunks[i]; + if (pathEntry2 == (rct_path_type*)-1) { + continue; + } + if (!(pathEntry2->flags & 4)) { + gFootpathSelectedId = i; + break; + } + gFootpathSelectedId = i; + } +} + static const object_type_vtable object_type_path_vtable[] = { object_type_path_load, object_type_path_unload, object_type_path_test, object_type_path_paint, - object_type_path_desc + object_type_path_desc, + object_type_path_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1606,8 +2025,8 @@ static uint8* object_type_path_bit_load(void *objectEntry, uint32 entryIndex, in extendedEntryData += sizeof(rct_object_entry); sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1648,12 +2067,36 @@ static rct_string_id object_type_path_bit_desc(void *objectEntry) return STR_NONE; } +static void object_type_path_bit_reset(void *objectEntry, uint32 entryIndex) +{ + rct_scenery_entry* sceneryEntry = (rct_scenery_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_entry)); + + sceneryEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PATH_BITS, entryIndex, 0); + sceneryEntry->path_bit.scenery_tab_id = 0xFF; + if (*extendedEntryData != 0xFF) { + uint8 entry_type, entry_index; + if (find_object_in_entry_group((rct_object_entry*)extendedEntryData, &entry_type, &entry_index)){ + sceneryEntry->path_bit.scenery_tab_id = entry_index; + } + } + + extendedEntryData += sizeof(rct_object_entry); + sceneryEntry->image = object_chunk_load_image_directory(&extendedEntryData); + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_path_bit_vtable[] = { object_type_path_bit_load, object_type_path_bit_unload, object_type_path_bit_test, object_type_path_bit_paint, - object_type_path_bit_desc + object_type_path_bit_desc, + object_type_path_bit_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1675,12 +2118,11 @@ static uint8* object_type_scenery_set_load(void *objectEntry, uint32 entryIndex, scenerySetEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_SCENERY_SETS, entryIndex, 0); rct_object_entry *entryObjects = NULL; - uint32 eax = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)eax != 0xFFFFFFFF){ + uintptr_t eax = RCT2_GLOBAL(0x9ADAF4, uint32); + if (eax != (uintptr_t)0xFFFFFFFF){ *((uint16*)eax) = 0; entryObjects = (rct_object_entry*)(eax + 2); } - scenerySetEntry->entry_count = 0; scenerySetEntry->var_107 = 0; @@ -1754,12 +2196,69 @@ static rct_string_id object_type_scenery_set_desc(void *objectEntry) return STR_NONE; } +static void object_type_scenery_set_reset(void *objectEntry, uint32 entryIndex) +{ + rct_scenery_set_entry *scenerySetEntry = (rct_scenery_set_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_scenery_set_entry)); + + scenerySetEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_SCENERY_SETS, entryIndex, 0); + + rct_object_entry *entryObjects = NULL; + uintptr_t eax = RCT2_GLOBAL(0x9ADAF4, uint32); + if (eax != (uintptr_t)0xFFFFFFFF){ + *((uint16*)eax) = 0; + entryObjects = (rct_object_entry*)(eax + 2); + } + + scenerySetEntry->entry_count = 0; + scenerySetEntry->var_107 = 0; + + for (; *extendedEntryData != 0xFF; extendedEntryData += sizeof(rct_object_entry)) { + scenerySetEntry->var_107++; + + if (entryObjects != NULL){ + memcpy(entryObjects, extendedEntryData, sizeof(rct_object_entry)); + entryObjects++; + (*((uint16*)(eax + 1)))++; + } + uint8 entry_type; + uint8 entry_index = 0; + if (!find_object_in_entry_group((rct_object_entry*)extendedEntryData, &entry_type, &entry_index)) + continue; + + uint16 scenery_entry = entry_index; + + switch (entry_type){ + case OBJECT_TYPE_SMALL_SCENERY: + break; + case OBJECT_TYPE_LARGE_SCENERY: + scenery_entry |= 0x300; + break; + case OBJECT_TYPE_WALLS: + scenery_entry |= 0x200; + break; + case OBJECT_TYPE_PATH_BITS: + scenery_entry |= 0x100; + break; + default: + scenery_entry |= 0x400; + break; + } + + scenerySetEntry->scenery_entries[scenerySetEntry->entry_count++] = scenery_entry; + } + + extendedEntryData++; + scenerySetEntry->image = object_chunk_load_image_directory(&extendedEntryData); +} + static const object_type_vtable object_type_scenery_set_vtable[] = { object_type_scenery_set_load, object_type_scenery_set_unload, object_type_scenery_set_test, object_type_scenery_set_paint, - object_type_scenery_set_desc + object_type_scenery_set_desc, + object_type_scenery_set_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1781,8 +2280,8 @@ static uint8* object_type_park_entrance_load(void *objectEntry, uint32 entryInde entranceType->string_idx = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PARK_ENTRANCE, entryIndex, 0); entranceType->image_id = object_chunk_load_image_directory(&extendedEntryData); - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1823,12 +2322,27 @@ static rct_string_id object_type_park_entrance_desc(void *objectEntry) return STR_NONE; } +static bool object_type_park_entrance_reset(void *objectEntry, uint32 entryIndex) +{ + rct_entrance_type *entranceType = (rct_entrance_type*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_entrance_type)); + + entranceType->string_idx = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PARK_ENTRANCE, entryIndex, 0); + entranceType->image_id = object_chunk_load_image_directory(&extendedEntryData); + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_park_entrance_vtable[] = { object_type_park_entrance_load, object_type_park_entrance_unload, object_type_park_entrance_test, object_type_park_entrance_paint, - object_type_park_entrance_desc + object_type_park_entrance_desc, + object_type_park_entrance_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1854,8 +2368,8 @@ static uint8* object_type_water_load(void *objectEntry, uint32 entryIndex, int * waterEntry->var_06 = imageId + 1; waterEntry->var_0A = imageId + 4; - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1894,12 +2408,36 @@ static rct_string_id object_type_water_desc(void *objectEntry) return STR_NONE; } +static void object_type_water_reset(void *objectEntry, uint32 entryIndex) +{ + rct_water_type *waterEntry = (rct_water_type*)objectEntry; + + uint8 *pStringTable = (uint8*)((size_t)objectEntry + sizeof(rct_water_type)); + waterEntry->string_idx = object_get_localised_text(&pStringTable, OBJECT_TYPE_WATER, entryIndex, 0); + + int imageId = object_chunk_load_image_directory(&pStringTable); + waterEntry->image_id = imageId; + waterEntry->var_06 = imageId + 1; + waterEntry->var_0A = imageId + 4; + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } + + if (RCT2_GLOBAL(0x009ADAFD, uint8) == 0) { + load_palette(); + gfx_invalidate_screen(); + } +} + static const object_type_vtable object_type_water_vtable[] = { object_type_water_load, object_type_water_unload, object_type_water_test, object_type_water_paint, - object_type_water_desc + object_type_water_desc, + object_type_water_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -1922,8 +2460,8 @@ static uint8* object_type_stex_load(void *objectEntry, uint32 entryIndex, int *c stexEntry->park_name = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 1); stexEntry->details = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 2); - uint32 some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); - if ((uint32)some_pointer != 0xFFFFFFFF){ + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ *((uint16*)some_pointer) = 0; } @@ -1957,12 +2495,28 @@ static rct_string_id object_type_stex_desc(void *objectEntry) return stexEntry->details; } +static void object_type_stex_reset(void *objectEntry, uint32 entryIndex) +{ + rct_stex_entry *stexEntry = (rct_stex_entry*)objectEntry; + uint8 *stringTable = (uint8*)((size_t)objectEntry + (size_t)0x08); + + stexEntry->scenario_name = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 0); + stexEntry->park_name = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 1); + stexEntry->details = object_get_localised_text(&stringTable, OBJECT_TYPE_SCENARIO_TEXT, entryIndex, 2); + + uintptr_t some_pointer = RCT2_GLOBAL(0x9ADAF4, uint32); + if (some_pointer != (uintptr_t)0xFFFFFFFF){ + *((uint16*)some_pointer) = 0; + } +} + static const object_type_vtable object_type_stex_vtable[] = { object_type_stex_load, object_type_stex_unload, object_type_stex_test, object_type_stex_paint, - object_type_stex_desc + object_type_stex_desc, + object_type_stex_reset, }; /////////////////////////////////////////////////////////////////////////////// @@ -2016,6 +2570,13 @@ rct_string_id object_desc(int type, void *objectEntry) return vtable->desc(objectEntry); } +void object_reset(int type, void *objectEntry, uint32 entryIndex) +{ + assert(type >= OBJECT_TYPE_RIDE && type <= OBJECT_TYPE_SCENARIO_TEXT); + const object_type_vtable *vtable = object_type_vtables[type]; + return vtable->reset(objectEntry, entryIndex); +} + /** * * rct2: 0x006A9428 diff --git a/src/object.h b/src/object.h index b7f7c97bd1..96cf73d6fb 100644 --- a/src/object.h +++ b/src/object.h @@ -144,5 +144,6 @@ void object_unload(int type, void *objectEntry); bool object_test(int type, void *objectEntry); void object_paint(int type, void *objectEntry, rct_drawpixelinfo *dpi, sint32 x, sint32 y); rct_string_id object_desc(int type, void *objectEntry); +void object_reset(int type, void *objectEntry, uint32 entryIndex); #endif diff --git a/src/object_list.c b/src/object_list.c index f527a04cfe..ec2edc29a3 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -229,7 +229,6 @@ static void object_list_examine() */ void reset_loaded_objects() { - return; reset_type_to_ride_entry_index_map(); RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E; @@ -238,7 +237,7 @@ void reset_loaded_objects() for (int j = 0; j < object_entry_group_counts[type]; j++){ uint8* chunk = object_entry_groups[type].chunks[j]; if (chunk != (uint8*)-1) - object_load(type, chunk, j, NULL); + object_reset(type, chunk, j); } } } diff --git a/src/ride/ride.c b/src/ride/ride.c index 17db2226ba..85d18073ef 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -6923,8 +6923,10 @@ void set_vehicle_type_image_max_sizes(rct_ride_entry_vehicle* vehicle_type, int .zoom_level = 0 }; - for (int i = 0; i < num_images; ++i){ - gfx_draw_sprite_software(&dpi, vehicle_type->base_image_id + i, 0, 0, 0); + if (!gOpenRCT2Headless) { + for (int i = 0; i < num_images; ++i){ + gfx_draw_sprite_software(&dpi, vehicle_type->base_image_id + i, 0, 0, 0); + } } int al = -1; for (int i = 99; i != 0; --i){ From ded905a259ea72c4bc797ccfd180576e67bb4750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 1 May 2016 19:11:41 +0200 Subject: [PATCH 03/17] Fixes to object loading --- src/common.h | 2 ++ src/object.c | 20 ++++++++++---------- src/openrct2.c | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/common.h b/src/common.h index cd2a13869c..9e6435a3df 100644 --- a/src/common.h +++ b/src/common.h @@ -32,6 +32,8 @@ #if defined(__i386__) || defined(_M_IX86) #define PLATFORM_X86 +#else +#define NO_RCT2 1 #endif #if defined(__LP64__) || defined(_WIN64) diff --git a/src/object.c b/src/object.c index 9f8731fbe7..59c0459947 100644 --- a/src/object.c +++ b/src/object.c @@ -822,15 +822,6 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c cur_vehicle_images_offset = image_index + vehicleEntry->no_seating_rows * vehicleEntry->no_vehicle_images; // 0x6DEB0D - if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_10)) { - int num_images = cur_vehicle_images_offset - vehicleEntry->base_image_id; - if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_13) { - num_images *= 2; - } - - set_vehicle_type_image_max_sizes(vehicleEntry, num_images); - } - // Copy the vehicle entry over to new one outVehicleEntry->rotation_frame_mask = vehicleEntry->rotation_frame_mask; outVehicleEntry->var_02 = vehicleEntry->var_02; @@ -876,6 +867,15 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c outVehicleEntry->draw_order = vehicleEntry->draw_order; outVehicleEntry->special_frames = vehicleEntry->special_frames; + if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_10)) { + int num_images = cur_vehicle_images_offset - vehicleEntry->base_image_id; + if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_13) { + num_images *= 2; + } + + set_vehicle_type_image_max_sizes(outVehicleEntry, num_images); + } + sint8 no_positions = *peep_loading_positions++; if (no_positions == -1) { // The no_positions is 16 bit skip over @@ -2322,7 +2322,7 @@ static rct_string_id object_type_park_entrance_desc(void *objectEntry) return STR_NONE; } -static bool object_type_park_entrance_reset(void *objectEntry, uint32 entryIndex) +static void object_type_park_entrance_reset(void *objectEntry, uint32 entryIndex) { rct_entrance_type *entranceType = (rct_entrance_type*)objectEntry; uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_entrance_type)); diff --git a/src/openrct2.c b/src/openrct2.c index e85d90d26b..f847cd1d55 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -49,6 +49,8 @@ #endif // defined(__unix__) int gExitCode; +int fdData; +void *segments; int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE; utf8 gOpenRCT2StartupActionPath[512] = { 0 }; @@ -338,6 +340,8 @@ void openrct2_dispose() language_close_all(); rct2_dispose(); config_release(); + munmap(segments, 16941056); + close(fdData); platform_free(); } @@ -524,6 +528,19 @@ bool openrct2_setup_rct2_segment() int pageSize = getpagesize(); int numPages = (len + pageSize - 1) / pageSize; unsigned char *dummy = malloc(numPages); + + fdData = open("openrct2_load", O_RDONLY); + if (fdData < 0) + { + log_fatal("failed to load rct2 data. cat openrct2_text openrct2_data > openrct2_load"); + exit(1); + } + segments = mmap((void*)0x401000, 16941056, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fdData, 0); + if (segments != (void*)0x401000) + { + log_fatal("mmap failed"); + exit(1); + } int err = mincore((void *)0x8a4000, len, dummy); bool pagesMissing = false; if (err != 0) From 580789bcf407653829de58e5267f32458f6e1565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 1 May 2016 22:52:52 +0200 Subject: [PATCH 04/17] Fixes to object loading for x86-64 --- src/drawing/drawing.c | 2 +- src/drawing/drawing.h | 19 ++++++++++++--- src/drawing/sprite.c | 17 ++------------ src/object.c | 54 ++++++++++++++++++++++++------------------- src/openrct2.c | 17 -------------- src/rct1.c | 15 +++++++++--- src/rct1.h | 1 + 7 files changed, 62 insertions(+), 63 deletions(-) diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index 55eb628397..e4ddeb5759 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -144,7 +144,7 @@ void load_palette(){ uint32 palette = 0x5FC; - if ((sint32)water_type != -1){ + if ((uintptr_t)water_type != (uint32)-1){ palette = water_type->image_id; } diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index 8321c688ef..d06b5df4e6 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -24,8 +24,9 @@ #ifndef NO_RCT2 #pragma pack(push, 1) #endif -// Size: 0x10 -typedef struct rct_g1_element { + +// Size: 0x10 or more +typedef struct { uint8* offset; // 0x00 sint16 width; // 0x04 sint16 height; // 0x06 @@ -57,7 +58,19 @@ typedef struct rct_drawpixelinfo { assert_struct_size(rct_drawpixelinfo, 0x10); #endif -enum { +// Size: 0x10 +typedef struct rct_g1_element_32bit { + uint32 offset; // 0x00 note: uint32 always! + sint16 width; // 0x04 + sint16 height; // 0x06 + sint16 x_offset; // 0x08 + sint16 y_offset; // 0x0A + uint16 flags; // 0x0C + uint16 zoomed_offset; // 0x0E +} rct_g1_element_32bit; +assert_struct_size(rct_g1_element_32bit, 0x10); + +enum{ G1_FLAG_BMP = (1 << 0), //No invisible sections G1_FLAG_RLE_COMPRESSION = (1<<2), }; diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 4787ed7684..d0c33b63db 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -52,20 +52,6 @@ int gfx_load_g1() * pointers to however long our machine wants them. */ - #pragma pack(push, 1) - // Size: 0x10 - typedef struct { - uint32 offset; // 0x00 note: uint32 always! - sint16 width; // 0x04 - sint16 height; // 0x06 - sint16 x_offset; // 0x08 - sint16 y_offset; // 0x0A - uint16 flags; // 0x0C - uint16 zoomed_offset; // 0x0E - } rct_g1_element_32bit; - assert_struct_size(rct_g1_element_32bit, 0x10); - #pragma pack(pop) - /* number of elements is stored in g1.dat, but because the entry * headers are static, this can't be variable until made into a * dynamic array. @@ -97,8 +83,9 @@ int gfx_load_g1() SDL_RWclose(file); // Fix entry data offsets - for (i = 0; i < header.num_entries; i++) + for (i = 0; i < header.num_entries; i++) { g1Elements[i].offset += (uintptr_t)_g1Buffer; + } // Successful return 1; diff --git a/src/object.c b/src/object.c index 59c0459947..db2fb495b7 100644 --- a/src/object.c +++ b/src/object.c @@ -461,17 +461,23 @@ int object_chunk_load_image_directory(uint8_t** chunk) rct_g1_element* g1_dest = &g1Elements[image_start_no]; // After length of data is the start of all g1 element structs - rct_g1_element* g1_source = (rct_g1_element*)(*chunk); + rct_g1_element_32bit* g1_source = (rct_g1_element_32bit*)(*chunk); // After the g1 element structs is the actual images. - uint8* image_offset = no_images * sizeof(rct_g1_element) + (uint8*)g1_source; + uintptr_t image_offset = no_images * sizeof(rct_g1_element_32bit) + (uintptr_t)g1_source; - for (int i = 0; i < no_images; ++i){ - *g1_dest = *g1_source++; - g1_dest->offset += (uint32)image_offset; + for (int i = 0; i < no_images; ++i) { + g1_dest->offset = (uint8*)(g1_source->offset + image_offset); + g1_dest->width = g1_source->width; + g1_dest->height = g1_source->height; + g1_dest->x_offset = g1_source->x_offset; + g1_dest->y_offset = g1_source->y_offset; + g1_dest->flags = g1_source->flags; + g1_dest->zoomed_offset = g1_source->zoomed_offset; g1_dest++; drawing_engine_invalidate_image(image_start_no + i); + g1_source++; } *chunk = ((uint8*)g1_source) + length_of_data; @@ -919,12 +925,6 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c int di = rideEntry->ride_type[0] | (rideEntry->ride_type[1] << 8) | (rideEntry->ride_type[2] << 16); - if ((rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) && !rideTypeShouldLoseSeparateFlag(rideEntry)) { - di |= 0x1000000; - } - - RCT2_GLOBAL(0xF433DD, uint32) = di; - outRideEntry->name = rideEntry->name; outRideEntry->description = rideEntry->description; outRideEntry->images_offset = rideEntry->images_offset; @@ -955,7 +955,13 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c outRideEntry->shop_item = rideEntry->shop_item; outRideEntry->shop_item_secondary = rideEntry->shop_item_secondary; - return outRideEntry; + if ((rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) && !rideTypeShouldLoseSeparateFlag(outRideEntry)) { + di |= 0x1000000; + } + + RCT2_GLOBAL(0xF433DD, uint32) = di; + + return (uint8*)outRideEntry; } static void object_type_ride_unload(void *objectEntry) @@ -1027,7 +1033,7 @@ static rct_string_id object_type_ride_desc(void *objectEntry) // Get description rct_string_id stringId = rideEntry->description; - if (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) || rideTypeShouldLoseSeparateFlag(rideEntry)) { + if (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) || rideTypeShouldLoseSeparateFlagByRideType(rideEntry->ride_type)) { uint8 rideType = rideEntry->ride_type[0]; if (rideType == 0xFF) { rideType = rideEntry->ride_type[1]; @@ -1393,7 +1399,7 @@ static uint8* object_type_small_scenery_load(void *objectEntry, uint32 entryInde // pad_14 not needed set outSceneryEntry->small_scenery.scenery_tab_id = sceneryEntry->small_scenery.scenery_tab_id; - return true; + return (uint8*)outSceneryEntry; } static void object_type_small_scenery_unload(void *objectEntry) @@ -1509,7 +1515,7 @@ static const object_type_vtable object_type_small_scenery_vtable[] = { // Large Scenery (rct2: 0x006B92A7) /////////////////////////////////////////////////////////////////////////////// -static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex, int *chunkSize) +static uint8* object_type_large_scenery_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { rct_scenery_entry_32bit* sceneryEntry = (rct_scenery_entry_32bit*)objectEntry; const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x1A); @@ -1572,7 +1578,7 @@ static bool object_type_large_scenery_load(void *objectEntry, uint32 entryIndex, // var_12 is a pointer, already set outSceneryEntry->large_scenery.text_image = sceneryEntry->large_scenery.text_image; - return true; + return (uint8*)outSceneryEntry; } static void object_type_large_scenery_unload(void *objectEntry) @@ -1711,7 +1717,7 @@ static uint8* object_type_wall_load(void *objectEntry, uint32 entryIndex, int *c outSceneryEntry->wall.scenery_tab_id = sceneryEntry->wall.scenery_tab_id; outSceneryEntry->wall.var_0D = sceneryEntry->wall.var_0D; - return outSceneryEntry; + return (uint8*)outSceneryEntry; } @@ -1833,7 +1839,7 @@ static uint8* object_type_banner_load(void *objectEntry, uint32 entryIndex, int outSceneryEntry->banner.price = sceneryEntry->banner.price; outSceneryEntry->banner.scenery_tab_id = sceneryEntry->banner.scenery_tab_id; - return outSceneryEntry; + return (uint8*)outSceneryEntry; } static void object_type_banner_unload(void *objectEntry) @@ -1927,7 +1933,7 @@ static uint8* object_type_path_load(void *objectEntry, uint32 entryIndex) // rct_path_Type has no pointer, its size does not change, safe to memcpy memcpy(outPathEntry, pathEntry, sizeof(rct_path_type)); - return outPathEntry; + return (uint8*)outPathEntry; } static void object_type_path_unload(void *objectEntry) @@ -2038,7 +2044,7 @@ static uint8* object_type_path_bit_load(void *objectEntry, uint32 entryIndex, in outSceneryEntry->path_bit.price = sceneryEntry->path_bit.price; outSceneryEntry->path_bit.scenery_tab_id = sceneryEntry->path_bit.scenery_tab_id; - return outSceneryEntry; + return (uint8*)outSceneryEntry; } static void object_type_path_bit_unload(void *objectEntry) @@ -2166,7 +2172,7 @@ static uint8* object_type_scenery_set_load(void *objectEntry, uint32 entryIndex, memcpy(outSceneryEntry, scenerySetEntry, sizeof(rct_scenery_set_entry)); - return outSceneryEntry; + return (uint8*)outSceneryEntry; } static void object_type_scenery_set_unload(void *objectEntry) @@ -2287,7 +2293,7 @@ static uint8* object_type_park_entrance_load(void *objectEntry, uint32 entryInde memcpy(outEntranceType, entranceType, sizeof(rct_entrance_type)); - return outEntranceType; + return (uint8*)outEntranceType; } static void object_type_park_entrance_unload(void *objectEntry) @@ -2380,7 +2386,7 @@ static uint8* object_type_water_load(void *objectEntry, uint32 entryIndex, int * memcpy(outWaterEntry, waterEntry, sizeof(rct_water_type)); - return outWaterEntry; + return (uint8*)outWaterEntry; } static void object_type_water_unload(void *objectEntry) @@ -2467,7 +2473,7 @@ static uint8* object_type_stex_load(void *objectEntry, uint32 entryIndex, int *c memcpy(outStexEntry, stexEntry, sizeof(rct_stex_entry)); - return outStexEntry; + return (uint8*)outStexEntry; } static void object_type_stex_unload(void *objectEntry) diff --git a/src/openrct2.c b/src/openrct2.c index f847cd1d55..e85d90d26b 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -49,8 +49,6 @@ #endif // defined(__unix__) int gExitCode; -int fdData; -void *segments; int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE; utf8 gOpenRCT2StartupActionPath[512] = { 0 }; @@ -340,8 +338,6 @@ void openrct2_dispose() language_close_all(); rct2_dispose(); config_release(); - munmap(segments, 16941056); - close(fdData); platform_free(); } @@ -528,19 +524,6 @@ bool openrct2_setup_rct2_segment() int pageSize = getpagesize(); int numPages = (len + pageSize - 1) / pageSize; unsigned char *dummy = malloc(numPages); - - fdData = open("openrct2_load", O_RDONLY); - if (fdData < 0) - { - log_fatal("failed to load rct2 data. cat openrct2_text openrct2_data > openrct2_load"); - exit(1); - } - segments = mmap((void*)0x401000, 16941056, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fdData, 0); - if (segments != (void*)0x401000) - { - log_fatal("mmap failed"); - exit(1); - } int err = mincore((void *)0x8a4000, len, dummy); bool pagesMissing = false; if (err != 0) diff --git a/src/rct1.c b/src/rct1.c index 04c2356359..8864ae7591 100644 --- a/src/rct1.c +++ b/src/rct1.c @@ -78,7 +78,11 @@ bool rct1_read_sv4(const char *path, rct1_s4 *s4) return success; } -bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry) +/** + * Only to be used when loading 32 bit items from files, otherwise use + * rideTypeShouldLoseSeparateFlag. + */ +bool rideTypeShouldLoseSeparateFlagByRideType(uint8 ride_type[3]) { if (!gConfigInterface.select_by_track_type) { return false; @@ -86,16 +90,21 @@ bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry) bool remove_flag = true; for (int j = 0; j < 3; j++) { - if (ride_type_has_flag(rideEntry->ride_type[j], RIDE_TYPE_FLAG_FLAT_RIDE)) { + if (ride_type_has_flag(ride_type[j], RIDE_TYPE_FLAG_FLAT_RIDE)) { remove_flag = false; } - if (rideEntry->ride_type[j] == RIDE_TYPE_MAZE || rideEntry->ride_type[j] == RIDE_TYPE_MINI_GOLF) { + if (ride_type[j] == RIDE_TYPE_MAZE || ride_type[j] == RIDE_TYPE_MINI_GOLF) { remove_flag = false; } } return remove_flag; } +bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry) +{ + return rideTypeShouldLoseSeparateFlagByRideType(rideEntry->ride_type); +} + const uint8 gRideCategories[] = { 2, // Spiral Roller coaster 2, // Stand Up Coaster diff --git a/src/rct1.h b/src/rct1.h index 4ae06a295e..4ac779c294 100644 --- a/src/rct1.h +++ b/src/rct1.h @@ -746,6 +746,7 @@ void rct1_import_s4(rct1_s4 *s4); void rct1_fix_landscape(); int vehicle_preference_compare(uint8 rideType, const char * a, const char * b); bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry); +bool rideTypeShouldLoseSeparateFlagByRideType(uint8 ride_type[3]); bool rct1_load_saved_game(const char *path); bool rct1_load_scenario(const char *path); From ea075fb736eb44abaa67686e072abea0aaa7c092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 3 May 2016 16:47:31 +0200 Subject: [PATCH 05/17] Fix VS warning --- src/object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object.c b/src/object.c index db2fb495b7..c524485b97 100644 --- a/src/object.c +++ b/src/object.c @@ -2580,7 +2580,7 @@ void object_reset(int type, void *objectEntry, uint32 entryIndex) { assert(type >= OBJECT_TYPE_RIDE && type <= OBJECT_TYPE_SCENARIO_TEXT); const object_type_vtable *vtable = object_type_vtables[type]; - return vtable->reset(objectEntry, entryIndex); + vtable->reset(objectEntry, entryIndex); } /** From 2273626bddfec0e06d636a60b16a9ff435164ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 3 May 2016 17:37:16 +0200 Subject: [PATCH 06/17] Refactor gX.dat loading, make sure g2.dat loads too --- src/drawing/sprite.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index d0c33b63db..cf4dc11582 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -31,6 +31,25 @@ rct_gx g2; rct_g1_element *g1Elements = (rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS; #endif +static void read_and_convert_gxdat(SDL_RWops *file, size_t count, rct_g1_element *elements) +{ + rct_g1_element_32bit *g1Elements32 = calloc(count, sizeof(rct_g1_element_32bit)); + SDL_RWread(file, g1Elements32, count * sizeof(rct_g1_element_32bit), 1); + for (size_t i = 0; i < count; i++) { + /* Double cast to silence compiler warning about casting to + * pointer from integer of mismatched length. + */ + elements[i].offset = (uint8*)(uintptr_t)g1Elements32[i].offset; + elements[i].width = g1Elements32[i].width; + elements[i].height = g1Elements32[i].height; + elements[i].x_offset = g1Elements32[i].x_offset; + elements[i].y_offset = g1Elements32[i].y_offset; + elements[i].flags = g1Elements32[i].flags; + elements[i].zoomed_offset = g1Elements32[i].zoomed_offset; + } + free(g1Elements32); +} + /** * * rct2: 0x00678998 @@ -63,18 +82,7 @@ int gfx_load_g1() g1Elements = calloc(324206, sizeof(rct_g1_element)); #endif - rct_g1_element_32bit *g1Elements32 = calloc(324206, sizeof(rct_g1_element_32bit)); - SDL_RWread(file, g1Elements32, header.num_entries * sizeof(rct_g1_element_32bit), 1); - for (uint32 i = 0; i < header.num_entries; i++) { - g1Elements[i].offset = (uint8*)g1Elements32[i].offset; - g1Elements[i].width = g1Elements32[i].width; - g1Elements[i].height = g1Elements32[i].height; - g1Elements[i].x_offset = g1Elements32[i].x_offset; - g1Elements[i].y_offset = g1Elements32[i].y_offset; - g1Elements[i].flags = g1Elements32[i].flags; - g1Elements[i].zoomed_offset = g1Elements32[i].zoomed_offset; - } - free(g1Elements32); + read_and_convert_gxdat(file, header.num_entries, g1Elements); // Read element data _g1Buffer = malloc(header.total_size); @@ -128,7 +136,8 @@ int gfx_load_g2() if (SDL_RWread(file, &g2.header, 8, 1) == 1) { // Read element headers g2.elements = malloc(g2.header.num_entries * sizeof(rct_g1_element)); - SDL_RWread(file, g2.elements, g2.header.num_entries * sizeof(rct_g1_element), 1); + + read_and_convert_gxdat(file, g2.header.num_entries, g2.elements); // Read element data g2.data = malloc(g2.header.total_size); From 30d0e35b17364aa54cb030f8de9dbc40d3914a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 17 Jun 2016 15:55:55 +0200 Subject: [PATCH 07/17] Rebase fixes --- src/object.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/object.c b/src/object.c index c524485b97..bf73270680 100644 --- a/src/object.c +++ b/src/object.c @@ -568,7 +568,7 @@ typedef struct rct_ride_entry_vehicle_32bit { uint8 powered_acceleration; // 0x5B , 0x75 uint8 powered_max_speed; // 0x5C , 0x76 uint8 car_visual; // 0x5D , 0x77 - uint8 pad_5E; + uint8 effect_visual; uint8 draw_order; uint8 special_frames; // 0x60 , 0x7A uint32 peep_loading_positions; // 0x61 , 0x7B note: uint32 @@ -869,7 +869,7 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c outVehicleEntry->powered_acceleration = vehicleEntry->powered_acceleration; outVehicleEntry->powered_max_speed = vehicleEntry->powered_max_speed; outVehicleEntry->car_visual = vehicleEntry->car_visual; - outVehicleEntry->pad_5E = vehicleEntry->pad_5E; + outVehicleEntry->effect_visual = vehicleEntry->effect_visual; outVehicleEntry->draw_order = vehicleEntry->draw_order; outVehicleEntry->special_frames = vehicleEntry->special_frames; @@ -1634,7 +1634,7 @@ static void object_type_large_scenery_reset(void *objectEntry, uint32 entryIndex extendedEntryData += sizeof(rct_object_entry); if (sceneryEntry->large_scenery.flags & (1 << 2)) { - sceneryEntry->large_scenery.var_12 = (uintptr_t)extendedEntryData; + sceneryEntry->large_scenery.text = (rct_large_scenery_text *)extendedEntryData; extendedEntryData += 1038; } @@ -1649,9 +1649,9 @@ static void object_type_large_scenery_reset(void *objectEntry, uint32 entryIndex int imageId = object_chunk_load_image_directory(&extendedEntryData); if (sceneryEntry->large_scenery.flags & (1 << 2)){ - sceneryEntry->large_scenery.var_16 = imageId; + sceneryEntry->large_scenery.text_image = imageId; - uint8* edx = (uint8*)sceneryEntry->large_scenery.var_12; + uint8* edx = (uint8*)sceneryEntry->large_scenery.text; if (!(edx[0xC] & 1)) { imageId += edx[0xD] * 4; } else{ @@ -1907,7 +1907,7 @@ static const object_type_vtable object_type_banner_vtable[] = { // Path (rct2: 0x006A8621) /////////////////////////////////////////////////////////////////////////////// -static uint8* object_type_path_load(void *objectEntry, uint32 entryIndex) +static uint8* object_type_path_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { rct_footpath_entry *pathEntry = (rct_footpath_entry*)objectEntry; const uint8 *origExtendedEntryData = (uint8*)((size_t)objectEntry + 0x0E); @@ -1931,7 +1931,7 @@ static uint8* object_type_path_load(void *objectEntry, uint32 entryIndex) } // rct_path_Type has no pointer, its size does not change, safe to memcpy - memcpy(outPathEntry, pathEntry, sizeof(rct_path_type)); + memcpy(outPathEntry, pathEntry, sizeof(rct_footpath_entry)); return (uint8*)outPathEntry; } @@ -1965,8 +1965,8 @@ static rct_string_id object_type_path_desc(void *objectEntry) static void object_type_path_reset(void *objectEntry, uint32 entryIndex) { - rct_path_type *pathEntry = (rct_path_type*)objectEntry; - uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_path_type)); + rct_footpath_entry *pathEntry = (rct_footpath_entry*)objectEntry; + uint8 *extendedEntryData = (uint8*)((size_t)objectEntry + sizeof(rct_footpath_entry)); pathEntry->string_idx = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_PATHS, entryIndex, 0); @@ -1982,8 +1982,8 @@ static void object_type_path_reset(void *objectEntry, uint32 entryIndex) gFootpathSelectedId = 0; // Set the default path for when opening footpath window for (int i = 0; i < object_entry_group_counts[OBJECT_TYPE_PATHS]; i++) { - rct_path_type *pathEntry2 = (rct_path_type*)object_entry_groups[OBJECT_TYPE_PATHS].chunks[i]; - if (pathEntry2 == (rct_path_type*)-1) { + rct_footpath_entry *pathEntry2 = (rct_footpath_entry*)object_entry_groups[OBJECT_TYPE_PATHS].chunks[i]; + if (pathEntry2 == (rct_footpath_entry*)-1) { continue; } if (!(pathEntry2->flags & 4)) { @@ -2038,8 +2038,8 @@ static uint8* object_type_path_bit_load(void *objectEntry, uint32 entryIndex, in outSceneryEntry->name = sceneryEntry->name; outSceneryEntry->image = sceneryEntry->image; - outSceneryEntry->path_bit.var_06 = sceneryEntry->path_bit.var_06; - outSceneryEntry->path_bit.pad_08 = sceneryEntry->path_bit.pad_08; + outSceneryEntry->path_bit.flags = sceneryEntry->path_bit.flags; + outSceneryEntry->path_bit.draw_type = sceneryEntry->path_bit.draw_type; outSceneryEntry->path_bit.tool_id = sceneryEntry->path_bit.tool_id; outSceneryEntry->path_bit.price = sceneryEntry->path_bit.price; outSceneryEntry->path_bit.scenery_tab_id = sceneryEntry->path_bit.scenery_tab_id; @@ -2559,6 +2559,7 @@ bool object_test(int type, void *objectEntry) { assert(type >= OBJECT_TYPE_RIDE && type <= OBJECT_TYPE_SCENARIO_TEXT); const object_type_vtable *vtable = object_type_vtables[type]; + log_warning("type = %d", type); return vtable->test(objectEntry); } From 858a781347de55eb0102a25a081e61bb643783ca Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 4 May 2016 00:03:17 +0100 Subject: [PATCH 08/17] remove RCT2 memory checksum for Win32 NO_RCT2 --- src/openrct2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openrct2.c b/src/openrct2.c index e85d90d26b..7b4dd5dbe5 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -571,6 +571,7 @@ bool openrct2_setup_rct2_segment() } #endif // defined(__unix__) +#if !defined(NO_RCT2) || !defined(__WINDOWS__) // Check that the expected data is at various addresses. // Start at 0x9a6000, which is start of .data, to skip the region containing addresses to DLL // calls, which can be changed by windows/wine loader. @@ -583,6 +584,7 @@ bool openrct2_setup_rct2_segment() log_warning("c2 = %u, expected %u, match %d", c2, exp_c2, c2 == exp_c2); return false; } +#endif return true; } From 613c7250f2a329eb76d52ef52b999f21c8a86d9d Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 4 May 2016 21:25:49 +0100 Subject: [PATCH 09/17] print NO_RCT2 flag in version info for binary confidence --- src/cmdline/RootCommands.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cmdline/RootCommands.cpp b/src/cmdline/RootCommands.cpp index 32c1e2045e..89f0a29571 100644 --- a/src/cmdline/RootCommands.cpp +++ b/src/cmdline/RootCommands.cpp @@ -411,6 +411,9 @@ static void PrintVersion() openrct2_write_full_version_info(buffer, sizeof(buffer)); Console::WriteLine(buffer); Console::WriteFormat("%s (%s)", OPENRCT2_PLATFORM, OPENRCT2_ARCHITECTURE); +#if NO_RCT2 + Console::Write(" (NO_RCT2)"); +#endif Console::WriteLine(); } From 58b4361e8d3db6a81a9de3913f349fc047e920ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 17 Jun 2016 22:48:42 +0200 Subject: [PATCH 10/17] Pack structs for when loading from files --- src/object.c | 9 +++++++++ src/ride/ride.h | 4 +--- src/ride/vehicle.h | 4 +--- src/world/scenery.h | 11 +++-------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/object.c b/src/object.c index bf73270680..c1658c264a 100644 --- a/src/object.c +++ b/src/object.c @@ -523,6 +523,7 @@ typedef struct object_type_vtable { // Ride (rct2: 0x006E6E2A) /////////////////////////////////////////////////////////////////////////////// +#pragma pack(push, 1) /** * Ride type vehicle structure. * size: 0x65 @@ -573,6 +574,7 @@ typedef struct rct_ride_entry_vehicle_32bit { uint8 special_frames; // 0x60 , 0x7A uint32 peep_loading_positions; // 0x61 , 0x7B note: uint32 } rct_ride_entry_vehicle_32bit; +assert_struct_size(rct_ride_entry_vehicle_32bit, 0x65); /** * Ride type structure. @@ -617,6 +619,8 @@ typedef struct rct_ride_entry_32bit { uint8 shop_item; // 0x1C0 uint8 shop_item_secondary; // 0x1C1 } rct_ride_entry_32bit; +assert_struct_size(rct_ride_entry_32bit, 0x1c2); +#pragma pack(pop) static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { @@ -1317,6 +1321,7 @@ static const object_type_vtable object_type_ride_vtable[] = { // Small Scenery (rct2: 0x006E3466) /////////////////////////////////////////////////////////////////////////////// +#pragma pack(push, 1) typedef struct rct_large_scenery_entry_32bit { uint8 tool_id; // 0x06 uint8 flags; // 0x07 @@ -1328,6 +1333,7 @@ typedef struct rct_large_scenery_entry_32bit { uint32 text; uint32 text_image; } rct_large_scenery_entry_32bit; +assert_struct_size(rct_large_scenery_entry_32bit, 20); typedef struct rct_small_scenery_entry_32bit { uint32 flags; // 0x06 @@ -1339,6 +1345,7 @@ typedef struct rct_small_scenery_entry_32bit { uint8 pad_14[0x06]; uint8 scenery_tab_id; // 0x1A } rct_small_scenery_entry_32bit; +assert_struct_size(rct_small_scenery_entry_32bit, 21); typedef struct rct_scenery_entry_32bit { rct_string_id name; // 0x00 @@ -1351,6 +1358,8 @@ typedef struct rct_scenery_entry_32bit { rct_banner_scenery_entry banner; }; } rct_scenery_entry_32bit; +assert_struct_size(rct_scenery_entry_32bit, 6 + 21); +#pragma pack(pop) static uint8* object_type_small_scenery_load(void *objectEntry, uint32 entryIndex, int *chunkSize) { diff --git a/src/ride/ride.h b/src/ride/ride.h index 3efc434c87..69809cbe7c 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -122,9 +122,7 @@ typedef struct rct_ride_entry { uint8 shop_item; // 0x1C0 uint8 shop_item_secondary; // 0x1C1 } rct_ride_entry; -#ifdef PLATFORM_32BIT -assert_struct_size(rct_ride_entry, 0x1c2); -#endif +// FIXME: unpack /** * Ride structure. diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h index 424fd2e21f..df7eca6e86 100644 --- a/src/ride/vehicle.h +++ b/src/ride/vehicle.h @@ -77,9 +77,7 @@ typedef struct rct_ride_entry_vehicle { uint8 special_frames; // 0x60 , 0x7A sint8* peep_loading_positions; // 0x61 , 0x7B } rct_ride_entry_vehicle; -#ifdef PLATFORM_32BIT -assert_struct_size(rct_ride_entry_vehicle, 0x65); -#endif +// FIXME: unpack typedef struct rct_vehicle { uint8 sprite_identifier; // 0x00 diff --git a/src/world/scenery.h b/src/world/scenery.h index 0f46018a55..5b83792066 100644 --- a/src/world/scenery.h +++ b/src/world/scenery.h @@ -21,7 +21,6 @@ #include "../object.h" #include "../world/map.h" -#pragma pack(push, 1) typedef struct rct_small_scenery_entry { uint32 flags; // 0x06 uint8 height; // 0x0A @@ -34,7 +33,6 @@ typedef struct rct_small_scenery_entry { uint16 var_18; uint8 scenery_tab_id; // 0x1A } rct_small_scenery_entry; -assert_struct_size(rct_small_scenery_entry, 21); typedef enum { SMALL_SCENERY_FLAG_FULL_TILE = (1 << 0), // 0x1 @@ -67,6 +65,7 @@ typedef enum { SMALL_SCENERY_FLAG27 = (1 << 27), // 0x8000000 } SMALL_SCENERY_FLAGS; +#pragma pack(push, 1) typedef struct rct_large_scenery_tile { sint16 x_offset; sint16 y_offset; @@ -104,9 +103,7 @@ typedef struct rct_large_scenery_entry { rct_large_scenery_text* text; // 0x12 uint32 text_image; // 0x16 } rct_large_scenery_entry; -#ifdef PLATFORM_32BIT -assert_struct_size(rct_large_scenery_entry, 20); -#endif +// FIXME: unpack typedef struct rct_wall_scenery_entry { uint8 tool_id; // 0x06 @@ -162,9 +159,7 @@ typedef struct rct_scenery_entry { rct_banner_scenery_entry banner; }; } rct_scenery_entry; -#ifdef PLATFORM_32BIT -assert_struct_size(rct_scenery_entry, 6 + 21); -#endif +// FIXME: unpack? typedef struct rct_scenery_set_entry { rct_string_id name; // 0x00 From 4d62d79528183be09376834ce1ef4045718c73c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 17 Jun 2016 22:53:24 +0200 Subject: [PATCH 11/17] Remove debugging messages --- src/object.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/object.c b/src/object.c index c1658c264a..3d1256ce0d 100644 --- a/src/object.c +++ b/src/object.c @@ -633,7 +633,6 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c assert(outRideEntry != NULL); uint8 *extendedEntryData = (uint8*)((size_t)outRideEntry + sizeof(rct_ride_entry)); memcpy(extendedEntryData, origExtendedEntryData, extendedDataSize); - log_warning("loading ride %p", objectEntry); // After rideEntry is 3 string tables rideEntry->name = object_get_localised_text(&extendedEntryData, OBJECT_TYPE_RIDE, entryIndex, 0); @@ -1010,7 +1009,6 @@ static void object_type_ride_unload(void *objectEntry) static bool object_type_ride_test(void *objectEntry) { - log_warning("testing ride"); rct_ride_entry_32bit* rideEntry = (rct_ride_entry_32bit*)objectEntry; if (rideEntry->excitement_multipler > 75) return false; if (rideEntry->intensity_multipler > 75) return false; @@ -2568,7 +2566,6 @@ bool object_test(int type, void *objectEntry) { assert(type >= OBJECT_TYPE_RIDE && type <= OBJECT_TYPE_SCENARIO_TEXT); const object_type_vtable *vtable = object_type_vtables[type]; - log_warning("type = %d", type); return vtable->test(objectEntry); } From 39aaf851828e17ffece929c89828ef23849cd7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 17 Jun 2016 23:00:54 +0200 Subject: [PATCH 12/17] Remove config_apply_to_old_addresses, not used anymore --- src/config.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/config.c b/src/config.c index 07fb167ba4..59b7f49a9c 100644 --- a/src/config.c +++ b/src/config.c @@ -331,8 +331,6 @@ static void config_write_enum(SDL_RWops *file, uint8 type, value_union *value, c static void utf8_skip_whitespace(utf8 **outch); static void utf8_skip_non_whitespace(utf8 **outch); -void config_apply_to_old_addresses(); - static int rwopsreadc(SDL_RWops *file) { int c = 0; @@ -466,7 +464,6 @@ bool config_open_default() config_get_default_path(path); if (config_open(path)) { - config_apply_to_old_addresses(); return true; } @@ -479,7 +476,6 @@ bool config_save_default() config_get_default_path(path); if (config_save(path)) { - config_apply_to_old_addresses(); return true; } @@ -944,36 +940,6 @@ bool config_find_or_browse_install_directory() return true; } -#pragma region Obsolete - -/** - * Any code not implemented in OpenRCT2 will still uses the old configuration option addresses. This function copies all the - * OpenRCT2 configuration options to those addresses until the process is no longer necessary. - */ -void config_apply_to_old_addresses() -{ - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, sint8) = gConfigGeneral.edge_scrolling; - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, sint8) = gConfigGeneral.currency_format; - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gConfigGeneral.measurement_format; - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gConfigGeneral.temperature_format; - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8) = gConfigGeneral.construction_marker_colour; - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, sint16) = get_height_marker_offset(); - - int configFlags = 0; - if (gConfigGeneral.always_show_gridlines) - configFlags |= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; - if (!gConfigGeneral.landscape_smoothing) - configFlags |= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; - if (gConfigGeneral.show_height_as_units) - configFlags |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; - if (gConfigGeneral.save_plugin_data) - configFlags |= CONFIG_FLAG_SAVE_PLUGIN_DATA; - - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) = configFlags; -} - -#pragma endregion - #pragma region Shortcuts #define SHIFT 0x100 From cb4b9ba1c3506c7f282ed8bc992819624cabdefd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 19 Jun 2016 22:57:45 +0200 Subject: [PATCH 13/17] Integrate gTypeToRideEntryIndexMap --- src/object.c | 4 ++-- src/ride/ride.c | 8 ++++---- src/ride/ride.h | 2 ++ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/object.c b/src/object.c index 3d1256ce0d..b496fd79a4 100644 --- a/src/object.c +++ b/src/object.c @@ -903,7 +903,7 @@ static uint8* object_type_ride_load(void *objectEntry, uint32 entryIndex, int *c continue; } - uint8 *typeToRideEntryIndexMap = RCT2_ADDRESS(0x009E32F8, uint8); + uint8 *typeToRideEntryIndexMap = gTypeToRideEntryIndexMap; while (dl >= 0) { if (*typeToRideEntryIndexMap++ == 0xFF) { dl--; @@ -1275,7 +1275,7 @@ static void object_type_ride_reset(void *objectEntry, uint32 entryIndex) continue; } - uint8 *typeToRideEntryIndexMap = RCT2_ADDRESS(0x009E32F8, uint8); + uint8 *typeToRideEntryIndexMap = gTypeToRideEntryIndexMap; while (dl >= 0) { if (*typeToRideEntryIndexMap++ == 0xFF) { dl--; diff --git a/src/ride/ride.c b/src/ride/ride.c index 85d18073ef..40df29bc6a 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -121,6 +121,8 @@ const uint8 gRideClassifications[255] = { RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE, RIDE_CLASS_RIDE }; +uint8 gTypeToRideEntryIndexMap[91]; + #pragma endregion static const int RideInspectionInterval[] = { @@ -250,14 +252,12 @@ rct_ride_entry *get_ride_entry_by_ride(rct_ride *ride) * rct2: 0x006DED68 */ void reset_type_to_ride_entry_index_map(){ - uint8* typeToRideEntryIndexMap = RCT2_ADDRESS(0x009E32F8, uint8); - memset(typeToRideEntryIndexMap, 0xFF, 91); + memset(gTypeToRideEntryIndexMap, 0xFF, 91); } uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType) { - uint8 *typeToRideEntryIndexMap = (uint8*)0x009E32F8; - uint8 *entryIndexList = typeToRideEntryIndexMap; + uint8 *entryIndexList = gTypeToRideEntryIndexMap; while (rideType > 0) { do { entryIndexList++; diff --git a/src/ride/ride.h b/src/ride/ride.h index 69809cbe7c..338f47ea81 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -369,6 +369,8 @@ assert_struct_size(track_begin_end, 36); #pragma pack(pop) +extern uint8 gTypeToRideEntryIndexMap[]; + enum { RIDE_CLASS_RIDE, RIDE_CLASS_SHOP_OR_STALL, From 5a1d802a6a8f661dc51778475a180c896e5054f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 19 Jun 2016 23:03:05 +0200 Subject: [PATCH 14/17] Integrate gTotalNoImages --- src/object.c | 15 ++++++++------- src/object.h | 1 + src/object_list.c | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/object.c b/src/object.c index b496fd79a4..d8cd4a360b 100644 --- a/src/object.c +++ b/src/object.c @@ -31,6 +31,7 @@ #include "world/water.h" char gTempObjectLoadName[9] = { 0 }; +uint32 gTotalNoImages = 0; int object_load_entry(const utf8 *path, rct_object_entry *outEntry) { @@ -112,7 +113,7 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi return 0; } - if (RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) >= 0x4726E){ + if (gTotalNoImages >= 0x4726E){ log_error("Object Load failed due to too many images loaded."); free(chunk); return 0; @@ -293,7 +294,7 @@ int object_load_packed(SDL_RWops* rw) return 0; } - if (RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) >= 0x4726E){ + if (gTotalNoImages >= 0x4726E){ log_error("Packed object has too many images."); free(chunk); return 0; @@ -447,7 +448,7 @@ int object_calculate_checksum(const rct_object_entry *entry, const uint8 *data, */ int object_chunk_load_image_directory(uint8_t** chunk) { - int image_start_no = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32_t); + int image_start_no = gTotalNoImages; // First dword of chunk is no_images int no_images = *((uint32_t*)(*chunk)); @@ -456,7 +457,7 @@ int object_chunk_load_image_directory(uint8_t** chunk) int length_of_data = *((uint32_t*)(*chunk)); *chunk += 4; - RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32_t) = no_images + image_start_no; + gTotalNoImages = no_images + image_start_no; rct_g1_element* g1_dest = &g1Elements[image_start_no]; @@ -2650,12 +2651,12 @@ int object_get_scenario_text(rct_object_entry *entry) } // Save the real total images. - int total_no_images = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32); + int total_no_images = gTotalNoImages; // This is being changed to force the images to be loaded into a different // image id. chunk = object_load(openedEntry.flags & 0x0F, chunk, 0, &chunkSize); - RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0x726E; + gTotalNoImages = 0x726E; gStexTempChunk = (rct_stex_entry*)chunk; // Not used anywhere. RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT, rct_object_entry) = openedEntry; @@ -2669,7 +2670,7 @@ int object_get_scenario_text(rct_object_entry *entry) RCT2_GLOBAL(0x009ADAFC, uint8) = 0; // Not used?? RCT2_GLOBAL(0x009ADAFD, uint8) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = total_no_images; + gTotalNoImages = total_no_images; return 1; } log_error("Opened object didn't match."); diff --git a/src/object.h b/src/object.h index 96cf73d6fb..2cd15feb30 100644 --- a/src/object.h +++ b/src/object.h @@ -106,6 +106,7 @@ extern uint32 gInstalledObjectsCount; extern rct_object_entry *gInstalledObjects; extern uint32 gNumInstalledRCT2Objects; extern uint32 gNumInstalledCustomObjects; +extern uint32 gTotalNoImages; extern void *gLastLoadedObjectChunkData; diff --git a/src/object_list.c b/src/object_list.c index ec2edc29a3..7212a4625e 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -231,7 +231,7 @@ void reset_loaded_objects() { reset_type_to_ride_entry_index_map(); - RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E; + gTotalNoImages = 0xF26E; for (int type = 0; type < 11; ++type){ for (int j = 0; j < object_entry_group_counts[type]; j++){ @@ -782,7 +782,7 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in *((uint16*)(installed_entry_pointer + 9)) = 0; *((uint32*)(installed_entry_pointer + 11)) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E; + gTotalNoImages = 0xF26E; gInstalledObjectsCount++; @@ -835,7 +835,7 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in // This is deceptive. Due to setting the total no images earlier to 0xF26E // this is actually the no_images in this entry. - *((uint32*)installed_entry_pointer) = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) - 0xF26E; + *((uint32*)installed_entry_pointer) = gTotalNoImages - 0xF26E; installed_entry_pointer += 4; uint8* esi = RCT2_ADDRESS(0x00F42BDB, uint8); From ba7008df187ea345d5368c051632ba006d3ae88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 19 Jun 2016 23:19:38 +0200 Subject: [PATCH 15/17] Integrate some scenario variables gScenarioTicks is still being used in some of native code --- src/scenario.c | 15 +++++++++++++++ src/scenario.h | 22 +++++++++++++--------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/scenario.c b/src/scenario.c index 7f22310439..018bbea720 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -66,6 +66,21 @@ char gScenarioSavePath[MAX_PATH]; int gFirstTimeSave = 1; uint32 gLastAutoSaveTick = 0; +#if defined(NO_RCT2) +uint32 gScenarioTicks; +#endif +uint32 gScenarioSrand0; +uint32 gScenarioSrand1; + +uint8 gScenarioObjectiveType; +uint8 gScenarioObjectiveYear; +uint16 gScenarioObjectiveNumGuests; +money32 gScenarioObjectiveCurrency; + +uint16 gScenarioParkRatingWarningDays; +money32 gScenarioCompletedCompanyValue; +money32 gScenarioCompanyValueRecord; + static int scenario_create_ducks(); static void scenario_objective_check(); diff --git a/src/scenario.h b/src/scenario.h index b9fa0a576d..dd35641e2a 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -427,18 +427,22 @@ typedef struct source_desc { extern const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT]; +#if defined(NO_RCT2) +extern uint32 gScenarioTicks; +#else #define gScenarioTicks RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) -#define gScenarioSrand0 RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32) -#define gScenarioSrand1 RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_1, uint32) +#endif +extern uint32 gScenarioSrand0; +extern uint32 gScenarioSrand1; -#define gScenarioObjectiveType RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) -#define gScenarioObjectiveYear RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8) -#define gScenarioObjectiveNumGuests RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16) -#define gScenarioObjectiveCurrency RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_CURRENCY, money32) +extern uint8 gScenarioObjectiveType; +extern uint8 gScenarioObjectiveYear; +extern uint16 gScenarioObjectiveNumGuests; +extern money32 gScenarioObjectiveCurrency; -#define gScenarioParkRatingWarningDays RCT2_GLOBAL(RCT2_ADDRESS_PARK_RATING_WARNING_DAYS, uint16) -#define gScenarioCompletedCompanyValue RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, money32) -#define gScenarioCompanyValueRecord RCT2_GLOBAL(RCT2_ADDRESS_COMPANY_VALUE_RECORD, money32) +extern uint16 gScenarioParkRatingWarningDays; +extern money32 gScenarioCompletedCompanyValue; +extern money32 gScenarioCompanyValueRecord; // Scenario list extern int gScenarioListCount; From 402e5a32a05896f0ed44015f468b0306df0ebb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 19 Jun 2016 23:47:06 +0200 Subject: [PATCH 16/17] Integrate path variables used by game --- src/game.c | 2 +- src/interface/console.c | 2 +- src/object.c | 8 +++--- src/object_list.c | 6 ++--- src/openrct2.c | 4 +-- src/rct2.c | 60 +++++++++++++++++++++-------------------- src/rct2.h | 7 +++++ src/scenario.c | 8 +++--- src/windows/loadsave.c | 2 +- 9 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/game.c b/src/game.c index d58214672c..9cdff4b448 100644 --- a/src/game.c +++ b/src/game.c @@ -783,7 +783,7 @@ bool game_load_save(const utf8 *path) log_verbose("loading saved game, %s", path); safe_strcpy((char*)0x0141EF68, path, MAX_PATH); - safe_strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, path, MAX_PATH); + safe_strcpy((char*)gRCT2AddressSavedGamesPath2, path, MAX_PATH); safe_strcpy(gScenarioSavePath, path, MAX_PATH); diff --git a/src/interface/console.c b/src/interface/console.c index 6bfde3df3b..998aa73a15 100644 --- a/src/interface/console.c +++ b/src/interface/console.c @@ -893,7 +893,7 @@ static int cc_load_object(const utf8 **argv, int argc) { if (argc > 0) { utf8 path[MAX_PATH]; - substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), argv[0]); + substitute_path(path, gRCT2AddressObjectDataPath, argv[0]); strcat(path, ".DAT\0"); rct_object_entry entry; diff --git a/src/object.c b/src/object.c index d8cd4a360b..c49e72f152 100644 --- a/src/object.c +++ b/src/object.c @@ -57,7 +57,7 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi char path[MAX_PATH]; SDL_RWops* rw; - substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), (char*)installedObject + 16); + substitute_path(path, gRCT2AddressObjectDataPath, (char*)installedObject + 16); log_verbose("loading object, %s", path); @@ -345,7 +345,7 @@ int object_load_packed(SDL_RWops* rw) objectPath[i] = '\0'; } - substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath); + substitute_path(path, gRCT2AddressObjectDataPath, objectPath); // Require pointer to start of filename char* last_char = path + strlen(path); strcat(path, ".DAT"); @@ -355,7 +355,7 @@ int object_load_packed(SDL_RWops* rw) for (; platform_file_exists(path);){ for (char* curr_char = last_char - 1;; --curr_char){ if (*curr_char == '\\'){ - substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), "00000000.DAT"); + substitute_path(path, gRCT2AddressObjectDataPath, "00000000.DAT"); break; } if (*curr_char < '0') *curr_char = '0'; @@ -2608,7 +2608,7 @@ int object_get_scenario_text(rct_object_entry *entry) char path[MAX_PATH]; char *objectPath = (char*)installedObject + 16; - substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath); + substitute_path(path, gRCT2AddressObjectDataPath, objectPath); rct_object_entry openedEntry; SDL_RWops* rw = SDL_RWFromFile(path, "rb"); diff --git a/src/object_list.c b/src/object_list.c index 7212a4625e..a0f5f9956c 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -253,7 +253,7 @@ static int object_list_query_directory(int *outTotalFiles, uint64 *outTotalFileS fileDateModifiedChecksum = 0; // Enumerate through each object in the directory - enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char)); + enumFileHandle = platform_enumerate_files_begin(gRCT2AddressObjectDataPath); if (enumFileHandle == INVALID_HANDLE) return 0; @@ -321,7 +321,7 @@ void object_list_load() _installedObjectFilters = NULL; } - enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char)); + enumFileHandle = platform_enumerate_files_begin(gRCT2AddressObjectDataPath); if (enumFileHandle != INVALID_HANDLE) { size_t installedObjectsCapacity = 4096; while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) { @@ -338,7 +338,7 @@ void object_list_load() } char path[MAX_PATH]; - substitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), enumFileInfo.path); + substitute_path(path, gRCT2AddressObjectDataPath, enumFileInfo.path); rct_object_entry entry; if (object_load_entry(path, &entry)) { diff --git a/src/openrct2.c b/src/openrct2.c index 7b4dd5dbe5..918a99dda1 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -166,10 +166,10 @@ static void openrct2_copy_original_user_files_over() utf8 path[MAX_PATH]; platform_get_user_directory(path, "save"); - openrct2_copy_files_over((utf8*)RCT2_ADDRESS_SAVED_GAMES_PATH, path, ".sv6"); + openrct2_copy_files_over((utf8*)gRCT2AddressSavedGamesPath, path, ".sv6"); platform_get_user_directory(path, "landscape"); - openrct2_copy_files_over((utf8*)RCT2_ADDRESS_LANDSCAPES_PATH, path, ".sc6"); + openrct2_copy_files_over((utf8*)gRCT2AddressLandscapesPath, path, ".sc6"); } bool openrct2_initialise() diff --git a/src/rct2.c b/src/rct2.c index b61f92046b..b081a7db5b 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -114,6 +114,13 @@ uint8 gSavePromptMode; sint32 gScreenWidth; sint32 gScreenHeight; +char gRCT2AddressSavedGamesPath[MAX_PATH]; +char gRCT2AddressSavedGamesPath2[MAX_PATH]; +char gRCT2AddressScenariosPath[MAX_PATH]; +char gRCT2AddressLandscapesPath[MAX_PATH]; +char gRCT2AddressObjectDataPath[MAX_PATH]; +char gRCT2AddressTracksPath[MAX_PATH]; + typedef struct tm tm_t; void print_launch_information(); @@ -213,41 +220,36 @@ int rct2_init_directories() char separator[] = {platform_get_path_separator(), 0}; - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gConfigGeneral.game_path); + char gRCT2AddressAppPath[MAX_PATH] = { 0 }; - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), separator); + strcpy(gRCT2AddressAppPath, gConfigGeneral.game_path); + strcat(gRCT2AddressAppPath, separator); - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), "Saved Games"); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), separator); + strcpy(gRCT2AddressSavedGamesPath, gRCT2AddressAppPath); + strcat(gRCT2AddressSavedGamesPath, "Saved Games"); + strcat(gRCT2AddressSavedGamesPath, separator); - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), "Scenarios"); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), "*.SC6"); + strcpy(gRCT2AddressScenariosPath, gRCT2AddressAppPath); + strcat(gRCT2AddressScenariosPath, "Scenarios"); + strcat(gRCT2AddressScenariosPath, separator); + strcat(gRCT2AddressScenariosPath, "*.SC6"); - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), "Landscapes"); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), "*.SC6"); + strcpy(gRCT2AddressLandscapesPath, gRCT2AddressAppPath); + strcat(gRCT2AddressLandscapesPath, "Landscapes"); + strcat(gRCT2AddressLandscapesPath, separator); + strcat(gRCT2AddressLandscapesPath, "*.SC6"); - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), "ObjData"); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), "*.DAT"); + strcpy(gRCT2AddressObjectDataPath, gRCT2AddressAppPath); + strcat(gRCT2AddressObjectDataPath, "ObjData"); + strcat(gRCT2AddressObjectDataPath, separator); + strcat(gRCT2AddressObjectDataPath, "*.DAT"); - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), "Tracks"); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), separator); - strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), "*.TD?"); + strcpy(gRCT2AddressTracksPath, gRCT2AddressAppPath); + strcat(gRCT2AddressTracksPath, "Tracks"); + strcat(gRCT2AddressTracksPath, separator); + strcat(gRCT2AddressTracksPath, "*.TD?"); - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char), RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char)); + strcpy(gRCT2AddressSavedGamesPath2, gRCT2AddressSavedGamesPath); return 1; } @@ -351,7 +353,7 @@ bool rct2_open_file(const char *path) extension++; if (_stricmp(extension, "sv6") == 0) { - strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, path); + strcpy((char*)gRCT2AddressSavedGamesPath2, path); game_load_save(path); gFirstTimeSave = 0; return true; diff --git a/src/rct2.h b/src/rct2.h index 923ab22f65..1d12df5cd1 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -279,6 +279,13 @@ extern uint8 gSavePromptMode; extern sint32 gScreenWidth; extern sint32 gScreenHeight; +extern char gRCT2AddressSavedGamesPath[]; +extern char gRCT2AddressSavedGamesPath2[]; +extern char gRCT2AddressScenariosPath[]; +extern char gRCT2AddressLandscapesPath[]; +extern char gRCT2AddressObjectDataPath[]; +extern char gRCT2AddressTracksPath[]; + int rct2_init(); void rct2_dispose(); void rct2_update(); diff --git a/src/scenario.c b/src/scenario.c index 018bbea720..d576cfc5c4 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -244,9 +244,9 @@ void scenario_begin() strncat(gScenarioSavePath, parkName, sizeof(gScenarioSavePath) - strlen(gScenarioSavePath) - 1); strncat(gScenarioSavePath, ".sv6", sizeof(gScenarioSavePath) - strlen(gScenarioSavePath) - 1); - strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*)RCT2_ADDRESS_SAVED_GAMES_PATH); - strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2 + strlen((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2), gScenarioSavePath); - strcat((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, ".SV6"); + strcpy(gRCT2AddressSavedGamesPath2, gRCT2AddressSavedGamesPath); + strcpy(gRCT2AddressSavedGamesPath2 + strlen(gRCT2AddressSavedGamesPath2), gScenarioSavePath); + strcat(gRCT2AddressSavedGamesPath2, ".SV6"); memset((void*)0x001357848, 0, 56); gCurrentExpenditure = 0; @@ -299,7 +299,7 @@ void scenario_end() void scenario_set_filename(const char *value) { - substitute_path(_scenarioPath, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), value); + substitute_path(_scenarioPath, gRCT2AddressScenariosPath, value); _scenarioFileName = path_get_filename(_scenarioPath); } diff --git a/src/windows/loadsave.c b/src/windows/loadsave.c index c068229904..c77eedc847 100644 --- a/src/windows/loadsave.c +++ b/src/windows/loadsave.c @@ -237,7 +237,7 @@ rct_window *window_loadsave_open(int type, char *defaultName) } */ - safe_strcpy(path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), MAX_PATH); + safe_strcpy(path, gRCT2AddressTracksPath, MAX_PATH); ch = strchr(path, '*'); if (ch != NULL) *ch = 0; From 5a7bbf71fe5c3ec077a68fa2e4a45245e45591ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Mon, 20 Jun 2016 00:05:03 +0200 Subject: [PATCH 17/17] Fix condition guarding memory checksum verification --- src/openrct2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2.c b/src/openrct2.c index 918a99dda1..f1e38c0161 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -571,7 +571,7 @@ bool openrct2_setup_rct2_segment() } #endif // defined(__unix__) -#if !defined(NO_RCT2) || !defined(__WINDOWS__) +#if !defined(NO_RCT2) && !defined(__WINDOWS__) // Check that the expected data is at various addresses. // Start at 0x9a6000, which is start of .data, to skip the region containing addresses to DLL // calls, which can be changed by windows/wine loader.