From a5e1433e25323d24fb5e7819d942ba3fa7ec65cb Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 13 Oct 2016 15:00:54 +0200 Subject: [PATCH 1/3] Check if segments heights are set before supports --- test/testpaint/intercept.c | 38 ++++++++++++++++++++++++++++++++++++++ test/testpaint/intercept.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/test/testpaint/intercept.c b/test/testpaint/intercept.c index b450854a9b..6a0c6dabfd 100644 --- a/test/testpaint/intercept.c +++ b/test/testpaint/intercept.c @@ -26,6 +26,13 @@ static const uint32 DEFAULT_SCHEME_SUPPORTS = COLOUR_LIGHT_BLUE << 19 | COLOUR_I 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; +#define BLANK_SUPPORT {.height = 0, .slope = 0xFF} +static const support_height DefaultSegmentHeight[9] = { + BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, + BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT, + BLANK_SUPPORT, BLANK_SUPPORT, BLANK_SUPPORT +}; + extern const utf8string RideNames[91]; extern const utf8string TrackNames[256]; extern const utf8string FlatTrackNames[256]; @@ -185,8 +192,26 @@ bool wooden_b_supports_paint_setup(int supportType, int special, int height, uin return false; } +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 = { @@ -205,6 +230,8 @@ bool metal_a_supports_paint_setup(int supportType, int segment, int special, int 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 = { @@ -294,6 +321,10 @@ bool assertFunctionCallEquals(function_call expected, function_call actual) { return true; } + if (function == SET_SEGMENT_HEIGHT) { + return true; + } + if (expected.paint.image_id != actual.paint.image_id) { int expectedSpriteGroup = getSpriteGroup(expected.paint.image_id & 0x7FFFF); int actualSpriteGroup = getSpriteGroup(actual.paint.image_id & 0x7FFFF); @@ -378,6 +409,10 @@ static void printFunctionCall(utf8string out, size_t len, function_call call) { case SUPPORTS_METAL_B: snprintf(out, len, "metal_b_supports_paint_setup(%d, %d, %d, %d, %s)", call.supports.type, call.supports.segment, call.supports.special, call.supports.height, imageId); return; + + case SET_SEGMENT_HEIGHT: + snprintf(out, len, "paint_util_set_segment_support_height"); + return; } utf8string name = "_default"; @@ -555,6 +590,8 @@ static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, callCount = 0; memset(&calls, 0, sizeof(calls)); + memcpy(gSupportSegments, DefaultSegmentHeight, sizeof(support_height) * 9); + uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[rideType][trackType]; // Have to call from this point as it pushes esi and expects callee to pop it @@ -578,6 +615,7 @@ static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string error, callCount = 0; testpaint_clear_ignore(); + memcpy(gSupportSegments, DefaultSegmentHeight, sizeof(support_height) * 9); newPaintFunction(rideIndex, trackSequence, direction, height, &mapElement); if (testpaint_is_ignored(direction, trackSequence)) { snprintf(error, len, "[ IGNORED ] [direction:%d trackSequence:%d chainLift:%d]\n", direction, trackSequence, chainLift); diff --git a/test/testpaint/intercept.h b/test/testpaint/intercept.h index 624688fac1..7194042178 100644 --- a/test/testpaint/intercept.h +++ b/test/testpaint/intercept.h @@ -44,6 +44,8 @@ enum SUPPORTS_METAL_B, SUPPORTS_WOOD_A, SUPPORTS_WOOD_B, + + SET_SEGMENT_HEIGHT, }; typedef struct From b7fc98037382fadfc771c7f351a1cdf89086ee2f Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 13 Oct 2016 15:04:17 +0200 Subject: [PATCH 2/3] Block segments before drawing supports --- test/testpaint/generate.cpp | 54 ++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/test/testpaint/generate.cpp b/test/testpaint/generate.cpp index 3b1f0532bb..a6807639b6 100644 --- a/test/testpaint/generate.cpp +++ b/test/testpaint/generate.cpp @@ -368,10 +368,23 @@ private: return false; } + void ExtractMetalSupportCalls(std::vector calls[4], std::vector output[4]) + { + for (int direction = 0; direction < 4; direction++) { + + auto cutPoint = std::find_if(calls[direction].begin(), calls[direction].end(), [](function_call call) { + return (call.function == SUPPORTS_METAL_A || call.function == SUPPORTS_METAL_B); + }); + output[direction].insert(output[direction].begin(), cutPoint, calls[direction].end()); + calls[direction].erase(cutPoint, calls[direction].end()); + } + } + void GenerateTrackSequence(int tabs, int trackType, int trackSequence) { int height = 48; _conditionalSupports = false; + bool blockSegmentsBeforeSupports = false; std::vector calls[4], chainLiftCalls[4], cableLiftCalls[4]; Intercept2::TunnelCall tileTunnelCalls[4][4]; @@ -399,6 +412,13 @@ private: int numCalls = intercept_get_calls(callBuffer); calls[direction].insert(calls[direction].begin(), callBuffer, callBuffer + numCalls); + for (auto &&call : calls[direction]) { + if (call.function == SET_SEGMENT_HEIGHT) { + blockSegmentsBeforeSupports = true; + break; + } + } + segmentSupportCalls[direction] = Intercept2::getSegmentCalls(gSupportSegments, direction); generalSupports[direction] = gSupport; if (gSupport.slope != 0xFF && gSupport.height != 0) @@ -444,6 +464,13 @@ private: GetTunnelCalls(trackType, direction, trackSequence, height, &mapElement, tileTunnelCalls, verticalTunnelHeights); } + std::vector supportCalls[4], chainLiftSupportCalls[4], cableLiftSupportCalls[4]; + if (blockSegmentsBeforeSupports) { + ExtractMetalSupportCalls(calls, supportCalls); + ExtractMetalSupportCalls(cableLiftCalls, cableLiftSupportCalls); + ExtractMetalSupportCalls(chainLiftCalls, chainLiftSupportCalls); + } + if (_rideType == RIDE_TYPE_GIGA_COASTER && !CompareFunctionCalls(calls, cableLiftCalls)) { WriteLine(tabs, "if (track_element_is_cable_lift(mapElement)) {"); @@ -472,8 +499,33 @@ private: GenerateCalls(tabs, calls, height); } + if (blockSegmentsBeforeSupports) { + if (_rideType == RIDE_TYPE_GIGA_COASTER && !CompareFunctionCalls(supportCalls, cableLiftSupportCalls)) { + printf("Error: Supports differ for cable lift.\n"); + } else if (!CompareFunctionCalls(supportCalls, chainLiftSupportCalls)) { + printf("Error: Supports differ for chain lift\n"); + } + WriteLine(); + GenerateSegmentSupportCall(tabs, segmentSupportCalls); + + bool conditionalSupports = _conditionalSupports; + _conditionalSupports = false; + if (conditionalSupports) { + WriteLine(tabs, "if (track_paint_util_should_paint_supports(gPaintMapPosition)) {"); + tabs++; + } + GenerateCalls(tabs, supportCalls, height); + if (conditionalSupports) { + tabs--; + WriteLine(tabs, "}"); + } + WriteLine(); + } + GenerateTunnelCall(tabs, tileTunnelCalls, verticalTunnelHeights); - GenerateSegmentSupportCall(tabs, segmentSupportCalls); + if (!blockSegmentsBeforeSupports) { + GenerateSegmentSupportCall(tabs, segmentSupportCalls); + } GenerateGeneralSupportCall(tabs, generalSupports); } From 5a77261ee90e6eb2559401cf0d52f77bbd4fd955 Mon Sep 17 00:00:00 2001 From: Marijn van der Werf Date: Thu, 13 Oct 2016 17:24:39 +0200 Subject: [PATCH 3/3] Generate empty station function --- test/testpaint/generate.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/testpaint/generate.cpp b/test/testpaint/generate.cpp index a6807639b6..9eec9ff9f5 100644 --- a/test/testpaint/generate.cpp +++ b/test/testpaint/generate.cpp @@ -129,6 +129,16 @@ private: GenerateTrackFunction(trackType); WriteLine(); } + + if (trackType == TRACK_ELEM_END_STATION) + { + const uint32 * paintFunctionList = RideTypeTrackPaintFunctionsOld[_rideType]; + WriteLine(0, "/** rct2: 0x%08X, 0x%08X, 0x%08X */", paintFunctionList[TRACK_ELEM_END_STATION], paintFunctionList[TRACK_ELEM_BEGIN_STATION], paintFunctionList[TRACK_ELEM_MIDDLE_STATION]); + WriteLine(0, "static void " + _rideName + "_track_station(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement)"); + WriteLine(0, "{"); + WriteLine(0, "}"); + WriteLine(); + } } } @@ -1045,6 +1055,14 @@ private: WriteLine(1, "switch (trackType) {"); for (int trackType = 0; trackType < 256; trackType++) { + if (trackType == TRACK_ELEM_END_STATION) { + WriteLine(1, "case " + std::string(TrackElemNames[TRACK_ELEM_END_STATION]) + ":"); + WriteLine(1, "case " + std::string(TrackElemNames[TRACK_ELEM_BEGIN_STATION]) + ":"); + WriteLine(1, "case " + std::string(TrackElemNames[TRACK_ELEM_MIDDLE_STATION]) + ":"); + WriteLine(2, "return %s_track_station;", _rideName.c_str()); + continue; + } + if (IsTrackTypeSupported(trackType)) { WriteLine(1, "case " + std::string(TrackElemNames[trackType]) + ":");