diff options
author | jbzdarkid <jbzdarkid@gmail.com> | 2019-11-08 22:06:07 -0800 |
---|---|---|
committer | jbzdarkid <jbzdarkid@gmail.com> | 2019-11-08 22:06:07 -0800 |
commit | 4d55d7d9aad8d3c2bedec371c165bbb848c3786b (patch) | |
tree | 6d9c17bcc538a95c8edb28045e1f92d1a9a6177b /Source | |
parent | 0e6b61f87b676028fcfd75bbf576f48a0ef91632 (diff) | |
download | witness-tutorializer-4d55d7d9aad8d3c2bedec371c165bbb848c3786b.tar.gz witness-tutorializer-4d55d7d9aad8d3c2bedec371c165bbb848c3786b.tar.bz2 witness-tutorializer-4d55d7d9aad8d3c2bedec371c165bbb848c3786b.zip |
Looks like chained read/write isn't working
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Memory.h | 140 | ||||
-rw-r--r-- | Source/Panel.cpp | 337 | ||||
-rw-r--r-- | Source/Panel.h | 224 | ||||
-rw-r--r-- | Source/Randomizer.h | 136 |
4 files changed, 379 insertions, 458 deletions
diff --git a/Source/Memory.h b/Source/Memory.h index c19d92b..95de884 100644 --- a/Source/Memory.h +++ b/Source/Memory.h | |||
@@ -54,6 +54,7 @@ public: | |||
54 | private: | 54 | private: |
55 | template<class T> | 55 | template<class T> |
56 | std::vector<T> ReadData(const std::vector<int>& offsets, size_t numItems) { | 56 | std::vector<T> ReadData(const std::vector<int>& offsets, size_t numItems) { |
57 | if (numItems == 0) return {}; | ||
57 | std::vector<T> data; | 58 | std::vector<T> data; |
58 | data.resize(numItems); | 59 | data.resize(numItems); |
59 | for (int i=0; i<5; i++) { | 60 | for (int i=0; i<5; i++) { |
@@ -68,6 +69,7 @@ private: | |||
68 | 69 | ||
69 | template <class T> | 70 | template <class T> |
70 | void WriteData(const std::vector<int>& offsets, const std::vector<T>& data) { | 71 | void WriteData(const std::vector<int>& offsets, const std::vector<T>& data) { |
72 | if (data.empty()) return; | ||
71 | for (int i=0; i<5; i++) { | 73 | for (int i=0; i<5; i++) { |
72 | if (WriteProcessMemory(_handle, ComputeOffset(offsets), &data[0], sizeof(T) * data.size(), nullptr)) { | 74 | if (WriteProcessMemory(_handle, ComputeOffset(offsets), &data[0], sizeof(T) * data.size(), nullptr)) { |
73 | return; | 75 | return; |
@@ -97,4 +99,140 @@ private: | |||
97 | friend class Temp; | 99 | friend class Temp; |
98 | friend class ChallengeRandomizer; | 100 | friend class ChallengeRandomizer; |
99 | friend class Randomizer; | 101 | friend class Randomizer; |
100 | }; \ No newline at end of file | 102 | }; |
103 | |||
104 | #if GLOBALS == 0x5B28C0 | ||
105 | #define PATH_COLOR 0xC8 | ||
106 | #define REFLECTION_PATH_COLOR 0xD8 | ||
107 | #define DOT_COLOR 0xF8 | ||
108 | #define ACTIVE_COLOR 0x108 | ||
109 | #define BACKGROUND_REGION_COLOR 0x118 | ||
110 | #define SUCCESS_COLOR_A 0x128 | ||
111 | #define SUCCESS_COLOR_B 0x138 | ||
112 | #define STROBE_COLOR_A 0x148 | ||
113 | #define STROBE_COLOR_B 0x158 | ||
114 | #define ERROR_COLOR 0x168 | ||
115 | #define PATTERN_POINT_COLOR 0x188 | ||
116 | #define PATTERN_POINT_COLOR_A 0x198 | ||
117 | #define PATTERN_POINT_COLOR_B 0x1A8 | ||
118 | #define SYMBOL_A 0x1B8 | ||
119 | #define SYMBOL_B 0x1C8 | ||
120 | #define SYMBOL_C 0x1D8 | ||
121 | #define SYMBOL_D 0x1E8 | ||
122 | #define SYMBOL_E 0x1F8 | ||
123 | #define PUSH_SYMBOL_COLORS 0x208 | ||
124 | #define OUTER_BACKGROUND 0x20C | ||
125 | #define OUTER_BACKGROUND_MODE 0x21C | ||
126 | #define TRACED_EDGES 0x230 | ||
127 | #define AUDIO_PREFIX 0x278 | ||
128 | #define POWER 0x2A8 | ||
129 | #define TARGET 0x2BC | ||
130 | #define POWER_OFF_ON_FAIL 0x2C0 | ||
131 | #define IS_CYLINDER 0x2FC | ||
132 | #define CYLINDER_Z0 0x300 | ||
133 | #define CYLINDER_Z1 0x304 | ||
134 | #define CYLINDER_RADIUS 0x308 | ||
135 | #define CURSOR_SPEED_SCALE 0x358 | ||
136 | #define NEEDS_REDRAW 0x384 | ||
137 | #define SPECULAR_ADD 0x398 | ||
138 | #define SPECULAR_POWER 0x39C | ||
139 | #define PATH_WIDTH_SCALE 0x3A4 | ||
140 | #define STARTPOINT_SCALE 0x3A8 | ||
141 | #define NUM_DOTS 0x3B8 | ||
142 | #define NUM_CONNECTIONS 0x3BC | ||
143 | #define MAX_BROADCAST_DISTANCE 0x3C0 | ||
144 | #define DOT_POSITIONS 0x3C8 | ||
145 | #define DOT_FLAGS 0x3D0 | ||
146 | #define DOT_CONNECTION_A 0x3D8 | ||
147 | #define DOT_CONNECTION_B 0x3E0 | ||
148 | #define DECORATIONS 0x420 | ||
149 | #define DECORATION_FLAGS 0x428 | ||
150 | #define DECORATION_COLORS 0x430 | ||
151 | #define NUM_DECORATIONS 0x438 | ||
152 | #define REFLECTION_DATA 0x440 | ||
153 | #define GRID_SIZE_X 0x448 | ||
154 | #define GRID_SIZE_Y 0x44C | ||
155 | #define STYLE_FLAGS 0x450 | ||
156 | #define SEQUENCE_LEN 0x45C | ||
157 | #define SEQUENCE 0x460 | ||
158 | #define DOT_SEQUENCE_LEN 0x468 | ||
159 | #define DOT_SEQUENCE 0x470 | ||
160 | #define DOT_SEQUENCE_LEN_REFLECTION 0x478 | ||
161 | #define DOT_SEQUENCE_REFLECTION 0x480 | ||
162 | #define NUM_COLORED_REGIONS 0x4A0 | ||
163 | #define COLORED_REGIONS 0x4A8 | ||
164 | #define PANEL_TARGET 0x4B0 | ||
165 | #define SPECULAR_TEXTURE 0x4D8 | ||
166 | #define CABLE_TARGET_2 0xD8 | ||
167 | #define AUDIO_LOG_NAME 0xC8 | ||
168 | #define OPEN_RATE 0xE8 | ||
169 | #define METADATA 0xF2 // sizeof(short) | ||
170 | #define HOTEL_EP_NAME 0x4BC640 | ||
171 | #elif GLOBALS == 0x62D0A0 | ||
172 | #define PATH_COLOR 0xC0 | ||
173 | #define REFLECTION_PATH_COLOR 0xD0 | ||
174 | #define DOT_COLOR 0xF0 | ||
175 | #define ACTIVE_COLOR 0x100 | ||
176 | #define BACKGROUND_REGION_COLOR 0x110 | ||
177 | #define SUCCESS_COLOR_A 0x120 | ||
178 | #define SUCCESS_COLOR_B 0x130 | ||
179 | #define STROBE_COLOR_A 0x140 | ||
180 | #define STROBE_COLOR_B 0x150 | ||
181 | #define ERROR_COLOR 0x160 | ||
182 | #define PATTERN_POINT_COLOR 0x180 | ||
183 | #define PATTERN_POINT_COLOR_A 0x190 | ||
184 | #define PATTERN_POINT_COLOR_B 0x1A0 | ||
185 | #define SYMBOL_A 0x1B0 | ||
186 | #define SYMBOL_B 0x1C0 | ||
187 | #define SYMBOL_C 0x1D0 | ||
188 | #define SYMBOL_D 0x1E0 | ||
189 | #define SYMBOL_E 0x1F0 | ||
190 | #define PUSH_SYMBOL_COLORS 0x200 | ||
191 | #define OUTER_BACKGROUND 0x204 | ||
192 | #define OUTER_BACKGROUND_MODE 0x214 | ||
193 | #define TRACED_EDGES 0x228 | ||
194 | #define AUDIO_PREFIX 0x270 | ||
195 | #define POWER 0x2A0 | ||
196 | #define TARGET 0x2B4 | ||
197 | #define POWER_OFF_ON_FAIL 0x2B8 | ||
198 | #define IS_CYLINDER 0x2F4 | ||
199 | #define CYLINDER_Z0 0x2F8 | ||
200 | #define CYLINDER_Z1 0x2FC | ||
201 | #define CYLINDER_RADIUS 0x300 | ||
202 | #define CURSOR_SPEED_SCALE 0x350 | ||
203 | #define NEEDS_REDRAW 0x37C | ||
204 | #define SPECULAR_ADD 0x38C | ||
205 | #define SPECULAR_POWER 0x390 | ||
206 | #define PATH_WIDTH_SCALE 0x39C | ||
207 | #define STARTPOINT_SCALE 0x3A0 | ||
208 | #define NUM_DOTS 0x3B4 | ||
209 | #define NUM_CONNECTIONS 0x3B8 | ||
210 | #define MAX_BROADCAST_DISTANCE 0x3BC | ||
211 | #define DOT_POSITIONS 0x3C0 | ||
212 | #define DOT_FLAGS 0x3C8 | ||
213 | #define DOT_CONNECTION_A 0x3D0 | ||
214 | #define DOT_CONNECTION_B 0x3D8 | ||
215 | #define DECORATIONS 0x418 | ||
216 | #define DECORATION_FLAGS 0x420 | ||
217 | #define DECORATION_COLORS 0x428 | ||
218 | #define NUM_DECORATIONS 0x430 | ||
219 | #define REFLECTION_DATA 0x438 | ||
220 | #define GRID_SIZE_X 0x440 | ||
221 | #define GRID_SIZE_Y 0x444 | ||
222 | #define STYLE_FLAGS 0x448 | ||
223 | #define SEQUENCE_LEN 0x454 | ||
224 | #define SEQUENCE 0x458 | ||
225 | #define DOT_SEQUENCE_LEN 0x460 | ||
226 | #define DOT_SEQUENCE 0x468 | ||
227 | #define DOT_SEQUENCE_LEN_REFLECTION 0x470 | ||
228 | #define DOT_SEQUENCE_REFLECTION 0x478 | ||
229 | #define NUM_COLORED_REGIONS 0x498 | ||
230 | #define COLORED_REGIONS 0x4A0 | ||
231 | #define PANEL_TARGET 0x4A8 | ||
232 | #define SPECULAR_TEXTURE 0x4D0 | ||
233 | #define CABLE_TARGET_2 0xD0 | ||
234 | #define AUDIO_LOG_NAME 0x0 | ||
235 | #define OPEN_RATE 0xE0 | ||
236 | #define METADATA 0x13A // sizeof(short) | ||
237 | #define HOTEL_EP_NAME 0x51E340 | ||
238 | #endif \ No newline at end of file | ||
diff --git a/Source/Panel.cpp b/Source/Panel.cpp index 43e9763..b6f0403 100644 --- a/Source/Panel.cpp +++ b/Source/Panel.cpp | |||
@@ -1,108 +1,36 @@ | |||
1 | #include "Panel.h" | 1 | #include "Panel.h" |
2 | #include "Random.h" | ||
3 | #include "Memory.h" | 2 | #include "Memory.h" |
4 | #include "Randomizer.h" | ||
5 | #include <sstream> | ||
6 | 3 | ||
7 | #pragma warning (disable:26451) | 4 | #pragma warning (disable:26451) |
5 | #pragma warning (disable:26812) | ||
8 | 6 | ||
9 | template <class T> | 7 | PuzzleSerializer::PuzzleSerializer(const std::shared_ptr<Memory>& memory) : _memory(memory) {} |
10 | int find(const std::vector<T> &data, T search, size_t startIndex = 0) { | ||
11 | for (size_t i=startIndex ; i<data.size(); i++) { | ||
12 | if (data[i] == search) return static_cast<int>(i); | ||
13 | } | ||
14 | return -1; | ||
15 | } | ||
16 | |||
17 | Panel::Panel(const std::shared_ptr<Memory>& memory, int id) : _memory(memory) { | ||
18 | _width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1; | ||
19 | _height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1; | ||
20 | _grid.resize(_width); | ||
21 | for (auto& row : _grid) row.resize(_height); | ||
22 | |||
23 | ReadIntersections(id); | ||
24 | ReadDecorations(id); | ||
25 | } | ||
26 | |||
27 | void Panel::Write(int id) { | ||
28 | WriteIntersections(id); | ||
29 | WriteDecorations(id); | ||
30 | |||
31 | _memory->WritePanelData<int>(id, GRID_SIZE_X, {(_width + 1)/2}); | ||
32 | _memory->WritePanelData<int>(id, GRID_SIZE_Y, {(_height + 1)/2}); | ||
33 | } | ||
34 | |||
35 | nlohmann::json Panel::Serialize() { | ||
36 | nlohmann::json puzzle = { | ||
37 | {"pillar", false}, | ||
38 | {"dots", nlohmann::json::array()}, | ||
39 | {"gaps", nlohmann::json::array()}, | ||
40 | {"name", "Imported from The Witness :O"}, | ||
41 | {"regionCache", nlohmann::json::object()}, | ||
42 | }; | ||
43 | if (_grid.empty()) return {}; | ||
44 | puzzle["grid"] = nlohmann::json::array(); | ||
45 | |||
46 | for (int x=0; x<_width; x++) { | ||
47 | for (int y=0; y<_height; y++) { | ||
48 | if (x%2 == 1 && y%2 == 1) { | ||
49 | puzzle["grid"][x][y] = Decoration_to_json(_grid[x][y]); | ||
50 | } else { | ||
51 | if (_grid[x][y] & IntersectionFlags::HAS_DOT) { | ||
52 | puzzle["dots"].emplace_back(nlohmann::json({{"x", x}, {"y", y}})); | ||
53 | } | ||
54 | puzzle["grid"][x][y] = false; | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | puzzle["startPoints"] = nlohmann::json::array(); | ||
60 | for (auto [x, y] : _startpoints) { | ||
61 | nlohmann::json startPoint = {{"x", x}, {"y", y}}; | ||
62 | puzzle["startPoints"].emplace_back(startPoint); | ||
63 | } | ||
64 | puzzle["endPoints"] = nlohmann::json::array(); | ||
65 | for (Endpoint endpoint : _endpoints) { | ||
66 | puzzle["endPoints"].emplace_back(endpoint.to_json()); | ||
67 | } | ||
68 | |||
69 | std::string out = puzzle.dump(); | ||
70 | return puzzle; | ||
71 | } | ||
72 | 8 | ||
73 | void Panel::ReadDecorations(int id) { | 9 | Puzzle PuzzleSerializer::ReadPuzzle(int id) { |
74 | int numDecorations = _memory->ReadPanelData<int>(id, NUM_DECORATIONS, 1)[0]; | 10 | Puzzle p; |
75 | std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations); | 11 | p.width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1; |
12 | p.height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1; | ||
13 | p.grid.resize(p.width); | ||
14 | for (auto& row : p.grid) row.resize(p.height); | ||
76 | 15 | ||
77 | for (int i=0; i<numDecorations; i++) { | 16 | ReadIntersections(p, id); |
78 | auto [x, y] = dloc_to_xy(i); | 17 | ReadDecorations(p, id); |
79 | _grid[x][y] = decorations[i]; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | void Panel::WriteDecorations(int id) { | ||
84 | std::vector<int> decorations; | ||
85 | for (int y=_height-2; y>0; y-=2) { | ||
86 | for (int x=1; x<_width - 1; x+=2) { | ||
87 | decorations.push_back(_grid[x][y]); | ||
88 | } | ||
89 | } | ||
90 | 18 | ||
91 | _memory->WritePanelData<int>(id, NUM_DECORATIONS, {static_cast<int>(decorations.size())}); | 19 | return p; |
92 | _memory->WriteArray<int>(id, DECORATIONS, decorations); | ||
93 | } | 20 | } |
94 | 21 | ||
95 | void Panel::ReadIntersections(int id) { | 22 | void PuzzleSerializer::ReadIntersections(Puzzle& p, int id) { |
96 | int numIntersections = _memory->ReadPanelData<int>(id, NUM_DOTS, 1)[0]; | 23 | int numIntersections = _memory->ReadPanelData<int>(id, NUM_DOTS, 1)[0]; |
97 | std::vector<int> intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, numIntersections); | 24 | std::vector<int> intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, numIntersections); |
98 | 25 | ||
99 | int i = 0; | 26 | int i = 0; |
100 | for (;; i++) { | 27 | for (;; i++) { |
101 | auto [x, y] = loc_to_xy(i); | 28 | auto [x, y] = loc_to_xy(p, i); |
102 | if (y < 0) break; | 29 | if (y < 0) break; |
103 | if (intersectionFlags[i] & IntersectionFlags::IS_STARTPOINT) { | 30 | if (intersectionFlags[i] & Flags::IS_STARTPOINT) { |
104 | _startpoints.push_back({x, y}); | 31 | p.grid[x][y].start = true; |
105 | } | 32 | } |
33 | p.grid[x][y].dot = FlagsToDot(intersectionFlags[i]); | ||
106 | } | 34 | } |
107 | 35 | ||
108 | int numConnections = _memory->ReadPanelData<int>(id, NUM_CONNECTIONS, 1)[0]; | 36 | int numConnections = _memory->ReadPanelData<int>(id, NUM_CONNECTIONS, 1)[0]; |
@@ -112,34 +40,32 @@ void Panel::ReadIntersections(int id) { | |||
112 | 40 | ||
113 | // Iterate the remaining intersections (endpoints, dots, gaps) | 41 | // Iterate the remaining intersections (endpoints, dots, gaps) |
114 | for (; i < numIntersections; i++) { | 42 | for (; i < numIntersections; i++) { |
115 | if (intersectionFlags[i] & IntersectionFlags::IS_ENDPOINT) { | 43 | if (intersectionFlags[i] & Flags::IS_ENDPOINT) { |
116 | for (int j=0; j<numConnections; j++) { | 44 | for (int j=0; j<numConnections; j++) { |
117 | int location = 0; | 45 | int location = 0; |
118 | if (connections_a[j] == i) location = connections_b[j]; | 46 | if (connections_a[j] == i) location = connections_b[j]; |
119 | if (connections_b[j] == i) location = connections_a[j]; | 47 | if (connections_b[j] == i) location = connections_a[j]; |
120 | if (location != 0) { | 48 | if (location != 0) { |
121 | Endpoint::Direction dir; | 49 | auto [x, y] = loc_to_xy(p, location); |
122 | if (intersections[2*i] < intersections[2*location]) { // Our (i) x coordinate is less than the target's (location) | 50 | if (intersections[2*i] < intersections[2*location]) { // Our (i) x coordinate is less than the target's (location) |
123 | dir = Endpoint::Direction::LEFT; | 51 | p.grid[x][y].end = Cell::Dir::LEFT; |
124 | } else if (intersections[2*i] > intersections[2*location]) { | 52 | } else if (intersections[2*i] > intersections[2*location]) { |
125 | dir = Endpoint::Direction::RIGHT; | 53 | p.grid[x][y].end = Cell::Dir::RIGHT; |
126 | } else if (intersections[2*i + 1] > intersections[2*location + 1]) { // y coordinate is 0 (bottom) 1 (top), so this check is reversed. | 54 | } else if (intersections[2*i + 1] > intersections[2*location + 1]) { // y coordinate is 0 (bottom) 1 (top), so this check is reversed. |
127 | dir = Endpoint::Direction::UP; | 55 | p.grid[x][y].end = Cell::Dir::UP; |
128 | } else { | 56 | } else { |
129 | dir = Endpoint::Direction::DOWN; | 57 | p.grid[x][y].end = Cell::Dir::DOWN; |
130 | } | 58 | } |
131 | auto [x, y] = loc_to_xy(location); | ||
132 | _endpoints.push_back(Endpoint(x, y, dir)); | ||
133 | break; | 59 | break; |
134 | } | 60 | } |
135 | } | 61 | } |
136 | } else if (intersectionFlags[i] & IntersectionFlags::HAS_DOT) { | 62 | } else if (intersectionFlags[i] & Flags::HAS_DOT) { |
137 | for (int j=0; j<numConnections; j++) { | 63 | for (int j=0; j<numConnections; j++) { |
138 | int location = 0; | 64 | int location = 0; |
139 | if (connections_a[j] == i) location = connections_b[j]; | 65 | if (connections_a[j] == i) location = connections_b[j]; |
140 | if (connections_b[j] == i) location = connections_a[j]; | 66 | if (connections_b[j] == i) location = connections_a[j]; |
141 | if (location != 0) { | 67 | if (location != 0) { |
142 | auto [x, y] = loc_to_xy(location); | 68 | auto [x, y] = loc_to_xy(p, location); |
143 | float x1 = intersections[2*i]; | 69 | float x1 = intersections[2*i]; |
144 | float y1 = intersections[2*i+1]; | 70 | float y1 = intersections[2*i+1]; |
145 | float x2 = intersections[2*location]; | 71 | float x2 = intersections[2*location]; |
@@ -156,7 +82,7 @@ void Panel::ReadIntersections(int id) { | |||
156 | y++; | 82 | y++; |
157 | } | 83 | } |
158 | 84 | ||
159 | _grid[x][y] |= IntersectionFlags::HAS_DOT; | 85 | p.grid[x][y].dot = FlagsToDot(intersectionFlags[i]); |
160 | break; | 86 | break; |
161 | } | 87 | } |
162 | } | 88 | } |
@@ -164,72 +90,134 @@ void Panel::ReadIntersections(int id) { | |||
164 | } | 90 | } |
165 | } | 91 | } |
166 | 92 | ||
167 | void Panel::WriteIntersections(int id) { | 93 | void PuzzleSerializer::ReadDecorations(Puzzle& p, int id) { |
94 | int numDecorations = _memory->ReadPanelData<int>(id, NUM_DECORATIONS, 1)[0]; | ||
95 | std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations); | ||
96 | if (numDecorations != decorations.size()) return; // @Error! | ||
97 | |||
98 | for (int i=0; i<numDecorations; i++) { | ||
99 | auto [x, y] = dloc_to_xy(p, i); | ||
100 | auto d = std::make_shared<Decoration>(); | ||
101 | p.grid[x][y].decoration = d; | ||
102 | d->type = static_cast<Shape>(decorations[i] & 0xFF00); | ||
103 | switch(d->type) { | ||
104 | case Shape::Poly: | ||
105 | case Shape::RPoly: | ||
106 | case Shape::Ylop: | ||
107 | d->polyshape = decorations[i] & 0xFFFF0000; | ||
108 | break; | ||
109 | case Shape::Triangle: | ||
110 | d->count = decorations[i] & 0x000F0000; | ||
111 | break; | ||
112 | } | ||
113 | d->color = static_cast<Color>(decorations[i] & 0xF); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | void PuzzleSerializer::WritePuzzle(const Puzzle& p, int id) { | ||
118 | _memory->WritePanelData<int>(id, GRID_SIZE_X, {(p.width + 1)/2}); | ||
119 | _memory->WritePanelData<int>(id, GRID_SIZE_Y, {(p.height + 1)/2}); | ||
120 | |||
121 | WriteIntersections(p, id); | ||
122 | WriteDecorations(p, id); | ||
123 | |||
124 | _memory->WritePanelData<int>(id, NEEDS_REDRAW, {1}); | ||
125 | } | ||
126 | |||
127 | void PuzzleSerializer::WriteIntersections(const Puzzle& p, int id) { | ||
168 | std::vector<float> intersections; | 128 | std::vector<float> intersections; |
169 | std::vector<int> intersectionFlags; | 129 | std::vector<int> intersectionFlags; |
170 | std::vector<int> connections_a; | 130 | std::vector<int> connections_a; |
171 | std::vector<int> connections_b; | 131 | std::vector<int> connections_b; |
172 | 132 | ||
173 | double min = 0.1; | 133 | float min = 0.1f; |
174 | double max = 0.9; | 134 | float max = 0.9f; |
175 | double width_interval = (max - min) / (_width/2); | 135 | float width_interval = (max - min) / (p.width/2); |
176 | double height_interval = (max - min) / (_height/2); | 136 | float height_interval = (max - min) / (p.height/2); |
177 | 137 | ||
178 | // TODO(future): Stop using push_back and set these into explicit locations, unrequires loop iteration order | 138 | // @Cleanup: If I write directly to locations, then I can remove this gross loop iterator. |
179 | for (int y=_height-1; y>=0; y-=2) { | 139 | for (int y=p.height-1; y>=0; y-=2) { |
180 | for (int x=0; x<_width; x+=2) { | 140 | for (int x=0; x<p.width; x+=2) { |
181 | intersections.push_back(static_cast<float>(min + (x/2) * width_interval)); | 141 | intersections.push_back(static_cast<float>(min + (x/2) * width_interval)); |
182 | intersections.push_back(static_cast<float>(max - (y/2) * height_interval)); | 142 | intersections.push_back(static_cast<float>(max - (y/2) * height_interval)); |
183 | int flags = 0; | 143 | int flags = 0; |
184 | if (find(_startpoints, {x, y}) != -1) flags |= IntersectionFlags::IS_STARTPOINT; | 144 | if (p.grid[x][y].start) { |
145 | flags |= Flags::IS_STARTPOINT; | ||
146 | } | ||
185 | intersectionFlags.push_back(flags); | 147 | intersectionFlags.push_back(flags); |
186 | 148 | ||
187 | // Create connections for this intersection -- always write low -> high | 149 | // Create connections for this intersection -- always write low -> high |
188 | if (y > 0) { | 150 | if (y > 0) { |
189 | connections_a.push_back(xy_to_loc(x, y-2)); | 151 | connections_a.push_back(xy_to_loc(p, x, y-2)); |
190 | connections_b.push_back(xy_to_loc(x, y)); | 152 | connections_b.push_back(xy_to_loc(p, x, y)); |
191 | } | 153 | } |
192 | if (x > 0) { | 154 | if (x > 0) { |
193 | connections_a.push_back(xy_to_loc(x-2, y)); | 155 | connections_a.push_back(xy_to_loc(p, x-2, y)); |
194 | connections_b.push_back(xy_to_loc(x, y)); | 156 | connections_b.push_back(xy_to_loc(p, x, y)); |
195 | } | 157 | } |
196 | } | 158 | } |
197 | } | 159 | } |
198 | 160 | ||
199 | for (Endpoint endpoint : _endpoints) { | 161 | for (int x=0; x<p.width; x++) { |
200 | connections_a.push_back(xy_to_loc(endpoint.GetX(), endpoint.GetY())); // Target to connect to | 162 | for (int y=0; y<p.height; y++) { |
201 | connections_b.push_back(static_cast<int>(intersectionFlags.size())); // This endpoint | 163 | if (p.grid[x][y].end == Cell::Dir::NONE) continue; |
202 | 164 | connections_a.push_back(xy_to_loc(p, x, y)); // Target to connect to | |
203 | double xPos = min + (endpoint.GetX()/2) * width_interval; | 165 | connections_b.push_back(static_cast<int>(intersectionFlags.size())); // This endpoint |
204 | double yPos = max - (endpoint.GetY()/2) * height_interval; | 166 | |
205 | if (endpoint.GetDir()== Endpoint::Direction::LEFT) { | 167 | float xPos = min + (x/2) * width_interval; |
206 | xPos -= .05; | 168 | float yPos = max - (y/2) * height_interval; |
207 | } else if (endpoint.GetDir() == Endpoint::Direction::RIGHT) { | 169 | switch (p.grid[x][y].end) { |
208 | xPos += .05; | 170 | case Cell::Dir::LEFT: |
209 | } else if (endpoint.GetDir() == Endpoint::Direction::UP) { | 171 | xPos -= .05f; |
210 | yPos += .05; // Y position goes from 0 (bottom) to 1 (top), so this is reversed. | 172 | break; |
211 | } else if (endpoint.GetDir() == Endpoint::Direction::DOWN) { | 173 | case Cell::Dir::RIGHT: |
212 | yPos -= .05; | 174 | xPos += .05f; |
213 | } | 175 | break; |
214 | intersections.push_back(static_cast<float>(xPos)); | 176 | case Cell::Dir::UP: |
215 | intersections.push_back(static_cast<float>(yPos)); | 177 | yPos += .05f; // Y position goes from 0 (bottom) to 1 (top), so this is reversed. |
216 | intersectionFlags.push_back(IntersectionFlags::IS_ENDPOINT); | 178 | break; |
217 | } | 179 | case Cell::Dir::DOWN: |
180 | yPos -= .05f; | ||
181 | break; | ||
182 | } | ||
183 | intersections.push_back(xPos); | ||
184 | intersections.push_back(yPos); | ||
185 | intersectionFlags.push_back(Flags::IS_ENDPOINT); | ||
186 | } | ||
187 | } | ||
218 | 188 | ||
219 | // Dots | 189 | // Dots |
220 | for (int y=0; y<_height; y++) { | 190 | for (int x=0; x<p.width; x++) { |
221 | for (int x=0; x<_width; x++) { | 191 | for (int y=0; y<p.height; y++) { |
222 | if (!(_grid[x][y] & IntersectionFlags::HAS_DOT)) continue; | 192 | if (p.grid[x][y].dot == Cell::Dot::NONE) continue; |
223 | if (x%2 == 1 && y%2 == 1) continue; | 193 | if (x%2 == 1 && y%2 == 1) continue; |
194 | |||
195 | int flags = Flags::HAS_DOT; | ||
196 | switch (p.grid[x][y].dot) { | ||
197 | case Cell::Dot::BLACK: | ||
198 | break; | ||
199 | case Cell::Dot::BLUE: | ||
200 | flags |= DOT_IS_BLUE; | ||
201 | break; | ||
202 | case Cell::Dot::YELLOW: | ||
203 | flags |= DOT_IS_ORANGE; | ||
204 | break; | ||
205 | case Cell::Dot::INVISIBLE: | ||
206 | flags |= DOT_IS_INVISIBLE; | ||
207 | break; | ||
208 | } | ||
209 | |||
210 | // Dot is already a point the grid, just overwrite the flags | ||
224 | if (x%2 == 0 && y%2 == 0) { | 211 | if (x%2 == 0 && y%2 == 0) { |
225 | intersectionFlags[xy_to_loc(x, y)] |= _grid[x][y]; | 212 | intersectionFlags[xy_to_loc(p, x, y)] |= flags; |
226 | continue; | 213 | continue; |
227 | } | 214 | } |
228 | 215 | ||
216 | // Else, we need to introduce a new segment | ||
229 | // Locate the segment we're breaking | 217 | // Locate the segment we're breaking |
230 | for (int i=0; i<connections_a.size(); i++) { | 218 | for (int i=0; i<connections_a.size(); i++) { |
231 | auto [x1, y1] = loc_to_xy(connections_a[i]); | 219 | auto [x1, y1] = loc_to_xy(p, connections_a[i]); |
232 | auto [x2, y2] = loc_to_xy(connections_b[i]); | 220 | auto [x2, y2] = loc_to_xy(p, connections_b[i]); |
233 | if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) || | 221 | if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) || |
234 | (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) { | 222 | (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) { |
235 | int other_connection = connections_b[i]; | 223 | int other_connection = connections_b[i]; |
@@ -241,21 +229,82 @@ void Panel::WriteIntersections(int id) { | |||
241 | } | 229 | } |
242 | } | 230 | } |
243 | // Add this dot to the end | 231 | // Add this dot to the end |
244 | double xPos = min + (x/2.0) * width_interval; | 232 | float xPos = min + (x/2.0f) * width_interval; |
245 | double yPos = max - (y/2.0) * height_interval; | 233 | float yPos = max - (y/2.0f) * height_interval; |
246 | intersections.push_back(static_cast<float>(xPos)); | 234 | intersections.push_back(xPos); |
247 | intersections.push_back(static_cast<float>(yPos)); | 235 | intersections.push_back(yPos); |
248 | intersectionFlags.push_back(_grid[x][y]); | 236 | intersectionFlags.push_back(flags); |
249 | } | 237 | } |
250 | } | 238 | } |
251 | 239 | ||
252 | |||
253 | _memory->WritePanelData<int>(id, NUM_DOTS, {static_cast<int>(intersectionFlags.size())}); | 240 | _memory->WritePanelData<int>(id, NUM_DOTS, {static_cast<int>(intersectionFlags.size())}); |
254 | _memory->WriteArray<float>(id, DOT_POSITIONS, intersections); | 241 | _memory->WriteArray<float>(id, DOT_POSITIONS, intersections); |
255 | _memory->WriteArray<int>(id, DOT_FLAGS, intersectionFlags); | 242 | _memory->WriteArray<int>(id, DOT_FLAGS, intersectionFlags); |
256 | _memory->WritePanelData<int>(id, NUM_CONNECTIONS, {static_cast<int>(connections_a.size())}); | 243 | _memory->WritePanelData<int>(id, NUM_CONNECTIONS, {static_cast<int>(connections_a.size())}); |
257 | _memory->WriteArray<int>(id, DOT_CONNECTION_A, connections_a); | 244 | _memory->WriteArray<int>(id, DOT_CONNECTION_A, connections_a); |
258 | _memory->WriteArray<int>(id, DOT_CONNECTION_B, connections_b); | 245 | _memory->WriteArray<int>(id, DOT_CONNECTION_B, connections_b); |
259 | _memory->WritePanelData<int>(id, NEEDS_REDRAW, {1}); | ||
260 | } | 246 | } |
261 | 247 | ||
248 | void PuzzleSerializer::WriteDecorations(const Puzzle& p, int id) { | ||
249 | std::vector<int> decorations; | ||
250 | for (int y=p.height-2; y>0; y-=2) { | ||
251 | for (int x=1; x<p.width-1; x+=2) { | ||
252 | auto d = p.grid[x][y].decoration; | ||
253 | if (d) { | ||
254 | decorations.push_back(d->color | d->type | d->count | d->polyshape); | ||
255 | } else { | ||
256 | decorations.push_back(0); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | _memory->WritePanelData<int>(id, NUM_DECORATIONS, {static_cast<int>(decorations.size())}); | ||
262 | _memory->WriteArray<int>(id, DECORATIONS, decorations); | ||
263 | } | ||
264 | |||
265 | std::tuple<int, int> PuzzleSerializer::loc_to_xy(const Puzzle& p, int location) { | ||
266 | int height2 = (p.height - 1) / 2; | ||
267 | int width2 = (p.width + 1) / 2; | ||
268 | |||
269 | int x = 2 * (location % width2); | ||
270 | int y = 2 * (height2 - location / width2); | ||
271 | return {x, y}; | ||
272 | } | ||
273 | |||
274 | int PuzzleSerializer::xy_to_loc(const Puzzle& p, int x, int y) { | ||
275 | int height2 = (p.height - 1) / 2; | ||
276 | int width2 = (p.width + 1) / 2; | ||
277 | |||
278 | int rowsFromBottom = height2 - y/2; | ||
279 | return rowsFromBottom * width2 + x/2; | ||
280 | } | ||
281 | |||
282 | std::tuple<int, int> PuzzleSerializer::dloc_to_xy(const Puzzle& p, int location) { | ||
283 | int height2 = (p.height - 3) / 2; | ||
284 | int width2 = (p.width - 1) / 2; | ||
285 | |||
286 | int x = 2 * (location % width2) + 1; | ||
287 | int y = 2 * (height2 - location / width2) + 1; | ||
288 | return {x, y}; | ||
289 | } | ||
290 | |||
291 | int PuzzleSerializer::xy_to_dloc(const Puzzle& p, int x, int y) { | ||
292 | int height2 = (p.height - 3) / 2; | ||
293 | int width2 = (p.width - 1) / 2; | ||
294 | |||
295 | int rowsFromBottom = height2 - (y - 1)/2; | ||
296 | return rowsFromBottom * width2 + (x - 1)/2; | ||
297 | } | ||
298 | |||
299 | Cell::Dot PuzzleSerializer::FlagsToDot(int flags) { | ||
300 | if (!(flags & Flags::HAS_DOT)) return Cell::Dot::NONE; | ||
301 | if (flags & Flags::DOT_IS_BLUE) { | ||
302 | return Cell::Dot::BLUE; | ||
303 | } else if (flags & Flags::DOT_IS_ORANGE) { | ||
304 | return Cell::Dot::YELLOW; | ||
305 | } else if (flags & Flags::DOT_IS_INVISIBLE) { | ||
306 | return Cell::Dot::INVISIBLE; | ||
307 | } else { | ||
308 | return Cell::Dot::BLACK; | ||
309 | } | ||
310 | } | ||
diff --git a/Source/Panel.h b/Source/Panel.h index 0d1af14..caa7b04 100644 --- a/Source/Panel.h +++ b/Source/Panel.h | |||
@@ -1,145 +1,45 @@ | |||
1 | #pragma once | 1 | #pragma once |
2 | #include "json.hpp" | 2 | #include <memory> |
3 | #include "Memory.h" | 3 | #include <vector> |
4 | 4 | ||
5 | enum IntersectionFlags { | 5 | class Memory; |
6 | IS_ENDPOINT = 0x1, | 6 | |
7 | IS_STARTPOINT = 0x2, | 7 | enum Shape { |
8 | IS_GAP = 0x10000, | 8 | Stone = 0x100, |
9 | HAS_DOT = 0x40020, | 9 | Star = 0x200, |
10 | DOT_IS_BLUE = 0x100, | 10 | Poly = 0x400, |
11 | DOT_IS_ORANGE = 0x200, | 11 | Eraser = 0x500, |
12 | DOT_IS_INVISIBLE = 0x1000, | 12 | Triangle = 0x600, |
13 | RPoly = 0x1000, | ||
14 | Ylop = 0x2000, | ||
13 | }; | 15 | }; |
14 | 16 | ||
15 | /* | 17 | enum Color { |
16 | enum Style { | 18 | Black = 0x1, |
17 | SYMMETRICAL = 0x2, | 19 | White = 0x2, |
18 | IS_2COLOR = 0x10, | 20 | Gray = 0x3, |
19 | HAS_DOTS = 0x4, | 21 | Purple = 0x4, |
20 | HAS_STARS = 0x40, | 22 | Green = 0x5, |
21 | HAS_STONES = 0x100, | 23 | Cyan = 0x6, |
22 | HAS_ERASERS = 0x1000, | 24 | Pink = 0x7, |
23 | HAS_SHAPERS = 0x2000, | 25 | Yellow = 0x8, |
24 | }; | 26 | Blue = 0x9, |
25 | */ | 27 | Orange = 0xA, |
26 | |||
27 | class Endpoint { | ||
28 | public: | ||
29 | enum class Direction { | ||
30 | LEFT, | ||
31 | RIGHT, | ||
32 | UP, | ||
33 | DOWN | ||
34 | }; | ||
35 | |||
36 | Endpoint(int x, int y, Direction dir) { | ||
37 | _x = x; | ||
38 | _y = y; | ||
39 | _dir = dir; | ||
40 | } | ||
41 | |||
42 | int GetX() {return _x;} | ||
43 | void SetX(int x) {_x = x;} | ||
44 | int GetY() {return _y;} | ||
45 | void SetY(int y) {_y = y;} | ||
46 | Direction GetDir() {return _dir;} | ||
47 | void SetDir(Direction dir) {_dir = dir;} | ||
48 | |||
49 | nlohmann::json to_json() { | ||
50 | nlohmann::json json = {{"x", _x}, {"y", _y}}; | ||
51 | if (_dir == Direction::LEFT) json["dir"] = "left"; | ||
52 | if (_dir == Direction::RIGHT) json["dir"] = "right"; | ||
53 | if (_dir == Direction::UP) json["dir"] = "up"; | ||
54 | if (_dir == Direction::DOWN) json["dir"] = "down"; | ||
55 | return json; | ||
56 | } | ||
57 | |||
58 | private: | ||
59 | int _x, _y; | ||
60 | Direction _dir; | ||
61 | }; | 28 | }; |
62 | 29 | ||
63 | class Panel { | ||
64 | public: | ||
65 | Panel(const std::shared_ptr<Memory>& memory, int id); | ||
66 | // explicit Panel(nlohmann::json json); | ||
67 | |||
68 | void Write(int id); | ||
69 | nlohmann::json Serialize(); | ||
70 | |||
71 | private: | ||
72 | // For testing | ||
73 | Panel() = default; | ||
74 | |||
75 | void ReadIntersections(int id); | ||
76 | void WriteIntersections(int id); | ||
77 | void ReadDecorations(int id); | ||
78 | void WriteDecorations(int id); | ||
79 | |||
80 | // TODO: Reflection data | ||
81 | // TODO: Decoration colors | ||
82 | |||
83 | std::tuple<int, int> loc_to_xy(int location) { | ||
84 | int height2 = (_height - 1) / 2; | ||
85 | int width2 = (_width + 1) / 2; | ||
86 | |||
87 | int x = 2 * (location % width2); | ||
88 | int y = 2 * (height2 - location / width2); | ||
89 | return {x, y}; | ||
90 | } | ||
91 | |||
92 | int xy_to_loc(int x, int y) { | ||
93 | int height2 = (_height - 1) / 2; | ||
94 | int width2 = (_width + 1) / 2; | ||
95 | |||
96 | int rowsFromBottom = height2 - y/2; | ||
97 | return rowsFromBottom * width2 + x/2; | ||
98 | } | ||
99 | |||
100 | std::tuple<int, int> dloc_to_xy(int location) { | ||
101 | int height2 = (_height - 3) / 2; | ||
102 | int width2 = (_width - 1) / 2; | ||
103 | |||
104 | int x = 2 * (location % width2) + 1; | ||
105 | int y = 2 * (height2 - location / width2) + 1; | ||
106 | return {x, y}; | ||
107 | } | ||
108 | |||
109 | int xy_to_dloc(int x, int y) { | ||
110 | int height2 = (_height - 3) / 2; | ||
111 | int width2 = (_width - 1) / 2; | ||
112 | |||
113 | int rowsFromBottom = height2 - (y - 1)/2; | ||
114 | return rowsFromBottom * width2 + (x - 1)/2; | ||
115 | } | ||
116 | |||
117 | std::shared_ptr<Memory> _memory; | ||
118 | |||
119 | int _width, _height; | ||
120 | |||
121 | std::vector<std::vector<int>> _grid; | ||
122 | std::vector<Endpoint> _endpoints; | ||
123 | std::vector<std::pair<int ,int>> _startpoints; | ||
124 | int _style; | ||
125 | |||
126 | friend class PanelExtractionTests; | ||
127 | }; | ||
128 | |||
129 | // V2 stuff here | ||
130 | struct Decoration { | 30 | struct Decoration { |
131 | enum class Type {STONE, STAR, POLY, ERASER, TRIANGLE, RPOLY, YLOP}; | 31 | Shape type; |
132 | Type type; | 32 | Color color; |
133 | // TODO: Color color; | 33 | int polyshape; |
134 | uint32_t polyshape; | 34 | // For triangles only |
135 | int count; // For triangles | 35 | int count; |
136 | }; | 36 | }; |
137 | 37 | ||
138 | struct Cell { | 38 | struct Cell { |
139 | bool start; | 39 | bool start; |
140 | enum class Dir {NONE, LEFT, RIGHT, UP, DOWN}; | 40 | enum class Dir {NONE, LEFT, RIGHT, UP, DOWN}; |
141 | Dir end; | 41 | Dir end; |
142 | Decoration* decoration; | 42 | std::shared_ptr<Decoration> decoration; |
143 | enum class Dot {NONE, BLACK, BLUE, YELLOW, INVISIBLE}; | 43 | enum class Dot {NONE, BLACK, BLUE, YELLOW, INVISIBLE}; |
144 | Dot dot; | 44 | Dot dot; |
145 | enum class Gap {NONE, BREAK, FULL}; | 45 | enum class Gap {NONE, BREAK, FULL}; |
@@ -149,7 +49,7 @@ struct Cell { | |||
149 | struct Puzzle { | 49 | struct Puzzle { |
150 | int16_t height; | 50 | int16_t height; |
151 | int16_t width; | 51 | int16_t width; |
152 | Cell** grid; | 52 | std::vector<std::vector<Cell>> grid; |
153 | 53 | ||
154 | enum class Symmetry {NONE, X, Y, XY}; | 54 | enum class Symmetry {NONE, X, Y, XY}; |
155 | Symmetry sym; | 55 | Symmetry sym; |
@@ -159,33 +59,11 @@ struct Puzzle { | |||
159 | class PuzzleSerializer { | 59 | class PuzzleSerializer { |
160 | public: | 60 | public: |
161 | PuzzleSerializer(const std::shared_ptr<Memory>& memory); | 61 | PuzzleSerializer(const std::shared_ptr<Memory>& memory); |
162 | Puzzle ReadPuzzle(int panelId); | 62 | Puzzle ReadPuzzle(int id); |
163 | void WritePuzzle(int panelId, const Puzzle& puzzle); | 63 | void WritePuzzle(const Puzzle& p, int id); |
164 | |||
165 | //private: | ||
166 | enum Shape { | ||
167 | Stone = 0x100, | ||
168 | Star = 0x200, | ||
169 | Poly = 0x400, | ||
170 | Eraser = 0x500, | ||
171 | Triangle = 0x600, | ||
172 | RPoly = 0x1000, | ||
173 | Ylop = 0x2000, | ||
174 | }; | ||
175 | |||
176 | enum Color { | ||
177 | Black = 0x1, | ||
178 | White = 0x2, | ||
179 | Gray = 0x3, | ||
180 | Purple = 0x4, | ||
181 | Green = 0x5, | ||
182 | Cyan = 0x6, | ||
183 | Pink = 0x7, | ||
184 | Yellow = 0x8, | ||
185 | Blue = 0x9, | ||
186 | Orange = 0xA, | ||
187 | }; | ||
188 | 64 | ||
65 | private: | ||
66 | // @Bug: Blue and orange are swapped? | ||
189 | enum Flags { | 67 | enum Flags { |
190 | IS_ENDPOINT = 0x1, | 68 | IS_ENDPOINT = 0x1, |
191 | IS_STARTPOINT = 0x2, | 69 | IS_STARTPOINT = 0x2, |
@@ -196,25 +74,17 @@ public: | |||
196 | HAS_DOT = 0x40020, | 74 | HAS_DOT = 0x40020, |
197 | }; | 75 | }; |
198 | 76 | ||
199 | std::shared_ptr<Memory> _memory; | 77 | void ReadIntersections(Puzzle& p, int id); |
200 | }; | 78 | void ReadDecorations(Puzzle& p, int id); |
201 | 79 | void WriteIntersections(const Puzzle& p, int id); | |
202 | static nlohmann::json Decoration_to_json(int decoration) { | 80 | void WriteDecorations(const Puzzle& p, int id); |
203 | nlohmann::json json = {}; | ||
204 | int shape = decoration & 0x00000F00; | ||
205 | if (shape == PuzzleSerializer::Shape::Stone) json["type"] = "square"; | ||
206 | if (shape == PuzzleSerializer::Shape::Star) json["type"] = "star"; | ||
207 | if (shape == PuzzleSerializer::Shape::Poly) json["type"] = "poly"; | ||
208 | if (shape == PuzzleSerializer::Shape::Eraser) json["type"] = "eraser"; | ||
209 | if (shape == PuzzleSerializer::Shape::Triangle) json["type"] = "triangle"; | ||
210 | 81 | ||
211 | int color = decoration & 0x0000000F; | 82 | std::tuple<int, int> loc_to_xy(const Puzzle& p, int location); |
212 | if (color == PuzzleSerializer::Color::Black) json["color"] = "black"; | 83 | int xy_to_loc(const Puzzle& p, int x, int y); |
213 | if (color == PuzzleSerializer::Color::White) json["color"] = "white"; | 84 | // Decoration location |
214 | if (color == PuzzleSerializer::Color::Gray) json["color"] = "gray"; | 85 | std::tuple<int, int> dloc_to_xy(const Puzzle& p, int location); |
215 | if (color == PuzzleSerializer::Color::Blue) json["color"] = "blue"; | 86 | int xy_to_dloc(const Puzzle& p, int x, int y); |
216 | if (color == PuzzleSerializer::Color::Green) json["color"] = "green"; | 87 | Cell::Dot FlagsToDot(int flags); |
217 | 88 | ||
218 | if (json.empty()) return false; | 89 | std::shared_ptr<Memory> _memory; |
219 | return json; | 90 | }; |
220 | } | ||
diff --git a/Source/Randomizer.h b/Source/Randomizer.h index d9ea700..87f1f59 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h | |||
@@ -47,139 +47,3 @@ private: | |||
47 | 47 | ||
48 | friend class SwapTests_Shipwreck_Test; | 48 | friend class SwapTests_Shipwreck_Test; |
49 | }; | 49 | }; |
50 | |||
51 | #if GLOBALS == 0x5B28C0 | ||
52 | #define PATH_COLOR 0xC8 | ||
53 | #define REFLECTION_PATH_COLOR 0xD8 | ||
54 | #define DOT_COLOR 0xF8 | ||
55 | #define ACTIVE_COLOR 0x108 | ||
56 | #define BACKGROUND_REGION_COLOR 0x118 | ||
57 | #define SUCCESS_COLOR_A 0x128 | ||
58 | #define SUCCESS_COLOR_B 0x138 | ||
59 | #define STROBE_COLOR_A 0x148 | ||
60 | #define STROBE_COLOR_B 0x158 | ||
61 | #define ERROR_COLOR 0x168 | ||
62 | #define PATTERN_POINT_COLOR 0x188 | ||
63 | #define PATTERN_POINT_COLOR_A 0x198 | ||
64 | #define PATTERN_POINT_COLOR_B 0x1A8 | ||
65 | #define SYMBOL_A 0x1B8 | ||
66 | #define SYMBOL_B 0x1C8 | ||
67 | #define SYMBOL_C 0x1D8 | ||
68 | #define SYMBOL_D 0x1E8 | ||
69 | #define SYMBOL_E 0x1F8 | ||
70 | #define PUSH_SYMBOL_COLORS 0x208 | ||
71 | #define OUTER_BACKGROUND 0x20C | ||
72 | #define OUTER_BACKGROUND_MODE 0x21C | ||
73 | #define TRACED_EDGES 0x230 | ||
74 | #define AUDIO_PREFIX 0x278 | ||
75 | #define POWER 0x2A8 | ||
76 | #define TARGET 0x2BC | ||
77 | #define POWER_OFF_ON_FAIL 0x2C0 | ||
78 | #define IS_CYLINDER 0x2FC | ||
79 | #define CYLINDER_Z0 0x300 | ||
80 | #define CYLINDER_Z1 0x304 | ||
81 | #define CYLINDER_RADIUS 0x308 | ||
82 | #define CURSOR_SPEED_SCALE 0x358 | ||
83 | #define NEEDS_REDRAW 0x384 | ||
84 | #define SPECULAR_ADD 0x398 | ||
85 | #define SPECULAR_POWER 0x39C | ||
86 | #define PATH_WIDTH_SCALE 0x3A4 | ||
87 | #define STARTPOINT_SCALE 0x3A8 | ||
88 | #define NUM_DOTS 0x3B8 | ||
89 | #define NUM_CONNECTIONS 0x3BC | ||
90 | #define MAX_BROADCAST_DISTANCE 0x3C0 | ||
91 | #define DOT_POSITIONS 0x3C8 | ||
92 | #define DOT_FLAGS 0x3D0 | ||
93 | #define DOT_CONNECTION_A 0x3D8 | ||
94 | #define DOT_CONNECTION_B 0x3E0 | ||
95 | #define DECORATIONS 0x420 | ||
96 | #define DECORATION_FLAGS 0x428 | ||
97 | #define DECORATION_COLORS 0x430 | ||
98 | #define NUM_DECORATIONS 0x438 | ||
99 | #define REFLECTION_DATA 0x440 | ||
100 | #define GRID_SIZE_X 0x448 | ||
101 | #define GRID_SIZE_Y 0x44C | ||
102 | #define STYLE_FLAGS 0x450 | ||
103 | #define SEQUENCE_LEN 0x45C | ||
104 | #define SEQUENCE 0x460 | ||
105 | #define DOT_SEQUENCE_LEN 0x468 | ||
106 | #define DOT_SEQUENCE 0x470 | ||
107 | #define DOT_SEQUENCE_LEN_REFLECTION 0x478 | ||
108 | #define DOT_SEQUENCE_REFLECTION 0x480 | ||
109 | #define NUM_COLORED_REGIONS 0x4A0 | ||
110 | #define COLORED_REGIONS 0x4A8 | ||
111 | #define PANEL_TARGET 0x4B0 | ||
112 | #define SPECULAR_TEXTURE 0x4D8 | ||
113 | #define CABLE_TARGET_2 0xD8 | ||
114 | #define AUDIO_LOG_NAME 0xC8 | ||
115 | #define OPEN_RATE 0xE8 | ||
116 | #define METADATA 0xF2 // sizeof(short) | ||
117 | #define HOTEL_EP_NAME 0x4BC640 | ||
118 | #elif GLOBALS == 0x62D0A0 | ||
119 | #define PATH_COLOR 0xC0 | ||
120 | #define REFLECTION_PATH_COLOR 0xD0 | ||
121 | #define DOT_COLOR 0xF0 | ||
122 | #define ACTIVE_COLOR 0x100 | ||
123 | #define BACKGROUND_REGION_COLOR 0x110 | ||
124 | #define SUCCESS_COLOR_A 0x120 | ||
125 | #define SUCCESS_COLOR_B 0x130 | ||
126 | #define STROBE_COLOR_A 0x140 | ||
127 | #define STROBE_COLOR_B 0x150 | ||
128 | #define ERROR_COLOR 0x160 | ||
129 | #define PATTERN_POINT_COLOR 0x180 | ||
130 | #define PATTERN_POINT_COLOR_A 0x190 | ||
131 | #define PATTERN_POINT_COLOR_B 0x1A0 | ||
132 | #define SYMBOL_A 0x1B0 | ||
133 | #define SYMBOL_B 0x1C0 | ||
134 | #define SYMBOL_C 0x1D0 | ||
135 | #define SYMBOL_D 0x1E0 | ||
136 | #define SYMBOL_E 0x1F0 | ||
137 | #define PUSH_SYMBOL_COLORS 0x200 | ||
138 | #define OUTER_BACKGROUND 0x204 | ||
139 | #define OUTER_BACKGROUND_MODE 0x214 | ||
140 | #define TRACED_EDGES 0x228 | ||
141 | #define AUDIO_PREFIX 0x270 | ||
142 | #define POWER 0x2A0 | ||
143 | #define TARGET 0x2B4 | ||
144 | #define POWER_OFF_ON_FAIL 0x2B8 | ||
145 | #define IS_CYLINDER 0x2F4 | ||
146 | #define CYLINDER_Z0 0x2F8 | ||
147 | #define CYLINDER_Z1 0x2FC | ||
148 | #define CYLINDER_RADIUS 0x300 | ||
149 | #define CURSOR_SPEED_SCALE 0x350 | ||
150 | #define NEEDS_REDRAW 0x37C | ||
151 | #define SPECULAR_ADD 0x38C | ||
152 | #define SPECULAR_POWER 0x390 | ||
153 | #define PATH_WIDTH_SCALE 0x39C | ||
154 | #define STARTPOINT_SCALE 0x3A0 | ||
155 | #define NUM_DOTS 0x3B4 | ||
156 | #define NUM_CONNECTIONS 0x3B8 | ||
157 | #define MAX_BROADCAST_DISTANCE 0x3BC | ||
158 | #define DOT_POSITIONS 0x3C0 | ||
159 | #define DOT_FLAGS 0x3C8 | ||
160 | #define DOT_CONNECTION_A 0x3D0 | ||
161 | #define DOT_CONNECTION_B 0x3D8 | ||
162 | #define DECORATIONS 0x418 | ||
163 | #define DECORATION_FLAGS 0x420 | ||
164 | #define DECORATION_COLORS 0x428 | ||
165 | #define NUM_DECORATIONS 0x430 | ||
166 | #define REFLECTION_DATA 0x438 | ||
167 | #define GRID_SIZE_X 0x440 | ||
168 | #define GRID_SIZE_Y 0x444 | ||
169 | #define STYLE_FLAGS 0x448 | ||
170 | #define SEQUENCE_LEN 0x454 | ||
171 | #define SEQUENCE 0x458 | ||
172 | #define DOT_SEQUENCE_LEN 0x460 | ||
173 | #define DOT_SEQUENCE 0x468 | ||
174 | #define DOT_SEQUENCE_LEN_REFLECTION 0x470 | ||
175 | #define DOT_SEQUENCE_REFLECTION 0x478 | ||
176 | #define NUM_COLORED_REGIONS 0x498 | ||
177 | #define COLORED_REGIONS 0x4A0 | ||
178 | #define PANEL_TARGET 0x4A8 | ||
179 | #define SPECULAR_TEXTURE 0x4D0 | ||
180 | #define CABLE_TARGET_2 0xD0 | ||
181 | #define AUDIO_LOG_NAME 0x0 | ||
182 | #define OPEN_RATE 0xE0 | ||
183 | #define METADATA 0x13A // sizeof(short) | ||
184 | #define HOTEL_EP_NAME 0x51E340 | ||
185 | #endif \ No newline at end of file | ||