home *** CD-ROM | disk | FTP | other *** search
- // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
- // Copyright (C) 1999-2003 Forgotten
- // Copyright (C) 2004 Forgotten and the VBA development team
-
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2, or(at your option)
- // any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software Foundation,
- // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- #include <stdlib.h>
- #include <memory.h>
-
- #include "CheatSearch.h"
-
- CheatSearchBlock cheatSearchBlocks[4];
-
- CheatSearchData cheatSearchData = {
- 0,
- cheatSearchBlocks
- };
-
- static bool cheatSearchEQ(u32 a, u32 b)
- {
- return a == b;
- }
-
- static bool cheatSearchNE(u32 a, u32 b)
- {
- return a != b;
- }
-
- static bool cheatSearchLT(u32 a, u32 b)
- {
- return a < b;
- }
-
- static bool cheatSearchLE(u32 a, u32 b)
- {
- return a <= b;
- }
-
- static bool cheatSearchGT(u32 a, u32 b)
- {
- return a > b;
- }
-
- static bool cheatSearchGE(u32 a, u32 b)
- {
- return a >= b;
- }
-
- static bool cheatSearchSignedEQ(s32 a, s32 b)
- {
- return a == b;
- }
-
- static bool cheatSearchSignedNE(s32 a, s32 b)
- {
- return a != b;
- }
-
- static bool cheatSearchSignedLT(s32 a, s32 b)
- {
- return a < b;
- }
-
- static bool cheatSearchSignedLE(s32 a, s32 b)
- {
- return a <= b;
- }
-
- static bool cheatSearchSignedGT(s32 a, s32 b)
- {
- return a > b;
- }
-
- static bool cheatSearchSignedGE(s32 a, s32 b)
- {
- return a >= b;
- }
-
- static bool (*cheatSearchFunc[])(u32,u32) = {
- cheatSearchEQ,
- cheatSearchNE,
- cheatSearchLT,
- cheatSearchLE,
- cheatSearchGT,
- cheatSearchGE
- };
-
- static bool (*cheatSearchSignedFunc[])(s32,s32) = {
- cheatSearchSignedEQ,
- cheatSearchSignedNE,
- cheatSearchSignedLT,
- cheatSearchSignedLE,
- cheatSearchSignedGT,
- cheatSearchSignedGE
- };
-
- void cheatSearchCleanup(CheatSearchData *cs)
- {
- int count = cs->count;
-
- for(int i = 0; i < count; i++) {
- free(cs->blocks[i].saved);
- free(cs->blocks[i].bits);
- }
- cs->count = 0;
- }
-
- void cheatSearchStart(const CheatSearchData *cs)
- {
- int count = cs->count;
-
- for(int i = 0; i < count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
-
- memset(block->bits, 0xff, block->size >> 3);
- memcpy(block->saved, block->data, block->size);
- }
- }
-
- s32 cheatSearchSignedRead(u8 *data, int off, int size)
- {
- u32 res = data[off++];
-
- switch(size) {
- case BITS_8:
- res <<= 24;
- return ((s32)res) >> 24;
- case BITS_16:
- res |= ((u32)data[off++])<<8;
- res <<= 16;
- return ((s32)res) >> 16;
- case BITS_32:
- res |= ((u32)data[off++])<<8;
- res |= ((u32)data[off++])<<16;
- res |= ((u32)data[off++])<<24;
- return (s32)res;
- }
- return (s32)res;
- }
-
- u32 cheatSearchRead(u8 *data, int off, int size)
- {
- u32 res = data[off++];
- if(size == BITS_16)
- res |= ((u32)data[off++])<<8;
- else if(size == BITS_32) {
- res |= ((u32)data[off++])<<8;
- res |= ((u32)data[off++])<<16;
- res |= ((u32)data[off++])<<24;
- }
- return res;
- }
-
- void cheatSearch(const CheatSearchData *cs, int compare, int size,
- bool isSigned)
- {
- if(compare < 0 || compare > SEARCH_GE)
- return;
- int inc = 1;
- if(size == BITS_16)
- inc = 2;
- else if(size == BITS_32)
- inc = 4;
-
- if(isSigned) {
- bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
-
- for(int i = 0; i < cs->count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
- int size2 = block->size;
- u8 *bits = block->bits;
- u8 *data = block->data;
- u8 *saved = block->saved;
-
- for(int j = 0; j < size2; j += inc) {
- if(IS_BIT_SET(bits, j)) {
- s32 a = cheatSearchSignedRead(data, j, size);
- s32 b = cheatSearchSignedRead(saved,j, size);
-
- if(!func(a, b)) {
- CLEAR_BIT(bits, j);
- if(size == BITS_16)
- CLEAR_BIT(bits, j+1);
- if(size == BITS_32) {
- CLEAR_BIT(bits, j+2);
- CLEAR_BIT(bits, j+3);
- }
- }
- }
- }
- }
- } else {
- bool (*func)(u32,u32) = cheatSearchFunc[compare];
-
- for(int i = 0; i < cs->count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
- int size2 = block->size;
- u8 *bits = block->bits;
- u8 *data = block->data;
- u8 *saved = block->saved;
-
- for(int j = 0; j < size2; j += inc) {
- if(IS_BIT_SET(bits, j)) {
- u32 a = cheatSearchRead(data, j, size);
- u32 b = cheatSearchRead(saved,j, size);
-
- if(!func(a, b)) {
- CLEAR_BIT(bits, j);
- if(size == BITS_16)
- CLEAR_BIT(bits, j+1);
- if(size == BITS_32) {
- CLEAR_BIT(bits, j+2);
- CLEAR_BIT(bits, j+3);
- }
- }
- }
- }
- }
- }
- }
-
- void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
- bool isSigned, u32 value)
- {
- if(compare < 0 || compare > SEARCH_GE)
- return;
- int inc = 1;
- if(size == BITS_16)
- inc = 2;
- else if(size == BITS_32)
- inc = 4;
-
- if(isSigned) {
- bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
-
- for(int i = 0; i < cs->count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
- int size2 = block->size;
- u8 *bits = block->bits;
- u8 *data = block->data;
-
- for(int j = 0; j < size2; j += inc) {
- if(IS_BIT_SET(bits, j)) {
- s32 a = cheatSearchSignedRead(data, j, size);
- s32 b = (s32)value;
-
- if(!func(a, b)) {
- CLEAR_BIT(bits, j);
- if(size == BITS_16)
- CLEAR_BIT(bits, j+1);
- if(size == BITS_32) {
- CLEAR_BIT(bits, j+2);
- CLEAR_BIT(bits, j+3);
- }
- }
- }
- }
- }
- } else {
- bool (*func)(u32,u32) = cheatSearchFunc[compare];
-
- for(int i = 0; i < cs->count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
- int size2 = block->size;
- u8 *bits = block->bits;
- u8 *data = block->data;
-
- for(int j = 0; j < size2; j += inc) {
- if(IS_BIT_SET(bits, j)) {
- u32 a = cheatSearchRead(data, j, size);
-
- if(!func(a, value)) {
- CLEAR_BIT(bits, j);
- if(size == BITS_16)
- CLEAR_BIT(bits, j+1);
- if(size == BITS_32) {
- CLEAR_BIT(bits, j+2);
- CLEAR_BIT(bits, j+3);
- }
- }
- }
- }
- }
- }
- }
-
- int cheatSearchGetCount(const CheatSearchData *cs, int size)
- {
- int res = 0;
- int inc = 1;
- if(size == BITS_16)
- inc = 2;
- else if(size == BITS_32)
- inc = 4;
-
- for(int i = 0; i < cs->count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
-
- int size2 = block->size;
- u8 *bits = block->bits;
- for(int j = 0; j < size2; j += inc) {
- if(IS_BIT_SET(bits, j))
- res++;
- }
- }
- return res;
- }
-
- void cheatSearchUpdateValues(const CheatSearchData *cs)
- {
- for(int i = 0; i < cs->count; i++) {
- CheatSearchBlock *block = &cs->blocks[i];
-
- memcpy(block->saved, block->data, block->size);
- }
- }
-
-