diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index b3952fc3af..a73bf33186 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -32,6 +32,8 @@ C606CCC71DB4054000FE4015 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCB81DB4054000FE4015 /* String.cpp */; }; C606CCC81DB4054000FE4015 /* TestTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCBA1DB4054000FE4015 /* TestTrack.cpp */; }; C606CCC91DB4054000FE4015 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCBC1DB4054000FE4015 /* Utils.cpp */; }; + C606CCCE1DB427A000FE4015 /* GeneralSupportHeightCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCCA1DB427A000FE4015 /* GeneralSupportHeightCall.cpp */; }; + C606CCCF1DB427A000FE4015 /* SegmentSupportHeightCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCCC1DB427A000FE4015 /* SegmentSupportHeightCall.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 */; }; @@ -520,6 +522,10 @@ C606CCBB1DB4054000FE4015 /* TestTrack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TestTrack.hpp; sourceTree = ""; }; C606CCBC1DB4054000FE4015 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utils.cpp; sourceTree = ""; }; C606CCBD1DB4054000FE4015 /* Utils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Utils.hpp; sourceTree = ""; }; + C606CCCA1DB427A000FE4015 /* GeneralSupportHeightCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeneralSupportHeightCall.cpp; sourceTree = ""; }; + C606CCCB1DB427A000FE4015 /* GeneralSupportHeightCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GeneralSupportHeightCall.hpp; sourceTree = ""; }; + C606CCCC1DB427A000FE4015 /* SegmentSupportHeightCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentSupportHeightCall.cpp; sourceTree = ""; }; + C606CCCD1DB427A000FE4015 /* SegmentSupportHeightCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SegmentSupportHeightCall.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; }; @@ -1191,6 +1197,8 @@ C606CCAD1DB4054000FE4015 /* data.h */, C606CCAE1DB4054000FE4015 /* FunctionCall.cpp */, C606CCAF1DB4054000FE4015 /* FunctionCall.hpp */, + C606CCCA1DB427A000FE4015 /* GeneralSupportHeightCall.cpp */, + C606CCCB1DB427A000FE4015 /* GeneralSupportHeightCall.hpp */, C606CCB01DB4054000FE4015 /* generate.cpp */, C606CCB11DB4054000FE4015 /* intercept_2.cpp */, C606CCB31DB4054000FE4015 /* intercept.h */, @@ -1198,6 +1206,8 @@ C606CCB51DB4054000FE4015 /* PaintIntercept.cpp */, C606CCB61DB4054000FE4015 /* Printer.cpp */, C606CCB71DB4054000FE4015 /* Printer.hpp */, + C606CCCC1DB427A000FE4015 /* SegmentSupportHeightCall.cpp */, + C606CCCD1DB427A000FE4015 /* SegmentSupportHeightCall.hpp */, C606CCB81DB4054000FE4015 /* String.cpp */, C606CCB91DB4054000FE4015 /* String.hpp */, C606CCBA1DB4054000FE4015 /* TestTrack.cpp */, @@ -2401,6 +2411,7 @@ C64FDA6C1D6D9A2100F259B9 /* inverted_impulse_coaster.c in Sources */, C64FDA6D1D6D9A2100F259B9 /* inverted_roller_coaster.c in Sources */, C64FDA6E1D6D9A2100F259B9 /* junior_roller_coaster.c in Sources */, + C606CCCF1DB427A000FE4015 /* SegmentSupportHeightCall.cpp in Sources */, C64FDA6F1D6D9A2100F259B9 /* lay_down_roller_coaster.c in Sources */, C64FDA701D6D9A2100F259B9 /* lim_launched_roller_coaster.c in Sources */, C64FDA711D6D9A2100F259B9 /* looping_roller_coaster.c in Sources */, @@ -2444,6 +2455,7 @@ C64FDA8F1D6D9A2100F259B9 /* mini_helicopters.c in Sources */, C606CCC51DB4054000FE4015 /* PaintIntercept.cpp in Sources */, C64FDA901D6D9A2100F259B9 /* monorail_cycles.c in Sources */, + C606CCCE1DB427A000FE4015 /* GeneralSupportHeightCall.cpp in Sources */, C64FDA911D6D9A2100F259B9 /* observation_tower.c in Sources */, C64FDA921D6D9A2100F259B9 /* space_rings.c in Sources */, C64FDA931D6D9A2100F259B9 /* spiral_slide.c in Sources */, diff --git a/test/testpaint/GeneralSupportHeightCall.cpp b/test/testpaint/GeneralSupportHeightCall.cpp new file mode 100644 index 0000000000..774414371b --- /dev/null +++ b/test/testpaint/GeneralSupportHeightCall.cpp @@ -0,0 +1,76 @@ +#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 + +#include "GeneralSupportHeightCall.hpp" + +bool GeneralSupportHeightCall::CallsMatch(SupportCall tileSupportCalls[4]) { + SupportCall baseCall = tileSupportCalls[0]; + for (int i = 1; i < 4; i++) { + if (tileSupportCalls[i] != baseCall) return false; + } + + return true; +} + +SupportCall *GeneralSupportHeightCall::FindMostCommonSupportCall(SupportCall calls[4]) { + std::map map; + + for (int i = 0; i < 4; ++i) { + if (map.count(calls[i]) == 0) { + map[calls[i]] = 1; + } else { + map[calls[i]] += 1; + } + } + + if (map.size() == 1) { + return &calls[0]; + } + + if (map.size() == 2) { + for (auto &&item : map) { + if (item.second == 3) { + return (SupportCall *)&item.first; + } + } + + return nullptr; + } + + if (map.size() == 3) { + for (auto &&item : map) { + if (item.second == 2) { + return (SupportCall *)&item.first; + } + } + + return nullptr; + } + + return nullptr; +} + +bool GeneralSupportHeightCall::AssertEquals(const SupportCall *lhs, const SupportCall *rhs) { + if (lhs == nullptr && rhs == nullptr) return true; + if (lhs == nullptr || rhs == nullptr) return false; + + if (lhs->height != rhs->height) return false; + if (lhs->slope != rhs->slope) return false; + + return true; +} diff --git a/test/testpaint/GeneralSupportHeightCall.hpp b/test/testpaint/GeneralSupportHeightCall.hpp new file mode 100644 index 0000000000..3127c634d8 --- /dev/null +++ b/test/testpaint/GeneralSupportHeightCall.hpp @@ -0,0 +1,52 @@ +#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" + +struct SupportCall { + sint32 height; + sint16 slope; + + friend bool operator==(const SupportCall& lhs, const SupportCall& rhs) { + if (lhs.height != rhs.height) return false; + if (lhs.slope != rhs.slope) return false; + + return true; + } + + bool operator!=(const SupportCall &other) const { + return !(*this == other); + } + + bool operator<(const SupportCall &other) const { + if (height != other.height) { + return height < other.height; + } + + return slope < other.slope; + } +}; + +class GeneralSupportHeightCall { +public: + static bool CallsMatch(SupportCall tileSupportCalls[4]); + + static SupportCall *FindMostCommonSupportCall(SupportCall calls[4]); + + static bool AssertEquals(const SupportCall *lhs, const SupportCall *rhs); +}; diff --git a/test/testpaint/Printer.cpp b/test/testpaint/Printer.cpp index bd3d8fb8b2..d59271556b 100644 --- a/test/testpaint/Printer.cpp +++ b/test/testpaint/Printer.cpp @@ -16,7 +16,6 @@ #include "Printer.hpp" #include "String.hpp" -#include "intercept.h" namespace Printer { @@ -37,6 +36,8 @@ namespace Printer { static std::string GetOffsetExpressionString(int offset); + static std::string PrintSegmentSupportHeightCall(SegmentSupportCall call); + std::string PrintFunctionCalls(std::vector calls, uint16 baseHeight) { std::string out; @@ -104,6 +105,41 @@ namespace Printer { return s; } + std::string PrintSegmentSupportHeightCalls(std::vector calls) { + std::string out = ""; + + for (auto &&call : calls) { + out += PrintSegmentSupportHeightCall(call); + } + + return out; + } + + static std::string PrintSegmentSupportHeightCall(SegmentSupportCall call) { + std::string out = ""; + + int segmentsPrinted = 0; + for (int i = 0; i < 9; i++) { + if (call.segments & segment_offsets[i]) { + if (segmentsPrinted > 0) { + out += " | "; + } + out += String::Format("SEGMENT_%02X", 0xB4 + 4 * i); + segmentsPrinted++; + } + } + + if (call.height == 0xFFFF) { + out += ", 0xFFFF"; + } else { + out += String::Format(", %d", call.height); + } + + out += String::Format(", 0x%02X\n", call.slope); + + return out; + } + static std::string GetImageIdString(uint32 imageId) { std::string result; diff --git a/test/testpaint/Printer.hpp b/test/testpaint/Printer.hpp index d8815bdee0..032aee77f7 100644 --- a/test/testpaint/Printer.hpp +++ b/test/testpaint/Printer.hpp @@ -20,8 +20,11 @@ #include #include "intercept.h" +#include "SegmentSupportHeightCall.hpp" namespace Printer { std::string PrintFunctionCall(function_call call, uint16 baseHeight); std::string PrintFunctionCalls(std::vector calls, uint16 baseHeight); + + std::string PrintSegmentSupportHeightCalls(std::vector calls); } diff --git a/test/testpaint/SegmentSupportHeightCall.cpp b/test/testpaint/SegmentSupportHeightCall.cpp new file mode 100644 index 0000000000..6bb5fcadc4 --- /dev/null +++ b/test/testpaint/SegmentSupportHeightCall.cpp @@ -0,0 +1,112 @@ +#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 "SegmentSupportHeightCall.hpp" + +extern "C" { +#include "../../src/paint/map_element/map_element.h" +} + +static bool SortSegmentSupportCalls(SegmentSupportCall lhs, SegmentSupportCall rhs) +{ + if (lhs.height != rhs.height) { + return lhs.height < rhs.height; + } + + if (lhs.slope != rhs.slope) { + return lhs.slope < rhs.slope; + } + + return lhs.segments < rhs.segments; +} + +std::vector SegmentSupportHeightCall::getSegmentCalls(support_height *supports, uint8 rotation) { + uint16 positionsRemaining = SEGMENTS_ALL; + + for (int i = 0; i < 9; i++) { + if (supports[i].height == 0 && supports[i].slope == 0xFF) { + positionsRemaining &= ~segment_offsets[i]; + } + } + + std::vector calls; + + while (positionsRemaining != 0) { + SegmentSupportCall call = {0}; + call.height = -1; + call.slope = -1; + + support_height referenceSupport = { 0 }; + + for (int i = 0; i < 9; i++) { + if (positionsRemaining & segment_offsets[i]) { + referenceSupport = supports[i]; + if (supports[i].height != 0) { + call.height = supports[i].height; + } + if (supports[i].slope != 0xFF) { + call.slope = supports[i].slope; + } + break; + } + } + + uint16 positionsMatched = 0; + for (int i = 0; i < 9; i++) { + if (supports[i].height == referenceSupport.height && supports[i].slope == referenceSupport.slope) { + positionsMatched |= segment_offsets[i]; + } + } + positionsRemaining &= ~positionsMatched; + + call.segments = paint_util_rotate_segments(positionsMatched, (4 - rotation) % 4); + + calls.push_back(call); + } + + if (calls.size() > 1) { + std::sort(calls.begin(), calls.end(), SortSegmentSupportCalls); + } + + return calls; +} + +bool SegmentSupportHeightCall::CallsMatch(std::vector tileSegmentSupportCalls[4]) +{ + std::vector baseCallList = tileSegmentSupportCalls[0]; + for (int i = 1; i < 4; i++) { + if (!CallsEqual(baseCallList, tileSegmentSupportCalls[i])) { + return false; + } + } + + return true; +} + +bool SegmentSupportHeightCall::CallsEqual(std::vector lhs, std::vector rhs) +{ + if (lhs.size() != rhs.size()) return false; + for (size_t i = 0; i < lhs.size(); ++i) { + if (lhs[i].segments != rhs[i].segments) + return false; + if (lhs[i].height != rhs[i].height) + return false; + if (lhs[i].slope != rhs[i].slope) + return false; + } + + return true; +} diff --git a/test/testpaint/SegmentSupportHeightCall.hpp b/test/testpaint/SegmentSupportHeightCall.hpp new file mode 100644 index 0000000000..5a87709967 --- /dev/null +++ b/test/testpaint/SegmentSupportHeightCall.hpp @@ -0,0 +1,36 @@ +#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 + +#include "../../src/common.h" +#include "../../src/paint/paint.h" + +struct SegmentSupportCall +{ + uint16 segments; + sint32 height; + sint16 slope; +}; + +class SegmentSupportHeightCall { +public: + static std::vector getSegmentCalls(support_height supports[9], uint8 rotation); + static bool CallsMatch(std::vector tileSegmentSupportCalls[4]); + static bool CallsEqual(std::vector lhs, std::vector rhs); +}; diff --git a/test/testpaint/generate.cpp b/test/testpaint/generate.cpp index 253e3cd8f8..3f5a5a7507 100644 --- a/test/testpaint/generate.cpp +++ b/test/testpaint/generate.cpp @@ -19,6 +19,7 @@ #include #include "intercept.h" +#include "SegmentSupportHeightCall.hpp" #include "String.hpp" #include "Utils.hpp" @@ -401,7 +402,7 @@ private: std::vector calls[4], chainLiftCalls[4], cableLiftCalls[4]; Intercept2::TunnelCall tileTunnelCalls[4][4]; sint16 verticalTunnelHeights[4]; - std::vector segmentSupportCalls[4]; + std::vector segmentSupportCalls[4]; support_height generalSupports[4] = { 0 }; for (int direction = 0; direction < 4; direction++) { rct_map_element mapElement = { 0 }; @@ -431,7 +432,7 @@ private: } } - segmentSupportCalls[direction] = Intercept2::getSegmentCalls(gSupportSegments, direction); + segmentSupportCalls[direction] = SegmentSupportHeightCall::getSegmentCalls(gSupportSegments, direction); generalSupports[direction] = gSupport; if (gSupport.slope != 0xFF && gSupport.height != 0) { @@ -894,7 +895,7 @@ private: WriteLine(tabs, "paint_util_push_tunnel_rotated(direction, height%s, TUNNEL_%d);", GetOffsetExpressionString(offset).c_str(), type); } - void GenerateSegmentSupportCall(int tabs, std::vector segmentSupportCalls[4]) + void GenerateSegmentSupportCall(int tabs, std::vector segmentSupportCalls[4]) { for (size_t i = 0; i < segmentSupportCalls[0].size(); i++) { diff --git a/test/testpaint/intercept.h b/test/testpaint/intercept.h index 1f1655ad97..581482bae7 100644 --- a/test/testpaint/intercept.h +++ b/test/testpaint/intercept.h @@ -108,19 +108,6 @@ namespace Intercept2 static const uint32 DEFAULT_SCHEME_MISC = COLOUR_DARK_PURPLE << 19 | COLOUR_LIGHT_PURPLE << 24 | 0xA0000000; static const uint32 DEFAULT_SCHEME_3 = COLOUR_BRIGHT_PURPLE << 19 | COLOUR_DARK_BLUE << 24 | 0xA0000000; - struct SegmentSupportCall - { - uint16 segments; - sint32 height; - sint16 slope; - }; - - struct SupportCall - { - sint32 height; - sint16 slope; - }; - enum { TUNNELCALL_SKIPPED, TUNNELCALL_NONE, @@ -134,7 +121,6 @@ namespace Intercept2 }; sint16 getTunnelOffset(uint32 baseHeight, tunnel_entry calls[3]); - std::vector getSegmentCalls(support_height supports[9], uint8 rotation); } #endif diff --git a/test/testpaint/intercept_2.cpp b/test/testpaint/intercept_2.cpp index a8fff99c51..c972b32bbc 100644 --- a/test/testpaint/intercept_2.cpp +++ b/test/testpaint/intercept_2.cpp @@ -18,6 +18,9 @@ #include #include "intercept.h" +#include "GeneralSupportHeightCall.hpp" +#include "Printer.hpp" +#include "SegmentSupportHeightCall.hpp" #include "Utils.hpp" extern "C" { @@ -83,141 +86,9 @@ namespace Intercept2 gSupport.slope = 0xFF; } - static bool SortSegmentSupportCalls(SegmentSupportCall lhs, SegmentSupportCall rhs) - { - if (lhs.height != rhs.height) { - return lhs.height < rhs.height; - } - - if (lhs.slope != rhs.slope) { - return lhs.slope < rhs.slope; - } - - return lhs.segments < rhs.segments; - } - - std::vector getSegmentCalls(support_height supports[9], uint8 rotation) - { - uint16 positionsRemaining = SEGMENTS_ALL; - - for (int i = 0; i < 9; i++) { - if (supports[i].height == 0 && supports[i].slope == 0xFF) { - positionsRemaining &= ~segment_offsets[i]; - } - } - - std::vector calls; - - while (positionsRemaining != 0) { - SegmentSupportCall call = {0}; - call.height = -1; - call.slope = -1; - - support_height referenceSupport = { 0 }; - - for (int i = 0; i < 9; i++) { - if (positionsRemaining & segment_offsets[i]) { - referenceSupport = supports[i]; - if (supports[i].height != 0) { - call.height = supports[i].height; - } - if (supports[i].slope != 0xFF) { - call.slope = supports[i].slope; - } - break; - } - } - - uint16 positionsMatched = 0; - for (int i = 0; i < 9; i++) { - if (supports[i].height == referenceSupport.height && supports[i].slope == referenceSupport.slope) { - positionsMatched |= segment_offsets[i]; - } - } - positionsRemaining &= ~positionsMatched; - - call.segments = paint_util_rotate_segments(positionsMatched, (4 - rotation) % 4); - - calls.push_back(call); - } - - if (calls.size() > 1) { - std::sort(calls.begin(), calls.end(), SortSegmentSupportCalls); - } - - return calls; - } - - static bool SegmentCallEquals(std::vector lhs, std::vector rhs) - { - if (lhs.size() != rhs.size()) return false; - for (size_t i = 0; i < lhs.size(); ++i) { - if (lhs[i].segments != rhs[i].segments) - return false; - if (lhs[i].height != rhs[i].height) - return false; - if (lhs[i].slope != rhs[i].slope) - return false; - } - - return true; - } - - static bool segmentCallsMatch(std::vector tileSegmentSupportCalls[4]) - { - std::vector baseCallList = tileSegmentSupportCalls[0]; - for (int i = 1; i < 4; i++) { - if (!SegmentCallEquals(baseCallList, tileSegmentSupportCalls[i])) { - return false; - } - } - - return true; - } - - static bool supportCallsMatch(SupportCall tileSupportCalls[4]) - { - SupportCall baseCall = tileSupportCalls[0]; - for (int i = 1; i < 4; i++) { - if (tileSupportCalls[i].height != baseCall.height) return false; - if (tileSupportCalls[i].slope != baseCall.slope) return false; - } - - return true; - } - static void printSegmentSupports(utf8string out, size_t len, std::vector segmentCalls) { - for (auto &&call : segmentCalls) { - int segmentsPrinted = 0; - for (int i = 0; i < 9; i++) { - if (call.segments & segment_offsets[i]) { - if (segmentsPrinted > 0) { - size_t slen = strlen(out); - if (slen < len) - snprintf(out + slen, len - slen, " | "); - } - size_t slen = strlen(out); - if (slen < len) - snprintf(out + slen, slen - len, "SEGMENT_%02X", 0xB4 + 4 * i); - segmentsPrinted++; - } - } - - if (call.height == 0xFFFF) { - size_t slen = strlen(out); - if (slen < len) - snprintf(out + slen, len - slen, ", 0xFFFF"); - } else { - size_t slen = strlen(out); - if (slen < len) - snprintf(out + slen, len - slen, ", %d", call.height); - } - - size_t slen = strlen(out); - if (slen < len) - snprintf(out + slen, len - slen, ", 0x%02X\n", call.slope); - } + snprintf(out, len, "%s", Printer::PrintSegmentSupportHeightCalls(segmentCalls).c_str()); } static bool tunnelCallsLineUp(TunnelCall tunnelCalls[4][4]) @@ -387,7 +258,7 @@ namespace Intercept2 trackSequence ); - tileSegmentSupportCalls[direction] = getSegmentCalls(gSupportSegments, direction); + tileSegmentSupportCalls[direction] = SegmentSupportHeightCall::getSegmentCalls(gSupportSegments, direction); tileGeneralSupportCalls[direction].height = -1; tileGeneralSupportCalls[direction].slope = -1; @@ -395,13 +266,16 @@ namespace Intercept2 tileGeneralSupportCalls[direction].height = gSupport.height; } if (gSupport.slope != 0xFF) { - tileGeneralSupportCalls[direction].height = gSupport.height; + tileGeneralSupportCalls[direction].slope = gSupport.slope; } } - if (!segmentCallsMatch(tileSegmentSupportCalls)) { + if (!SegmentSupportHeightCall::CallsMatch(tileSegmentSupportCalls)) { // TODO: if 3 directions do share the same mask, use that call list as a reference. printf("Original segment calls didn't match. [trackSequence:%d chainLift:%d]\n", trackSequence, chainLift); + for (int i = 0; i < 4; i++) { + printf("# %d\n%s", i, Printer::PrintSegmentSupportHeightCalls(tileSegmentSupportCalls[i]).c_str()); + } continue; } @@ -415,9 +289,10 @@ namespace Intercept2 continue; } - std::vector newCalls = getSegmentCalls(gSupportSegments, direction); + std::vector newCalls = SegmentSupportHeightCall::getSegmentCalls(gSupportSegments, + direction); - if (!SegmentCallEquals(tileSegmentSupportCalls[0], newCalls)) { + if (!SegmentSupportHeightCall::CallsEqual(tileSegmentSupportCalls[0], newCalls)) { // TODO put this into *error utf8string diff = new utf8[2048]; snprintf(diff, 2048, "<<< EXPECTED\n"); @@ -440,14 +315,22 @@ namespace Intercept2 } } - if (!supportCallsMatch(tileGeneralSupportCalls)) { - // TODO: if 3 directions do share the output, use that. - printf("Original support calls didn't match. [trackSequence:%d chainLift:%d]\n", trackSequence, chainLift); - continue; - } - SupportCall referenceGeneralSupportCall = tileGeneralSupportCalls[0]; + if (!GeneralSupportHeightCall::CallsMatch(tileGeneralSupportCalls)) { + SupportCall *found = GeneralSupportHeightCall::FindMostCommonSupportCall(tileGeneralSupportCalls); + if (found == nullptr) { + // TODO: if 3 directions do share the output, use that. + printf("Original support calls didn't match. [trackSequence:%d chainLift:%d]\n", trackSequence, chainLift); + for (int i = 0; i < 4; ++i) { + printf("[%d, 0x%02X] ", tileGeneralSupportCalls[i].height, tileGeneralSupportCalls[i].slope); + } + printf("\n"); + continue; + } + referenceGeneralSupportCall = *found; + } + for (int direction = 0; direction < 4; direction++) { ResetSegmentHeights(); diff --git a/test/testpaint/main.cpp b/test/testpaint/main.cpp index 78383d4482..68bac9d702 100644 --- a/test/testpaint/main.cpp +++ b/test/testpaint/main.cpp @@ -358,7 +358,40 @@ static void PrintRideTypes() } } +#import "GeneralSupportHeightCall.hpp" + +static void TestGeneralSupportHeightCall() { + SupportCall callA = {16, 0x20}; + SupportCall callB = {32, 0x20}; + SupportCall callC = {48, 0x20}; + SupportCall callD = {48, 0x1F}; + + SupportCall *result; + + SupportCall groupA[4] = {callA, callA, callA, callA}; + result = GeneralSupportHeightCall::FindMostCommonSupportCall(groupA); + assert(GeneralSupportHeightCall::AssertEquals(result, &callA)); + + SupportCall groupB[4] = {callB, callA, callA, callA}; + result = GeneralSupportHeightCall::FindMostCommonSupportCall(groupB); + assert(GeneralSupportHeightCall::AssertEquals(result, &callA)); + + SupportCall groupC[4] = {callB, callA, callB, callA}; + result = GeneralSupportHeightCall::FindMostCommonSupportCall(groupC); + assert(GeneralSupportHeightCall::AssertEquals(result, nullptr)); + + SupportCall groupD[4] = {callB, callC, callB, callA}; + result = GeneralSupportHeightCall::FindMostCommonSupportCall(groupD); + assert(GeneralSupportHeightCall::AssertEquals(result, &callB)); + + SupportCall groupE[4] = {callD, callC, callB, callA}; + result = GeneralSupportHeightCall::FindMostCommonSupportCall(groupE); + assert(GeneralSupportHeightCall::AssertEquals(result, nullptr)); +} + int main(int argc, char *argv[]) { + TestGeneralSupportHeightCall(); + std::vector testCases; bool generate = false; diff --git a/test/testpaint/testpaint.vcxproj b/test/testpaint/testpaint.vcxproj index 5ecb055bdc..1a99508a9e 100644 --- a/test/testpaint/testpaint.vcxproj +++ b/test/testpaint/testpaint.vcxproj @@ -96,11 +96,13 @@ + +