1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-10 09:32:29 +01:00

Extract vertical tunnel testing

This commit is contained in:
Marijn van der Werf
2016-10-17 12:22:15 +02:00
parent 9efb41a13f
commit d3ce7d1d75
8 changed files with 140 additions and 137 deletions

View File

@@ -35,6 +35,7 @@
C606CCCE1DB427A000FE4015 /* GeneralSupportHeightCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCCA1DB427A000FE4015 /* GeneralSupportHeightCall.cpp */; };
C606CCCF1DB427A000FE4015 /* SegmentSupportHeightCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCCC1DB427A000FE4015 /* SegmentSupportHeightCall.cpp */; };
C606CCD21DB4D7C800FE4015 /* SideTunnelCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCD01DB4D7C800FE4015 /* SideTunnelCall.cpp */; };
C606CCD51DB4DD6C00FE4015 /* VerticalTunnelCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCD31DB4DD6C00FE4015 /* VerticalTunnelCall.cpp */; };
C612A8991D64825300B634CA /* vehicle_data.c in Sources */ = {isa = PBXBuildFile; fileRef = C612A8971D64825300B634CA /* vehicle_data.c */; };
C61FB7241CF86356004CE991 /* NetworkUser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C61FB7221CF86356004CE991 /* NetworkUser.cpp */; };
C64FDA641D6D9A2100F259B9 /* air_powered_vertical_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8BB1CDBC3B7009F9BFC /* air_powered_vertical_coaster.c */; };
@@ -529,6 +530,8 @@
C606CCCD1DB427A000FE4015 /* SegmentSupportHeightCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SegmentSupportHeightCall.hpp; sourceTree = "<group>"; };
C606CCD01DB4D7C800FE4015 /* SideTunnelCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SideTunnelCall.cpp; sourceTree = "<group>"; };
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>"; };
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; };
@@ -1219,6 +1222,8 @@
C606CCBB1DB4054000FE4015 /* TestTrack.hpp */,
C606CCBC1DB4054000FE4015 /* Utils.cpp */,
C606CCBD1DB4054000FE4015 /* Utils.hpp */,
C606CCD31DB4DD6C00FE4015 /* VerticalTunnelCall.cpp */,
C606CCD41DB4DD6C00FE4015 /* VerticalTunnelCall.hpp */,
);
name = Paint;
path = test/testpaint;
@@ -2407,6 +2412,7 @@
C606CCD21DB4D7C800FE4015 /* SideTunnelCall.cpp in Sources */,
C64FDABC1D6D9C8800F259B9 /* addresses.c in Sources */,
C64FDA641D6D9A2100F259B9 /* air_powered_vertical_coaster.c in Sources */,
C606CCD51DB4DD6C00FE4015 /* VerticalTunnelCall.cpp in Sources */,
C64FDA651D6D9A2100F259B9 /* bobsleigh_coaster.c in Sources */,
C64FDA661D6D9A2100F259B9 /* compact_inverted_coaster.c in Sources */,
C64FDA671D6D9A2100F259B9 /* corkscrew_roller_coaster.c in Sources */,

View File

