Skip to content

Commit

Permalink
Merge pull request #5092 from IntelOrca/add-rct1-path
Browse files Browse the repository at this point in the history
Load CSG1
  • Loading branch information
Gymnasiast committed Jan 19, 2017
2 parents 55972f1 + a5b280e commit ea23539
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 33 deletions.
2 changes: 2 additions & 0 deletions src/openrct2/drawing/drawing.h
Expand Up @@ -313,8 +313,10 @@ void gfx_filter_rect(rct_drawpixelinfo *dpi, sint32 left, sint32 top, sint32 rig
// sprite
bool gfx_load_g1();
bool gfx_load_g2();
bool gfx_load_csg();
void gfx_unload_g1();
void gfx_unload_g2();
void gfx_unload_csg();
rct_g1_element* gfx_get_g1_element(sint32 image_id);
uint32 gfx_object_allocate_images(const rct_g1_element * images, uint32 count);
void gfx_object_free_images(uint32 baseImageId, uint32 count);
Expand Down
78 changes: 75 additions & 3 deletions src/openrct2/drawing/sprite.c
Expand Up @@ -14,16 +14,18 @@
*****************************************************************************/
#pragma endregion

#include "../rct2/addresses.h"
#include "../common.h"
#include "../config.h"
#include "../OpenRCT2.h"
#include "../rct2/addresses.h"
#include "../sprites.h"
#include "../util/util.h"
#include "drawing.h"

void *_g1Buffer = NULL;

rct_gx g2;
rct_gx csg;

#ifdef NO_RCT2
rct_g1_element *g1Elements = NULL;
Expand Down Expand Up @@ -121,6 +123,11 @@ void gfx_unload_g2()
SafeFree(g2.elements);
}

void gfx_unload_csg()
{
SafeFree(csg.elements);
}

bool gfx_load_g2()
{
log_verbose("loading g2 graphics");
Expand Down Expand Up @@ -159,6 +166,69 @@ bool gfx_load_g2()
return false;
}

bool gfx_load_csg()
{
if (str_is_null_or_empty(gConfigGeneral.rct1_path)) {
return false;
}

bool success = false;
log_verbose("loading csg graphics");

char pathHeader[MAX_PATH];
safe_strcpy(pathHeader, gConfigGeneral.rct1_path, sizeof(pathHeader));
safe_strcat_path(pathHeader, "Data", sizeof(pathHeader));
safe_strcat_path(pathHeader, "csg1i.dat", sizeof(pathHeader));

char pathData[MAX_PATH];
safe_strcpy(pathData, gConfigGeneral.rct1_path, sizeof(pathData));
safe_strcat_path(pathData, "Data", sizeof(pathData));
safe_strcat_path(pathData, "csg1.1", sizeof(pathData));

SDL_RWops * fileHeader = SDL_RWFromFile(pathHeader, "rb");
SDL_RWops * fileData = SDL_RWFromFile(pathData, "rb");
if (fileHeader != NULL && fileData != NULL) {
SDL_RWseek(fileHeader, 0, RW_SEEK_END);
SDL_RWseek(fileData, 0, RW_SEEK_END);
size_t fileHeaderSize = SDL_RWtell(fileHeader);
size_t fileDataSize = SDL_RWtell(fileData);
SDL_RWseek(fileHeader, 0, RW_SEEK_SET);
SDL_RWseek(fileData, 0, RW_SEEK_SET);

csg.header.num_entries = (uint32)(fileHeaderSize / sizeof(rct_g1_element_32bit));
csg.header.total_size = (uint32)fileDataSize;

// Read element headers
csg.elements = malloc(csg.header.num_entries * sizeof(rct_g1_element));
read_and_convert_gxdat(fileHeader, csg.header.num_entries, csg.elements);

// Read element data
csg.data = malloc(csg.header.total_size);
SDL_RWread(fileData, csg.data, csg.header.total_size, 1);

// Fix entry data offsets
for (uint32 i = 0; i < csg.header.num_entries; i++) {
csg.elements[i].offset += (uintptr_t)csg.data;
}

success = true;
}

if (fileHeader != NULL) {
SDL_RWclose(fileHeader);
}
if (fileData != NULL) {
SDL_RWclose(fileData);
}

if (success) {
return true;
} else {
log_error("Unable to load csg graphics");
return false;
}
}

