1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-24 15:24:30 +01:00

Merge pull request #3639 from zsilencer/paint-setup/scenery

Decompile scenery_paint
This commit is contained in:
Ted John
2016-05-20 08:12:26 +01:00
4 changed files with 279 additions and 2 deletions

View File

@@ -16,8 +16,279 @@
#include "map_element.h"
#include "../../addresses.h"
#include "../../config.h"
#include "../../game.h"
#include "../../interface/viewport.h"
#include "../../paint/paint.h"
#include "../../paint/supports.h"
#include "../../world/map.h"
#include "../../world/scenery.h"
/**
*
* rct2: 0x006DFF47
*/
void scenery_paint(uint8 direction, int height, rct_map_element* mapElement) {
RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)mapElement, 0, 0);
//RCT2_CALLPROC_X(0x6DFF47, 0, 0, direction, height, (int)mapElement, 0, 0); return;
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_SCENERY;
rct_xyz16 boxlength;
rct_xyz16 boxoffset;
boxoffset.x = 0;
boxoffset.y = 0;
boxoffset.z = height;
int baseImageid = 0;
if (RCT2_GLOBAL(0x009DEA6F, uint8) & 1) {
if (track_design_save_contains_map_element(mapElement)) {
baseImageid = 0x21700000;
}
}
if (mapElement->flags & MAP_ELEMENT_FLAG_GHOST) {
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8_t) = VIEWPORT_INTERACTION_ITEM_NONE;
baseImageid = RCT2_ADDRESS(0x993CC4, uint32_t)[gConfigGeneral.construction_marker_colour];
}
uint32 dword_F64EB0 = baseImageid;
rct_scenery_entry *entry = get_small_scenery_entry(mapElement->properties.scenery.type);
baseImageid = entry->image + direction;
boxlength.x = 2;
boxlength.y = 2;
sint8 x_offset = 0;
sint8 y_offset = 0;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE) {
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG24) {
// 6DFFE3:
boxoffset.x = RCT2_ADDRESS(0x009A3E7C, uint16)[direction * 4];
boxoffset.y = RCT2_ADDRESS(0x009A3E7E, uint16)[direction * 4];
boxlength.x = RCT2_ADDRESS(0x009A3E8C, uint16)[direction * 4];
boxlength.y = RCT2_ADDRESS(0x009A3E8E, uint16)[direction * 4];
x_offset = 3;
y_offset = 3;
} else {
x_offset = 15;
y_offset = 15;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_VOFFSET_CENTRE) {
x_offset = 3;
y_offset = 3;
boxlength.x = 26;
boxlength.y = 26;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_ALLOW_WALLS) {
x_offset = 1;
y_offset = 1;
boxlength.x = 30;
boxlength.y = 30;
}
}
}
} else {
// 6DFFC2:
uint32 ecx = ((mapElement->type >> 6) + get_current_rotation()) & 3;
x_offset = RCT2_ADDRESS(0x009A3E74, sint8)[ecx * 2];
y_offset = RCT2_ADDRESS(0x009A3E75, sint8)[ecx * 2];
}
// 6E0074:
boxoffset.x = x_offset;
boxoffset.y = y_offset;
boxlength.z = entry->small_scenery.height - 4;
if (boxlength.z > 0x80) {
boxlength.z = 0x80;
}
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG6) {
if (mapElement->properties.scenery.age >= 40) {
baseImageid += 4;
}
if (mapElement->properties.scenery.age >= 55) {
baseImageid += 4;
}
}
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR) {
baseImageid |= ((mapElement->properties.scenery.colour_1 & 0x1F) << 19) | 0x20000000;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR) {
baseImageid |= ((mapElement->properties.scenery.colour_2 & 0x1F) << 24) | 0x80000000;
}
}
if (dword_F64EB0 != 0) {
baseImageid = (baseImageid & 0x7FFFF) | dword_F64EB0;
}
if (!(entry->small_scenery.flags & SMALL_SCENERY_FLAG21)) {
sub_98197C(baseImageid, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
}
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG10) {
if (dword_F64EB0 == 0) {
// Draw translucent overlay:
int image_id = (baseImageid & 0x7FFFF) + (((mapElement->properties.scenery.colour_1 & 0x1F) + 112) << 19) + 0x40000004;
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
}
}
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_ANIMATED) {
rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*);
if ( !(entry->small_scenery.flags & SMALL_SCENERY_FLAG21) || (dpi->zoom_level <= 1) ) {
// 6E01A9:
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG12) {
// 6E0512:
int image_id = ((gCurrentTicks / 2) & 0xF) + entry->image + 4;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
} else
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG13) {
// 6E043B:
int image_id = ((gCurrentTicks / 2) & 0xF) + entry->image + 8;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
image_id = direction + entry->image + 4;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
image_id = ((gCurrentTicks / 2) & 0xF) + entry->image + 24;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
} else
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_IS_CLOCK) {
// 6E035C:
int si = ((RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MINUTE, uint16) + 6) * 17) / 256;
int bx = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_HOUR, uint16);
while (bx >= 12) {
bx -= 12;
}
bx = (bx * 4) + si;
if (bx >= 48) {
bx -= 48;
}
int image_id = bx + (direction * 12);
if (image_id >= 48) {
image_id -= 48;
}
image_id = image_id + entry->image + 68;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
image_id = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MINUTE, uint16) + (direction * 15);
if (image_id >= 60) {
image_id -= 60;
}
image_id = image_id + entry->image + 8;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
} else
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG15) {
// 6E02F6:
int image_id = ((gCurrentTicks + (RCT2_GLOBAL(0x9DE568, sint16) / 4) + (RCT2_GLOBAL(0x9DE56C, sint16) / 4) / 4) & 0xF) + entry->image;
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
} else {
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG16) {
// nothing
}
int esi = gCurrentTicks;
if (!(entry->small_scenery.flags & SMALL_SCENERY_FLAG22)) {
// 6E01F8:
esi += ((RCT2_GLOBAL(0x9DE568, sint16) / 4) + (RCT2_GLOBAL(0x9DE56C, sint16) / 4));
esi += (mapElement->type & 0xC0) / 16;
}
// 6E0222:
uint16 cx = entry->small_scenery.var_14;
uint8 cl = cx & 0xFF;
esi >>= cl;
esi &= entry->small_scenery.var_16;
int image_id = 0;
if (esi < entry->small_scenery.var_18) {
image_id = ((uint8*)entry->small_scenery.var_10)[esi];
}
image_id = (image_id * 4) + direction + entry->image;
if (entry->small_scenery.flags & (SMALL_SCENERY_FLAG21 | SMALL_SCENERY_FLAG17)) {
image_id += 4;
}
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_HAS_PRIMARY_COLOUR) {
image_id |= ((mapElement->properties.scenery.colour_1 & 0x1F) << 19) | 0x20000000;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR) {
image_id |= ((mapElement->properties.scenery.colour_1 & 0x1F) << 24) | 0x80000000;
}
}
if (dword_F64EB0 != 0) {
image_id = (image_id & 0x7FFFF) | dword_F64EB0;
}
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG21) {
sub_98197C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
} else {
sub_98199C(image_id, x_offset, y_offset, boxlength.x, boxlength.y, boxlength.z - 1, height, boxoffset.x, boxoffset.y, boxoffset.z, get_current_rotation());
}
}
}
}
// 6E0556: Draw supports:
if (mapElement->properties.scenery.colour_1 & 0x20) {
if (!(entry->small_scenery.flags & SMALL_SCENERY_FLAG20)) {
int ax = 0;
int supportHeight = height;
if (supportHeight & 0xF) {
supportHeight &= 0xFFFFFFF0;
ax = 49;
}
uint32 supportImageColourFlags = 0x20000000;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG26) {
supportImageColourFlags = ((mapElement->properties.scenery.colour_1 & 0x1F) << 19) | 0x20000000;
}
if (dword_F64EB0 != 0) {
supportImageColourFlags = dword_F64EB0;
}
if (direction & 1) {
wooden_b_supports_paint_setup(1, ax, supportHeight, supportImageColourFlags);
} else {
wooden_b_supports_paint_setup(0, ax, supportHeight, supportImageColourFlags);
}
}
}
// 6E05D1:
height += entry->small_scenery.height;
uint16 word_F64F2A = height;
height += 7;
height &= 0xFFF8;
paint_util_set_general_support_height(height, 0x20);
// 6E05FF:
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG23) {
height = word_F64F2A;
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE) {
// 6E0825:
paint_util_set_segment_support_height(SEGMENT_C4, height, 0x20);
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_VOFFSET_CENTRE) {
paint_util_set_segment_support_height(SEGMENTS_ALL & ~SEGMENT_C4, height, 0x20);
}
return;
}
if (!(entry->small_scenery.flags & SMALL_SCENERY_FLAG_VOFFSET_CENTRE)) {
return;
}
// 6E075C:
paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_B4 | SEGMENT_C8 | SEGMENT_CC, get_current_rotation()), height, 0x20);
return;
}
if (entry->small_scenery.flags & (SMALL_SCENERY_FLAG27 | SMALL_SCENERY_FLAG_FULL_TILE)) {
paint_util_set_segment_support_height(SEGMENT_C4, 0xFFFF, 0);
if (entry->small_scenery.flags & SMALL_SCENERY_FLAG_VOFFSET_CENTRE) {
paint_util_set_segment_support_height(SEGMENTS_ALL & ~SEGMENT_C4, 0xFFFF, 0);
}
return;
}
if (!(entry->small_scenery.flags & SMALL_SCENERY_FLAG_VOFFSET_CENTRE)) {
return;
}
paint_util_set_segment_support_height(paint_util_rotate_segments(SEGMENT_B4 | SEGMENT_C8 | SEGMENT_CC, get_current_rotation()), 0xFFFF, 0);
return;
}

