diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 6340354d87..3775dd0bbc 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -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 = ""; }; C606CCD01DB4D7C800FE4015 /* SideTunnelCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SideTunnelCall.cpp; sourceTree = ""; }; C606CCD11DB4D7C800FE4015 /* SideTunnelCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SideTunnelCall.hpp; sourceTree = ""; }; + C606CCD31DB4DD6C00FE4015 /* VerticalTunnelCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VerticalTunnelCall.cpp; sourceTree = ""; }; + C606CCD41DB4DD6C00FE4015 /* VerticalTunnelCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VerticalTunnelCall.hpp; sourceTree = ""; }; C612A8971D64825300B634CA /* vehicle_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vehicle_data.c; sourceTree = ""; }; C612A8981D64825300B634CA /* vehicle_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vehicle_data.h; sourceTree = ""; }; C61FB7221CF86356004CE991 /* NetworkUser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkUser.cpp; sourceTree = ""; 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 */, diff --git a/test/testpaint/Printer.cpp b/test/testpaint/Printer.cpp index d90c8cb885..87882dbbda 100644 --- a/test/testpaint/Printer.cpp +++ b/test/testpaint/Printer.cpp @@ -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()); diff --git a/test/testpaint/Printer.hpp b/test/testpaint/Printer.hpp index f9b59a4100..30b0749adf 100644 --- a/test/testpaint/Printer.hpp +++ b/test/testpaint/Printer.hpp @@ -30,4 +30,6 @@ namespace Printer { std::string PrintSegmentSupportHeightCalls(std::vector calls); std::string PrintSideTunnelCalls(TunnelCall tunnelCalls[4][4]); + + std::string PrintHeightOffset(uint16 height, uint16 baseHeight); } diff --git a/test/testpaint/TestTrack.cpp b/test/testpaint/TestTrack.cpp index af66c79a42..524d0d794c 100644 --- a/test/testpaint/TestTrack.cpp +++ b/test/testpaint/TestTrack.cpp @@ -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++) { @@ -497,4 +501,74 @@ static uint8 TestTrackElementSideTunnels(uint8 rideType, uint8 trackType, uint8 } return TEST_SUCCESS; -} \ No newline at end of file +} + +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; +} diff --git a/test/testpaint/VerticalTunnelCall.cpp b/test/testpaint/VerticalTunnelCall.cpp new file mode 100644 index 0000000000..e989febe4b --- /dev/null +++ b/test/testpaint/VerticalTunnelCall.cpp @@ -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; +} diff --git a/test/testpaint/VerticalTunnelCall.hpp b/test/testpaint/VerticalTunnelCall.hpp new file mode 100644 index 0000000000..b72c4cd41d --- /dev/null +++ b/test/testpaint/VerticalTunnelCall.hpp @@ -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]); +}; diff --git a/test/testpaint/intercept_2.cpp b/test/testpaint/intercept_2.cpp index b98be2fd35..8695423ea1 100644 --- a/test/testpaint/intercept_2.cpp +++ b/test/testpaint/intercept_2.cpp @@ -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(); diff --git a/test/testpaint/testpaint.vcxproj b/test/testpaint/testpaint.vcxproj index 5cb14b45ac..c3d28cd492 100644 --- a/test/testpaint/testpaint.vcxproj +++ b/test/testpaint/testpaint.vcxproj @@ -107,6 +107,7 @@ +