Don't use C for PaintIntercept functions

This commit is contained in:
Marijn van der Werf 2016-10-17 12:42:59 +02:00
parent d3ce7d1d75
commit 18d9b1e91e
9 changed files with 119 additions and 96 deletions

View File

@ -532,6 +532,7 @@
C606CCD11DB4D7C800FE4015 /* SideTunnelCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SideTunnelCall.hpp; sourceTree = "<group>"; };
C606CCD31DB4DD6C00FE4015 /* VerticalTunnelCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VerticalTunnelCall.cpp; sourceTree = "<group>"; };
C606CCD41DB4DD6C00FE4015 /* VerticalTunnelCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VerticalTunnelCall.hpp; sourceTree = "<group>"; };
C606CCD61DB4E1CD00FE4015 /* PaintIntercept.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PaintIntercept.hpp; sourceTree = "<group>"; };
C612A8971D64825300B634CA /* vehicle_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vehicle_data.c; sourceTree = "<group>"; };
C612A8981D64825300B634CA /* vehicle_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vehicle_data.h; sourceTree = "<group>"; };
C61FB7221CF86356004CE991 /* NetworkUser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkUser.cpp; sourceTree = "<group>"; usesTabs = 0; };
@ -1210,6 +1211,7 @@
C606CCB31DB4054000FE4015 /* intercept.h */,
C606CCB41DB4054000FE4015 /* main.cpp */,
C606CCB51DB4054000FE4015 /* PaintIntercept.cpp */,
C606CCD61DB4E1CD00FE4015 /* PaintIntercept.hpp */,
C606CCB61DB4054000FE4015 /* Printer.cpp */,
C606CCB71DB4054000FE4015 /* Printer.hpp */,
C606CCCC1DB427A000FE4015 /* SegmentSupportHeightCall.cpp */,

View File

