mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 00:03:11 +01:00
Extract method interception to seperate class
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
355
test/testpaint/PaintIntercept.cpp
Normal file
355
test/testpaint/PaintIntercept.cpp
Normal file
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user