mirror of https://github.com/OpenRCT2/OpenRCT2.git
commit
dcf0a9dad1
|
@ -20,6 +20,28 @@
|
|||
#include "../common.h"
|
||||
#include "font.h"
|
||||
|
||||
// For g1 only enable packing when still relying on vanilla
|
||||
#ifndef NO_RCT2
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
// Size: 0x10
|
||||
typedef struct rct_g1_element {
|
||||
uint8* offset; // 0x00
|
||||
sint16 width; // 0x04
|
||||
sint16 height; // 0x06
|
||||
sint16 x_offset; // 0x08
|
||||
sint16 y_offset; // 0x0A
|
||||
uint16 flags; // 0x0C
|
||||
uint16 zoomed_offset; // 0x0E
|
||||
} rct_g1_element;
|
||||
#ifndef NO_RCT2
|
||||
#ifdef PLATFORM_32BIT
|
||||
assert_struct_size(rct_g1_element, 0x10);
|
||||
#endif
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
// Enable packing for remaining elements
|
||||
#pragma pack(push, 1)
|
||||
// Size: 0x10
|
||||
typedef struct rct_drawpixelinfo {
|
||||
|
@ -35,20 +57,6 @@ typedef struct rct_drawpixelinfo {
|
|||
assert_struct_size(rct_drawpixelinfo, 0x10);
|
||||
#endif
|
||||
|
||||
// Size: 0x10
|
||||
typedef struct rct_g1_element {
|
||||
uint8* offset; // 0x00
|
||||
sint16 width; // 0x04
|
||||
sint16 height; // 0x06
|
||||
sint16 x_offset; // 0x08
|
||||
sint16 y_offset; // 0x0A
|
||||
uint16 flags; // 0x0C
|
||||
uint16 zoomed_offset; // 0x0E
|
||||
} rct_g1_element;
|
||||
#ifdef PLATFORM_32BIT
|
||||
assert_struct_size(rct_g1_element, 0x10);
|
||||
#endif
|
||||
|
||||
enum {
|
||||
G1_FLAG_BMP = (1 << 0), //No invisible sections
|
||||
G1_FLAG_RLE_COMPRESSION = (1<<2),
|
||||
|
|
|
@ -46,15 +46,49 @@ int gfx_load_g1()
|
|||
file = SDL_RWFromFile(get_file_path(PATH_ID_G1), "rb");
|
||||
if (file != NULL) {
|
||||
if (SDL_RWread(file, &header, 8, 1) == 1) {
|
||||
// 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
|
||||
/* We need to load in the data file, which has an `offset` field,
|
||||
* which is supposed to hold a pointer, but is only 32 bit long.
|
||||
* We will load a 32 bit version of rct_g1_element and then convert
|
||||
* 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.
|
||||
*/
|
||||
header.num_entries = 29294;
|
||||
|
||||
// Read element headers
|
||||
#if NO_RCT2
|
||||
g1Elements = calloc(324206, sizeof(rct_g1_element));
|
||||
#endif
|
||||
SDL_RWread(file, g1Elements, header.num_entries * sizeof(rct_g1_element), 1);
|
||||
|
||||
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 element data
|
||||
_g1Buffer = malloc(header.total_size);
|
||||
|
@ -64,7 +98,7 @@ int gfx_load_g1()
|
|||
|
||||
// Fix entry data offsets
|
||||
for (i = 0; i < header.num_entries; i++)
|
||||
g1Elements[i].offset += (int)_g1Buffer;
|
||||
g1Elements[i].offset += (uintptr_t)_g1Buffer;
|
||||
|
||||
// Successful
|
||||
return 1;
|
||||
|
|
|
@ -339,8 +339,8 @@ static int editor_read_s6(const char *path)
|
|||
sawyercoding_read_chunk(rw, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
|
||||
|
||||
// Read map elements
|
||||
memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
|
||||
sawyercoding_read_chunk(rw, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
|
||||
memset((void*)gMapElements, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
|
||||
sawyercoding_read_chunk(rw, (uint8*)gMapElements);
|
||||
|
||||
// Read game data, including sprites
|
||||
sawyercoding_read_chunk(rw, (uint8*)0x010E63B8);
|
||||
|
|
|
@ -1810,12 +1810,12 @@ static map_backup *track_design_preview_backup_map()
|
|||
if (backup != NULL) {
|
||||
memcpy(
|
||||
backup->map_elements,
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element),
|
||||
gMapElements,
|
||||
sizeof(backup->map_elements)
|
||||
);
|
||||
memcpy(
|
||||
backup->tile_pointers,
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*),
|
||||
gMapElementTilePointers,
|
||||
sizeof(backup->tile_pointers)
|
||||
);
|
||||
backup->next_free_map_element = gNextFreeMapElement;
|
||||
|
@ -1834,12 +1834,12 @@ static map_backup *track_design_preview_backup_map()
|
|||
static void track_design_preview_restore_map(map_backup *backup)
|
||||
{
|
||||
memcpy(
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element),
|
||||
gMapElements,
|
||||
backup->map_elements,
|
||||
sizeof(backup->map_elements)
|
||||
);
|
||||
memcpy(
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*),
|
||||
gMapElementTilePointers,
|
||||
backup->tile_pointers,
|
||||
sizeof(backup->tile_pointers)
|
||||
);
|
||||
|
@ -1866,7 +1866,7 @@ static void track_design_preview_clear_map()
|
|||
|
||||
rct_map_element* map_element;
|
||||
for (int i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++) {
|
||||
map_element = GET_MAP_ELEMENT(i);
|
||||
map_element = &gMapElements[i];
|
||||
map_element->type = MAP_ELEMENT_TYPE_SURFACE;
|
||||
map_element->flags = MAP_ELEMENT_FLAG_LAST_TILE;
|
||||
map_element->base_height = 2;
|
||||
|
|
|
@ -346,10 +346,8 @@ void vehicle_update_sound_params(rct_vehicle* vehicle)
|
|||
i->id = vehicle->sprite_index;
|
||||
i->volume = 0;
|
||||
if (vehicle->x != (sint16)0x8000) {
|
||||
int tile_idx = (((vehicle->y & 0xFFE0) * 256) + (vehicle->x & 0xFFE0)) / 32;
|
||||
rct_map_element* map_element;
|
||||
for (map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; map_element->type & MAP_ELEMENT_TYPE_MASK; map_element++);
|
||||
if (map_element->base_height * 8 > vehicle->z) { // vehicle underground
|
||||
rct_map_element* map_element = map_get_surface_element_at(vehicle->x >> 5, vehicle->y >> 5);
|
||||
if (map_element != NULL && map_element->base_height * 8 > vehicle->z) { // vehicle underground
|
||||
i->volume = 0x30;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,13 @@ uint8 gMapSelectArrowDirection;
|
|||
|
||||
uint8 gMapGroundFlags;
|
||||
|
||||
#if defined(NO_RCT2)
|
||||
rct_map_element gMapElements[MAX_MAP_ELEMENTS];
|
||||
rct_map_element *gMapElementTilePointers[MAX_TILE_MAP_ELEMENT_POINTERS];
|
||||
#else
|
||||
rct_map_element *gMapElements = (rct_map_element*)RCT2_ADDRESS_MAP_ELEMENTS;
|
||||
rct_map_element **gMapElementTilePointers = (rct_map_element**)RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS;
|
||||
#endif
|
||||
rct_xy16 *gMapSelectionTiles = (rct_xy16*)0x009DE596;
|
||||
rct2_peep_spawn *gPeepSpawns = (rct2_peep_spawn*)RCT2_ADDRESS_PEEP_SPAWNS;
|
||||
|
||||
|
@ -85,7 +90,6 @@ money32 gWaterToolLowerCost;
|
|||
|
||||
rct_xyz16 gCommandPosition;
|
||||
|
||||
static void tiles_init();
|
||||
static void map_update_grass_length(int x, int y, rct_map_element *mapElement);
|
||||
static void map_set_grass_length(int x, int y, rct_map_element *mapElement, int length);
|
||||
static void clear_elements_at(int x, int y);
|
||||
|
@ -186,7 +190,7 @@ rct_map_element *map_get_first_element_at(int x, int y)
|
|||
log_error("Trying to access element outside of range");
|
||||
return NULL;
|
||||
}
|
||||
return TILE_MAP_ELEMENT_POINTER(x + y * 256);
|
||||
return gMapElementTilePointers[x + y * 256];
|
||||
}
|
||||
|
||||
void map_set_tile_elements(int x, int y, rct_map_element *elements)
|
||||
|
@ -195,7 +199,7 @@ void map_set_tile_elements(int x, int y, rct_map_element *elements)
|
|||
log_error("Trying to access element outside of range");
|
||||
return;
|
||||
}
|
||||
TILE_MAP_ELEMENT_POINTER(x + y * 256) = elements;
|
||||
gMapElementTilePointers[x + y * 256] = elements;
|
||||
}
|
||||
|
||||
int map_element_is_last_for_tile(const rct_map_element *element)
|
||||
|
@ -322,12 +326,13 @@ void map_init(int size)
|
|||
int i;
|
||||
rct_map_element *map_element;
|
||||
|
||||
|
||||
date_reset();
|
||||
gNumMapAnimations = 0;
|
||||
RCT2_GLOBAL(0x010E63B8, sint32) = 0;
|
||||
|
||||
for (i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++) {
|
||||
map_element = GET_MAP_ELEMENT(i);
|
||||
map_element = &gMapElements[i];
|
||||
map_element->type = (MAP_ELEMENT_TYPE_SURFACE << 2);
|
||||
map_element->flags = MAP_ELEMENT_FLAG_LAST_TILE;
|
||||
map_element->base_height = 14;
|
||||
|
@ -362,11 +367,12 @@ void map_update_tile_pointers()
|
|||
{
|
||||
int i, x, y;
|
||||
|
||||
for (i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++)
|
||||
TILE_MAP_ELEMENT_POINTER(i) = TILE_UNDEFINED_MAP_ELEMENT;
|
||||
for (i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++) {
|
||||
gMapElementTilePointers[i] = TILE_UNDEFINED_MAP_ELEMENT;
|
||||
}
|
||||
|
||||
rct_map_element *mapElement = RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element);
|
||||
rct_map_element **tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*);
|
||||
rct_map_element *mapElement = gMapElements;
|
||||
rct_map_element **tile = gMapElementTilePointers;
|
||||
for (y = 0; y < 256; y++) {
|
||||
for (x = 0; x < 256; x++) {
|
||||
*tile++ = mapElement;
|
||||
|
@ -537,13 +543,13 @@ void sub_68B089()
|
|||
i++;
|
||||
if (i >= MAX_TILE_MAP_ELEMENT_POINTERS)
|
||||
i = 0;
|
||||
} while (TILE_MAP_ELEMENT_POINTER(i) == TILE_UNDEFINED_MAP_ELEMENT);
|
||||
} while (gMapElementTilePointers[i] == TILE_UNDEFINED_MAP_ELEMENT);
|
||||
RCT2_GLOBAL(0x0010E63B8, uint32) = i;
|
||||
|
||||
mapElementFirst = mapElement = TILE_MAP_ELEMENT_POINTER(i);
|
||||
mapElementFirst = mapElement = gMapElementTilePointers[i];
|
||||
do {
|
||||
mapElement--;
|
||||
if (mapElement < (rct_map_element*)RCT2_ADDRESS_MAP_ELEMENTS)
|
||||
if (mapElement < gMapElements)
|
||||
break;
|
||||
} while (mapElement->base_height == 255);
|
||||
mapElement++;
|
||||
|
@ -552,7 +558,7 @@ void sub_68B089()
|
|||
return;
|
||||
|
||||
//
|
||||
TILE_MAP_ELEMENT_POINTER(i) = mapElement;
|
||||
gMapElementTilePointers[i] = mapElement;
|
||||
do {
|
||||
*mapElement = *mapElementFirst;
|
||||
mapElementFirst->base_height = 255;
|
||||
|
@ -3951,8 +3957,8 @@ void map_reorganise_elements()
|
|||
}
|
||||
|
||||
num_elements = (new_elements_pointer - new_map_elements);
|
||||
memcpy(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element), new_map_elements, num_elements * sizeof(rct_map_element));
|
||||
memset(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element) + num_elements, 0, (0x30000 - num_elements) * sizeof(rct_map_element));
|
||||
memcpy(gMapElements, new_map_elements, num_elements * sizeof(rct_map_element));
|
||||
memset(gMapElements + num_elements, 0, (0x30000 - num_elements) * sizeof(rct_map_element));
|
||||
|
||||
free(new_map_elements);
|
||||
|
||||
|
@ -3965,18 +3971,18 @@ void map_reorganise_elements()
|
|||
*/
|
||||
int sub_68B044()
|
||||
{
|
||||
if (gNextFreeMapElement <= RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS_END, rct_map_element))
|
||||
if (gNextFreeMapElement <= gMapElements + MAX_MAP_ELEMENTS)
|
||||
return 1;
|
||||
|
||||
for (int i = 1000; i != 0; --i)
|
||||
sub_68B089();
|
||||
|
||||
if (gNextFreeMapElement <= RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS_END, rct_map_element))
|
||||
if (gNextFreeMapElement <= gMapElements + MAX_MAP_ELEMENTS)
|
||||
return 1;
|
||||
|
||||
map_reorganise_elements();
|
||||
|
||||
if (gNextFreeMapElement <= RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS_END, rct_map_element))
|
||||
if (gNextFreeMapElement <= gMapElements + MAX_MAP_ELEMENTS)
|
||||
return 1;
|
||||
else{
|
||||
gGameCommandErrorText = 894;
|
||||
|
@ -3998,10 +4004,10 @@ rct_map_element *map_element_insert(int x, int y, int z, int flags)
|
|||
}
|
||||
|
||||
newMapElement = gNextFreeMapElement;
|
||||
originalMapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
|
||||
originalMapElement = gMapElementTilePointers[y * 256 + x];
|
||||
|
||||
// Set tile index pointer to point to new element block
|
||||
TILE_MAP_ELEMENT_POINTER(y * 256 + x) = newMapElement;
|
||||
gMapElementTilePointers[y * 256 + x] = newMapElement;
|
||||
|
||||
// Copy all elements that are below the insert height
|
||||
while (z >= originalMapElement->base_height) {
|
||||
|
|
|
@ -333,8 +333,13 @@ extern uint8 gMapSelectArrowDirection;
|
|||
|
||||
extern uint8 gMapGroundFlags;
|
||||
|
||||
#ifdef NO_RCT2
|
||||
extern rct_map_element gMapElements[];
|
||||
extern rct_map_element *gMapElementTilePointers[];
|
||||
#else
|
||||
extern rct_map_element *gMapElements;
|
||||
extern rct_map_element **gMapElementTilePointers;
|
||||
#endif
|
||||
|
||||
extern rct_xy16 *gMapSelectionTiles;
|
||||
extern rct2_peep_spawn *gPeepSpawns;
|
||||
|
@ -436,9 +441,6 @@ void game_command_set_sign_name(int* eax, int* ebx, int* ecx, int* edx, int* esi
|
|||
void game_command_set_banner_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_sign_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
|
||||
#define GET_MAP_ELEMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element)[x]))
|
||||
#define TILE_MAP_ELEMENT_POINTER(x) (RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[x])
|
||||
|
||||
typedef struct map_element_iterator {
|
||||
int x;
|
||||
int y;
|
||||
|
|
Loading…
Reference in New Issue