diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Memory.h | 4 | ||||
-rw-r--r-- | Source/Panel.cpp | 16 | ||||
-rw-r--r-- | Source/Panel.h | 323 | ||||
-rw-r--r-- | Source/Source.vcxproj | 3 |
4 files changed, 195 insertions, 151 deletions
diff --git a/Source/Memory.h b/Source/Memory.h index c19d92b..6e0c7b1 100644 --- a/Source/Memory.h +++ b/Source/Memory.h | |||
@@ -5,8 +5,8 @@ | |||
5 | #include <vector> | 5 | #include <vector> |
6 | #include <windows.h> | 6 | #include <windows.h> |
7 | 7 | ||
8 | // #define GLOBALS 0x5B28C0 | 8 | #define GLOBALS 0x5B28C0 |
9 | #define GLOBALS 0x62D0A0 | 9 | // #define GLOBALS 0x62D0A0 |
10 | 10 | ||
11 | #define HEARTBEAT 0x401 | 11 | #define HEARTBEAT 0x401 |
12 | enum class ProcStatus { | 12 | enum class ProcStatus { |
diff --git a/Source/Panel.cpp b/Source/Panel.cpp index c0fb7ec..ea65142 100644 --- a/Source/Panel.cpp +++ b/Source/Panel.cpp | |||
@@ -12,8 +12,7 @@ int find(const std::vector<T> &data, T search, size_t startIndex = 0) { | |||
12 | return -1; | 12 | return -1; |
13 | } | 13 | } |
14 | 14 | ||
15 | Panel::Panel(int id) { | 15 | Panel::Panel(const std::shared_ptr<Memory>& memory, int id) : _memory(memory) { |
16 | _memory = std::make_shared<Memory>("witness64_d3d11.exe"); | ||
17 | _width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1; | 16 | _width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1; |
18 | _height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1; | 17 | _height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1; |
19 | _grid.resize(_width); | 18 | _grid.resize(_width); |
@@ -45,7 +44,7 @@ nlohmann::json Panel::Serialize() { | |||
45 | for (int x=0; x<_width; x++) { | 44 | for (int x=0; x<_width; x++) { |
46 | for (int y=0; y<_height; y++) { | 45 | for (int y=0; y<_height; y++) { |
47 | if (x%2 == 1 && y%2 == 1) { | 46 | if (x%2 == 1 && y%2 == 1) { |
48 | puzzle["grid"][x][y] = Decoration::to_json(_grid[x][y]); | 47 | puzzle["grid"][x][y] = Decoration_to_json(_grid[x][y]); |
49 | } else { | 48 | } else { |
50 | if (_grid[x][y] & IntersectionFlags::HAS_DOT) { | 49 | if (_grid[x][y] & IntersectionFlags::HAS_DOT) { |
51 | puzzle["dots"].emplace_back(nlohmann::json({{"x", x}, {"y", y}})); | 50 | puzzle["dots"].emplace_back(nlohmann::json({{"x", x}, {"y", y}})); |
@@ -69,17 +68,6 @@ nlohmann::json Panel::Serialize() { | |||
69 | return puzzle; | 68 | return puzzle; |
70 | } | 69 | } |
71 | 70 | ||
72 | void Panel::Random() { | ||
73 | /* | ||
74 | for (auto& row : _decorations) { | ||
75 | for (auto& cell : row) { | ||
76 | cell.SetShape(cell.GetShape() & 0xFFFFFFF0); | ||
77 | cell.SetShape(cell.GetShape() | Random::RandInt(1, 10)); | ||
78 | } | ||
79 | } | ||
80 | */ | ||
81 | } | ||
82 | |||
83 | void Panel::ReadDecorations(int id) { | 71 | void Panel::ReadDecorations(int id) { |
84 | int numDecorations = _memory->ReadPanelData<int>(id, NUM_DECORATIONS, 1)[0]; | 72 | int numDecorations = _memory->ReadPanelData<int>(id, NUM_DECORATIONS, 1)[0]; |
85 | std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations); | 73 | std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations); |
diff --git a/Source/Panel.h b/Source/Panel.h index 1f2b8c6..0d1af14 100644 --- a/Source/Panel.h +++ b/Source/Panel.h | |||
@@ -2,166 +2,219 @@ | |||
2 | #include "json.hpp" | 2 | #include "json.hpp" |
3 | #include "Memory.h" | 3 | #include "Memory.h" |
4 | 4 | ||
5 | class Decoration | ||
6 | { | ||
7 | public: | ||
8 | enum Shape { | ||
9 | Stone = 0x100, | ||
10 | Star = 0x200, | ||
11 | Poly = 0x400, | ||
12 | Eraser = 0x500, | ||
13 | Triangle = 0x600, | ||
14 | }; | ||
15 | enum Color { | ||
16 | Black = 0x1, | ||
17 | White = 0x2, | ||
18 | Red = 0x3, | ||
19 | Blue = 0x4, | ||
20 | Green = 0x5, | ||
21 | }; | ||
22 | |||
23 | static nlohmann::json to_json(int decoration) { | ||
24 | nlohmann::json json = {}; | ||
25 | int shape = decoration & 0x00000F00; | ||
26 | if (shape == Shape::Stone) json["type"] = "square"; | ||
27 | if (shape == Shape::Star) json["type"] = "star"; | ||
28 | if (shape == Shape::Poly) json["type"] = "poly"; | ||
29 | if (shape == Shape::Eraser) json["type"] = "eraser"; | ||
30 | if (shape == Shape::Triangle) json["type"] = "triangle"; | ||
31 | |||
32 | int color = decoration & 0x0000000F; | ||
33 | if (color == Color::Black) json["color"] = "black"; | ||
34 | if (color == Color::White) json["color"] = "white"; | ||
35 | if (color == Color::Red) json["color"] = "red"; | ||
36 | if (color == Color::Blue) json["color"] = "blue"; | ||
37 | if (color == Color::Green) json["color"] = "green"; | ||
38 | |||
39 | if (json.empty()) return false; | ||
40 | return json; | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | enum IntersectionFlags { | 5 | enum IntersectionFlags { |
45 | IS_ENDPOINT = 0x1, | 6 | IS_ENDPOINT = 0x1, |
46 | IS_STARTPOINT = 0x2, | 7 | IS_STARTPOINT = 0x2, |
47 | IS_GAP = 0x10000, | 8 | IS_GAP = 0x10000, |
48 | HAS_DOT = 0x40020, | 9 | HAS_DOT = 0x40020, |
49 | DOT_IS_BLUE = 0x100, | 10 | DOT_IS_BLUE = 0x100, |
50 | DOT_IS_ORANGE = 0x200, | 11 | DOT_IS_ORANGE = 0x200, |
51 | DOT_IS_INVISIBLE = 0x1000, | 12 | DOT_IS_INVISIBLE = 0x1000, |
52 | }; | 13 | }; |
53 | 14 | ||
15 | /* | ||
16 | enum Style { | ||
17 | SYMMETRICAL = 0x2, | ||
18 | IS_2COLOR = 0x10, | ||
19 | HAS_DOTS = 0x4, | ||
20 | HAS_STARS = 0x40, | ||
21 | HAS_STONES = 0x100, | ||
22 | HAS_ERASERS = 0x1000, | ||
23 | HAS_SHAPERS = 0x2000, | ||
24 | }; | ||
25 | */ | ||
26 | |||
54 | class Endpoint { | 27 | class Endpoint { |
55 | public: | 28 | public: |
56 | enum class Direction { | 29 | enum class Direction { |
57 | LEFT, | 30 | LEFT, |
58 | RIGHT, | 31 | RIGHT, |
59 | UP, | 32 | UP, |
60 | DOWN | 33 | DOWN |
61 | }; | 34 | }; |
62 | 35 | ||
63 | Endpoint(int x, int y, Direction dir) { | 36 | Endpoint(int x, int y, Direction dir) { |
64 | _x = x; | 37 | _x = x; |
65 | _y = y; | 38 | _y = y; |
66 | _dir = dir; | 39 | _dir = dir; |
67 | } | 40 | } |
68 | 41 | ||
69 | int GetX() {return _x;} | 42 | int GetX() {return _x;} |
70 | void SetX(int x) {_x = x;} | 43 | void SetX(int x) {_x = x;} |
71 | int GetY() {return _y;} | 44 | int GetY() {return _y;} |
72 | void SetY(int y) {_y = y;} | 45 | void SetY(int y) {_y = y;} |
73 | Direction GetDir() {return _dir;} | 46 | Direction GetDir() {return _dir;} |
74 | void SetDir(Direction dir) {_dir = dir;} | 47 | void SetDir(Direction dir) {_dir = dir;} |
75 | 48 | ||
76 | nlohmann::json to_json() { | 49 | nlohmann::json to_json() { |
77 | nlohmann::json json = {{"x", _x}, {"y", _y}}; | 50 | nlohmann::json json = {{"x", _x}, {"y", _y}}; |
78 | if (_dir == LEFT) json["dir"] = "left"; | 51 | if (_dir == Direction::LEFT) json["dir"] = "left"; |
79 | if (_dir == RIGHT) json["dir"] = "right"; | 52 | if (_dir == Direction::RIGHT) json["dir"] = "right"; |
80 | if (_dir == UP) json["dir"] = "up"; | 53 | if (_dir == Direction::UP) json["dir"] = "up"; |
81 | if (_dir == DOWN) json["dir"] = "down"; | 54 | if (_dir == Direction::DOWN) json["dir"] = "down"; |
82 | return json; | 55 | return json; |
83 | } | 56 | } |
84 | 57 | ||
85 | private: | 58 | private: |
86 | int _x, _y; | 59 | int _x, _y; |
87 | Direction _dir; | 60 | Direction _dir; |
88 | }; | 61 | }; |
89 | 62 | ||
90 | class Panel | 63 | class Panel { |
91 | { | ||
92 | public: | 64 | public: |
93 | Panel(int id); | 65 | Panel(const std::shared_ptr<Memory>& memory, int id); |
94 | // explicit Panel(nlohmann::json json); | 66 | // explicit Panel(nlohmann::json json); |
95 | 67 | ||
96 | void Write(int id); | 68 | void Write(int id); |
97 | nlohmann::json Serialize(); | 69 | nlohmann::json Serialize(); |
98 | 70 | ||
99 | void Random(); | 71 | private: |
72 | // For testing | ||
73 | Panel() = default; | ||
100 | 74 | ||
101 | enum Style { | 75 | void ReadIntersections(int id); |
102 | SYMMETRICAL = 0x2, | 76 | void WriteIntersections(int id); |
103 | IS_2COLOR = 0x10, | 77 | void ReadDecorations(int id); |
104 | HAS_DOTS = 0x4, | 78 | void WriteDecorations(int id); |
105 | HAS_STARS = 0x40, | ||
106 | HAS_STONES = 0x100, | ||
107 | HAS_ERASERS = 0x1000, | ||
108 | HAS_SHAPERS = 0x2000, | ||
109 | }; | ||
110 | 79 | ||
111 | private: | 80 | // TODO: Reflection data |
112 | // For testing | 81 | // TODO: Decoration colors |
113 | Panel() = default; | 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 | } | ||
114 | 91 | ||
115 | void ReadIntersections(int id); | 92 | int xy_to_loc(int x, int y) { |
116 | void WriteIntersections(int id); | 93 | int height2 = (_height - 1) / 2; |
117 | void ReadDecorations(int id); | 94 | int width2 = (_width + 1) / 2; |
118 | void WriteDecorations(int id); | ||
119 | 95 | ||
120 | // TODO: Reflection data | 96 | int rowsFromBottom = height2 - y/2; |
121 | // TODO: Decoration colors | 97 | return rowsFromBottom * width2 + x/2; |
98 | } | ||
122 | 99 | ||
123 | std::tuple<int, int> loc_to_xy(int location) { | 100 | std::tuple<int, int> dloc_to_xy(int location) { |
124 | int height2 = (_height - 1) / 2; | 101 | int height2 = (_height - 3) / 2; |
125 | int width2 = (_width + 1) / 2; | 102 | int width2 = (_width - 1) / 2; |
126 | 103 | ||
127 | int x = 2 * (location % width2); | 104 | int x = 2 * (location % width2) + 1; |
128 | int y = 2 * (height2 - location / width2); | 105 | int y = 2 * (height2 - location / width2) + 1; |
129 | return {x, y}; | 106 | return {x, y}; |
130 | } | 107 | } |
131 | 108 | ||
132 | int xy_to_loc(int x, int y) { | 109 | int xy_to_dloc(int x, int y) { |
133 | int height2 = (_height - 1) / 2; | 110 | int height2 = (_height - 3) / 2; |
134 | int width2 = (_width + 1) / 2; | 111 | int width2 = (_width - 1) / 2; |
135 | 112 | ||
136 | int rowsFromBottom = height2 - y/2; | 113 | int rowsFromBottom = height2 - (y - 1)/2; |
137 | return rowsFromBottom * width2 + x/2; | 114 | return rowsFromBottom * width2 + (x - 1)/2; |
138 | } | 115 | } |
139 | 116 | ||
140 | std::tuple<int, int> dloc_to_xy(int location) { | 117 | std::shared_ptr<Memory> _memory; |
141 | int height2 = (_height - 3) / 2; | ||
142 | int width2 = (_width - 1) / 2; | ||
143 | 118 | ||
144 | int x = 2 * (location % width2) + 1; | 119 | int _width, _height; |
145 | int y = 2 * (height2 - location / width2) + 1; | ||
146 | return {x, y}; | ||
147 | } | ||
148 | 120 | ||
149 | int xy_to_dloc(int x, int y) { | 121 | std::vector<std::vector<int>> _grid; |
150 | int height2 = (_height - 3) / 2; | 122 | std::vector<Endpoint> _endpoints; |
151 | int width2 = (_width - 1) / 2; | 123 | std::vector<std::pair<int ,int>> _startpoints; |
124 | int _style; | ||
152 | 125 | ||
153 | int rowsFromBottom = height2 - (y - 1)/2; | 126 | friend class PanelExtractionTests; |
154 | return rowsFromBottom * width2 + (x - 1)/2; | 127 | }; |
155 | } | 128 | |
129 | // V2 stuff here | ||
130 | struct Decoration { | ||
131 | enum class Type {STONE, STAR, POLY, ERASER, TRIANGLE, RPOLY, YLOP}; | ||
132 | Type type; | ||
133 | // TODO: Color color; | ||
134 | uint32_t polyshape; | ||
135 | int count; // For triangles | ||
136 | }; | ||
137 | |||
138 | struct Cell { | ||
139 | bool start; | ||
140 | enum class Dir {NONE, LEFT, RIGHT, UP, DOWN}; | ||
141 | Dir end; | ||
142 | Decoration* decoration; | ||
143 | enum class Dot {NONE, BLACK, BLUE, YELLOW, INVISIBLE}; | ||
144 | Dot dot; | ||
145 | enum class Gap {NONE, BREAK, FULL}; | ||
146 | Gap gap; | ||
147 | }; | ||
156 | 148 | ||
157 | std::shared_ptr<Memory> _memory; | 149 | struct Puzzle { |
150 | int16_t height; | ||
151 | int16_t width; | ||
152 | Cell** grid; | ||
158 | 153 | ||
159 | int _width, _height; | 154 | enum class Symmetry {NONE, X, Y, XY}; |
155 | Symmetry sym; | ||
156 | bool pillar; | ||
157 | }; | ||
160 | 158 | ||
161 | std::vector<std::vector<int>> _grid; | 159 | class PuzzleSerializer { |
162 | std::vector<Endpoint> _endpoints; | 160 | public: |
163 | std::vector<std::pair<int ,int>> _startpoints; | 161 | PuzzleSerializer(const std::shared_ptr<Memory>& memory); |
164 | int _style; | 162 | Puzzle ReadPuzzle(int panelId); |
163 | void WritePuzzle(int panelId, const Puzzle& puzzle); | ||
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 | |||
189 | enum Flags { | ||
190 | IS_ENDPOINT = 0x1, | ||
191 | IS_STARTPOINT = 0x2, | ||
192 | DOT_IS_BLUE = 0x100, | ||
193 | DOT_IS_ORANGE = 0x200, | ||
194 | DOT_IS_INVISIBLE = 0x1000, | ||
195 | IS_GAP = 0x10000, | ||
196 | HAS_DOT = 0x40020, | ||
197 | }; | ||
198 | |||
199 | std::shared_ptr<Memory> _memory; | ||
200 | }; | ||
165 | 201 | ||
166 | friend class PanelExtractionTests; | 202 | static nlohmann::json Decoration_to_json(int decoration) { |
167 | }; \ No newline at end of file | 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 | |||
211 | int color = decoration & 0x0000000F; | ||
212 | if (color == PuzzleSerializer::Color::Black) json["color"] = "black"; | ||
213 | if (color == PuzzleSerializer::Color::White) json["color"] = "white"; | ||
214 | if (color == PuzzleSerializer::Color::Gray) json["color"] = "gray"; | ||
215 | if (color == PuzzleSerializer::Color::Blue) json["color"] = "blue"; | ||
216 | if (color == PuzzleSerializer::Color::Green) json["color"] = "green"; | ||
217 | |||
218 | if (json.empty()) return false; | ||
219 | return json; | ||
220 | } | ||
diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index b60349c..0fed93c 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj | |||
@@ -158,7 +158,9 @@ | |||
158 | </ItemDefinitionGroup> | 158 | </ItemDefinitionGroup> |
159 | <ItemGroup> | 159 | <ItemGroup> |
160 | <ClInclude Include="ChallengeRandomizer.h" /> | 160 | <ClInclude Include="ChallengeRandomizer.h" /> |
161 | <ClInclude Include="json.hpp" /> | ||
161 | <ClInclude Include="Memory.h" /> | 162 | <ClInclude Include="Memory.h" /> |
163 | <ClInclude Include="Panel.h" /> | ||
162 | <ClInclude Include="Panels.h" /> | 164 | <ClInclude Include="Panels.h" /> |
163 | <ClInclude Include="Random.h" /> | 165 | <ClInclude Include="Random.h" /> |
164 | <ClInclude Include="Randomizer.h" /> | 166 | <ClInclude Include="Randomizer.h" /> |
@@ -166,6 +168,7 @@ | |||
166 | <ItemGroup> | 168 | <ItemGroup> |
167 | <ClCompile Include="ChallengeRandomizer.cpp" /> | 169 | <ClCompile Include="ChallengeRandomizer.cpp" /> |
168 | <ClCompile Include="Memory.cpp" /> | 170 | <ClCompile Include="Memory.cpp" /> |
171 | <ClCompile Include="Panel.cpp" /> | ||
169 | <ClCompile Include="Random.cpp" /> | 172 | <ClCompile Include="Random.cpp" /> |
170 | <ClCompile Include="Randomizer.cpp" /> | 173 | <ClCompile Include="Randomizer.cpp" /> |
171 | </ItemGroup> | 174 | </ItemGroup> |