Fix testpaint

This commit is contained in:
Ted John 2017-09-02 17:33:12 +01:00
parent b314cc4d74
commit 4ea9ac2d07
4 changed files with 69 additions and 34 deletions

View File

@ -26,6 +26,8 @@ extern "C" {
#include <openrct2/sprites.h> #include <openrct2/sprites.h>
} }
paint_session gPaintSession;
static bool _woodenSupports = false; static bool _woodenSupports = false;
static uint8 _callCount = 0; static uint8 _callCount = 0;
static function_call _calls[256] = {0}; static function_call _calls[256] = {0};
@ -42,9 +44,9 @@ namespace PaintIntercept {
static uint8 InterceptPaint9C(registers *regs); static uint8 InterceptPaint9C(registers *regs);
static uint8 InterceptPaintFull(uint8 function, registers *regs); static uint8 InterceptPaintFull(uint8 function, registers *regs);
bool PaintMetalSupports(uint8 function, int supportType, uint8 segment, int special, int height, uint32 imageColourFlags); bool PaintMetalSupports(uint8 function, int supportType, uint8 segment, int special, int height, uint32 imageColourFlags, const support_height * supportSegments);
bool PaintWoodenSupports(uint8 function, int supportType, int special, int height, uint32 imageColourFlags, bool *underground); bool PaintWoodenSupports(uint8 function, int supportType, int special, int height, uint32 imageColourFlags, bool *underground, const paint_struct * prependTo);
static void CheckSegmentSupportHeight(); static void CheckSegmentSupportHeight(const support_height * supportSegments);
void InitHooks() { void InitHooks() {
addhook(0x006629BC, InterceptWoodenASupports); addhook(0x006629BC, InterceptWoodenASupports);
@ -74,7 +76,7 @@ namespace PaintIntercept {
addhook(0x00687902, InterceptPaint9C); addhook(0x00687902, InterceptPaint9C);
} }
bool PaintWoodenSupports(uint8 function, int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { bool PaintWoodenSupports(uint8 function, int supportType, int special, int height, uint32 imageColourFlags, bool *underground, const paint_struct * prependTo) {
function_call * call = &_calls[_callCount]; function_call * call = &_calls[_callCount];
call->function = function; call->function = function;
call->supports.type = supportType; call->supports.type = supportType;
@ -83,11 +85,11 @@ namespace PaintIntercept {
call->supports.colour_flags = imageColourFlags; call->supports.colour_flags = imageColourFlags;
call->supports.prepend_to = SPR_NONE; call->supports.prepend_to = SPR_NONE;
if (gWoodenSupportsPrependTo != nullptr) if (prependTo != nullptr)
{ {
for (int i = 0; i < _callCount; i++) for (int i = 0; i < _callCount; i++)
{ {
if (&_calls[i].paint.output_struct == gWoodenSupportsPrependTo) if (&_calls[i].paint.output_struct == prependTo)
{ {
call->supports.prepend_to = _calls[i].paint.image_id; call->supports.prepend_to = _calls[i].paint.image_id;
break; break;
@ -100,8 +102,8 @@ namespace PaintIntercept {
return _woodenSupports; return _woodenSupports;
} }
bool PaintMetalSupports(uint8 function, int supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { bool PaintMetalSupports(uint8 function, int supportType, uint8 segment, int special, int height, uint32 imageColourFlags, const support_height * supportSegments) {
CheckSegmentSupportHeight(); CheckSegmentSupportHeight(supportSegments);
function_call * call = &_calls[_callCount]; function_call * call = &_calls[_callCount];
call->function = function; call->function = function;
@ -175,23 +177,23 @@ namespace PaintIntercept {
static uint8 InterceptMetalASupports(registers *regs) static uint8 InterceptMetalASupports(registers *regs)
{ {
bool output = PaintMetalSupports(SUPPORTS_METAL_A, regs->edi, regs->ebx, (sint16) regs->ax, regs->dx, regs->ebp); bool output = PaintMetalSupports(SUPPORTS_METAL_A, regs->edi, regs->ebx, (sint16) regs->ax, regs->dx, regs->ebp, gSupportSegments);
return output ? X86_FLAG_CARRY : 0; return output ? X86_FLAG_CARRY : 0;
} }
static uint8 InterceptMetalBSupports(registers *regs) static uint8 InterceptMetalBSupports(registers *regs)
{ {
bool output = PaintMetalSupports(SUPPORTS_METAL_B, regs->edi, regs->ebx, (sint16) regs->ax, regs->dx, regs->ebp); bool output = PaintMetalSupports(SUPPORTS_METAL_B, regs->edi, regs->ebx, (sint16) regs->ax, regs->dx, regs->ebp, gSupportSegments);
return output ? X86_FLAG_CARRY : 0; return output ? X86_FLAG_CARRY : 0;
} }
static void CheckSegmentSupportHeight() { static void CheckSegmentSupportHeight(const support_height * supportSegments) {
bool hasChanged = false; bool hasChanged = false;
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
if (gSupportSegments[i].height != 0) hasChanged = true; if (supportSegments[i].height != 0) hasChanged = true;
if (gSupportSegments[i].slope != 0xFF) hasChanged = true; if (supportSegments[i].slope != 0xFF) hasChanged = true;
} }
if (!hasChanged) { if (!hasChanged) {
@ -208,7 +210,7 @@ namespace PaintIntercept {
static uint8 InterceptWoodenASupports(registers *regs) static uint8 InterceptWoodenASupports(registers *regs)
{ {
bool cf = false; bool cf = false;
regs->al = PaintWoodenSupports(SUPPORTS_WOOD_A, regs->edi, regs->ax, regs->dx, regs->ebp, &cf); regs->al = PaintWoodenSupports(SUPPORTS_WOOD_A, regs->edi, regs->ax, regs->dx, regs->ebp, &cf, gWoodenSupportsPrependTo);
if (cf) if (cf)
{ {
@ -221,7 +223,7 @@ namespace PaintIntercept {
static uint8 InterceptWoodenBSupports(registers *regs) static uint8 InterceptWoodenBSupports(registers *regs)
{ {
bool cf = false; bool cf = false;
regs->al = PaintWoodenSupports(SUPPORTS_WOOD_B, regs->edi, regs->ax, regs->dx, regs->ebp, &cf); regs->al = PaintWoodenSupports(SUPPORTS_WOOD_B, regs->edi, regs->ax, regs->dx, regs->ebp, &cf, gWoodenSupportsPrependTo);
if (cf) if (cf)
{ {
@ -307,19 +309,19 @@ namespace PaintIntercept {
extern "C" { extern "C" {
bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) {
return PaintIntercept::PaintWoodenSupports(SUPPORTS_WOOD_A, supportType, special, height, imageColourFlags, underground); return PaintIntercept::PaintWoodenSupports(SUPPORTS_WOOD_A, supportType, special, height, imageColourFlags, underground, gPaintSession.WoodenSupportsPrependTo);
} }
bool wooden_b_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 *underground) {
return PaintIntercept::PaintWoodenSupports(SUPPORTS_WOOD_B, supportType, special, height, imageColourFlags, underground); return PaintIntercept::PaintWoodenSupports(SUPPORTS_WOOD_B, supportType, special, height, imageColourFlags, underground, gPaintSession.WoodenSupportsPrependTo);
} }
bool metal_a_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { bool metal_a_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) {
return PaintIntercept::PaintMetalSupports(SUPPORTS_METAL_A, supportType, segment, special, height, imageColourFlags); return PaintIntercept::PaintMetalSupports(SUPPORTS_METAL_A, supportType, segment, special, height, imageColourFlags, gPaintSession.SupportSegments);
} }
bool metal_b_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { bool metal_b_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) {
return PaintIntercept::PaintMetalSupports(SUPPORTS_METAL_B, supportType, segment, special, height, imageColourFlags); return PaintIntercept::PaintMetalSupports(SUPPORTS_METAL_B, supportType, segment, special, height, imageColourFlags, gPaintSession.SupportSegments);
} }
paint_struct *sub_98196C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, sint16 z_offset, uint32 rotation) { paint_struct *sub_98196C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, sint16 z_offset, uint32 rotation) {

View File

@ -19,7 +19,7 @@
#include <openrct2/common.h> #include <openrct2/common.h>
extern "C" { extern "C" {
#include <openrct2/paint/map_element/map_element.h> #include <openrct2/paint/paint.h>
} }
enum { enum {

View File

@ -35,6 +35,8 @@ namespace TestPaint
{ {
void ResetEnvironment() { void ResetEnvironment() {
gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE; gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE;
gPaintSession.InteractionType = VIEWPORT_INTERACTION_ITEM_RIDE;
gTrackColours[SCHEME_TRACK] = DEFAULT_SCHEME_TRACK; gTrackColours[SCHEME_TRACK] = DEFAULT_SCHEME_TRACK;
gTrackColours[SCHEME_SUPPORTS] = DEFAULT_SCHEME_SUPPORTS; gTrackColours[SCHEME_SUPPORTS] = DEFAULT_SCHEME_SUPPORTS;
gTrackColours[SCHEME_MISC] = DEFAULT_SCHEME_MISC; gTrackColours[SCHEME_MISC] = DEFAULT_SCHEME_MISC;
@ -43,6 +45,7 @@ namespace TestPaint
rct_drawpixelinfo dpi = { 0 }; rct_drawpixelinfo dpi = { 0 };
dpi.zoom_level = 1; dpi.zoom_level = 1;
unk_140E9A8 = &dpi; unk_140E9A8 = &dpi;
gPaintSession.Unk140E9A8 = &dpi;
rct_ride ride = {0}; rct_ride ride = {0};
ride.entrance_style = RIDE_ENTRANCE_STYLE_PLAIN; ride.entrance_style = RIDE_ENTRANCE_STYLE_PLAIN;
@ -56,23 +59,34 @@ namespace TestPaint
gRideEntries[0] = &rideEntry; gRideEntries[0] = &rideEntry;
g141E9DB = G141E9DB_FLAG_1 | G141E9DB_FLAG_2; g141E9DB = G141E9DB_FLAG_1 | G141E9DB_FLAG_2;
gPaintSession.Unk141E9DB = G141E9DB_FLAG_1 | G141E9DB_FLAG_2;
} }
void ResetTunnels() { void ResetTunnels() {
gLeftTunnelCount = 0; gLeftTunnelCount = 0;
gRightTunnelCount = 0; gRightTunnelCount = 0;
gPaintSession.LeftTunnelCount = 0;
gPaintSession.RightTunnelCount = 0;
for (int i = 0; i < TUNNEL_MAX_COUNT; i++) { for (int i = 0; i < TUNNEL_MAX_COUNT; i++) {
gLeftTunnels[i].height = 0; gLeftTunnels[i].height = 0;
gLeftTunnels[i].type = 0; gLeftTunnels[i].type = 0;
gRightTunnels[i].height = 0; gRightTunnels[i].height = 0;
gRightTunnels[i].type = 0; gRightTunnels[i].type = 0;
gPaintSession.LeftTunnels[i].height = 0;
gPaintSession.LeftTunnels[i].type = 0;
gPaintSession.RightTunnels[i].height = 0;
gPaintSession.RightTunnels[i].type = 0;
} }
gLeftTunnels[0].height = 0xFF; gLeftTunnels[0].height = 0xFF;
gLeftTunnels[0].type = 0xFF; gLeftTunnels[0].type = 0xFF;
gRightTunnels[0].height = 0xFF; gRightTunnels[0].height = 0xFF;
gRightTunnels[0].type = 0xFF; gRightTunnels[0].type = 0xFF;
gPaintSession.LeftTunnels[0].height = 0xFF;
gPaintSession.LeftTunnels[0].type = 0xFF;
gPaintSession.RightTunnels[0].height = 0xFF;
gPaintSession.RightTunnels[0].type = 0xFF;
} }
void ResetSupportHeights() { void ResetSupportHeights() {
@ -80,10 +94,14 @@ namespace TestPaint
{ {
gSupportSegments[s].height = 0; gSupportSegments[s].height = 0;
gSupportSegments[s].slope = 0xFF; gSupportSegments[s].slope = 0xFF;
gPaintSession.SupportSegments[s].height = 0;
gPaintSession.SupportSegments[s].slope = 0xFF;
} }
gSupport.height = 0; gSupport.height = 0;
gSupport.slope = 0xFF; gSupport.slope = 0xFF;
gPaintSession.Support.height = 0;
gPaintSession.Support.slope = 0xFF;
} }
struct IgnoredEntry struct IgnoredEntry

View File

@ -272,6 +272,10 @@ static uint8 TestTrackElementPaintCalls(uint8 rideType, uint8 trackType, uint8 t
gSurfaceElement = &surfaceElement; gSurfaceElement = &surfaceElement;
gDidPassSurface = true; gDidPassSurface = true;
gPaintSession.CurrentlyDrawnItem = &mapElement;
gPaintSession.SurfaceElement = &surfaceElement;
gPaintSession.DidPassSurface = true;
TestPaint::ResetEnvironment(); TestPaint::ResetEnvironment();
TestPaint::ResetTunnels(); TestPaint::ResetTunnels();
@ -359,7 +363,7 @@ static uint8 TestTrackElementPaintCalls(uint8 rideType, uint8 trackType, uint8 t
PaintIntercept::ClearCalls(); PaintIntercept::ClearCalls();
testpaint_clear_ignore(); testpaint_clear_ignore();
TestPaint::ResetSupportHeights(); TestPaint::ResetSupportHeights();
gWoodenSupportsPrependTo = nullptr; gPaintSession.WoodenSupportsPrependTo = nullptr;
CallNew(rideType, trackType, direction, trackSequence, height, &mapElement); CallNew(rideType, trackType, direction, trackSequence, height, &mapElement);
@ -407,13 +411,17 @@ static uint8 TestTrackElementSegmentSupportHeight(uint8 rideType, uint8 trackTyp
mapElement.properties.track.type = trackType; mapElement.properties.track.type = trackType;
mapElement.base_height = height / 16; mapElement.base_height = height / 16;
g_currently_drawn_item = &mapElement; g_currently_drawn_item = &mapElement;
rct_map_element surfaceElement = {0}; rct_map_element surfaceElement = {0};
surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE; surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE;
surfaceElement.base_height = 2; surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement; gSurfaceElement = &surfaceElement;
gDidPassSurface = true; gDidPassSurface = true;
gPaintSession.CurrentlyDrawnItem = &mapElement;
gPaintSession.SurfaceElement = &surfaceElement;
gPaintSession.DidPassSurface = true;
TestPaint::ResetEnvironment(); TestPaint::ResetEnvironment();
TestPaint::ResetTunnels(); TestPaint::ResetTunnels();
@ -456,8 +464,7 @@ static uint8 TestTrackElementSegmentSupportHeight(uint8 rideType, uint8 trackTyp
continue; continue;
} }
std::vector<SegmentSupportCall> newCalls = SegmentSupportHeightCall::getSegmentCalls(gSupportSegments, std::vector<SegmentSupportCall> newCalls = SegmentSupportHeightCall::getSegmentCalls(gPaintSession.SupportSegments, direction);
direction);
if (!SegmentSupportHeightCall::CallsEqual(referenceCalls, newCalls)) { if (!SegmentSupportHeightCall::CallsEqual(referenceCalls, newCalls)) {
*error += String::Format( *error += String::Format(
"Segment support heights didn't match. [direction:%d] %s\n", "Segment support heights didn't match. [direction:%d] %s\n",
@ -490,6 +497,10 @@ static uint8 TestTrackElementGeneralSupportHeight(uint8 rideType, uint8 trackTyp
gSurfaceElement = &surfaceElement; gSurfaceElement = &surfaceElement;
gDidPassSurface = true; gDidPassSurface = true;
gPaintSession.CurrentlyDrawnItem = &mapElement;
gPaintSession.SurfaceElement = &surfaceElement;
gPaintSession.DidPassSurface = true;
TestPaint::ResetEnvironment(); TestPaint::ResetEnvironment();
TestPaint::ResetTunnels(); TestPaint::ResetTunnels();
@ -539,11 +550,11 @@ static uint8 TestTrackElementGeneralSupportHeight(uint8 rideType, uint8 trackTyp
if (referenceCall.height != -1) { if (referenceCall.height != -1) {
if (gSupport.height != referenceCall.height) { if (gPaintSession.Support.height != referenceCall.height) {
*error += String::Format( *error += String::Format(
"General support heights didn't match. (expected height + %d, actual: height + %d) [direction:%d] %s\n", "General support heights didn't match. (expected height + %d, actual: height + %d) [direction:%d] %s\n",
referenceCall.height - height, referenceCall.height - height,
gSupport.height - height, gPaintSession.Support.height - height,
direction, direction,
state.c_str() state.c_str()
); );
@ -551,11 +562,11 @@ static uint8 TestTrackElementGeneralSupportHeight(uint8 rideType, uint8 trackTyp
} }
} }
if (referenceCall.slope != -1) { if (referenceCall.slope != -1) {
if (gSupport.slope != referenceCall.slope) { if (gPaintSession.Support.slope != referenceCall.slope) {
*error += String::Format( *error += String::Format(
"General support slopes didn't match. (expected 0x%02X, actual: 0x%02X) [direction:%d] %s\n", "General support slopes didn't match. (expected 0x%02X, actual: 0x%02X) [direction:%d] %s\n",
referenceCall.slope, referenceCall.slope,
gSupport.slope, gPaintSession.Support.slope,
direction, direction,
state.c_str() state.c_str()
); );
@ -582,6 +593,10 @@ static uint8 TestTrackElementSideTunnels(uint8 rideType, uint8 trackType, uint8
gSurfaceElement = &surfaceElement; gSurfaceElement = &surfaceElement;
gDidPassSurface = true; gDidPassSurface = true;
gPaintSession.CurrentlyDrawnItem = &mapElement;
gPaintSession.SurfaceElement = &surfaceElement;
gPaintSession.DidPassSurface = true;
TestPaint::ResetEnvironment(); TestPaint::ResetEnvironment();
TestPaint::ResetTunnels(); TestPaint::ResetTunnels();
@ -635,12 +650,8 @@ static uint8 TestTrackElementSideTunnels(uint8 rideType, uint8 trackType, uint8
} }
bool err = false; bool err = false;
newTileTunnelCalls[direction][rightIndex] = SideTunnelCall::ExtractTunnelCalls(gRightTunnels, gRightTunnelCount, height, newTileTunnelCalls[direction][rightIndex] = SideTunnelCall::ExtractTunnelCalls(gPaintSession.RightTunnels, gPaintSession.RightTunnelCount, height, &err);
&err); newTileTunnelCalls[direction][leftIndex] = SideTunnelCall::ExtractTunnelCalls(gPaintSession.LeftTunnels, gPaintSession.LeftTunnelCount, height, &err);
newTileTunnelCalls[direction][leftIndex] = SideTunnelCall::ExtractTunnelCalls(gLeftTunnels, gLeftTunnelCount, height,
&err);
if (err) { if (err) {
*error += "Multiple tunnels on one side aren't supported.\n"; *error += "Multiple tunnels on one side aren't supported.\n";
return TEST_FAILED; return TEST_FAILED;
@ -698,6 +709,10 @@ static uint8 TestTrackElementVerticalTunnels(uint8 rideType, uint8 trackType, ui
gSurfaceElement = &surfaceElement; gSurfaceElement = &surfaceElement;
gDidPassSurface = true; gDidPassSurface = true;
gPaintSession.CurrentlyDrawnItem = &mapElement;
gPaintSession.SurfaceElement = &surfaceElement;
gPaintSession.DidPassSurface = true;
TestPaint::ResetEnvironment(); TestPaint::ResetEnvironment();
TestPaint::ResetTunnels(); TestPaint::ResetTunnels();