home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / CheatSearch.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  6.9 KB  |  330 lines

  1. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
  2. // Copyright (C) 1999-2003 Forgotten
  3. // Copyright (C) 2004 Forgotten and the VBA development team
  4.  
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2, or(at your option)
  8. // any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software Foundation,
  17. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19. #include <stdlib.h>
  20. #include <memory.h>
  21.  
  22. #include "CheatSearch.h"
  23.  
  24. CheatSearchBlock cheatSearchBlocks[4];
  25.  
  26. CheatSearchData cheatSearchData = {
  27.   0,
  28.   cheatSearchBlocks
  29. };
  30.  
  31. static bool cheatSearchEQ(u32 a, u32 b)
  32. {
  33.   return a == b;
  34. }
  35.  
  36. static bool cheatSearchNE(u32 a, u32 b)
  37. {
  38.   return a != b;
  39. }
  40.  
  41. static bool cheatSearchLT(u32 a, u32 b)
  42. {
  43.   return a < b;
  44. }
  45.  
  46. static bool cheatSearchLE(u32 a, u32 b)
  47. {
  48.   return a <= b;
  49. }
  50.  
  51. static bool cheatSearchGT(u32 a, u32 b)
  52. {
  53.   return a > b;
  54. }
  55.  
  56. static bool cheatSearchGE(u32 a, u32 b)
  57. {
  58.   return a >= b;
  59. }
  60.  
  61. static bool cheatSearchSignedEQ(s32 a, s32 b)
  62. {
  63.   return a == b;
  64. }
  65.  
  66. static bool cheatSearchSignedNE(s32 a, s32 b)
  67. {
  68.   return a != b;
  69. }
  70.  
  71. static bool cheatSearchSignedLT(s32 a, s32 b)
  72. {
  73.   return a < b;
  74. }
  75.  
  76. static bool cheatSearchSignedLE(s32 a, s32 b)
  77. {
  78.   return a <= b;
  79. }
  80.  
  81. static bool cheatSearchSignedGT(s32 a, s32 b)
  82. {
  83.   return a > b;
  84. }
  85.  
  86. static bool cheatSearchSignedGE(s32 a, s32 b)
  87. {
  88.   return a >= b;
  89. }
  90.  
  91. static bool (*cheatSearchFunc[])(u32,u32) = {
  92.   cheatSearchEQ,
  93.   cheatSearchNE,
  94.   cheatSearchLT,
  95.   cheatSearchLE,
  96.   cheatSearchGT,
  97.   cheatSearchGE
  98. };
  99.  
  100. static bool (*cheatSearchSignedFunc[])(s32,s32) = {
  101.   cheatSearchSignedEQ,
  102.   cheatSearchSignedNE,
  103.   cheatSearchSignedLT,
  104.   cheatSearchSignedLE,
  105.   cheatSearchSignedGT,
  106.   cheatSearchSignedGE
  107. };
  108.  
  109. void cheatSearchCleanup(CheatSearchData *cs)
  110. {
  111.   int count = cs->count;
  112.  
  113.   for(int i = 0; i < count; i++) {
  114.     free(cs->blocks[i].saved);
  115.     free(cs->blocks[i].bits);
  116.   }
  117.   cs->count = 0;
  118. }
  119.  
  120. void cheatSearchStart(const CheatSearchData *cs)
  121. {
  122.   int count = cs->count;
  123.   
  124.   for(int i = 0; i < count; i++) {
  125.     CheatSearchBlock *block = &cs->blocks[i];
  126.  
  127.     memset(block->bits, 0xff, block->size >> 3);
  128.     memcpy(block->saved, block->data, block->size);
  129.   }
  130. }
  131.  
  132. s32 cheatSearchSignedRead(u8 *data, int off, int size)
  133. {
  134.   u32 res = data[off++];
  135.  
  136.   switch(size) {
  137.   case BITS_8:
  138.     res <<= 24;
  139.     return ((s32)res) >> 24;
  140.   case BITS_16:
  141.     res |= ((u32)data[off++])<<8;
  142.     res <<= 16;
  143.     return ((s32)res) >> 16;
  144.   case BITS_32:
  145.     res |= ((u32)data[off++])<<8;
  146.     res |= ((u32)data[off++])<<16;
  147.     res |= ((u32)data[off++])<<24;
  148.     return (s32)res;
  149.   }
  150.   return (s32)res;
  151. }
  152.  
  153. u32 cheatSearchRead(u8 *data, int off, int size)
  154. {
  155.   u32 res = data[off++];
  156.   if(size == BITS_16)
  157.     res |= ((u32)data[off++])<<8;
  158.   else if(size == BITS_32) {
  159.     res |= ((u32)data[off++])<<8;
  160.     res |= ((u32)data[off++])<<16;
  161.     res |= ((u32)data[off++])<<24;
  162.   }
  163.   return res;
  164. }
  165.  
  166. void cheatSearch(const CheatSearchData *cs, int compare, int size, 
  167.                  bool isSigned)
  168. {
  169.   if(compare < 0 || compare > SEARCH_GE)
  170.     return;
  171.   int inc = 1;
  172.   if(size == BITS_16)
  173.     inc = 2;
  174.   else if(size == BITS_32)
  175.     inc = 4;
  176.  
  177.   if(isSigned) {
  178.     bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
  179.  
  180.     for(int i = 0; i < cs->count; i++) {
  181.       CheatSearchBlock *block = &cs->blocks[i];
  182.       int size2 = block->size;
  183.       u8 *bits = block->bits;
  184.       u8 *data = block->data;
  185.       u8 *saved = block->saved;
  186.       
  187.       for(int j = 0; j < size2; j += inc) {
  188.     if(IS_BIT_SET(bits, j)) {
  189.       s32 a = cheatSearchSignedRead(data, j, size);
  190.       s32 b = cheatSearchSignedRead(saved,j, size);
  191.  
  192.       if(!func(a, b)) {
  193.         CLEAR_BIT(bits, j);
  194.         if(size == BITS_16)
  195.           CLEAR_BIT(bits, j+1);
  196.         if(size == BITS_32) {
  197.           CLEAR_BIT(bits, j+2);
  198.           CLEAR_BIT(bits, j+3);
  199.         }
  200.       }
  201.     }
  202.       }
  203.     }
  204.   } else {
  205.     bool (*func)(u32,u32) = cheatSearchFunc[compare];
  206.  
  207.     for(int i = 0; i < cs->count; i++) {
  208.       CheatSearchBlock *block = &cs->blocks[i];
  209.       int size2 = block->size;
  210.       u8 *bits = block->bits;
  211.       u8 *data = block->data;
  212.       u8 *saved = block->saved;
  213.       
  214.       for(int j = 0; j < size2; j += inc) {
  215.     if(IS_BIT_SET(bits, j)) {
  216.       u32 a = cheatSearchRead(data, j, size);
  217.       u32 b = cheatSearchRead(saved,j, size);
  218.  
  219.       if(!func(a, b)) {
  220.         CLEAR_BIT(bits, j);
  221.         if(size == BITS_16)
  222.           CLEAR_BIT(bits, j+1);
  223.         if(size == BITS_32) {
  224.           CLEAR_BIT(bits, j+2);
  225.           CLEAR_BIT(bits, j+3);
  226.         }
  227.       }
  228.     }
  229.       }
  230.     }
  231.   }
  232. }
  233.  
  234. void cheatSearchValue(const CheatSearchData *cs, int compare, int size, 
  235.               bool isSigned, u32 value)
  236. {
  237.   if(compare < 0 || compare > SEARCH_GE)
  238.     return;
  239.   int inc = 1;
  240.   if(size == BITS_16)
  241.     inc = 2;
  242.   else if(size == BITS_32)
  243.     inc = 4;
  244.  
  245.   if(isSigned) {
  246.     bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
  247.  
  248.     for(int i = 0; i < cs->count; i++) {
  249.       CheatSearchBlock *block = &cs->blocks[i];
  250.       int size2 = block->size;
  251.       u8 *bits = block->bits;
  252.       u8 *data = block->data;
  253.       
  254.       for(int j = 0; j < size2; j += inc) {
  255.     if(IS_BIT_SET(bits, j)) {
  256.       s32 a = cheatSearchSignedRead(data, j, size);
  257.       s32 b = (s32)value;
  258.  
  259.       if(!func(a, b)) {
  260.         CLEAR_BIT(bits, j);
  261.         if(size == BITS_16)
  262.           CLEAR_BIT(bits, j+1);
  263.         if(size == BITS_32) {
  264.           CLEAR_BIT(bits, j+2);
  265.           CLEAR_BIT(bits, j+3);
  266.         }
  267.       }
  268.     }
  269.       }
  270.     }
  271.   } else {
  272.     bool (*func)(u32,u32) = cheatSearchFunc[compare];
  273.  
  274.     for(int i = 0; i < cs->count; i++) {
  275.       CheatSearchBlock *block = &cs->blocks[i];
  276.       int size2 = block->size;
  277.       u8 *bits = block->bits;
  278.       u8 *data = block->data;
  279.       
  280.       for(int j = 0; j < size2; j += inc) {
  281.     if(IS_BIT_SET(bits, j)) {
  282.       u32 a = cheatSearchRead(data, j, size);
  283.  
  284.       if(!func(a, value)) {
  285.         CLEAR_BIT(bits, j);
  286.         if(size == BITS_16)
  287.           CLEAR_BIT(bits, j+1);
  288.         if(size == BITS_32) {
  289.           CLEAR_BIT(bits, j+2);
  290.           CLEAR_BIT(bits, j+3);
  291.         }
  292.       }
  293.     }
  294.       }
  295.     }
  296.   }
  297. }
  298.  
  299. int cheatSearchGetCount(const CheatSearchData *cs, int size) 
  300. {
  301.   int res = 0;
  302.   int inc = 1;
  303.   if(size == BITS_16)
  304.     inc = 2;
  305.   else if(size == BITS_32)
  306.     inc = 4;
  307.  
  308.   for(int i = 0; i < cs->count; i++) {
  309.     CheatSearchBlock *block = &cs->blocks[i];
  310.     
  311.     int size2 = block->size;
  312.     u8 *bits = block->bits;
  313.     for(int j = 0; j < size2; j += inc) {
  314.       if(IS_BIT_SET(bits, j))
  315.     res++;
  316.     }
  317.   }
  318.   return res;
  319. }
  320.  
  321. void cheatSearchUpdateValues(const CheatSearchData *cs)
  322. {
  323.   for(int i = 0; i < cs->count; i++) {
  324.     CheatSearchBlock *block = &cs->blocks[i];
  325.  
  326.     memcpy(block->saved, block->data, block->size);
  327.   }
  328. }
  329.  
  330.