about summary refs log tree commit diff stats
path: root/App/Main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'App/Main.cpp')
-rw-r--r--App/Main.cpp180
1 files changed, 19 insertions, 161 deletions
diff --git a/App/Main.cpp b/App/Main.cpp index 00bf29a..ad3d127 100644 --- a/App/Main.cpp +++ b/App/Main.cpp
@@ -5,17 +5,12 @@
5#include "Memory.h" 5#include "Memory.h"
6#include "Random.h" 6#include "Random.h"
7#include "Randomizer.h" 7#include "Randomizer.h"
8#include "Randomizer2.h"
9#include "Panels_.h" 8#include "Panels_.h"
10 9
11#define HEARTBEAT 0x401 10#define HEARTBEAT 0x401
12#define RANDOMIZE_READY 0x402 11#define RANDOMIZE_READY 0x402
13#define RANDOMIZING 0403 12#define RANDOMIZING 0403
14#define RANDOMIZE_DONE 0x404 13#define RANDOMIZE_DONE 0x404
15#define RANDOMIZE_CHALLENGE_DONE 0x405
16#define CHALLENGE_ONLY 0x406
17#define DISABLE_SNIPES 0x407
18#define SPEED_UP_AUTOSCROLLERS 0x408
19 14
20/* ------- Temp ------- */ 15/* ------- Temp ------- */
21#include "Solver.h" 16#include "Solver.h"
@@ -23,10 +18,6 @@
23#include <sstream> 18#include <sstream>
24#include <iomanip> 19#include <iomanip>
25 20
26#define TMP1 0x501
27#define TMP2 0x502
28#define TMP3 0x503
29#define TMP4 0x504
30 21
31HWND g_panelId; 22HWND g_panelId;
32Puzzle g_puzzle; 23Puzzle g_puzzle;
@@ -37,13 +28,11 @@ HWND g_rngDebug;
37 28
38// Globals 29// Globals
39HWND g_hwnd; 30HWND g_hwnd;
40HWND g_seed; 31//HWND g_seed;
41HWND g_randomizerStatus; 32HWND g_randomizerStatus;
42HINSTANCE g_hInstance; 33HINSTANCE g_hInstance;
43auto g_witnessProc = std::make_shared<Memory>(L"witness64_d3d11.exe"); 34auto g_witnessProc = std::make_shared<Memory>(L"witness64_d3d11.exe");
44std::shared_ptr<Randomizer> g_randomizer; 35std::shared_ptr<Randomizer> g_randomizer;
45std::shared_ptr<Randomizer2> g_randomizer2;
46void SetRandomSeed();
47 36
48LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { 37LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
49 if (message == WM_DESTROY) { 38 if (message == WM_DESTROY) {
@@ -64,171 +53,57 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
64 // Shut down randomizer, wait for startup 53 // Shut down randomizer, wait for startup
65 if (g_randomizer) { 54 if (g_randomizer) {
66 g_randomizer = nullptr; 55 g_randomizer = nullptr;
67 g_randomizer2 = nullptr;
68 EnableWindow(g_randomizerStatus, FALSE); 56 EnableWindow(g_randomizerStatus, FALSE);
69 } 57 }
70 break; 58 break;
71 case ProcStatus::Running: 59 case ProcStatus::Running:
72 if (!g_randomizer) { 60 if (!g_randomizer) {
73 g_randomizer = std::make_shared<Randomizer>(g_witnessProc); 61 g_randomizer = std::make_shared<Randomizer>(g_witnessProc);
74 g_randomizer2 = std::make_shared<Randomizer2>(g_witnessProc);
75 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL); 62 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL);
76 } 63 }
77 break; 64 break;
78 case ProcStatus::NewGame: // This status will fire only once per new game 65 case ProcStatus::NewGame: // This status will fire only once per new game
79 SetWindowText(g_seed, L""); 66 //SetWindowText(g_seed, L"");
80 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL); 67 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL);
81 break; 68 break;
82 } 69 }
83 break; 70 break;
84 case RANDOMIZE_READY: 71 case RANDOMIZE_READY:
85 EnableWindow(g_randomizerStatus, TRUE); 72 EnableWindow(g_randomizerStatus, TRUE);
86 if (IsDlgButtonChecked(hwnd, CHALLENGE_ONLY)) { 73 SetWindowText(g_randomizerStatus, L"Tutorialise");
87 SetWindowText(g_randomizerStatus, L"Randomize Challenge");
88 } else {
89 SetWindowText(g_randomizerStatus, L"Randomize");
90 }
91 break; 74 break;
92 case RANDOMIZING: 75 case RANDOMIZING:
93 if (!g_randomizer) break; // E.g. an enter press at the wrong time 76 if (!g_randomizer) break; // E.g. an enter press at the wrong time
94 EnableWindow(g_randomizerStatus, FALSE); 77 EnableWindow(g_randomizerStatus, FALSE);
95 78
96 SetRandomSeed();
97 std::thread([]{ 79 std::thread([]{
98 if (IsDlgButtonChecked(g_hwnd, DISABLE_SNIPES)) { 80 SetWindowText(g_randomizerStatus, L"Tutorialising...");
99 MEMORY_CATCH(g_randomizer->PreventSnipes()); 81 g_randomizer->Randomize();
100 } 82 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_DONE, NULL);
101 if (IsDlgButtonChecked(g_hwnd, SPEED_UP_AUTOSCROLLERS)) {
102 MEMORY_CATCH(g_randomizer->AdjustSpeed());
103 }
104 if (IsDlgButtonChecked(g_hwnd, CHALLENGE_ONLY)) {
105 SetWindowText(g_randomizerStatus, L"Randomizing Challenge...");
106 MEMORY_CATCH(g_randomizer->RandomizeChallenge());
107 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_CHALLENGE_DONE, NULL);
108 } else {
109 SetWindowText(g_randomizerStatus, L"Randomizing...");
110 g_randomizer->Randomize();
111 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_DONE, NULL);
112 }
113 }).detach(); 83 }).detach();
114 break; 84 break;
115 case RANDOMIZE_DONE: 85 case RANDOMIZE_DONE:
116 EnableWindow(g_randomizerStatus, FALSE); 86 EnableWindow(g_randomizerStatus, FALSE);
117 SetWindowText(g_randomizerStatus, L"Randomized!"); 87 SetWindowText(g_randomizerStatus, L"Tutorialised!");
118 break;
119 case RANDOMIZE_CHALLENGE_DONE:
120 EnableWindow(g_randomizerStatus, FALSE);
121 SetWindowText(g_randomizerStatus, L"Randomized Challenge!");
122 std::thread([]{
123 // Allow re-randomization for challenge -- it doesn't break the rest of the game.
124 std::this_thread::sleep_for(std::chrono::seconds(10));
125 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL);
126 }).detach();
127 break;
128 case CHALLENGE_ONLY:
129 CheckDlgButton(hwnd, CHALLENGE_ONLY, !IsDlgButtonChecked(hwnd, CHALLENGE_ONLY));
130 if (IsWindowEnabled(g_randomizerStatus)) {
131 PostMessage(g_hwnd, WM_COMMAND, RANDOMIZE_READY, NULL);
132 }
133 break;
134 case DISABLE_SNIPES:
135 CheckDlgButton(hwnd, DISABLE_SNIPES, !IsDlgButtonChecked(hwnd, DISABLE_SNIPES));
136 break;
137 case SPEED_UP_AUTOSCROLLERS:
138 CheckDlgButton(hwnd, SPEED_UP_AUTOSCROLLERS, !IsDlgButtonChecked(hwnd, SPEED_UP_AUTOSCROLLERS));
139 break;
140 case TMP1:
141 {
142 std::wstring text(128, L'\0');
143 int length = GetWindowText(g_panelId, text.data(), static_cast<int>(text.size()));
144 text.resize(length);
145 std::wstringstream s;
146 int panelId;
147 s << text;
148 s >> std::hex >> panelId;
149 g_puzzle = PuzzleSerializer(g_witnessProc).ReadPuzzle(panelId);
150 }
151 break;
152 case TMP2:
153 {
154 std::wstring text(128, L'\0');
155 int length = GetWindowText(g_panelId, text.data(), static_cast<int>(text.size()));
156 text.resize(length);
157 std::wstringstream s;
158 int panelId;
159 s << text;
160 s >> std::hex >> panelId;
161 PuzzleSerializer(g_witnessProc).WritePuzzle(g_puzzle, panelId);
162 }
163 break; 88 break;
164 case TMP3:
165 {
166 for (auto [key, value] : PANELS) {
167 std::stringstream out;
168 std::string name(value);
169 out << " {'id': 0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(5) << key << ", 'area':'";
170 int k;
171 for (k=0; name[k] != ' '; k++) out << name[k];
172 if (name[k+2] == ' ') {
173 out << name[k] << name[k+1];
174 k += 2;
175 }
176 out << "', 'name':'";
177 k++;
178 for (k; k < name.size(); k++) out << name[k];
179 out << "', 'data':'";
180 auto puzzle = PuzzleSerializer(g_witnessProc).ReadPuzzle(key);
181 out << puzzle.Serialize();
182 out << "'},\r\n";
183 DebugPrint(out.str());
184 }
185 }
186 89
187 // Solver::Solve(g_puzzle);
188 break;
189 case TMP4:
190 SetRandomSeed();
191 g_randomizer2->Randomize();
192 case TMP5:
193 {
194 std::wstring text;
195 for (int i=0; i<10; i++) {
196 Random::SetSeed(i);
197 int rng = Random::RandInt(0, 999999);
198 text += std::to_wstring(rng) + L"\n";
199 }
200 SetWindowText(g_rngDebug, text.c_str());
201 }
202 } 90 }
203 } 91 }
204 return DefWindowProc(hwnd, message, wParam, lParam); 92 return DefWindowProc(hwnd, message, wParam, lParam);
205} 93}
206 94
207void SetRandomSeed() {
208 std::wstring text(128, L'\0');
209 int length = GetWindowText(g_seed, text.data(), static_cast<int>(text.size()));
210 if (length > 0) { // Set seed
211 text.resize(length);
212 Random::SetSeed(_wtoi(text.c_str()));
213 } else { // Random seed
214 int seed = Random::RandInt(0, 999999);
215
216 text = std::to_wstring(seed);
217 SetWindowText(g_seed, text.c_str());
218 CHARRANGE range = {0, static_cast<long>(text.length())};
219 PostMessage(g_seed, EM_EXSETSEL, NULL, (LPARAM)&range);
220 SetFocus(g_seed);
221
222 Random::SetSeed(seed);
223 }
224}
225
226HWND CreateLabel(int x, int y, int width, LPCWSTR text) { 95HWND CreateLabel(int x, int y, int width, LPCWSTR text) {
227 return CreateWindow(L"STATIC", text, 96 return CreateWindow(L"STATIC", text,
228 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT, 97 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
229 x, y, width, 16, g_hwnd, NULL, g_hInstance, NULL); 98 x, y, width, 16, g_hwnd, NULL, g_hInstance, NULL);
230} 99}
231 100
101HWND CreateMultiLabel(int x, int y, int width, int height, LPCWSTR text) {
102 return CreateWindow(L"STATIC", text,
103 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
104 x, y, width, height, g_hwnd, NULL, g_hInstance, NULL);
105}
106
232HWND CreateText(int x, int y, int width, LPCWSTR defaultText = L"") { 107HWND CreateText(int x, int y, int width, LPCWSTR defaultText = L"") {
233 return CreateWindow(MSFTEDIT_CLASS, defaultText, 108 return CreateWindow(MSFTEDIT_CLASS, defaultText,
234 WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER, 109 WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER,
@@ -271,32 +146,15 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
271 RECT rect; 146 RECT rect;
272 GetClientRect(GetDesktopWindow(), &rect); 147 GetClientRect(GetDesktopWindow(), &rect);
273 g_hwnd = CreateWindow(WINDOW_CLASS, PRODUCT_NAME, WS_OVERLAPPEDWINDOW, 148 g_hwnd = CreateWindow(WINDOW_CLASS, PRODUCT_NAME, WS_OVERLAPPEDWINDOW,
274 rect.right - 550, 200, 500, 500, nullptr, nullptr, hInstance, nullptr); 149 rect.right - 550, 200, 500, 180, nullptr, nullptr, hInstance, nullptr);
275 150
276 CreateLabel(390, 15, 90, L"Version: " VERSION_STR); 151 CreateMultiLabel(10, 10, 460, 86, L"This mod replaces most puzzles in the game with Tutorial Straight (the first puzzle in the tunnel where you start the game). Certain special panels are unaffected. Additionally, some panels (e.g. the tutorial gate, and every puzzle in Bunker) behave a little strangely now, and can be solved by simply double clicking in the middle of the panel.");
277 g_seed = CreateText(10, 10, 100); 152 CreateLabel(390, 110, 90, L"Version: " VERSION_STR);
278 PostMessage(g_seed, EM_SETEVENTMASK, 0, ENM_KEYEVENTS); 153 //g_seed = CreateText(10, 10, 100);
279 g_randomizerStatus = CreateButton(120, 10, 180, L"Randomize", RANDOMIZING); 154 //PostMessage(g_seed, EM_SETEVENTMASK, 0, ENM_KEYEVENTS);
155 g_randomizerStatus = CreateButton(120, 105, 180, L"Tutorialise", RANDOMIZING);
280 EnableWindow(g_randomizerStatus, FALSE); 156 EnableWindow(g_randomizerStatus, FALSE);
281 CreateCheckbox(10, 300, CHALLENGE_ONLY);
282 CreateLabel(30, 300, 200, L"Randomize the challenge only");
283 CreateCheckbox(10, 320, DISABLE_SNIPES);
284 CheckDlgButton(g_hwnd, DISABLE_SNIPES, TRUE);
285 CreateLabel(30, 320, 240, L"Disable Swamp and Shadows snipes");
286 CreateCheckbox(10, 340, SPEED_UP_AUTOSCROLLERS);
287 CreateLabel(30, 340, 205, L"Speed up various autoscrollers");
288 157
289 // CreateButton(200, 50, 200, L"Test RNG", TMP5);
290 // g_rngDebug = CreateWindow(L"STATIC", L"",
291 // WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
292 // 200, 80, 200, 200, g_hwnd, NULL, g_hInstance, NULL);
293#ifndef NDEBUG
294 g_panelId = CreateText(200, 100, 100, L"59");
295 CreateButton(200, 130, 100, L"Read", TMP1);
296 CreateButton(200, 160, 100, L"Write", TMP2);
297 CreateButton(200, 190, 100, L"Solve", TMP3);
298 CreateButton(200, 220, 100, L"Randomize2", TMP4);
299#endif
300 158
301 g_witnessProc->StartHeartbeat(g_hwnd, HEARTBEAT); 159 g_witnessProc->StartHeartbeat(g_hwnd, HEARTBEAT);
302 160