View File

@@ -20,5 +20,6 @@
#include "../common.h"
bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool* underground);
bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags);
bool metal_a_supports_paint_setup(int supportType, int segment, int special, int height, uint32 imageColourFlags);
#endif

View File

@@ -44,6 +44,7 @@ static uint8 _trackSaveDirection;
static bool track_design_save_should_select_scenery_around(int rideIndex, rct_map_element *mapElement);
static void track_design_save_select_nearby_scenery_for_tile(int rideIndex, int cx, int cy);
bool track_design_save_contains_map_element(rct_map_element *mapElement);
static bool track_design_save_add_map_element(int interactionType, int x, int y, rct_map_element *mapElement);
static void track_design_save_remove_map_element(int interactionType, int x, int y, rct_map_element *mapElement);
static bool track_design_save_copy_scenery_to_td6(rct_track_td6 *td6);

View File

@@ -28,7 +28,9 @@ typedef struct rct_small_scenery_entry {
sint16 price; // 0x0C
sint16 removal_price; // 0x0E
uint32 var_10;
uint8 pad_14[0x06];
uint16 var_14;
uint16 var_16;
uint16 var_18;
uint8 scenery_tab_id; // 0x1A
} rct_small_scenery_entry;
@@ -59,6 +61,8 @@ typedef enum {
SMALL_SCENERY_FLAG23 = (1 << 23), // 0x800000
SMALL_SCENERY_FLAG24 = (1 << 24), // 0x1000000
SMALL_SCENERY_FLAG25 = (1 << 25), // 0x2000000
SMALL_SCENERY_FLAG26 = (1 << 26), // 0x4000000
SMALL_SCENERY_FLAG27 = (1 << 27), // 0x8000000
} SMALL_SCENERY_FLAGS;
typedef struct rct_large_scenery_tile {