mirror of https://github.com/OpenRCT2/OpenRCT2.git
Extract SupportHeightCalls
This commit is contained in:
parent
7d69446464
commit
deb266c443
|
@ -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 = "<group>"; };
|
||||
C606CCBC1DB4054000FE4015 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utils.cpp; sourceTree = "<group>"; };
|
||||
C606CCBD1DB4054000FE4015 /* Utils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Utils.hpp; sourceTree = "<group>"; };
|
||||
C606CCCA1DB427A000FE4015 /* GeneralSupportHeightCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeneralSupportHeightCall.cpp; sourceTree = "<group>"; };
|
||||
C606CCCB1DB427A000FE4015 /* GeneralSupportHeightCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GeneralSupportHeightCall.hpp; sourceTree = "<group>"; };
|
||||
C606CCCC1DB427A000FE4015 /* SegmentSupportHeightCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentSupportHeightCall.cpp; sourceTree = "<group>"; };
|
||||
C606CCCD1DB427A000FE4015 /* SegmentSupportHeightCall.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SegmentSupportHeightCall.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; };
|
||||
|
@ -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 */,
|
||||
|
|
|
@ -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 <map>
|
||||
|
||||
#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<SupportCall, int> 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;
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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<function_call> calls, uint16 baseHeight) {
|
||||
std::string out;
|
||||
|
||||
|
@ -104,6 +105,41 @@ namespace Printer {
|
|||
return s;
|
||||
}
|
||||
|
||||
std::string PrintSegmentSupportHeightCalls(std::vector<SegmentSupportCall> 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;
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
#include <vector>
|
||||
|
||||
#include "intercept.h"
|
||||
#include "SegmentSupportHeightCall.hpp"
|
||||
|
||||
namespace Printer {
|
||||
std::string PrintFunctionCall(function_call call, uint16 baseHeight);
|
||||
std::string PrintFunctionCalls(std::vector <function_call> calls, uint16 baseHeight);
|
||||
|
||||
std::string PrintSegmentSupportHeightCalls(std::vector<SegmentSupportCall> calls);
|
||||
}
|
||||
|
|
|
@ -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<SegmentSupportCall> 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<SegmentSupportCall> 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<SegmentSupportCall> tileSegmentSupportCalls[4])
|
||||
{
|
||||
std::vector<SegmentSupportCall> baseCallList = tileSegmentSupportCalls[0];
|
||||
for (int i = 1; i < 4; i++) {
|
||||
if (!CallsEqual(baseCallList, tileSegmentSupportCalls[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SegmentSupportHeightCall::CallsEqual(std::vector<SegmentSupportCall> lhs, std::vector<SegmentSupportCall> 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;
|
||||
}
|
|
@ -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 <vector>
|
||||
|
||||
#include "../../src/common.h"
|
||||
#include "../../src/paint/paint.h"
|
||||
|
||||
struct SegmentSupportCall
|
||||
{
|
||||
uint16 segments;
|
||||
sint32 height;
|
||||
sint16 slope;
|
||||
};
|
||||
|
||||
class SegmentSupportHeightCall {
|
||||
public:
|
||||
static std::vector<SegmentSupportCall> getSegmentCalls(support_height supports[9], uint8 rotation);
|
||||
static bool CallsMatch(std::vector<SegmentSupportCall> tileSegmentSupportCalls[4]);
|
||||
static bool CallsEqual(std::vector<SegmentSupportCall> lhs, std::vector<SegmentSupportCall> rhs);
|
||||
};
|
|
@ -19,6 +19,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "intercept.h"
|
||||
#include "SegmentSupportHeightCall.hpp"
|
||||
#include "String.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
|
@ -401,7 +402,7 @@ private:
|
|||
std::vector<function_call> calls[4], chainLiftCalls[4], cableLiftCalls[4];
|
||||
Intercept2::TunnelCall tileTunnelCalls[4][4];
|
||||
sint16 verticalTunnelHeights[4];
|
||||
std::vector<Intercept2::SegmentSupportCall> segmentSupportCalls[4];
|
||||
std::vector<SegmentSupportCall> 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<Intercept2::SegmentSupportCall> segmentSupportCalls[4])
|
||||
void GenerateSegmentSupportCall(int tabs, std::vector<SegmentSupportCall> segmentSupportCalls[4])
|
||||
{
|
||||
for (size_t i = 0; i < segmentSupportCalls[0].size(); i++)
|
||||
{
|
||||
|
|
|
@ -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<SegmentSupportCall> getSegmentCalls(support_height supports[9], uint8 rotation);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <algorithm>
|
||||
|
||||
#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<SegmentSupportCall> 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<SegmentSupportCall> 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<SegmentSupportCall> lhs, std::vector<SegmentSupportCall> 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<SegmentSupportCall> tileSegmentSupportCalls[4])
|
||||
{
|
||||
std::vector<SegmentSupportCall> 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<SegmentSupportCall> 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<SegmentSupportCall> newCalls = getSegmentCalls(gSupportSegments, direction);
|
||||
std::vector<SegmentSupportCall> 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();
|
||||
|
|
|
@ -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<TestCase> testCases;
|
||||
|
||||
bool generate = false;
|
||||
|
|
|
@ -96,11 +96,13 @@
|
|||
<ClCompile Include="compat.c" />
|
||||
<ClCompile Include="data.c" />
|
||||
<ClCompile Include="FunctionCall.cpp" />
|
||||
<ClCompile Include="GeneralSupportHeightCall.cpp" />
|
||||
<ClCompile Include="generate.cpp" />
|
||||
<ClCompile Include="intercept_2.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="PaintIntercept.cpp" />
|
||||
<ClCompile Include="Printer.cpp" />
|
||||
<ClCompile Include="SegmentSupportHeightCall.cpp" />
|
||||
<ClCompile Include="String.cpp" />
|
||||
<ClCompile Include="TestTrack.cpp" />
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
|
|
Loading…
Reference in New Issue