view src/common/CheatSearch.cpp @ 68:86093f2ce7d1

got the speedrun to play
author Robert McIntyre <rlm@mit.edu>
date Thu, 08 Mar 2012 02:10:03 -0600
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include <cstdlib>
2 #include <cstring>
4 #include "CheatSearch.h"
6 CheatSearchBlock cheatSearchBlocks[4];
8 CheatSearchData cheatSearchData = {
9 0,
10 cheatSearchBlocks
11 };
13 static bool cheatSearchEQ(u32 a, u32 b)
14 {
15 return a == b;
16 }
18 static bool cheatSearchNE(u32 a, u32 b)
19 {
20 return a != b;
21 }
23 static bool cheatSearchLT(u32 a, u32 b)
24 {
25 return a < b;
26 }
28 static bool cheatSearchLE(u32 a, u32 b)
29 {
30 return a <= b;
31 }
33 static bool cheatSearchGT(u32 a, u32 b)
34 {
35 return a > b;
36 }
38 static bool cheatSearchGE(u32 a, u32 b)
39 {
40 return a >= b;
41 }
43 static bool cheatSearchSignedEQ(s32 a, s32 b)
44 {
45 return a == b;
46 }
48 static bool cheatSearchSignedNE(s32 a, s32 b)
49 {
50 return a != b;
51 }
53 static bool cheatSearchSignedLT(s32 a, s32 b)
54 {
55 return a < b;
56 }
58 static bool cheatSearchSignedLE(s32 a, s32 b)
59 {
60 return a <= b;
61 }
63 static bool cheatSearchSignedGT(s32 a, s32 b)
64 {
65 return a > b;
66 }
68 static bool cheatSearchSignedGE(s32 a, s32 b)
69 {
70 return a >= b;
71 }
73 static bool (*cheatSearchFunc[])(u32, u32) = {
74 cheatSearchEQ,
75 cheatSearchNE,
76 cheatSearchLT,
77 cheatSearchLE,
78 cheatSearchGT,
79 cheatSearchGE
80 };
82 static bool (*cheatSearchSignedFunc[])(s32, s32) = {
83 cheatSearchSignedEQ,
84 cheatSearchSignedNE,
85 cheatSearchSignedLT,
86 cheatSearchSignedLE,
87 cheatSearchSignedGT,
88 cheatSearchSignedGE
89 };
91 void cheatSearchSetSavedAndBits(CheatSearchBlock *block)
92 {
93 if (!block->saved)
94 {
95 block->saved = (u8 *)malloc(block->size);
96 memcpy(block->saved, block->data, block->size);
97 }
98 if (!block->bits)
99 {
100 block->bits = (u8 *)malloc(block->size >> 3);
101 memset(block->bits, 0xff, block->size >> 3);
102 }
103 }
105 void cheatSearchZeroBlock(CheatSearchBlock *block)
106 {
107 block->data = 0;
108 block->offset = 0;
109 block->size = 0;
110 free(block->saved);
111 free(block->bits);
112 block->saved = 0;
113 block->bits = 0;
114 }
116 void cheatSearchCleanup(CheatSearchData *cs)
117 {
118 int count = cs->count;
120 for (int i = 0; i < count; i++)
121 {
122 CheatSearchBlock &block = cs->blocks[i];
123 free(block.saved);
124 free(block.bits);
125 block.saved = 0;
126 block.bits = 0;
127 }
128 cs->count = 0;
129 }
131 void cheatSearchStart(const CheatSearchData *cs)
132 {
133 int count = cs->count;
135 for (int i = 0; i < count; i++)
136 {
137 CheatSearchBlock *block = &cs->blocks[i];
139 memset(block->bits, 0xff, block->size >> 3);
140 memcpy(block->saved, block->data, block->size);
141 }
142 }
144 s32 cheatSearchSignedRead(u8 *data, int off, int size)
145 {
146 u32 res = data[off++];
148 switch (size)
149 {
150 case BITS_8:
151 res <<= 24;
152 return ((s32)res) >> 24;
153 case BITS_16:
154 res |= ((u32)data[off++])<<8;
155 res <<= 16;
156 return ((s32)res) >> 16;
157 case BITS_32:
158 res |= ((u32)data[off++])<<8;
159 res |= ((u32)data[off++])<<16;
160 res |= ((u32)data[off++])<<24;
161 return (s32)res;
162 }
163 return (s32)res;
164 }
166 u32 cheatSearchRead(u8 *data, int off, int size)
167 {
168 u32 res = data[off++];
169 if (size == BITS_16)
170 res |= ((u32)data[off++])<<8;
171 else if (size == BITS_32)
172 {
173 res |= ((u32)data[off++])<<8;
174 res |= ((u32)data[off++])<<16;
175 res |= ((u32)data[off++])<<24;
176 }
177 return res;
178 }
180 void cheatSearch(const CheatSearchData *cs, int compare, int size,
181 bool isSigned)
182 {
183 if (compare < 0 || compare > SEARCH_GE)
184 return;
185 int inc = 1;
186 if (size == BITS_16)
187 inc = 2;
188 else if (size == BITS_32)
189 inc = 4;
191 if (isSigned)
192 {
193 bool (*func)(s32, s32) = cheatSearchSignedFunc[compare];
195 for (int i = 0; i < cs->count; i++)
196 {
197 CheatSearchBlock *block = &cs->blocks[i];
198 int size2 = block->size;
199 u8 *bits = block->bits;
200 u8 *data = block->data;
201 u8 *saved = block->saved;
203 for (int j = 0; j < size2; j += inc)
204 {
205 if (IS_BIT_SET(bits, j))
206 {
207 s32 a = cheatSearchSignedRead(data, j, size);
208 s32 b = cheatSearchSignedRead(saved, j, size);
210 if (!func(a, b))
211 {
212 CLEAR_BIT(bits, j);
213 if (size == BITS_16)
214 CLEAR_BIT(bits, j+1);
215 if (size == BITS_32)
216 {
217 CLEAR_BIT(bits, j+2);
218 CLEAR_BIT(bits, j+3);
219 }
220 }
221 }
222 }
223 }
224 }
225 else
226 {
227 bool (*func)(u32, u32) = cheatSearchFunc[compare];
229 for (int i = 0; i < cs->count; i++)
230 {
231 CheatSearchBlock *block = &cs->blocks[i];
232 int size2 = block->size;
233 u8 *bits = block->bits;
234 u8 *data = block->data;
235 u8 *saved = block->saved;
237 for (int j = 0; j < size2; j += inc)
238 {
239 if (IS_BIT_SET(bits, j))
240 {
241 u32 a = cheatSearchRead(data, j, size);
242 u32 b = cheatSearchRead(saved, j, size);
244 if (!func(a, b))
245 {
246 CLEAR_BIT(bits, j);
247 if (size == BITS_16)
248 CLEAR_BIT(bits, j+1);
249 if (size == BITS_32)
250 {
251 CLEAR_BIT(bits, j+2);
252 CLEAR_BIT(bits, j+3);
253 }
254 }
255 }
256 }
257 }
258 }
259 }
261 void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
262 bool isSigned, u32 value)
263 {
264 if (compare < 0 || compare > SEARCH_GE)
265 return;
266 int inc = 1;
267 if (size == BITS_16)
268 inc = 2;
269 else if (size == BITS_32)
270 inc = 4;
272 if (isSigned)
273 {
274 bool (*func)(s32, s32) = cheatSearchSignedFunc[compare];
276 for (int i = 0; i < cs->count; i++)
277 {
278 CheatSearchBlock *block = &cs->blocks[i];
279 int size2 = block->size;
280 u8 *bits = block->bits;
281 u8 *data = block->data;
283 for (int j = 0; j < size2; j += inc)
284 {
285 if (IS_BIT_SET(bits, j))
286 {
287 s32 a = cheatSearchSignedRead(data, j, size);
288 s32 b = (s32)value;
290 if (!func(a, b))
291 {
292 CLEAR_BIT(bits, j);
293 if (size == BITS_16)
294 CLEAR_BIT(bits, j+1);
295 if (size == BITS_32)
296 {
297 CLEAR_BIT(bits, j+2);
298 CLEAR_BIT(bits, j+3);
299 }
300 }
301 }
302 }
303 }
304 }
305 else
306 {
307 bool (*func)(u32, u32) = cheatSearchFunc[compare];
309 for (int i = 0; i < cs->count; i++)
310 {
311 CheatSearchBlock *block = &cs->blocks[i];
312 int size2 = block->size;
313 u8 *bits = block->bits;
314 u8 *data = block->data;
316 for (int j = 0; j < size2; j += inc)
317 {
318 if (IS_BIT_SET(bits, j))
319 {
320 u32 a = cheatSearchRead(data, j, size);
322 if (!func(a, value))
323 {
324 CLEAR_BIT(bits, j);
325 if (size == BITS_16)
326 CLEAR_BIT(bits, j+1);
327 if (size == BITS_32)
328 {
329 CLEAR_BIT(bits, j+2);
330 CLEAR_BIT(bits, j+3);
331 }
332 }
333 }
334 }
335 }
336 }
337 }
339 int cheatSearchGetCount(const CheatSearchData *cs, int size)
340 {
341 int res = 0;
342 int inc = 1;
343 if (size == BITS_16)
344 inc = 2;
345 else if (size == BITS_32)
346 inc = 4;
348 for (int i = 0; i < cs->count; i++)
349 {
350 CheatSearchBlock *block = &cs->blocks[i];
352 int size2 = block->size;
353 u8 *bits = block->bits;
354 for (int j = 0; j < size2; j += inc)
355 {
356 if (IS_BIT_SET(bits, j))
357 res++;
358 }
359 }
360 return res;
361 }
363 void cheatSearchUpdateValues(const CheatSearchData *cs)
364 {
365 for (int i = 0; i < cs->count; i++)
366 {
367 CheatSearchBlock *block = &cs->blocks[i];
369 memcpy(block->saved, block->data, block->size);
370 }
371 }