Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "resource.h"
  4. #include "emul.h"
  5. #include "vars.h"
  6.  
  7. #include "gui.h"
  8. #include "dx.h"
  9. #include "util.h"
  10.  
  11. #include "cheat.h"
  12.  
  13. static struct CHEATDLG
  14. {
  15.    HWND dlg;
  16.    HWND resBox;
  17.    HWND resLabel;
  18.  
  19.    void ShowResults();
  20.    void SetControls();
  21.    void Search();
  22.  
  23.    unsigned char *lastsnap;
  24.    unsigned char *bitmask;
  25.    unsigned searchSize;
  26.    int nFound;
  27.    unsigned char wordmode, hex;
  28.  
  29.    CHEATDLG() { lastsnap = nullptr; bitmask = nullptr; nFound = -1; mode = S_NEW; }
  30.    ~CHEATDLG()
  31.    {
  32.        if(lastsnap)
  33.        {
  34.            free(lastsnap);
  35.        }
  36.  
  37.        if(bitmask)
  38.        {
  39.            free(bitmask);
  40.        }
  41.    }
  42.  
  43.    enum SR_MODE { S_NEW, S_VAL, S_INC, S_DEC } mode;
  44.  
  45. } CheatDlg;
  46.  
  47. void CHEATDLG::Search()
  48. {
  49.    if (nFound == -1) searchSize = conf.ramsize*1024;
  50.    searchSize = min(searchSize, conf.ramsize*1024);
  51.  
  52.    bitmask = (unsigned char*)realloc(bitmask, searchSize/8);
  53.    if (nFound == -1) memset(bitmask, 0xFF, searchSize/8);
  54.  
  55.    unsigned i;
  56.  
  57.    switch (mode) {
  58.  
  59.       case S_NEW:
  60.       {
  61.          memset(bitmask, 0xFF, searchSize/8);
  62.          nFound = -1;
  63.          break;
  64.       }
  65.  
  66.       case S_VAL:
  67.       {
  68.          char str[16]; GetDlgItemText(dlg, IDE_VALUE, str, sizeof(str));
  69.          unsigned val; sscanf(str, hex? "%X" : "%d", &val);
  70.          if (wordmode) {
  71.             for (i = 0; i < searchSize-1; i++)
  72.                if (*(WORD*)(memory+i) != (WORD)val)
  73.                   bitmask[i/8] &= ~(1 << (i & 7));
  74.          } else {
  75.             for (i = 0; i < searchSize; i++)
  76.                if (memory[i] != (BYTE)val)
  77.                   bitmask[i/8] &= ~(1 << (i & 7));
  78.          }
  79.          break;
  80.       }
  81.  
  82.       case S_INC:
  83.       case S_DEC:
  84.       {
  85.           unsigned char *ptr1, *ptr2;
  86.           if(mode == S_INC)
  87.           {
  88.               ptr1 = memory;
  89.               ptr2 = lastsnap;
  90.           }
  91.           else
  92.           {
  93.               ptr2 = memory;
  94.               ptr1 = lastsnap;
  95.           }
  96.  
  97.           if(wordmode)
  98.           {
  99.               for(i = 0; i < searchSize - 1; i++)
  100.               {
  101.                   if(*(WORD*)(ptr1 + i) <= *(WORD*)(ptr2 + i))
  102.                   {
  103.                       bitmask[i / 8] &= ~(1 << (i & 7));
  104.                   }
  105.               }
  106.           }
  107.           else
  108.           {
  109.               for(i = 0; i < searchSize; i++)
  110.               {
  111.                   if(ptr1[i] <= ptr2[i])
  112.                   {
  113.                       bitmask[i / 8] &= ~(1 << (i & 7));
  114.                   }
  115.               }
  116.           }
  117.           break;
  118.       }
  119.  
  120.    }
  121.  
  122.    if (wordmode) bitmask[(searchSize-1)/8] &= 0x7F;
  123.  
  124.    if (mode != S_NEW) {
  125.       for (nFound = i = 0; i < searchSize/8; i++) {
  126.          if (!bitmask[i]) continue;
  127.          if (bitmask[i] & 0x01) nFound++;
  128.          if (bitmask[i] & 0x02) nFound++;
  129.          if (bitmask[i] & 0x04) nFound++;
  130.          if (bitmask[i] & 0x08) nFound++;
  131.          if (bitmask[i] & 0x10) nFound++;
  132.          if (bitmask[i] & 0x20) nFound++;
  133.          if (bitmask[i] & 0x40) nFound++;
  134.          if (bitmask[i] & 0x80) nFound++;
  135.       }
  136.    }
  137.  
  138.    lastsnap = (unsigned char*)realloc(lastsnap, searchSize);
  139.    memcpy(lastsnap, memory, searchSize);
  140.    ShowResults();
  141. }
  142.  
  143. void CHEATDLG::SetControls()
  144. {
  145.    int enabled;
  146.  
  147.    setcheck(IDC_HEX, hex);
  148.    setcheck(IDC_BYTE, !wordmode);
  149.    setcheck(IDC_WORD, wordmode);
  150.  
  151.    enabled = lastsnap && (nFound != 0);
  152.    EnableWindow(GetDlgItem(dlg, IDC_DEC), enabled);
  153.    EnableWindow(GetDlgItem(dlg, IDC_INC), enabled);
  154.    if (!enabled && (mode == S_DEC || mode == S_INC)) mode = S_NEW;
  155.  
  156.    enabled = (nFound != 0);
  157.    EnableWindow(GetDlgItem(dlg, IDC_EXACT), enabled);
  158.    if (!enabled && mode == S_VAL) mode = S_NEW;
  159.  
  160.    setcheck(IDC_NEW, (mode == S_NEW));
  161.    setcheck(IDC_EXACT, (mode == S_VAL));
  162.    setcheck(IDC_INC, (mode == S_INC));
  163.    setcheck(IDC_DEC, (mode == S_DEC));
  164.  
  165.    enabled = (nFound == -1);// || (mode == S_NEW);
  166.    EnableWindow(GetDlgItem(dlg, IDC_BYTE), enabled);
  167.    EnableWindow(GetDlgItem(dlg, IDC_WORD), enabled);
  168.  
  169.    enabled = (mode == S_VAL);
  170.    EnableWindow(GetDlgItem(dlg, IDE_VALUE), enabled);
  171.    EnableWindow(GetDlgItem(dlg, IDC_HEX), enabled);
  172. }
  173.  
  174. void CHEATDLG::ShowResults()
  175. {
  176.    if (nFound > 0 && nFound <= 100) {
  177.  
  178.       ShowWindow(resLabel, SW_HIDE);
  179.       ShowWindow(resBox, SW_SHOW);
  180.       SendMessage(resBox, LVM_DELETEALLITEMS, 0, 0);
  181.  
  182.       char fn[10];
  183.       LVITEM item; int count = 0;
  184.       item.mask = LVIF_TEXT;
  185.       item.pszText = fn;
  186.  
  187.       for (unsigned i = 0; i < searchSize; i++) {
  188.          if (!(bitmask[i/8] & (1 << (i & 7)))) continue;
  189.  
  190.          unsigned base = 0xC000;
  191.          unsigned page = i / PAGE;
  192.          if (page == 2) base = 0x8000;
  193.          if (page == 5) base = 0x4000;
  194.  
  195.          sprintf(fn, "%04X", base + (i & (PAGE-1)));
  196.          item.iItem = count++;
  197.          item.iSubItem = 0;
  198.          item.iItem = (int)SendMessage(resBox, LVM_INSERTITEM, 0, (LPARAM) &item);
  199.  
  200.          sprintf(fn, "%02X", page);
  201.          item.iSubItem = 1;
  202.          SendMessage(resBox, LVM_SETITEM, 0, (LPARAM) &item);
  203.  
  204.          sprintf(fn, "%04X", i & (PAGE-1));
  205.          item.iSubItem = 2;
  206.          SendMessage(resBox, LVM_SETITEM, 0, (LPARAM) &item);
  207.  
  208.          if (wordmode) sprintf(fn, "%04X", *(WORD*)(memory+i));
  209.          else sprintf(fn, "%02X", memory[i]);
  210.          item.iSubItem = 3;
  211.          SendMessage(resBox, LVM_SETITEM, 0, (LPARAM) &item);
  212.  
  213.       }
  214.    } else {
  215.       ShowWindow(resBox, SW_HIDE);
  216.       ShowWindow(resLabel, SW_SHOW);
  217.       char str[128];
  218.       if (!lastsnap) strcpy(str, "no active search");
  219.       else if (nFound == -1) strcpy(str, "new search started");
  220.       else if (!nFound) strcpy(str, "found nothing");
  221.       else sprintf(str, "result list too large (%d entries)", nFound);
  222.       SetWindowText(resLabel, str);
  223.    }
  224. }
  225.  
  226. static INT_PTR CALLBACK cheatdlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  227. {
  228.     (void)lp;
  229.  
  230.    if (msg == WM_INITDIALOG) {
  231.  
  232.       ::dlg = CheatDlg.dlg = dlg;
  233.       CheatDlg.resLabel = GetDlgItem(dlg, IDC_STATUS);
  234.       CheatDlg.resBox = GetDlgItem(dlg, IDC_RESULTS);
  235.  
  236.       unsigned exflags = LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT;
  237.       SendMessage(CheatDlg.resBox, LVM_SETEXTENDEDLISTVIEWSTYLE, exflags, exflags);
  238.  
  239.       LVCOLUMN sizeCol;
  240.       sizeCol.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  241.       sizeCol.fmt = LVCFMT_LEFT;
  242.  
  243.       sizeCol.cx = 50;
  244.       sizeCol.pszText = LPSTR("Address");
  245.       SendMessage(CheatDlg.resBox, LVM_INSERTCOLUMN, 0, (LPARAM)&sizeCol);
  246.  
  247.       sizeCol.cx = 40;
  248.       sizeCol.pszText = LPSTR("Page");
  249.       SendMessage(CheatDlg.resBox, LVM_INSERTCOLUMN, 1, (LPARAM)&sizeCol);
  250.  
  251.       sizeCol.cx = 50;
  252.       sizeCol.pszText = LPSTR("Offset");
  253.       SendMessage(CheatDlg.resBox, LVM_INSERTCOLUMN, 2, (LPARAM)&sizeCol);
  254.  
  255.       sizeCol.cx = 50;
  256.       sizeCol.pszText = LPSTR("Value");
  257.       SendMessage(CheatDlg.resBox, LVM_INSERTCOLUMN, 3, (LPARAM)&sizeCol);
  258.  
  259.       // SetFocus(GetDlgItem(dlg, IDE_VALUE));
  260.       SendDlgItemMessage(dlg, IDE_VALUE, EM_LIMITTEXT, 5, 0);
  261.       CheatDlg.SetControls();
  262.       CheatDlg.ShowResults();
  263.       return 1;
  264.    }
  265.  
  266.    if ((msg == WM_COMMAND && wp == IDCANCEL) ||
  267.        (msg == WM_SYSCOMMAND && (wp & 0xFFF0) == SC_CLOSE)) EndDialog(dlg, 0);
  268.  
  269.    if (msg == WM_COMMAND && HIWORD(wp) == BN_CLICKED)
  270.    {
  271.       int id = LOWORD(wp);
  272.       if (id == IDC_NEW) CheatDlg.mode = CHEATDLG::S_NEW;
  273.       else if (id == IDC_EXACT) CheatDlg.mode = CHEATDLG::S_VAL;
  274.       else if (id == IDC_INC) CheatDlg.mode = CHEATDLG::S_INC;
  275.       else if (id == IDC_DEC) CheatDlg.mode = CHEATDLG::S_DEC;
  276.       else if (id == IDC_HEX) CheatDlg.hex = getcheck(id);
  277.       else if (id == IDC_BYTE) CheatDlg.wordmode = 0;
  278.       else if (id == IDC_WORD) CheatDlg.wordmode = 1;
  279.       else if (id == IDB_SEARCH) CheatDlg.Search();
  280.       else id = 0;
  281.  
  282.       if (id) CheatDlg.SetControls();
  283.    }
  284.  
  285.    return 0;
  286. }
  287.  
  288. void main_cheat()
  289. {
  290.    OnEnterGui();
  291.    DialogBox(hIn, MAKEINTRESOURCE(IDD_CHEAT), wnd, cheatdlg);
  292.    eat();
  293.    OnExitGui();
  294. }
  295.