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