From e17180db089b627835ebaec83157add2736afd6d Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 8 Oct 2016 00:27:07 +0100 Subject: [PATCH] Generate basic tunnels --- test/testpaint/generate.cpp | 94 ++++++++++++++++++++++++++++++++++ test/testpaint/intercept.h | 2 + test/testpaint/intercept_2.cpp | 2 +- 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/test/testpaint/generate.cpp b/test/testpaint/generate.cpp index 5bdba5f3f5..fe32ff7bb6 100644 --- a/test/testpaint/generate.cpp +++ b/test/testpaint/generate.cpp @@ -84,6 +84,7 @@ private: WriteLine(0, "static void " + GetTrackFunctionName(trackType) + "(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement)"); WriteLine(0, "{"); + Intercept2::TunnelCall tileTunnelCalls[4][4]; std::vector segmentSupportCalls[4]; support_height generalSupports[4] = { 0 }; for (int direction = 0; direction < 4; direction++) { @@ -100,14 +101,107 @@ private: segmentSupportCalls[direction] = Intercept2::getSegmentCalls(gSupportSegments, direction); generalSupports[direction] = gSupport; generalSupports[direction].height -= height; + + GetTunnelCalls(trackType, direction, trackSequence, height, &mapElement, tileTunnelCalls); } + GenerateTunnelCall(tileTunnelCalls); GenerateSegmentSupportCall(segmentSupportCalls); GenerateGeneralSupportCall(generalSupports); WriteLine(0, "}"); } + bool GetTunnelCalls(int trackType, int direction, int trackSequence, int height, rct_map_element * mapElement, Intercept2::TunnelCall tileTunnelCalls[4][4]) + { + gLeftTunnelCount = 0; + gRightTunnelCount = 0; + for (int offset = -8; offset <= 8; offset += 8) + { + CallOriginal(trackType, direction, trackSequence, height + offset, mapElement); + } + + uint8 rightIndex = (4 - direction) % 4; + uint8 leftIndex = (rightIndex + 1) % 4; + + for (int i = 0; i < 4; ++i) { + tileTunnelCalls[direction][i].call = Intercept2::TUNNELCALL_SKIPPED; + } + if (gRightTunnelCount == 0) { + tileTunnelCalls[direction][rightIndex].call = Intercept2::TUNNELCALL_NONE; + } else if (gRightTunnelCount == 3) { + tileTunnelCalls[direction][rightIndex].call = Intercept2::TUNNELCALL_CALL; + tileTunnelCalls[direction][rightIndex].offset = Intercept2::getTunnelOffset(height, gRightTunnels); + tileTunnelCalls[direction][rightIndex].type = gRightTunnels[0].type; + } else { + printf("Multiple tunnels on one side aren't supported.\n"); + return false; + } + + if (gLeftTunnelCount == 0) { + tileTunnelCalls[direction][leftIndex].call = Intercept2::TUNNELCALL_NONE; + } else if (gLeftTunnelCount == 3) { + tileTunnelCalls[direction][leftIndex].call = Intercept2::TUNNELCALL_CALL; + tileTunnelCalls[direction][leftIndex].offset = Intercept2::getTunnelOffset(height, gLeftTunnels); + tileTunnelCalls[direction][leftIndex].type = gLeftTunnels[0].type; + } else { + printf("Multiple tunnels on one side aren't supported.\n"); + return false; + } + + return true; + } + + void GenerateTunnelCall(Intercept2::TunnelCall tileTunnelCalls[4][4]) + { + sint16 tunnelOffset[4] = { 0 }; + uint8 tunnelType[4] = { 0xFF }; + for (int direction = 0; direction < 4; direction++) + { + for (int side = 0; side < 4; side++) + { + auto tunnel = tileTunnelCalls[direction][side]; + if (tunnel.call == Intercept2::TUNNELCALL_CALL) + { + tunnelOffset[direction] = tunnel.offset; + tunnelType[direction] = tunnel.type; + break; + } + } + } + + if (tunnelOffset[0] == tunnelOffset[1] && + tunnelOffset[0] == tunnelOffset[2] && + tunnelOffset[0] == tunnelOffset[3]) + { + GenerateTunnelCall(1, tunnelOffset[0], tunnelType[0]); + } + else + { + WriteLine(1, "if (direction == 0 || direction == 3) {"); + GenerateTunnelCall(2, tunnelOffset[0], tunnelType[0]); + WriteLine(1, "} else {"); + GenerateTunnelCall(2, tunnelOffset[1], tunnelType[1]); + WriteLine(1, "}"); + } + } + + void GenerateTunnelCall(int tabs, int offset, int type) + { + if (offset == 0) + { + WriteLine(tabs, "paint_util_push_tunnel_rotated(direction, height, TUNNEL_%d);", offset); + } + else if (offset < 0) + { + WriteLine(tabs, "paint_util_push_tunnel_rotated(direction, height - %d, TUNNEL_%d);", -offset, type); + } + else + { + WriteLine(tabs, "paint_util_push_tunnel_rotated(direction, height + %d, TUNNEL_%d);", offset, type); + } + } + void GenerateSegmentSupportCall(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 6a0cff586c..60f7f2d46a 100644 --- a/test/testpaint/intercept.h +++ b/test/testpaint/intercept.h @@ -25,6 +25,7 @@ extern "C" #endif #include "../../src/interface/colour.h" #include "../../src/paint/paint.h" + #include "../../src/paint/map_element/map_element.h" #ifdef __cplusplus } #endif @@ -87,6 +88,7 @@ namespace Intercept2 uint8 type; }; + sint16 getTunnelOffset(uint32 baseHeight, tunnel_entry calls[3]); std::vector getSegmentCalls(support_height supports[9], uint8 rotation); } diff --git a/test/testpaint/intercept_2.cpp b/test/testpaint/intercept_2.cpp index 92afc5341a..d4a55f47d7 100644 --- a/test/testpaint/intercept_2.cpp +++ b/test/testpaint/intercept_2.cpp @@ -457,7 +457,7 @@ namespace Intercept2 return true; } - static sint16 getTunnelOffset(uint32 baseHeight, tunnel_entry calls[3]) + sint16 getTunnelOffset(uint32 baseHeight, tunnel_entry calls[3]) { for (sint16 offset = -56; offset <= 56; offset += 8) { if (calls[0].height != (baseHeight - 8 + offset) / 16) continue;