about summary refs log tree commit diff stats
path: root/Source/ChallengeRandomizer.cpp
diff options
context:
space:
mode:
authorjbzdarkid <jbzdarkid@gmail.com>2018-11-19 09:27:29 -0800
committerjbzdarkid <jbzdarkid@gmail.com>2018-11-19 09:27:29 -0800
commiteb420604814dfdfa37fd542dda9ba7477c198b39 (patch)
tree449794ffbdbe111e48ec7d5dc05fe563339d8f3a /Source/ChallengeRandomizer.cpp
parent0d4ebf34bfb93dbb215f49e9ca64b58fd7284a2b (diff)
downloadwitness-tutorializer-eb420604814dfdfa37fd542dda9ba7477c198b39.tar.gz
witness-tutorializer-eb420604814dfdfa37fd542dda9ba7477c198b39.tar.bz2
witness-tutorializer-eb420604814dfdfa37fd542dda9ba7477c198b39.zip
Cleanup packaging story, add more settings
Diffstat (limited to 'Source/ChallengeRandomizer.cpp')
-rw-r--r--Source/ChallengeRandomizer.cpp218
1 files changed, 123 insertions, 95 deletions
diff --git a/Source/ChallengeRandomizer.cpp b/Source/ChallengeRandomizer.cpp index 0bc51f6..401771e 100644 --- a/Source/ChallengeRandomizer.cpp +++ b/Source/ChallengeRandomizer.cpp
@@ -16,116 +16,33 @@ int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t
16 return -1; 16 return -1;
17} 17}
18 18
19// Reads the (relative!) address of the RNG, then shifts it to point at RNG2
19void ChallengeRandomizer::AdjustRng(int offset) { 20void ChallengeRandomizer::AdjustRng(int offset) {
20 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0]; 21 int currentRng = _memory->ReadData<int>({offset}, 0x1)[0];
21 _memory->WriteData<int>({offset}, {currentRng + 0x20}); 22 _memory->WriteData<int>({offset}, {currentRng + 0x20});
22} 23}
23 24
25// Overwrite the pointer for the lightmap_generator (which is unused, afaict) to point to a secondary RNG.
26// Then, adjust all the RNG functions in challenge/doors to use this RNG.
24ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory) 27ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed) : _memory(memory)
25{ 28{
26 int RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0]; 29 RNG_ADDR = _memory->ReadData<int>({GLOBALS + 0x10}, 1)[0];
27 int RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0]; 30 RNG2_ADDR = _memory->ReadData<int>({GLOBALS + 0x30}, 1)[0];
28 _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4}); 31 bool alreadyInjected = (RNG2_ADDR == RNG_ADDR + 4);
29 if (RNG2_ADDR == RNG_ADDR + 4) return; // Already applied hack 32
33 if (!alreadyInjected) _memory->WriteData<int>({GLOBALS + 0x30}, {RNG_ADDR + 4});
34 _memory->WriteData<int>({GLOBALS + 0x30, 0}, {seed});
30 35
31 int shuffle_integers = -1;
32 int cut_random_edges = -1;
33 int get_empty_decoration_slot = -1;
34 int get_empty_dot_spot = -1;
35 int add_exactly_this_many_bisection_dots = -1;
36 int make_a_shaper = -1;
37 int init_pattern_data_lotus = -1;
38 int reroll_lotus_eater_stuff = -1;
39 int do_lotus_minutes = -1;
40 int do_lotus_eighths = -1;
41 int do_success_side_effects = -1; 36 int do_success_side_effects = -1;
42 37
43 for (int i=0; i<0x200000; i+=0x1000) { 38 for (int i=0; i<0x200000; i+=0x1000) {
44 std::vector<byte> data = _memory->ReadData<byte>({i}, 0x1100); 39 std::vector<byte> data = _memory->ReadData<byte>({i}, 0x1100);
45 std::cout << data.size() << std::endl; 40 std::cout << data.size() << std::endl;
46 41
47 if (shuffle_integers == -1) { 42 if (!alreadyInjected) HandleSigScans(i, data);
48 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01}); 43
49 if (index != -1) {
50 shuffle_integers = i + index;
51 AdjustRng(shuffle_integers + 0x23);
52 }
53 }
54 if (cut_random_edges == -1) {
55 int index = find(data, {0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA});
56 if (index != -1) {
57 cut_random_edges = i + index - 0x22;
58 AdjustRng(cut_random_edges + 0x5D);
59 }
60 }
61 if (get_empty_decoration_slot == -1) {
62 int index = find(data, {0x57, 0x48, 0x83, 0xEC, 0x20, 0x8B, 0xB9, 0x38, 0x04}); // TODO: Sync versions
63 if (index != -1) {
64 get_empty_decoration_slot = i + index - 0x5;
65 AdjustRng(get_empty_decoration_slot + 0x16);
66 }
67 }
68 if (get_empty_dot_spot == -1) {
69 int index = find(data, {0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC}); // TODO: Sync versions
70 if (index != -1) {
71 get_empty_dot_spot = i + index - 0x2E;
72 AdjustRng(get_empty_dot_spot + 0x23);
73 }
74 }
75 if (add_exactly_this_many_bisection_dots == -1) {
76 int index = find(data, {0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00}); // TODO: Sync versions
77 if (index != -1) {
78 add_exactly_this_many_bisection_dots = i + index - 0x20;
79 AdjustRng(add_exactly_this_many_bisection_dots + 0x1C);
80 }
81 }
82 if (make_a_shaper == -1) {
83 int index = find(data, {0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52}); // TODO: Sync versions
84 if (index != -1) {
85 make_a_shaper = i + index - 0x19;
86 AdjustRng(make_a_shaper + 0x9);
87 AdjustRng(make_a_shaper + 0x35);
88 AdjustRng(make_a_shaper + 0x62);
89 }
90 }
91 if (/*Entity_Machine_Panel::*/init_pattern_data_lotus == -1) {
92 int index = find(data, {0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1}); // TODO: Sync versions
93 if (index != -1) {
94 init_pattern_data_lotus = i + index;
95 AdjustRng(init_pattern_data_lotus + 0x433);
96 AdjustRng(init_pattern_data_lotus + 0x45B);
97 AdjustRng(init_pattern_data_lotus + 0x5A7);
98 AdjustRng(init_pattern_data_lotus + 0x5D6);
99 AdjustRng(init_pattern_data_lotus + 0x6F6);
100 AdjustRng(init_pattern_data_lotus + 0xD17);
101 AdjustRng(init_pattern_data_lotus + 0xFDA);
102 }
103 }
104 if (/*Entity_Record_Player::*/reroll_lotus_eater_stuff == -1) {
105 int index = find(data, {0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8}); // TODO: Sync versions
106 if (index != -1) {
107 reroll_lotus_eater_stuff = i + index - 0x37;
108 AdjustRng(reroll_lotus_eater_stuff + 0x24);
109 AdjustRng(reroll_lotus_eater_stuff + 0x6B);
110 }
111 }
112 // These disable the random locations on timer panels, which would otherwise increment the RNG.
113 if (do_lotus_minutes == -1) {
114 int index = find(data, {0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45}); // TODO: Sync versions
115 if (index != -1) {
116 do_lotus_minutes = i + index - 0x2B;
117 _memory->WriteData<byte>({do_lotus_minutes + 0x43B}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
118 _memory->WriteData<byte>({do_lotus_minutes + 0x5B3}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
119 }
120 }
121 if (do_lotus_eighths == -1) {
122 int index = find(data, {0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF}); // TODO: Sync versions
123 if (index != -1) {
124 do_lotus_eighths = i + index - 0x39;
125 _memory->WriteData<byte>({do_lotus_eighths + 0x1E7}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
126 }
127 }
128 // This injection ensures that the seed is set every time the challenge is started. 44 // This injection ensures that the seed is set every time the challenge is started.
45 // We always do this sigscan since it affects the seed.
129 if (do_success_side_effects == -1) { 46 if (do_success_side_effects == -1) {
130 int index = find(data, {0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0}); 47 int index = find(data, {0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0});
131 if (index != -1) { 48 if (index != -1) {
@@ -144,3 +61,114 @@ ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory,
144 } 61 }
145 } 62 }
146} 63}
64
65void ChallengeRandomizer::HandleSigScans(int i, const std::vector<byte>& data) {
66 static int shuffle_integers = -1;
67 static int shuffle_int = -1;
68 static int cut_random_edges = -1;
69 static int get_empty_decoration_slot = -1;
70 static int get_empty_dot_spot = -1;
71 static int add_exactly_this_many_bisection_dots = -1;
72 static int make_a_shaper = -1;
73 static int init_pattern_data_lotus = -1;
74 static int reroll_lotus_eater_stuff = -1;
75 static int do_lotus_minutes = -1;
76 static int do_lotus_tenths = -1;
77 static int do_lotus_eighths = -1;
78
79 if (shuffle_integers == -1) {
80 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01});
81 if (index != -1) {
82 shuffle_integers = i + index;
83 AdjustRng(shuffle_integers + 0x23);
84 }
85 }
86 // shuffle<int>
87 if (shuffle_int == -1) {
88 int index = find(data, {0x33, 0xF6, 0x48, 0x8B, 0xD9, 0x39, 0x31, 0x7E, 0x51});
89 if (index != -1) {
90 shuffle_int = i + index - 0x16;
91 AdjustRng(shuffle_int + 0x12);
92 }
93 }
94 if (cut_random_edges == -1) {
95 int index = find(data, {0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA});
96 if (index != -1) {
97 cut_random_edges = i + index - 0x22;
98 AdjustRng(cut_random_edges + 0x5D);
99 }
100 }
101 if (get_empty_decoration_slot == -1) {
102 int index = find(data, {0x42, 0x83, 0x3C, 0x80, 0x00, 0x75, 0xDF});
103 if (index != -1) {
104 get_empty_decoration_slot = i + index - 0x2D;
105 AdjustRng(get_empty_decoration_slot + 0x16);
106 }
107 }
108 if (get_empty_dot_spot == -1) {
109 int index = find(data, {0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC});
110 if (index != -1) {
111 get_empty_dot_spot = i + index - 0x2E;
112 AdjustRng(get_empty_dot_spot + 0x23);
113 }
114 }
115 if (add_exactly_this_many_bisection_dots == -1) {
116 int index = find(data, {0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00});
117 if (index != -1) {
118 add_exactly_this_many_bisection_dots = i + index - 0x20;
119 AdjustRng(add_exactly_this_many_bisection_dots + 0x1C);
120 }
121 }
122 if (make_a_shaper == -1) {
123 int index = find(data, {0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52});
124 if (index != -1) {
125 make_a_shaper = i + index - 0x19;
126 AdjustRng(make_a_shaper + 0x9);
127 AdjustRng(make_a_shaper + 0x35);
128 AdjustRng(make_a_shaper + 0x62);
129 }
130 }
131 if (/*Entity_Machine_Panel::*/init_pattern_data_lotus == -1) {
132 int index = find(data, {0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1});
133 if (index != -1) {
134 init_pattern_data_lotus = i + index;
135 AdjustRng(init_pattern_data_lotus + 0x433);
136 AdjustRng(init_pattern_data_lotus + 0x45B);
137 AdjustRng(init_pattern_data_lotus + 0x5A7);
138 AdjustRng(init_pattern_data_lotus + 0x5D6);
139 AdjustRng(init_pattern_data_lotus + 0x6F6);
140 AdjustRng(init_pattern_data_lotus + 0xD17);
141 AdjustRng(init_pattern_data_lotus + 0xFDA);
142 }
143 }
144 if (/*Entity_Record_Player::*/reroll_lotus_eater_stuff == -1) {
145 int index = find(data, {0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8});
146 if (index != -1) {
147 reroll_lotus_eater_stuff = i + index - 0x37;
148 AdjustRng(reroll_lotus_eater_stuff + 0x24);
149 AdjustRng(reroll_lotus_eater_stuff + 0x6B);
150 }
151 }
152 // These disable the random locations on timer panels, which would otherwise increment the RNG.
153 if (do_lotus_minutes == -1) {
154 int index = find(data, {0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45});
155 if (index != -1) {
156 do_lotus_minutes = i + index - 0x2B;
157 _memory->WriteData<byte>({do_lotus_minutes + 0x43B}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
158 }
159 }
160 if (do_lotus_tenths == -1) {
161 int index = find(data, {0x00, 0x04, 0x00, 0x00, 0x41, 0x8D, 0x50, 0x09});
162 if (index != -1) {
163 do_lotus_tenths = i + index - 0x61;
164 _memory->WriteData<byte>({do_lotus_tenths + 0x103}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
165 }
166 }
167 if (do_lotus_eighths == -1) {
168 int index = find(data, {0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF});
169 if (index != -1) {
170 do_lotus_eighths = i + index - 0x39;
171 _memory->WriteData<byte>({do_lotus_eighths + 0x1E7}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
172 }
173 }
174} \ No newline at end of file