@@ -32,8 +32,6 @@ namespace Printer {
static std::string GetImageIdString(uint32 imageId);
static std::string GetHeightOffset(uint16 height, uint16 baseHeight);
static std::string GetOffsetExpressionString(int offset);
static std::string PrintSegmentSupportHeightCall(SegmentSupportCall call);
@@ -60,14 +58,14 @@ namespace Printer {
case SUPPORTS_WOOD_B:
return String::Format(
"%s(%d, %d, %s, %s)", functionName, call.supports.type, call.supports.special,
GetHeightOffset(call.supports.height, baseHeight).c_str(), imageId.c_str()
PrintHeightOffset(call.supports.height, baseHeight).c_str(), imageId.c_str()
);
case SUPPORTS_METAL_A:
case SUPPORTS_METAL_B:
return String::Format(
"%s(%d, %d, %d, %s, %s)", functionName, call.supports.type, call.supports.segment, call.supports.special,
GetHeightOffset(call.supports.height, baseHeight).c_str(), imageId.c_str()
PrintHeightOffset(call.supports.height, baseHeight).c_str(), imageId.c_str()
);
case SET_SEGMENT_HEIGHT:
@@ -83,12 +81,13 @@ namespace Printer {
"%d, %d, %d, ",
call.paint.bound_box_length.x, call.paint.bound_box_length.y, call.paint.bound_box_length.z
);
s += String::Format("%s, ", GetHeightOffset(call.paint.z_offset, baseHeight).c_str());
s += String::Format("%s, ", PrintHeightOffset(call.paint.z_offset, baseHeight).c_str());
if (call.function != PAINT_98196C) {
s += String::Format(
"%d, %d, %s, ",
call.paint.bound_box_offset.x, call.paint.bound_box_offset.y, GetHeightOffset(call.paint.bound_box_offset.z, baseHeight).c_str()
call.paint.bound_box_offset.x, call.paint.bound_box_offset.y,
PrintHeightOffset(call.paint.bound_box_offset.z, baseHeight).c_str()
);
}
@@ -98,9 +97,9 @@ namespace Printer {
if (call.function != PAINT_98196C) {
s += String::Format(
" = { %d, %d, %s }, { %d, %d, %s }, { %d, %d, %d }",
call.paint.offset.x, call.paint.offset.y, GetHeightOffset(call.paint.z_offset, baseHeight).c_str(),
call.paint.offset.x, call.paint.offset.y, PrintHeightOffset(call.paint.z_offset, baseHeight).c_str(),
call.paint.bound_box_offset.x, call.paint.bound_box_offset.y,
GetHeightOffset(call.paint.bound_box_offset.z, baseHeight).c_str(),
PrintHeightOffset(call.paint.bound_box_offset.z, baseHeight).c_str(),
call.paint.bound_box_length.x, call.paint.bound_box_length.y, call.paint.bound_box_length.z);
}
@@ -236,7 +235,7 @@ namespace Printer {
return result;
}
static std::string GetHeightOffset(uint16 height, uint16 baseHeight) {
std::string PrintHeightOffset(uint16 height, uint16 baseHeight) {
int offset = height - baseHeight;
return String::Format("height%s", GetOffsetExpressionString(offset).c_str());

View File

@@ -30,4 +30,6 @@ namespace Printer {
std::string PrintSegmentSupportHeightCalls(std::vector<SegmentSupportCall> calls);
std::string PrintSideTunnelCalls(TunnelCall tunnelCalls[4][4]);
std::string PrintHeightOffset(uint16 height, uint16 baseHeight);
}

View File

@@ -26,6 +26,7 @@
#include "String.hpp"
#include "TestTrack.hpp"
#include "Utils.hpp"
#include "VerticalTunnelCall.hpp"
extern "C" {
#include "../../src/ride/ride.h"
@@ -81,6 +82,8 @@ static uint8 TestTrackElementGeneralSupportHeight(uint8 rideType, uint8 trackTyp
static uint8 TestTrackElementSideTunnels(uint8 rideType, uint8 trackType, uint8 trackSequence, std::string *error);
static uint8 TestTrackElementVerticalTunnels(uint8 rideType, uint8 trackType, uint8 trackSequence, std::string *error);
uint8 TestTrack::TestPaintTrackElement(uint8 rideType, uint8 trackType) {
if (!Utils::rideSupportsTrackType(rideType, trackType)) {
return TEST_FAILED;
@@ -104,6 +107,7 @@ uint8 TestTrack::TestPaintTrackElement(uint8 rideType, uint8 trackType) {
TestTrackElementSegmentSupportHeight,
TestTrackElementGeneralSupportHeight,
TestTrackElementSideTunnels,
TestTrackElementVerticalTunnels,
};
for (int trackSequence = 0; trackSequence < sequenceCount; trackSequence++) {
@@ -498,3 +502,73 @@ static uint8 TestTrackElementSideTunnels(uint8 rideType, uint8 trackType, uint8
return TEST_SUCCESS;
}
static uint8 TestTrackElementVerticalTunnels(uint8 rideType, uint8 trackType, uint8 trackSequence, std::string *error) {
uint8 rideIndex = 0;
uint16 height = 3 * 16;
rct_map_element mapElement = {0};
mapElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
mapElement.properties.track.type = trackType;
mapElement.base_height = height / 16;
g_currently_drawn_item = &mapElement;
rct_map_element surfaceElement = {0};
surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE;
surfaceElement.base_height = 2;
gSurfaceElement = &surfaceElement;
gDidPassSurface = true;
Intercept2::ResetEnvironment();
Intercept2::ResetTunnels();
uint8 verticalTunnelHeight[4];
for (int direction = 0; direction < 4; direction++) {
gVerticalTunnelHeight = 0;
CallOriginal(rideType, trackType, direction, trackSequence, height, &mapElement);
verticalTunnelHeight[direction] = gVerticalTunnelHeight;
}
if (!VerticalTunnelCall::HeightIsConsistent(verticalTunnelHeight)) {
*error += String::Format(
"Original vertical tunnel height is inconsistent, skipping test. [trackSequence:%d]\n",
trackSequence
);
return TEST_SUCCESS;
}
uint8 referenceHeight = verticalTunnelHeight[0];
for (int direction = 0; direction < 4; direction++) {
gVerticalTunnelHeight = 0;
testpaint_clear_ignore();
CallOriginal(rideType, trackType, direction, trackSequence, height, &mapElement);
if (testpaint_is_ignored(direction, trackSequence)) {
continue;
}
if (gVerticalTunnelHeight != referenceHeight) {
if (gVerticalTunnelHeight == 0) {
*error += String::Format(
"Expected no tunnel. Actual: %d [trackSequence:%d]\n",
gVerticalTunnelHeight, trackSequence
);
return TEST_FAILED;
}
*error += String::Format(
"Expected vertical tunnel height to be `%s`, was `%s`. [trackSequence:%d direction:%d]\n",
Printer::PrintHeightOffset((referenceHeight * 16), height).c_str(),
Printer::PrintHeightOffset((gVerticalTunnelHeight * 16), height).c_str(),
trackSequence,
direction
);
return TEST_FAILED;
}
}
return TEST_SUCCESS;
}

View File

@@ -0,0 +1,25 @@
#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 "VerticalTunnelCall.hpp"
bool VerticalTunnelCall::HeightIsConsistent(uint8 heights[4]) {
for (int i = 1; i < 4; ++i) {
if (heights[i] != heights[0]) return false;
}
return true;
}

View File

@@ -0,0 +1,23 @@
#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"
namespace VerticalTunnelCall {
bool HeightIsConsistent(uint8 heights[4]);
};

View File

@@ -86,128 +86,6 @@ namespace Intercept2
gSupport.slope = 0xFF;
}
static bool verticalTunnelHeightIsConsistent(uint8 heights[4])
{
for (int i = 1; i < 4; ++i) {
if (heights[i] != heights[0]) return false;
}
return true;
}
static void printRelativeHeight(utf8string out, size_t len, sint16 height)
{
if (height == 0) {
snprintf(out, len, "height");
return;
}
if (height > 0) {
snprintf(out, len, "height + %d", height);
return;
}
if (height < 0) {
snprintf(out, len, "height - %d", int(abs(height)));
return;
}
}
static bool testVerticalTunnels(uint8 rideType, uint8 trackType)
{
uint8 rideIndex = 0;
rct_map_element mapElement = {0};
mapElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
mapElement.properties.track.type = trackType;
mapElement.base_height = 3;
g_currently_drawn_item = &mapElement;
ResetEnvironment();
int height = 48;
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
int sequenceCount = Utils::getTrackSequenceCount(rideType, trackType);
for (int trackSequence = 0; trackSequence < sequenceCount; trackSequence++) {
uint8 verticalTunnelHeight[4];
for (int direction = 0; direction < 4; direction++) {
gVerticalTunnelHeight = 0;
uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[rideType][trackType];
// Have to call from this point as it pushes esi and expects callee to pop it
RCT2_CALLPROC_X(
0x006C4934,
rideType,
(int) trackDirectionList,
direction,
height,
(int) &mapElement,
rideIndex * sizeof(rct_ride),
trackSequence
);
verticalTunnelHeight[direction] = gVerticalTunnelHeight;
}
if (!verticalTunnelHeightIsConsistent(verticalTunnelHeight)) {
printf(
"Original vertical tunnel height is inconsistent, skipping test. [trackSequence:%d]\n",
trackSequence
);
continue;
}
uint8 referenceHeight = verticalTunnelHeight[0];
for (int direction = 0; direction < 4; direction++) {
gVerticalTunnelHeight = 0;
testpaint_clear_ignore();
TRACK_PAINT_FUNCTION newPaintFunction = newPaintGetter(trackType, direction);
newPaintFunction(rideIndex, trackSequence, direction, height, &mapElement);
if (testpaint_is_ignored(direction, trackSequence)) {
continue;
}
if (gVerticalTunnelHeight != referenceHeight) {
if (referenceHeight == 0) {
printf(
"Expected no vertical tunnel. [trackSequence:%d direction:%d]\n",
trackSequence,
direction
);
return false;
}
utf8string strExpectedTunnelHeight = new utf8[16];
utf8string strActualTunnelHeight = new utf8[16];
printRelativeHeight(strExpectedTunnelHeight, 16, (referenceHeight * 16) - 48);
printRelativeHeight(strActualTunnelHeight, 16, (gVerticalTunnelHeight * 16) - 48);
printf(
"Expected vertical tunnel height to be `%s`, was `%s`. [trackSequence:%d direction:%d]\n",
strExpectedTunnelHeight,
strActualTunnelHeight,
trackSequence,
direction
);
delete []strExpectedTunnelHeight;
delete []strActualTunnelHeight;
return false;
}
}
}
return true;
}
struct IgnoredEntry
{
uint8 Direction;
@@ -250,11 +128,6 @@ namespace Intercept2
extern "C"
{
bool testVerticalTunnels(uint8 rideType, uint8 trackType)
{
return Intercept2::testVerticalTunnels(rideType, trackType);
}
void testpaint_clear_ignore()
{
Intercept2::testClearIgnore();

View File

@@ -107,6 +107,7 @@
<ClCompile Include="String.cpp" />
<ClCompile Include="TestTrack.cpp" />
<ClCompile Include="Utils.cpp" />
<ClCompile Include="VerticalTunnelCall.cpp" />
<ClCompile Include="..\..\src\addresses.c" />
<ClCompile Include="..\..\src\diagnostic.c" />
<ClCompile Include="..\..\src\hook.c" />