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