annotate src/common/CheatSearch.cpp @ 67:8cb500493ec2

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