summary refs log tree commit diff stats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Main.cpp187
-rw-r--r--Source/Panels.h2
-rw-r--r--Source/Randomizer.cpp29
-rw-r--r--Source/Randomizer.h1
-rw-r--r--Source/RandomizerCore.cpp21
-rw-r--r--Source/RandomizerCore.h5
6 files changed, 119 insertions, 126 deletions
diff --git a/Source/Main.cpp b/Source/Main.cpp index 86a784b..b227e3d 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp
@@ -1,49 +1,73 @@
1// Source.cpp : Defines the entry point for the application. 1// Source.cpp : Defines the entry point for the application.
2// 2//
3 3
4#include "stdafx.h"
5#include "resource.h" 4#include "resource.h"
6#include "tchar.h"
7#include "Randomizer.h"
8#include <Richedit.h> 5#include <Richedit.h>
9#include <iostream>
10#include <ctime> 6#include <ctime>
11#include <string> 7#include <string>
8#include "Randomizer.h"
9#include "windows.h"
12 10
13#define MAX_LOADSTRING 100 11#define IDC_RANDOMIZE 0x401
14#define IDC_RANDOMIZE 0x464 12#define IDC_TOGGLESPEED 0x402
15
16HINSTANCE hInst;
17WCHAR szWindowClass[MAX_LOADSTRING];
18HWND hwndSeed, hwndRandomize;
19 13
20// Forward declares 14HWND hwndSeed, hwndRandomize, hwndSpeedSetting;
21ATOM MyRegisterClass(HINSTANCE hInstance);
22BOOL InitInstance(HINSTANCE, int);
23LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
24INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
25 15
26int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 16LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
27{ 17{
28 LoadStringW(hInstance, IDC_SOURCE, szWindowClass, MAX_LOADSTRING); 18 static bool wasSeedRandomlyGenerated;
29 MyRegisterClass(hInstance);
30 if (!InitInstance(hInstance, nCmdShow)) {
31 return FALSE;
32 }
33
34 MSG msg;
35 while (!GetMessage(&msg, nullptr, 0, 0) == 0)
36 {
37 TranslateMessage(&msg);
38 DispatchMessage(&msg);
39 }
40 19
41 return (int) msg.wParam; 20 if (message == WM_DESTROY) {
21 PostQuitMessage(0);
22 } else if (message == WM_COMMAND) {
23 switch (LOWORD(wParam)) {
24 // Speed checkbox
25 case IDC_TOGGLESPEED:
26 if (IsDlgButtonChecked(hwndSpeedSetting, 1)) {
27 CheckDlgButton(hwndSpeedSetting, 1, BST_UNCHECKED);
28 } else {
29 CheckDlgButton(hwndSpeedSetting, 1, BST_CHECKED);
30 }
31 break;
32
33 // Randomize button
34 case IDC_RANDOMIZE:
35 {
36 std::wstring text(100, '\0');
37 GetWindowText(hwndSeed, &text[0], 100);
38 int seed = 0;
39 if (wasSeedRandomlyGenerated || wcslen(text.c_str()) == 0) {
40 srand(static_cast<unsigned int>(time(nullptr))); // Seed from the time in milliseconds
41 rand(); // Increment RNG so that RNG isn't still using the time
42 seed = rand() % 100000;
43 std::wstring seedString = std::to_wstring(seed);
44 SetWindowText(hwndSeed, seedString.c_str());
45 wasSeedRandomlyGenerated = true;
46 } else {
47 seed = _wtoi(text.c_str());
48 wasSeedRandomlyGenerated = false;
49 }
50 srand(seed);
51 Randomizer randomizer;
52 randomizer.Randomize();
53 if (IsDlgButtonChecked(hwndSpeedSetting, 1)) {
54 randomizer.AdjustSpeed();
55 }
56 SetWindowText(hwndRandomize, L"Randomized!");
57 break;
58 }
59 }
60 }
61 return DefWindowProc(hwnd, message, wParam, lParam);
42} 62}
43 63
44ATOM MyRegisterClass(HINSTANCE hInstance) 64int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
45{ 65{
46 WNDCLASSEXW wcex = { 66 #define MAX_LOADSTRING 100
67 WCHAR szWindowClass[MAX_LOADSTRING];
68 LoadStringW(hInstance, IDC_SOURCE, szWindowClass, MAX_LOADSTRING);
69
70 WNDCLASSEXW wcex = {
47 sizeof(WNDCLASSEX), 71 sizeof(WNDCLASSEX),
48 CS_HREDRAW | CS_VREDRAW, 72 CS_HREDRAW | CS_VREDRAW,
49 WndProc, 73 WndProc,
@@ -57,95 +81,42 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
57 szWindowClass, 81 szWindowClass,
58 LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)), 82 LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)),
59 }; 83 };
60 84 RegisterClassExW(&wcex);
61 return RegisterClassExW(&wcex);
62}
63
64BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
65{
66 hInst = hInstance; // Store instance handle in our global variable
67 85
68 WCHAR szTitle[MAX_LOADSTRING]; 86 WCHAR szTitle[MAX_LOADSTRING];
69 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 87 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
70 HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 88 HWND hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
71 400, 200, 500, 500, nullptr, nullptr, hInstance, nullptr); 89 400, 200, 500, 500, nullptr, nullptr, hInstance, nullptr);
72 90
73 if (!hWnd) return FALSE;
74
75 LoadLibrary(L"Msftedit.dll"); 91 LoadLibrary(L"Msftedit.dll");
76 HWND label = CreateWindow(L"STATIC", L"Enter a seed:",
77 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
78 10, 15, 90, 16, hWnd, NULL, hInst, NULL);
79 92
80 hwndSeed = CreateWindowEx(0, MSFTEDIT_CLASS, L"",
81 WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER,
82 100, 10, 50, 26, hWnd, NULL, hInst, NULL);
83 93
94 CreateWindow(L"STATIC", L"Enter a seed:",
95 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
96 10, 15, 90, 16, hwnd, NULL, hInstance, NULL);
97 hwndSeed = CreateWindow(MSFTEDIT_CLASS, L"",
98 WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER,
99 100, 10, 50, 26, hwnd, NULL, hInstance, NULL);
84 hwndRandomize = CreateWindow(L"BUTTON", L"Randomize", 100 hwndRandomize = CreateWindow(L"BUTTON", L"Randomize",
85 WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 101 WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
86 160, 10, 100, 26, hWnd, (HMENU)IDC_RANDOMIZE, hInst, NULL); 102 160, 10, 100, 26, hwnd, (HMENU)IDC_RANDOMIZE, hInstance, NULL);
87
88 HDC hdc = GetDC(hWnd);
89 RECT rect;
90 GetClientRect(hWnd, &rect);
91 LPCWSTR text = L"this Window cannot be used";
92 DrawText(hdc, text, static_cast<int>(wcslen(text)), &rect, DT_CENTER | DT_VCENTER);
93 ReleaseDC(hWnd, hdc);
94
95 ShowWindow(hWnd, nCmdShow);
96 UpdateWindow(hWnd);
97 return TRUE;
98}
99 103
100LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 104 hwndSpeedSetting = CreateWindow(L"BUTTON", L"",
101{ 105 WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
102 if (message == WM_DESTROY) { 106 10, 52, 12, 12, hwnd, (HMENU)IDC_TOGGLESPEED, hInstance, NULL);
103 PostQuitMessage(0); 107 CreateWindow(L"STATIC", L"Speed up various autoscrollers",
104 } else if (message == WM_COMMAND) { 108 WS_TABSTOP | WS_VISIBLE | WS_CHILD | SS_LEFT,
105 int wmId = LOWORD(wParam); 109 27, 50, 205, 16, hwnd, NULL, hInstance, NULL);
106 // Parse the menu selections:
107 if (wmId == IDC_RANDOMIZE) {
108 std::wstring text(100, '\0');
109 GetWindowText(hwndSeed, &text[0], 100);
110 int seed = 0;
111 if (wcslen(text.c_str()) == 0) {
112 srand(static_cast<unsigned int>(time(nullptr))); // Seed from the time in milliseconds
113 rand();
114 seed = rand() % 100000;
115 std::wstring seedString = std::to_wstring(seed);
116 SetWindowText(hwndSeed, seedString.c_str());
117 } else {
118 seed = _wtoi(text.c_str());
119 }
120 srand(seed);
121 Randomizer randomizer;
122 randomizer.Randomize();
123 /*
124 if (adjustSpeed.isChecked()) {
125 randomizer.AdjustSpeed();
126 }
127 */
128 SetWindowText(hwndRandomize, L"Randomized!");
129 }
130 }
131 return DefWindowProc(hWnd, message, wParam, lParam);
132}
133 110
134INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 111 ShowWindow(hwnd, nCmdShow);
135{ 112 UpdateWindow(hwnd);
136 UNREFERENCED_PARAMETER(lParam); 113
137 switch (message) 114 MSG msg;
115 while (!GetMessage(&msg, nullptr, 0, 0) == 0)
138 { 116 {
139 case WM_INITDIALOG: 117 TranslateMessage(&msg);
140 return TRUE; 118 DispatchMessage(&msg);
141
142 case WM_COMMAND:
143 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
144 {
145 EndDialog(hDlg, LOWORD(wParam));
146 return TRUE;
147 }
148 break;
149 } 119 }
150 return FALSE; 120
121 return (int) msg.wParam;
151} 122}
diff --git a/Source/Panels.h b/Source/Panels.h index 6aa0d47..85fa28b 100644 --- a/Source/Panels.h +++ b/Source/Panels.h
@@ -72,10 +72,12 @@ std::vector<int> pillars = {
72 0x0383F, // Mountain 3 Left Pillar 2 72 0x0383F, // Mountain 3 Left Pillar 2
73 0x03859, // Mountain 3 Left Pillar 3 73 0x03859, // Mountain 3 Left Pillar 3
74 0x339BB, // Mountain 3 Left Pillar 4 74 0x339BB, // Mountain 3 Left Pillar 4
75 0x3C113, // Mountain 3 Left Open Door
75 0x0383A, // Mountain 3 Right Pillar 1 76 0x0383A, // Mountain 3 Right Pillar 1
76 0x09E56, // Mountain 3 Right Pillar 2 77 0x09E56, // Mountain 3 Right Pillar 2
77 0x09E5A, // Mountain 3 Right Pillar 3 78 0x09E5A, // Mountain 3 Right Pillar 3
78 0x33961, // Mountain 3 Right Pillar 4 79 0x33961, // Mountain 3 Right Pillar 4
80 0x3C114, // Mountain 3 Right Open Door
79// 0x09DD5, // UTM Challenge Pillar 81// 0x09DD5, // UTM Challenge Pillar
80}; 82};
81 83
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index 4541512..406468c 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp
@@ -5,9 +5,8 @@
5 * Tutorial sounds don't always play 5 * Tutorial sounds don't always play
6 * FEATURES: 6 * FEATURES:
7 * Speed up some of the slow things (like swamp) 7 * Speed up some of the slow things (like swamp)
8 * Determine if the user has entered the seed, and re-randomize it if not
9 * Prevent re-randomization (?) 8 * Prevent re-randomization (?)
10 * Clear "Randomized" state on NG (?) 9 * Clear "Randomized" state on NG (?) -- Or on a short delay
11 * Randomize audio logs -- Hard, seem to be unloaded some times? 10 * Randomize audio logs -- Hard, seem to be unloaded some times?
12 * Swap sounds in jungle (along with panels) -- maybe impossible 11 * Swap sounds in jungle (along with panels) -- maybe impossible
13 * Make orange 7 (all of oranges?) hard. Like big = hard. 12 * Make orange 7 (all of oranges?) hard. Like big = hard.
@@ -60,6 +59,10 @@ void Randomizer::Randomize()
60 // RandomizeAudioLogs(); 59 // RandomizeAudioLogs();
61} 60}
62 61
62void Randomizer::AdjustSpeed() {
63
64}
65
63void Randomizer::RandomizeTutorial() { 66void Randomizer::RandomizeTutorial() {
64 // Disable tutorial cursor speed modifications (not working?) 67 // Disable tutorial cursor speed modifications (not working?)
65 _core.WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0}); 68 _core.WritePanelData<float>(0x00295, CURSOR_SPEED_SCALE, {1.0});
@@ -158,10 +161,30 @@ void Randomizer::RandomizeSwamp() {
158} 161}
159 162
160void Randomizer::RandomizeMountain() { 163void Randomizer::RandomizeMountain() {
164 // Randomize lasers & some of mountain
161 _core.Randomize(lasers, SWAP_TARGETS); 165 _core.Randomize(lasers, SWAP_TARGETS);
162 _core.Randomize(pillars, SWAP_LINES | SWAP_BACK_DISTANCE);
163 _core.Randomize(mountainMultipanel, SWAP_LINES); 166 _core.Randomize(mountainMultipanel, SWAP_LINES);
164 167
168 // Randomize final pillars order
169 std::vector<int> targets = {pillars[0] + 1};
170 for (const int pillar : pillars) {
171 int target = _core.ReadPanelData<int>(pillar, TARGET, 1)[0];
172 targets.push_back(target);
173 }
174 targets[5] = pillars[5] + 1;
175
176 std::vector<int> randomOrder(pillars.size(), 0);
177 std::iota(randomOrder.begin(), randomOrder.end(), 0);
178 _core.RandomizeRange(randomOrder, SWAP_NONE, 0, 4); // Left Pillars 1-4
179 _core.RandomizeRange(randomOrder, SWAP_NONE, 5, 9); // Right Pillars 1-4
180 _core.ReassignTargets(pillars, randomOrder, targets);
181 // Turn off original starting panels
182 _core.WritePanelData<float>(pillars[0], POWER, {0.0f, 0.0f});
183 _core.WritePanelData<float>(pillars[5], POWER, {0.0f, 0.0f});
184 // Turn on new starting panels
185 _core.WritePanelData<float>(pillars[randomOrder[0]], POWER, {1.0f, 1.0f});
186 _core.WritePanelData<float>(pillars[randomOrder[5]], POWER, {1.0f, 1.0f});
187
165 // Read the target of keep front laser, and write it to keep back laser. 188 // Read the target of keep front laser, and write it to keep back laser.
166 std::vector<int> keepFrontLaserTarget = _core.ReadPanelData<int>(0x0360E, TARGET, 1); 189 std::vector<int> keepFrontLaserTarget = _core.ReadPanelData<int>(0x0360E, TARGET, 1);
167 _core.WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget); 190 _core.WritePanelData<int>(0x03317, TARGET, keepFrontLaserTarget);
diff --git a/Source/Randomizer.h b/Source/Randomizer.h index 552e33d..b0da4fe 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h
@@ -4,6 +4,7 @@
4class Randomizer { 4class Randomizer {
5public: 5public:
6 void Randomize(); 6 void Randomize();
7 void AdjustSpeed();
7 8
8private: 9private:
9 void RandomizeTutorial(); 10 void RandomizeTutorial();
diff --git a/Source/RandomizerCore.cpp b/Source/RandomizerCore.cpp index c673e2d..77977c6 100644 --- a/Source/RandomizerCore.cpp +++ b/Source/RandomizerCore.cpp
@@ -30,9 +30,6 @@ void RandomizerCore::SwapPanels(int panel1, int panel2, int flags) {
30 if (flags & SWAP_AUDIO_NAMES) { 30 if (flags & SWAP_AUDIO_NAMES) {
31 offsets[AUDIO_LOG_NAME] = sizeof(void*); 31 offsets[AUDIO_LOG_NAME] = sizeof(void*);
32 } 32 }
33 if (flags & SWAP_BACK_DISTANCE) {
34 offsets[EXTRA_BACK_DISTANCE] = sizeof(float);
35 }
36 if (flags & SWAP_LINES) { 33 if (flags & SWAP_LINES) {
37 offsets[PATH_COLOR] = 16; 34 offsets[PATH_COLOR] = 16;
38 offsets[REFLECTION_PATH_COLOR] = 16; 35 offsets[REFLECTION_PATH_COLOR] = 16;
@@ -99,18 +96,20 @@ void RandomizerCore::SwapPanels(int panel1, int panel2, int flags) {
99 } 96 }
100} 97}
101 98
102void RandomizerCore::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order) { 99void RandomizerCore::ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets) {
103 // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element) 100 if (targets.empty()) {
104 // The first panel may not have a wire to power it, so we use the panel ID itself. 101 // This list is offset by 1, so the target of the Nth panel is in position N (aka the N+1th element)
105 std::vector<int> targetToActivatePanel = {panels[0] + 1}; 102 // The first panel may not have a wire to power it, so we use the panel ID itself.
106 for (const int panel : panels) { 103 targets = {panels[0] + 1};
107 int target = ReadPanelData<int>(panel, TARGET, 1)[0]; 104 for (const int panel : panels) {
108 targetToActivatePanel.push_back(target); 105 int target = ReadPanelData<int>(panel, TARGET, 1)[0];
106 targets.push_back(target);
107 }
109 } 108 }
110 109
111 for (size_t i=0; i<order.size() - 1; i++) { 110 for (size_t i=0; i<order.size() - 1; i++) {
112 // Set the target of order[i] to order[i+1], using the "real" target as determined above. 111 // Set the target of order[i] to order[i+1], using the "real" target as determined above.
113 const int panelTarget = targetToActivatePanel[order[i+1]]; 112 const int panelTarget = targets[order[i+1]];
114 WritePanelData<int>(panels[order[i]], TARGET, {panelTarget}); 113 WritePanelData<int>(panels[order[i]], TARGET, {panelTarget});
115 } 114 }
116} 115}
diff --git a/Source/RandomizerCore.h b/Source/RandomizerCore.h index 2a8e42e..711cc89 100644 --- a/Source/RandomizerCore.h +++ b/Source/RandomizerCore.h
@@ -8,7 +8,6 @@ __declspec(selectany) int SWAP_NONE = 0x0;
8__declspec(selectany) int SWAP_TARGETS = 0x1; 8__declspec(selectany) int SWAP_TARGETS = 0x1;
9__declspec(selectany) int SWAP_LINES = 0x2; 9__declspec(selectany) int SWAP_LINES = 0x2;
10__declspec(selectany) int SWAP_AUDIO_NAMES = 0x4; 10__declspec(selectany) int SWAP_AUDIO_NAMES = 0x4;
11__declspec(selectany) int SWAP_BACK_DISTANCE = 0x8;
12 11
13class RandomizerCore 12class RandomizerCore
14{ 13{
@@ -16,7 +15,7 @@ public:
16 void Randomize(std::vector<int>& panels, int flags); 15 void Randomize(std::vector<int>& panels, int flags);
17 void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex); 16 void RandomizeRange(std::vector<int> &panels, int flags, size_t startIndex, size_t endIndex);
18 void SwapPanels(int panel1, int panel2, int flags); 17 void SwapPanels(int panel1, int panel2, int flags);
19 void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order); 18 void ReassignTargets(const std::vector<int>& panels, const std::vector<int>& order, std::vector<int> targets = {});
20 void ReassignNames(const std::vector<int>& panels, const std::vector<int>& order); 19 void ReassignNames(const std::vector<int>& panels, const std::vector<int>& order);
21 20
22 template <class T> 21 template <class T>
@@ -55,7 +54,6 @@ private:
55#define PUSH_SYMBOL_COLORS 0x208 54#define PUSH_SYMBOL_COLORS 0x208
56#define OUTER_BACKGROUND 0x20C 55#define OUTER_BACKGROUND 0x20C
57#define OUTER_BACKGROUND_MODE 0x21C 56#define OUTER_BACKGROUND_MODE 0x21C
58#define EXTRA_BACK_DISTANCE 0x22C
59#define TRACED_EDGES 0x230 57#define TRACED_EDGES 0x230
60#define AUDIO_PREFIX 0x278 58#define AUDIO_PREFIX 0x278
61#define POWER 0x2A8 59#define POWER 0x2A8
@@ -118,7 +116,6 @@ private:
118#define PUSH_SYMBOL_COLORS 0x200 116#define PUSH_SYMBOL_COLORS 0x200
119#define OUTER_BACKGROUND 0x204 117#define OUTER_BACKGROUND 0x204
120#define OUTER_BACKGROUND_MODE 0x214 118#define OUTER_BACKGROUND_MODE 0x214
121#define EXTRA_BACK_DISTANCE 0x224
122#define TRACED_EDGES 0x228 119#define TRACED_EDGES 0x228
123#define AUDIO_PREFIX 0x270 120#define AUDIO_PREFIX 0x270
124#define POWER 0x2A0 121#define POWER 0x2A0