diff --git a/src/paint/supports.c b/src/paint/supports.c index 263020d17f..320f3fbbcb 100644 --- a/src/paint/supports.c +++ b/src/paint/supports.c @@ -687,7 +687,7 @@ bool wooden_b_supports_paint_setup(int supportType, int special, int height, uin * @param imageColourFlags (ebp) * rct2: 0x00663105 */ -bool metal_a_supports_paint_setup(int supportType, int segment, int special, int height, uint32 imageColourFlags) +bool metal_a_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) { return false; @@ -876,7 +876,7 @@ bool metal_a_supports_paint_setup(int supportType, int segment, int special, int * * @return (Carry Flag) */ -bool metal_b_supports_paint_setup(int 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) { #ifndef NO_RCT2 if (gUseOriginalRidePaint) { diff --git a/src/paint/supports.h b/src/paint/supports.h index 06e4feb187..5c0985cf87 100644 --- a/src/paint/supports.h +++ b/src/paint/supports.h @@ -28,8 +28,8 @@ extern paint_struct * gWoodenSupportsPrependTo; 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* underground); -bool metal_a_supports_paint_setup(int supportType, int segment, int special, int height, uint32 imageColourFlags); -bool metal_b_supports_paint_setup(int 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); +bool metal_b_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags); bool path_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, rct_footpath_entry * pathEntry, bool * underground); bool path_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, rct_footpath_entry * pathEntry); diff --git a/test/testpaint/PaintIntercept.cpp b/test/testpaint/PaintIntercept.cpp new file mode 100644 index 0000000000..ebaa33cee3 --- /dev/null +++ b/test/testpaint/PaintIntercept.cpp @@ -0,0 +1,355 @@ +#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + + +#include "intercept.h" + +extern "C" { +#include "../../src/common.h" +#include "../../src/hook.h" +#include "../../src/interface/viewport.h" +} + +class PaintInterceptor { +public: + static void InitHooks() { + addhook(0x006629BC, (int) InterceptWoodenASupports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); + addhook(0x00662D5C, (int) InterceptWoodenBSupports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); + + addhook(0x00663105, (int) InterceptMetalASupports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); + addhook(0x00663584, (int) InterceptMetalBSupports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); + + addhook(0x006861AC, (int) InterceptPaint6C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x00686337, (int) InterceptPaint6C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x006864D0, (int) InterceptPaint6C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x0068666B, (int) InterceptPaint6C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + + addhook(0x00686806, (int) InterceptPaint7C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x006869B2, (int) InterceptPaint7C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x00686B6F, (int) InterceptPaint7C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x00686D31, (int) InterceptPaint7C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + + addhook(0x00686EF0, (int) InterceptPaint8C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x00687056, (int) InterceptPaint8C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x006871C8, (int) InterceptPaint8C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x0068733C, (int) InterceptPaint8C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + + addhook(0x006874B0, (int) InterceptPaint9C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x00687618, (int) InterceptPaint9C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x0068778C, (int) InterceptPaint9C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + addhook(0x00687902, (int) InterceptPaint9C, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); + } + + static bool PaintWoodenSupports(uint8 function, int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { + function_call call = { + .function = function, + .supports = { + .type = supportType, + .special = special, + .height = height, + .colour_flags = imageColourFlags, + } + }; + + _calls[_callCount] = call; + _callCount++; + + return _woodenSupports; + } + + static bool PaintMetalSupports(uint8 function, int supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { + CheckSegmentSupportHeight(); + + function_call call = { + .function = function, + .supports = { + .type = supportType, + .segment = segment, + .special = special, + .height = height, + .colour_flags = imageColourFlags, + } + }; + + _calls[_callCount] = call; + _callCount++; + return false; + } + + static paint_struct *Paint6C( + uint32 imageID, + sint8 xOffset, sint8 yOffset, + sint16 boundBoxLengthX, sint16 boundBoxLengthY, sint8 boundBoxLengthZ, + sint16 zOffset, + uint32 rotation + ) { + function_call call = { + .function = PAINT_98196C, + .paint = { + .image_id = imageID, + .offset = {xOffset, yOffset}, + .bound_box_length = {boundBoxLengthX, boundBoxLengthY, boundBoxLengthZ}, + .z_offset = zOffset, + .rotation = rotation + }, + }; + + _calls[_callCount] = call; + _callCount++; + + return nullptr; + } + + static paint_struct *PaintFull( + uint8 function, + uint32 imageID, + sint8 xOffset, sint8 yOffset, + sint16 boundBoxLengthX, sint16 boundBoxLengthY, sint8 boundBoxLengthZ, + sint16 zOffset, + sint16 boundBoxOffsetX, sint16 boundBoxOffsetY, sint16 boundBoxOffsetZ, + uint32 rotation + ) { + function_call call = { + .function = function, + .paint = { + .image_id = imageID, + .offset = {xOffset, yOffset}, + .bound_box_length = {boundBoxLengthX, boundBoxLengthY, boundBoxLengthZ}, + .bound_box_offset = {boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ}, + .z_offset = zOffset, + .rotation = rotation + }, + }; + + _calls[_callCount] = call; + _callCount++; + + return nullptr; + } + + static void ClearCalls() { + _callCount = 0; + memset(_calls, 0, sizeof(_calls)); + } + + static int GetCalls(function_call *buffer) { + memcpy(buffer, _calls, _callCount * sizeof(function_call)); + return _callCount; + } + + static void SetSimulateWoodenSupports(bool enabled) { + _woodenSupports = enabled; + } + +private: + static bool _woodenSupports; + static uint8 _callCount; + static function_call _calls[256]; + + static uint32 InterceptMetalASupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { + bool output = PaintMetalSupports(SUPPORTS_METAL_A, edi, ebx, (sint16) (eax & 0xFFFF), (edx & 0xFFFF), ebp); + + return output ? 1 : 0; + } + + static uint32 InterceptMetalBSupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { + bool output = PaintMetalSupports(SUPPORTS_METAL_B, edi, ebx, (sint16) (eax & 0xFFFF), (edx & 0xFFFF), ebp); + + return output ? 1 : 0; + } + + static void CheckSegmentSupportHeight() { + // First get last known support height state + if (memcmp(gSupportSegments, &DefaultSegmentHeight, sizeof(support_height) * 9) == 0) { + // Nothing changed + return; + } + + + function_call call = { + .function = SET_SEGMENT_HEIGHT + }; + + _calls[_callCount] = call; + _callCount++; + } + + static uint32 InterceptWoodenASupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { + bool output = PaintWoodenSupports(SUPPORTS_WOOD_A, edi, eax & 0xFFFF, edx & 0xFFFF, ebp, nullptr); + + return output ? 1 : 0; + } + + static uint32 InterceptWoodenBSupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { + bool output = PaintWoodenSupports(SUPPORTS_WOOD_B, edi, eax & 0xFFFF, edx & 0xFFFF, ebp, nullptr); + + return output ? 1 : 0; + } + + static uint32 InterceptPaint6C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { + if ((ebp & 0x03) != get_current_rotation()) { + // Log error + log_error("Ebp is different from current rotation"); + } + + return (uintptr_t) Paint6C( + ebx, + (sint8) (eax & 0xFF), (sint8) (ecx & 0xFF), + (sint16) (edi & 0xFFFF), (sint16) (esi & 0xFFFF), (sint8) ((eax >> 8) & 0xFF), + edx & 0xFFFF, + ebp & 0x03 + ); + } + + static uint32 InterceptPaint7C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { + return InterceptPaintFull(PAINT_98197C, eax, ebx, ecx, edx, esi, edi, ebp); + } + + static uint32 InterceptPaint8C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { + return InterceptPaintFull(PAINT_98198C, eax, ebx, ecx, edx, esi, edi, ebp); + } + + static uint32 InterceptPaint9C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { + return InterceptPaintFull(PAINT_98199C, eax, ebx, ecx, edx, esi, edi, ebp); + } + + static uint32 InterceptPaintFull(uint8 function, uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { + if ((ebp & 0x03) != get_current_rotation()) { + // Log error + log_error("Ebp is different from current rotation"); + } + + rct_xyz16 boundOffset = { + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, sint16) + }; + + return (uintptr_t) PaintFull( + function, + ebx, + (sint8) (eax & 0xFF), (sint8) (ecx & 0xFF), + (sint16) (edi & 0xFFFF), (sint16) (esi & 0xFFFF), (sint8) ((eax >> 8) & 0xFF), + edx & 0xFFFF, + boundOffset.x, boundOffset.y, boundOffset.z, + ebp & 0x03 + ); + } +}; + +bool PaintInterceptor::_woodenSupports = false; +uint8 PaintInterceptor::_callCount = 0; +function_call PaintInterceptor::_calls[256] = {0}; + +extern "C" { +bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { + return PaintInterceptor::PaintWoodenSupports(SUPPORTS_WOOD_A, supportType, special, height, imageColourFlags, underground); +} + +bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { + return PaintInterceptor::PaintWoodenSupports(SUPPORTS_WOOD_B, supportType, special, height, imageColourFlags, underground); +} + +bool metal_a_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { + return PaintInterceptor::PaintMetalSupports(SUPPORTS_METAL_A, supportType, segment, special, height, imageColourFlags); +} + +bool metal_b_supports_paint_setup(uint8 supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { + return PaintInterceptor::PaintMetalSupports(SUPPORTS_METAL_B, supportType, segment, special, height, imageColourFlags); +} + +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) { + return PaintInterceptor::Paint6C(image_id, x_offset, y_offset, bound_box_length_x, bound_box_length_y, bound_box_length_z, z_offset, rotation); +} + +paint_struct *sub_98197C( + 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, + sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, + uint32 rotation +) { + return PaintInterceptor::PaintFull( + PAINT_98197C, + image_id, + x_offset, y_offset, + bound_box_length_x, bound_box_length_y, bound_box_length_z, + z_offset, + bound_box_offset_x, bound_box_offset_y, bound_box_offset_z, + rotation + ); +} + +paint_struct *sub_98198C( + 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, + sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, + uint32 rotation +) { + return PaintInterceptor::PaintFull( + PAINT_98198C, + image_id, + x_offset, y_offset, + bound_box_length_x, bound_box_length_y, bound_box_length_z, + z_offset, + bound_box_offset_x, bound_box_offset_y, bound_box_offset_z, + rotation + ); +} + +paint_struct *sub_98199C( + 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, + sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, + uint32 rotation +) { + return PaintInterceptor::PaintFull( + PAINT_98199C, + image_id, + x_offset, y_offset, + bound_box_length_x, bound_box_length_y, bound_box_length_z, + z_offset, + bound_box_offset_x, bound_box_offset_y, bound_box_offset_z, + rotation + ); +} + +bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y) { + return false; +} + +void intercept_clear_calls() { + PaintInterceptor::ClearCalls(); +} + +int intercept_get_calls(function_call *buffer) { + return PaintInterceptor::GetCalls(buffer); +} + +void intercept_simulate_wooden_supports(bool enabled) { + return PaintInterceptor::SetSimulateWoodenSupports(enabled); +} + +void initHooks() { + PaintInterceptor::InitHooks(); +} + +} diff --git a/test/testpaint/intercept.c b/test/testpaint/intercept.c index 12e546b2eb..f628050f9b 100644 --- a/test/testpaint/intercept.c +++ b/test/testpaint/intercept.c @@ -27,7 +27,7 @@ static const uint32 DEFAULT_SCHEME_MISC = COLOUR_DARK_PURPLE << 19 | COLOUR_LIGH static const uint32 DEFAULT_SCHEME_3 = COLOUR_BRIGHT_PURPLE << 19 | COLOUR_DARK_BLUE << 24 | 0xA0000000; #define BLANK_SUPPORT {.height = 0, .slope = 0xFF} -static const support_height DefaultSegmentHeight[9] = { +const support_height DefaultSegmentHeight[9] = { BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT @@ -37,218 +37,6 @@ extern const utf8string RideNames[91]; extern const utf8string TrackNames[256]; extern const utf8string FlatTrackNames[256]; -static bool _woodenSupports; -static uint8 callCount; -static function_call calls[256]; - -void intercept_clear_calls() -{ - callCount = 0; - memset(calls, 0, sizeof(calls)); -} - -int intercept_get_calls(function_call * buffer) -{ - memcpy(buffer, calls, 256); - return callCount; -} - -bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y) { - return false; -} - -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 -) { - function_call call = { - .function = PAINT_98196C, - .paint = { - .image_id = image_id, - .offset = {x_offset, y_offset}, - .bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z}, - .z_offset = z_offset, - .rotation = rotation - }, - }; - - calls[callCount] = call; - callCount++; - - return NULL; -} - -paint_struct *sub_98197C( - 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, - sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, - uint32 rotation -) { - function_call call = { - .function = PAINT_98197C, - .paint = { - .image_id = image_id, - .offset = {x_offset, y_offset}, - .bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z}, - .bound_box_offset = {bound_box_offset_x, bound_box_offset_y, bound_box_offset_z}, - .z_offset = z_offset, - .rotation = rotation, - }, - }; - - calls[callCount] = call; - callCount++; - - return NULL; -} - -paint_struct *sub_98198C( - 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, - sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, - uint32 rotation -) { - function_call call = { - .function = PAINT_98198C, - .paint = { - .image_id = image_id, - .offset = {x_offset, y_offset}, - .bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z}, - .bound_box_offset = {bound_box_offset_x, bound_box_offset_y, bound_box_offset_z}, - .z_offset = z_offset, - .rotation = rotation, - }, - }; - - calls[callCount] = call; - callCount++; - - return NULL; -} - -paint_struct *sub_98199C( - 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, - sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, - uint32 rotation -) { - function_call call = { - .function = PAINT_98199C, - .paint = { - .image_id = image_id, - .offset = {x_offset, y_offset}, - .bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z}, - .bound_box_offset = {bound_box_offset_x, bound_box_offset_y, bound_box_offset_z}, - .z_offset = z_offset, - .rotation = rotation, - }, - }; - - calls[callCount] = call; - callCount++; - - return NULL; -} - -bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { - - function_call call = { - .function = SUPPORTS_WOOD_A, - .supports = { - .type = supportType, - .special = special, - .height = height, - .colour_flags = imageColourFlags, - } - }; - - calls[callCount] = call; - callCount++; - return _woodenSupports; -} - -bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) { - - function_call call = { - .function = SUPPORTS_WOOD_B, - .supports = { - .type = supportType, - .special = special, - .height = height, - .colour_flags = imageColourFlags, - } - }; - - calls[callCount] = call; - callCount++; - return _woodenSupports; -} - -static void check_support_height() -{ - // First get last known support height state - if (memcmp(gSupportSegments, &DefaultSegmentHeight, sizeof(support_height) * 9) == 0) { - // Nothing changed - return; - } - - function_call call = { - .function = SET_SEGMENT_HEIGHT - }; - - calls[callCount] = call; - callCount++; -} - -bool metal_a_supports_paint_setup(int supportType, int segment, int special, int height, uint32 imageColourFlags) { - - check_support_height(); - - function_call call = { - .function = SUPPORTS_METAL_A, - .supports = { - .type = supportType, - .segment = segment, - .special = special, - .height = height, - .colour_flags = imageColourFlags, - } - }; - - calls[callCount] = call; - callCount++; - return false; -} - -bool metal_b_supports_paint_setup(int supportType, uint8 segment, int special, int height, uint32 imageColourFlags) { - - check_support_height(); - - function_call call = { - .function = SUPPORTS_METAL_B, - .supports = { - .type = supportType, - .segment = segment, - .special = special, - .height = height, - .colour_flags = imageColourFlags, - } - }; - - calls[callCount] = call; - callCount++; - return false; -} - enum { SPRITEGROUP_NONE, @@ -257,7 +45,6 @@ enum { SPRITEGROUP_FENCE_SPIRAL_SLIDE, // 20564 SPRITEGROUP_FLOOR_CORK, // 22134 SPRITEGROUP_FENCE_ROPE, // 22138 - }; static int getSpriteGroup(uint16 spriteIndex) { @@ -524,6 +311,7 @@ extern bool testSupportSegments(uint8 rideType, uint8 trackType); extern bool testTunnels(uint8 rideType, uint8 trackType); extern bool testVerticalTunnels(uint8 rideType, uint8 trackType); + static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, size_t len) { if (rideType == RIDE_TYPE_CHAIRLIFT) { if (trackType == TRACK_ELEM_BEGIN_STATION || trackType == TRACK_ELEM_MIDDLE_STATION || trackType == TRACK_ELEM_END_STATION) { @@ -573,9 +361,9 @@ static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, for (int supports = 0; supports < 2; supports++) { if (supports == 0) { - _woodenSupports = false; + intercept_simulate_wooden_supports(false); } else { - _woodenSupports = true; + intercept_simulate_wooden_supports(true); } for (int inverted = 0; inverted < 2; inverted++) { if (inverted == 0) { @@ -600,8 +388,7 @@ static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, gSurfaceElement = &surfaceElement; g141E9DB = G141E9DB_FLAG_1 | G141E9DB_FLAG_2; - callCount = 0; - memset(&calls, 0, sizeof(calls)); + intercept_clear_calls(); memcpy(gSupportSegments, DefaultSegmentHeight, sizeof(support_height) * 9); @@ -621,11 +408,10 @@ static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, // segment heights // tunnels - uint8 oldCallCount = callCount; function_call oldCalls[256]; - memcpy(&oldCalls, &calls, sizeof(calls)); + int oldCallCount = intercept_get_calls(oldCalls); - callCount = 0; + intercept_clear_calls(); testpaint_clear_ignore(); memcpy(gSupportSegments, DefaultSegmentHeight, sizeof(support_height) * 9); @@ -636,9 +422,8 @@ static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, continue; } - uint8 newCallCount = callCount; function_call newCalls[256]; - memcpy(&newCalls, &calls, sizeof(calls)); + int newCallCount = intercept_get_calls(newCalls); if (!assertFunctionCallArrayEquals(oldCalls, oldCallCount, newCalls, newCallCount)) { utf8string diff = malloc(2048); @@ -724,97 +509,3 @@ bool testTrackPainting(int rideType, int trackType) { return success; } - -static int intercept_draw_6c(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .ecx = ecx, .edx = edx, .esi = esi, .edi = edi, .ebp = ebp}; - if ((ebp & 0x03) != get_current_rotation()) { - // Log error - log_error("Ebp is different from current rotation"); - } - - return (int) sub_98196C(ebx, regs.al, regs.cl, regs.di, regs.si, regs.ah, regs.dx, regs.ebp & 0x03); -} - -static int intercept_draw_7c(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .ecx = ecx, .edx = edx, .esi = esi, .edi = edi, .ebp = ebp}; - if ((ebp & 0x03) != get_current_rotation()) { - // Log error - log_error("Ebp is different from current rotation"); - } - - rct_xyz16 boundOffset = { - RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, sint16) - }; - - return (int) sub_98197C(ebx, regs.al, regs.cl, regs.di, regs.si, regs.ah, regs.dx, boundOffset.x, boundOffset.y, boundOffset.z, regs.ebp & 0x03); -} - -static int intercept_draw_9c(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .ecx = ecx, .edx = edx, .esi = esi, .edi = edi, .ebp = ebp}; - if ((ebp & 0x03) != get_current_rotation()) { - // Log error - log_error("Ebp is different from current rotation"); - } - - rct_xyz16 boundOffset = { - RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, sint16) - }; - - return (int) sub_98199C(ebx, regs.al, regs.cl, regs.di, regs.si, regs.ah, regs.dx, boundOffset.x, boundOffset.y, boundOffset.z, regs.ebp & 0x03); -} - -static uint32 intercept_wooden_a_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp}; - bool output = wooden_a_supports_paint_setup(regs.edi, (sint16) regs.ax, regs.dx, (uint32) regs.ebp, NULL); - - return output ? 1 : 0; -} - -static uint32 intercept_wooden_b_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp}; - bool output = wooden_b_supports_paint_setup(regs.edi, (sint16) regs.ax, regs.dx, (uint32) regs.ebp, NULL); - - return output ? 1 : 0; -} - -static uint32 intercept_metal_a_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp}; - metal_a_supports_paint_setup(regs.edi, regs.ebx, (sint16) regs.ax, regs.dx, (uint32) regs.ebp); - - return 0; -} - -static uint32 intercept_metal_b_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) { - registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp}; - metal_b_supports_paint_setup(regs.edi, regs.ebx, (sint16) regs.ax, regs.dx, (uint32) regs.ebp); - - return 0; -} - - -void initHooks() { - addhook(0x00686806, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x006869B2, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x00686B6F, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x00686D31, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - - addhook(0x006861AC, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x00686337, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x006864D0, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x0068666B, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - - addhook(0x006874B0, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x00687618, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x0068778C, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - addhook(0x00687902, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP); - - addhook(0x006629BC, (int) intercept_wooden_a_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); - addhook(0x00662D5C, (int) intercept_wooden_b_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); - - addhook(0x00663105, (int) intercept_metal_a_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); - addhook(0x00663584, (int) intercept_metal_b_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX); -} diff --git a/test/testpaint/intercept.h b/test/testpaint/intercept.h index 7194042178..fef78af70d 100644 --- a/test/testpaint/intercept.h +++ b/test/testpaint/intercept.h @@ -85,9 +85,13 @@ extern "C" bool testVerticalTunnels(uint8 rideType, uint8 trackType); void intercept_clear_calls(); int intercept_get_calls(function_call * buffer); + void intercept_simulate_wooden_supports(bool enabled); bool assertFunctionCallEquals(function_call expected, function_call actual); int generatePaintCode(uint8 rideType); + + extern const support_height DefaultSegmentHeight[9]; + #ifdef __cplusplus } #endif