Merge pull request #3887 from janisozaur/rebase-no-rct2

NO_RCT2 work
This commit is contained in:
Ted John 2016-06-16 22:27:38 +01:00 committed by GitHub
commit dcf0a9dad1
7 changed files with 99 additions and 51 deletions

View File

@ -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),

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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;