@ -19,6 +19,43 @@
#include "../../src/common.h"
#include "intercept.h"
enum
{
PAINT_98196C,
PAINT_98197C,
PAINT_98198C,
PAINT_98199C,
SUPPORTS_METAL_A,
SUPPORTS_METAL_B,
SUPPORTS_WOOD_A,
SUPPORTS_WOOD_B,
SET_SEGMENT_HEIGHT,
};
typedef struct
{
uint8 function;
struct paint
{
uint32 image_id;
rct_xy16 offset;
rct_xyz16 bound_box_length;
sint16 z_offset;
rct_xyz16 bound_box_offset;
uint32 rotation;
} paint;
struct supports
{
int type;
uint8 segment;
int special;
int height;
uint32 colour_flags;
} supports;
} function_call;
class FunctionCall {
public:
static bool AssertsEquals(function_call expected, function_call actual);

View File

@ -15,7 +15,7 @@
#pragma endregion
#include "intercept.h"
#include "PaintIntercept.hpp"
extern "C" {
#include "../../src/common.h"
@ -24,9 +24,23 @@ extern "C" {
#include "../../src/paint/supports.h"
}
class PaintInterceptor {
public:
static void InitHooks() {
static bool _woodenSupports = false;
static uint8 _callCount = 0;
static function_call _calls[256] = {0};
namespace PaintIntercept {
static uint32 InterceptWoodenASupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp);
static uint32 InterceptWoodenBSupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp);
static uint32 InterceptMetalASupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp);
static uint32 InterceptMetalBSupports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp);
static uint32 InterceptPaint6C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
static uint32 InterceptPaint7C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
static uint32 InterceptPaint8C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
static uint32 InterceptPaint9C(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
static uint32 InterceptPaintFull(uint8 function, uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
static void CheckSegmentSupportHeight();
void InitHooks() {
int supportsRegisterArgs[] = {EAX, EBX, EDX, EDI, EBP, END};
addhook(0x006629BC, (int) InterceptWoodenASupports, 0, supportsRegisterArgs, 0, EAX);
addhook(0x00662D5C, (int) InterceptWoodenBSupports, 0, supportsRegisterArgs, 0, EAX);
@ -56,7 +70,7 @@ public:
addhook(0x00687902, (int) InterceptPaint9C, 0, paintRegisterArgs, 0, EBP);
}
static 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) {
function_call call = {0};
call.function = function;
call.supports.type = supportType;
@ -70,7 +84,7 @@ public:
return _woodenSupports;
}
static 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) {
CheckSegmentSupportHeight();
function_call call = {0};
@ -132,25 +146,20 @@ public:
return nullptr;
}
static void ClearCalls() {
void ClearCalls() {
_callCount = 0;
memset(_calls, 0, sizeof(_calls));
}
static int GetCalls(function_call *buffer) {
int GetCalls(function_call *buffer) {
memcpy(buffer, _calls, _callCount * sizeof(function_call));
return _callCount;
}
static void SetSimulateWoodenSupports(bool enabled) {
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);
@ -244,29 +253,26 @@ private:
}
};
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);
return PaintIntercept::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);
return PaintIntercept::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);
return PaintIntercept::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);
return PaintIntercept::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);
return PaintIntercept::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(
@ -277,7 +283,7 @@ paint_struct *sub_98197C(
sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z,
uint32 rotation
) {
return PaintInterceptor::PaintFull(
return PaintIntercept::PaintFull(
PAINT_98197C,
image_id,
x_offset, y_offset,
@ -296,7 +302,7 @@ paint_struct *sub_98198C(
sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z,
uint32 rotation
) {
return PaintInterceptor::PaintFull(
return PaintIntercept::PaintFull(
PAINT_98198C,
image_id,
x_offset, y_offset,
@ -315,7 +321,7 @@ paint_struct *sub_98199C(
sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z,
uint32 rotation
) {
return PaintInterceptor::PaintFull(
return PaintIntercept::PaintFull(
PAINT_98199C,
image_id,
x_offset, y_offset,
@ -330,16 +336,4 @@ 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 initHooks() {
PaintInterceptor::InitHooks();
}
}

View File

@ -0,0 +1,29 @@
#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
#pragma once
#include "../../src/common.h"
#include "FunctionCall.hpp"
namespace PaintIntercept {
void InitHooks();
void ClearCalls();
int GetCalls(function_call *buffer);
void SetSimulateWoodenSupports(bool enabled);
};

View File

@ -19,7 +19,7 @@
#include <string>
#include <vector>
#include "intercept.h"
#include "FunctionCall.hpp"
#include "SideTunnelCall.hpp"
#include "SegmentSupportHeightCall.hpp"

View File

@ -20,6 +20,7 @@
#include "intercept.h"
#include "FunctionCall.hpp"
#include "GeneralSupportHeightCall.hpp"
#include "PaintIntercept.hpp"
#include "Printer.hpp"
#include "SegmentSupportHeightCall.hpp"
#include "SideTunnelCall.hpp"
@ -165,16 +166,16 @@ static uint8 TestTrackElementPaintCalls(uint8 rideType, uint8 trackType, uint8 t
direction, trackSequence, chainLift, inverted
);
intercept_clear_calls();
PaintIntercept::ClearCalls();
Intercept2::ResetSupportHeights();
CallOriginal(rideType, trackType, direction, trackSequence, height, &mapElement);
callCount = intercept_get_calls(callBuffer);
callCount = PaintIntercept::GetCalls(callBuffer);
std::vector<function_call> oldCalls;
oldCalls.insert(oldCalls.begin(), callBuffer, callBuffer + callCount);
intercept_clear_calls();
PaintIntercept::ClearCalls();
testpaint_clear_ignore();
Intercept2::ResetSupportHeights();
@ -185,7 +186,7 @@ static uint8 TestTrackElementPaintCalls(uint8 rideType, uint8 trackType, uint8 t
continue;
}
callCount = intercept_get_calls(callBuffer);
callCount = PaintIntercept::GetCalls(callBuffer);
std::vector<function_call> newCalls;
newCalls.insert(newCalls.begin(), callBuffer, callBuffer + callCount);

View File

@ -18,7 +18,8 @@
#include <string>
#include <vector>
#include "intercept.h"
#include "FunctionCall.hpp"
#include "PaintIntercept.hpp"
#include "SegmentSupportHeightCall.hpp"
#include "SideTunnelCall.hpp"
#include "String.hpp"
@ -421,9 +422,9 @@ private:
RCT2_GLOBAL(0x009DE56E, sint16) = 64;
function_call callBuffer[256] = { 0 };
intercept_clear_calls();
PaintIntercept::ClearCalls();
CallOriginal(trackType, direction, trackSequence, height, &mapElement);
int numCalls = intercept_get_calls(callBuffer);
int numCalls = PaintIntercept::GetCalls(callBuffer);
calls[direction].insert(calls[direction].begin(), callBuffer, callBuffer + numCalls);
for (auto &&call : calls[direction]) {
@ -442,9 +443,9 @@ private:
// Get chain lift calls
mapElement.type |= 0x80;
intercept_clear_calls();
PaintIntercept::ClearCalls();
CallOriginal(trackType, direction, trackSequence, height, &mapElement);
numCalls = intercept_get_calls(callBuffer);
numCalls = PaintIntercept::GetCalls(callBuffer);
chainLiftCalls[direction].insert(chainLiftCalls[direction].begin(), callBuffer, callBuffer + numCalls);
// Get cable lift calls (giga coaster only)
@ -452,9 +453,9 @@ private:
{
mapElement.type = 0;
mapElement.properties.track.colour |= TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT;
intercept_clear_calls();
PaintIntercept::ClearCalls();
CallOriginal(trackType, direction, trackSequence, height, &mapElement);
numCalls = intercept_get_calls(callBuffer);
numCalls = PaintIntercept::GetCalls(callBuffer);
cableLiftCalls[direction].insert(cableLiftCalls[direction].begin(), callBuffer, callBuffer + numCalls);
}
@ -465,9 +466,9 @@ private:
RCT2_GLOBAL(0x009DE56E, sint16) = 64;
mapElement.type = 0;
mapElement.properties.track.colour &= ~TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT;
intercept_clear_calls();
PaintIntercept::ClearCalls();
CallOriginal(trackType, direction, trackSequence, height, &mapElement);
numCalls = intercept_get_calls(callBuffer);
numCalls = PaintIntercept::GetCalls(callBuffer);
std::vector<function_call> checkCalls = std::vector<function_call>(callBuffer, callBuffer + numCalls);
if (!CompareFunctionCalls(checkCalls, calls[direction]))
{
@ -715,7 +716,7 @@ private:
bool CompareFunctionCall(const function_call a, const function_call &b)
{
return assertFunctionCallEquals(a, b);
return FunctionCall::AssertsEquals(a, b);
}
const char * GetFunctionCallName(int function)

View File

@ -33,20 +33,7 @@ extern "C"
#define gRideEntries RCT2_ADDRESS(RCT2_ADDRESS_RIDE_ENTRIES, rct_ride_entry*)
#define gCurrentRotation RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)
enum
{
PAINT_98196C,
PAINT_98197C,
PAINT_98198C,
PAINT_98199C,
SUPPORTS_METAL_A,
SUPPORTS_METAL_B,
SUPPORTS_WOOD_A,
SUPPORTS_WOOD_B,
SET_SEGMENT_HEIGHT,
};
enum {
TEST_SUCCESS,
@ -54,41 +41,13 @@ enum {
TEST_SKIPPED,
};
typedef struct
{
uint8 function;
struct paint
{
uint32 image_id;
rct_xy16 offset;
rct_xyz16 bound_box_length;
sint16 z_offset;
rct_xyz16 bound_box_offset;
uint32 rotation;
} paint;
struct supports
{
int type;
uint8 segment;
int special;
int height;
uint32 colour_flags;
} supports;
} function_call;
#ifdef __cplusplus
extern "C"
{
#endif
void initHooks();
bool testTunnels(uint8 rideType, uint8 trackType);
bool testVerticalTunnels(uint8 rideType, uint8 trackType);
void intercept_clear_calls();
int intercept_get_calls(function_call * buffer);
void intercept_reset_environment();
void intercept_reset_segment_heights();
void intercept_reset_tunnels();
bool assertFunctionCallEquals(function_call expected, function_call actual);
int generatePaintCode(uint8 rideType);

View File

@ -23,7 +23,7 @@
#include <sys/mman.h>
#endif // defined(__unix__)
#include "intercept.h"
#include "PaintIntercept.hpp"
#include "TestTrack.hpp"
#include "Utils.hpp"
@ -422,7 +422,7 @@ int main(int argc, char *argv[]) {
}
openrct2_setup_rct2_segment();
initHooks();
PaintIntercept::InitHooks();
return generatePaintCode(specificRideType);
}
@ -464,7 +464,7 @@ int main(int argc, char *argv[]) {
ColouredPrintF(CLIColour::GREEN, "[----------] ");
printf("Global test environment set-up.\n");
openrct2_setup_rct2_segment();
initHooks();
PaintIntercept::InitHooks();
int successCount = 0;
std::vector<utf8string> failures;