Mercurial > vba-clojure
view src/common/CheatSearch.cpp @ 498:554883a95de0
discovered gameboy->vga color map.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 11 Jun 2012 10:07:01 -0500 |
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 cheatSearchBlocks11 };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 cheatSearchGE80 };82 static bool (*cheatSearchSignedFunc[])(s32, s32) = {83 cheatSearchSignedEQ,84 cheatSearchSignedNE,85 cheatSearchSignedLT,86 cheatSearchSignedLE,87 cheatSearchSignedGT,88 cheatSearchSignedGE89 };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 else226 {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 else306 {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 }