/**
* This function looks like it initialises the 0x009E3CE4 array which references sprites used for background / palette mixing or
* something. Further investigation is needed.
Expand Down Expand Up @@ -548,6 +618,8 @@ rct_g1_element *gfx_get_g1_element(sint32 image_id) {
if (image_id < SPR_G2_BEGIN) {
return &g1Elements[image_id];
}

return &g2.elements[image_id - SPR_G2_BEGIN];
if (image_id < SPR_CSG_BEGIN) {
return &g2.elements[image_id - SPR_G2_BEGIN];
}
return &csg.elements[image_id - SPR_CSG_BEGIN];
}
86 changes: 56 additions & 30 deletions src/openrct2/paint/map_element/surface.c
Expand Up @@ -19,6 +19,7 @@
#include "../../interface/viewport.h"
#include "../../peep/staff.h"
#include "../../rct2.h"
#include "../../sprites.h"
#include "map_element.h"
#include "surface.h"

Expand Down Expand Up @@ -182,18 +183,43 @@ const uint8 byte_97B5B0[] = {
10, 11, 12, 13, 14, 14
};

const uint32 stru_97B5C0[][5] = {
{1579, 1599, 1589, 1609, 0},
{1747, 1767, 1757, 1777, 1},
{1663, 1683, 1673, 1693, 2},
{1831, 1851, 1841, 1861, 3},
#define DEFINE_EDGE_SPRITES(base) { \
(base) + 0, \
(base) + 20, \
(base) + 10, \
(base) + 30, \
}
#define DEFINE_EDGE_TUNNEL_SPRITES(base) { \
(base) + 36, \
(base) + 40, \
(base) + 44, \
(base) + 48, \
(base) + 52, \
(base) + 56, \
(base) + 60, \
(base) + 64, \
(base) + 68, \
(base) + 72, \
(base) + 76, \
(base) + 80, \
(base) + 36, \
(base) + 48, \
(base) + 60, \
(base) + 72, \
}

static const uint32 _terrainEdgeSpriteIds[][4] = {
DEFINE_EDGE_SPRITES(SPR_EDGE_ROCK_BASE),
DEFINE_EDGE_SPRITES(SPR_EDGE_WOOD_RED_BASE),
DEFINE_EDGE_SPRITES(SPR_EDGE_WOOD_BLACK_BASE),
DEFINE_EDGE_SPRITES(SPR_EDGE_ICE_BASE),
};

const uint32 stru_97B640[][16] = {
{1615, 1619, 1623, 1627, 1631, 1635, 1639, 1643, 1647, 1651, 1655, 1659, 1615, 1627, 1639, 1651},
{1783, 1787, 1791, 1795, 1799, 1803, 1807, 1811, 1815, 1819, 1823, 1827, 1783, 1795, 1807, 1819},
{1699, 1703, 1707, 1711, 1715, 1719, 1723, 1727, 1731, 1735, 1739, 1743, 1699, 1711, 1723, 1735},
{1867, 1871, 1875, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 1907, 1911, 1867, 1879, 1891, 1903},
static const uint32 _terrainEdgeTunnelSpriteIds[][16] = {
DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_ROCK_BASE),
DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_WOOD_RED_BASE),
DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_WOOD_BLACK_BASE),
DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_ICE_BASE),
};

const uint8 byte_97B740[] = {
Expand Down Expand Up @@ -479,13 +505,13 @@ static void viewport_surface_draw_land_side_top(enum edge_t edge, uint8 height,
if (!(gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)) {
uint8 incline = (regs.cl - regs.al) + 1;

uint32 image_id = stru_97B5C0[terrain][3] + (edge == EDGE_TOPLEFT ? 3 : 0) + incline; // var_c;
uint32 image_id = _terrainEdgeSpriteIds[terrain][3] + (edge == EDGE_TOPLEFT ? 3 : 0) + incline; // var_c;
sint16 y = (regs.dl - regs.al) * 16;
paint_attach_to_previous_ps(image_id, 0, y);
return;
}

uint32 base_image_id = stru_97B5C0[terrain][1] + (edge == EDGE_TOPLEFT ? 5 : 0); // var_04
uint32 base_image_id = _terrainEdgeSpriteIds[terrain][1] + (edge == EDGE_TOPLEFT ? 5 : 0); // var_04

const uint8 rotation = get_current_rotation();
uint8 cur_height = min(regs.ch, regs.ah);
Expand Down Expand Up @@ -580,9 +606,9 @@ static void viewport_surface_draw_land_side_bottom(enum edge_t edge, uint8 heigh
return;
}

uint32 base_image_id = stru_97B5C0[edgeStyle][0];
uint32 base_image_id = _terrainEdgeSpriteIds[edgeStyle][0];
if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
base_image_id = stru_97B5C0[edgeStyle][1];
base_image_id = _terrainEdgeSpriteIds[edgeStyle][1];
}

if (edge == EDGE_BOTTOMRIGHT) {
Expand Down Expand Up @@ -661,7 +687,7 @@ static void viewport_surface_draw_land_side_bottom(enum edge_t edge, uint8 heigh
}


uint32 image_id = stru_97B640[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0);
uint32 image_id = _terrainEdgeTunnelSpriteIds[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0);
sub_98197C(image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, zOffset, 0, 0, boundBoxOffsetZ, rotation);


Expand All @@ -673,7 +699,7 @@ static void viewport_surface_draw_land_side_bottom(enum edge_t edge, uint8 heigh
boundBoxLength -= 16;
}

image_id = stru_97B640[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0) + 1;
image_id = _terrainEdgeTunnelSpriteIds[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0) + 1;
sub_98197C(image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, curHeight * 16, tunnelTopBoundBoxOffset.x, tunnelTopBoundBoxOffset.y, boundBoxOffsetZ, rotation);

curHeight += stru_97B570[tunnelType][0];
Expand Down Expand Up @@ -741,10 +767,10 @@ static void viewport_surface_draw_water_side_top(enum edge_t edge, uint8 height,
return;
}

uint32 base_image_id = stru_97B5C0[terrain][2]; // var_08
uint32 base_image_id = _terrainEdgeSpriteIds[terrain][2]; // var_08

if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
base_image_id = stru_97B5C0[terrain][1]; // var_04
base_image_id = _terrainEdgeSpriteIds[terrain][1]; // var_04
}

base_image_id += (edge == EDGE_TOPLEFT ? 5 : 0);
Expand Down Expand Up @@ -852,9 +878,9 @@ static void viewport_surface_draw_water_side_bottom(enum edge_t edge, uint8 heig
return;
}

uint32 base_image_id = stru_97B5C0[edgeStyle][0];
uint32 base_image_id = _terrainEdgeSpriteIds[edgeStyle][0];
if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) {
base_image_id = stru_97B5C0[edgeStyle][1];
base_image_id = _terrainEdgeSpriteIds[edgeStyle][1];
}

if (edge == EDGE_BOTTOMRIGHT) {
Expand Down Expand Up @@ -931,7 +957,7 @@ static void viewport_surface_draw_water_side_bottom(enum edge_t edge, uint8 heig
}


uint32 image_id = stru_97B640[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0);
uint32 image_id = _terrainEdgeTunnelSpriteIds[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0);
sub_98197C(image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, zOffset, 0, 0, boundBoxOffsetZ, rotation);


Expand All @@ -943,7 +969,7 @@ static void viewport_surface_draw_water_side_bottom(enum edge_t edge, uint8 heig
boundBoxLength -= 16;
}

image_id = stru_97B640[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0) + 1;
image_id = _terrainEdgeTunnelSpriteIds[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0) + 1;
sub_98197C(image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, curHeight * 16, tunnelTopBoundBoxOffset.x, tunnelTopBoundBoxOffset.y, boundBoxOffsetZ, rotation);

curHeight += stru_97B570[tunnelType][0];
Expand Down Expand Up @@ -1177,7 +1203,7 @@ void surface_paint(uint8 direction, uint16 height, rct_map_element * mapElement)
}

if (gCurrentViewportFlags & VIEWPORT_FLAG_CONSTRUCTION_RIGHTS
&& !(mapElement->properties.surface.ownership & OWNERSHIP_OWNED)) {
&& !(mapElement->properties.surface.ownership & OWNERSHIP_OWNED)) {
if (mapElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED) {
assert(surfaceShape < countof(byte_97B444));
// TODO: SPR_TERRAIN_SELECTION_DOTTED ???
Expand Down Expand Up @@ -1236,7 +1262,7 @@ void surface_paint(uint8 direction, uint16 height, rct_map_element * mapElement)
local_height += 16;

if (waterHeight != local_height
|| !(local_surfaceShape & 0x10)) {
|| !(local_surfaceShape & 0x10)) {
local_height = waterHeight;
local_surfaceShape = 0;
} else {
Expand Down Expand Up @@ -1279,10 +1305,10 @@ void surface_paint(uint8 direction, uint16 height, rct_map_element * mapElement)
}

if (zoomLevel == 0
&& has_surface
&& !(gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)
&& !(gCurrentViewportFlags & VIEWPORT_FLAG_HIDE_BASE)
&& gConfigGeneral.landscape_smoothing) {
&& has_surface
&& !(gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)
&& !(gCurrentViewportFlags & VIEWPORT_FLAG_HIDE_BASE)
&& gConfigGeneral.landscape_smoothing) {
viewport_surface_smoothen_edge(EDGE_TOPLEFT, tileDescriptors[0], tileDescriptors[3]);
viewport_surface_smoothen_edge(EDGE_TOPRIGHT, tileDescriptors[0], tileDescriptors[4]);
viewport_surface_smoothen_edge(EDGE_BOTTOMLEFT, tileDescriptors[0], tileDescriptors[1]);
Expand All @@ -1291,8 +1317,8 @@ void surface_paint(uint8 direction, uint16 height, rct_map_element * mapElement)


if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE
&& !(gCurrentViewportFlags & VIEWPORT_FLAG_HIDE_BASE)
&& !(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) {
&& !(gCurrentViewportFlags & VIEWPORT_FLAG_HIDE_BASE)
&& !(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) {

uint8 image_offset = byte_97B444[surfaceShape];
uint32 base_image = terrain_type;
Expand Down
1 change: 1 addition & 0 deletions src/openrct2/rct2.c
Expand Up @@ -167,6 +167,7 @@ bool rct2_init()
if (!gfx_load_g2()) {
return false;
}
gfx_load_csg();

font_sprite_initialise_characters();
if (!gOpenRCT2Headless) {
Expand Down
21 changes: 21 additions & 0 deletions src/openrct2/sprites.h
Expand Up @@ -23,6 +23,11 @@ enum {
SPR_SCROLLING_TEXT_START = 1542,
SPR_SCROLLING_TEXT_DEFAULT = 1574,

SPR_EDGE_ROCK_BASE = 1579,
SPR_EDGE_WOOD_RED_BASE = 1747,
SPR_EDGE_WOOD_BLACK_BASE = 1663,
SPR_EDGE_ICE_BASE = 1831,

SPR_PALETTE_1_START = 3100,
SPR_PALETTE_1_END = 3110,

Expand Down Expand Up @@ -746,6 +751,22 @@ enum {
SPR_G2_SORT = SPR_G2_BEGIN + 77,
SPR_G2_COPY = SPR_G2_BEGIN + 78,
SPR_G2_PASTE = SPR_G2_BEGIN + 79,

// 0x60000, chosen because it's a round hex number
// of the last possible range of image ID values that is large enough to fit all csg1 sprites.
SPR_CSG_BEGIN = 393216,

SPR_CSG_EDGE_BRICK_BASE = SPR_CSG_BEGIN + 40506,
SPR_CSG_EDGE_IRON_BASE = SPR_CSG_BEGIN + 40590,
SPR_CSG_EDGE_RED_BASE = SPR_CSG_BEGIN + 40926,
SPR_CSG_EDGE_YELLOW_BASE = SPR_CSG_BEGIN + 41030,
SPR_CSG_EDGE_GREY_BASE = SPR_CSG_BEGIN + 41134,
SPR_CSG_EDGE_PURPLE_BASE = SPR_CSG_BEGIN + 41238,
SPR_CSG_EDGE_GREEN_BASE = SPR_CSG_BEGIN + 41342,
SPR_CSG_EDGE_STONE_BROWN_BASE = SPR_CSG_BEGIN + 41446,
SPR_CSG_EDGE_STONE_GREY_BASE = SPR_CSG_BEGIN + 41550,
SPR_CSG_EDGE_SKYSCRAPER_A_BASE = SPR_CSG_BEGIN + 41654,
SPR_CSG_EDGE_SKYSCRAPER_B_BASE = SPR_CSG_BEGIN + 41758,
};

#endif

0 comments on commit ea23539

Please sign in to comment.