c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator\r |
2 | *\r |
3 | * Copyright notice for this file:\r |
4 | * Copyright (C) 2002 Ben Parnell\r |
5 | *\r |
6 | * This program is free software; you can redistribute it and/or modify\r |
7 | * it under the terms of the GNU General Public License as published by\r |
8 | * the Free Software Foundation; either version 2 of the License, or\r |
9 | * (at your option) any later version.\r |
10 | *\r |
11 | * This program is distributed in the hope that it will be useful,\r |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of\r |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r |
14 | * GNU General Public License for more details.\r |
15 | *\r |
16 | * You should have received a copy of the GNU General Public License\r |
17 | * along with this program; if not, write to the Free Software\r |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r |
19 | */\r |
20 | \r |
21 | #include "common.h"\r |
22 | \r |
23 | #include "cheat.h"\r |
24 | \r |
25 | static int selcheat;\r |
26 | static int scheatmethod=0;\r |
27 | static uint8 cheatval1=0;\r |
28 | static uint8 cheatval2=0;\r |
29 | \r |
30 | static void ConfigAddCheat(HWND wnd);\r |
31 | \r |
32 | \r |
33 | static uint16 StrToU16(char *s)\r |
34 | {\r |
35 | unsigned int ret=0;\r |
36 | sscanf(s,"%4x",&ret);\r |
37 | return ret;\r |
38 | }\r |
39 | \r |
40 | static uint8 StrToU8(char *s)\r |
41 | {\r |
42 | unsigned int ret=0;\r |
43 | sscanf(s,"%d",&ret);\r |
44 | return ret;\r |
45 | }\r |
46 | \r |
47 | \r |
48 | /* Need to be careful where these functions are used. */\r |
49 | static char *U16ToStr(uint16 a)\r |
50 | {\r |
51 | static char TempArray[16];\r |
52 | sprintf(TempArray,"%04X",a);\r |
53 | return TempArray;\r |
54 | }\r |
55 | \r |
56 | static char *U8ToStr(uint8 a)\r |
57 | {\r |
58 | static char TempArray[16];\r |
59 | sprintf(TempArray,"%03d",a);\r |
60 | return TempArray;\r |
61 | }\r |
62 | \r |
63 | \r |
64 | static HWND RedoCheatsWND;\r |
65 | static int RedoCheatsCallB(char *name, uint32 a, uint8 v, int s)\r |
66 | {\r |
67 | SendDlgItemMessage(RedoCheatsWND,101,LB_ADDSTRING,0,(LPARAM)(LPSTR)name);\r |
68 | return(1);\r |
69 | }\r |
70 | \r |
71 | static void RedoCheatsLB(HWND hwndDlg)\r |
72 | {\r |
73 | SendDlgItemMessage(hwndDlg,101,LB_RESETCONTENT,0,0);\r |
74 | RedoCheatsWND=hwndDlg;\r |
75 | FCEUI_ListCheats(RedoCheatsCallB);\r |
76 | }\r |
77 | \r |
78 | \r |
79 | BOOL CALLBACK CheatsConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r |
80 | {\r |
81 | switch(uMsg)\r |
82 | {\r |
83 | case WM_INITDIALOG: \r |
84 | RedoCheatsLB(hwndDlg);\r |
85 | break;\r |
86 | case WM_CLOSE:\r |
87 | case WM_QUIT: goto gornk;\r |
88 | case WM_COMMAND:\r |
89 | switch(HIWORD(wParam))\r |
90 | {\r |
91 | case BN_CLICKED:\r |
92 | if(selcheat>=0)\r |
93 | {\r |
94 | if(LOWORD(wParam)==107)\r |
95 | FCEUI_SetCheat(selcheat,0,-1,-1,1);\r |
96 | else if(LOWORD(wParam)==108)\r |
97 | FCEUI_SetCheat(selcheat,0,-1,-1,0);\r |
98 | }\r |
99 | break;\r |
100 | case EN_KILLFOCUS:\r |
101 | if(selcheat>=0)\r |
102 | {\r |
103 | char TempArray[256];\r |
104 | int32 t;\r |
105 | \r |
106 | GetDlgItemText(hwndDlg,LOWORD(wParam),TempArray,256);\r |
107 | switch(LOWORD(wParam))\r |
108 | {\r |
109 | case 102:FCEUI_SetCheat(selcheat,TempArray,-1,-1,-1);\r |
110 | SendDlgItemMessage(hwndDlg,101,LB_INSERTSTRING,selcheat,(LPARAM)(LPCTSTR)TempArray);\r |
111 | SendDlgItemMessage(hwndDlg,101,LB_DELETESTRING,selcheat+1,0);\r |
112 | SendDlgItemMessage(hwndDlg,101,LB_SETCURSEL,selcheat,0);\r |
113 | break;\r |
114 | case 103:t=StrToU16(TempArray);\r |
115 | FCEUI_SetCheat(selcheat,0,t,-1,-1);\r |
116 | break;\r |
117 | case 104:t=StrToU8(TempArray);\r |
118 | FCEUI_SetCheat(selcheat,0,-1,t,-1);\r |
119 | break;\r |
120 | }\r |
121 | }\r |
122 | break;\r |
123 | }\r |
124 | \r |
125 | switch(LOWORD(wParam))\r |
126 | {\r |
127 | case 101:\r |
128 | if(HIWORD(wParam)==LBN_SELCHANGE)\r |
129 | {\r |
130 | char *s;\r |
131 | uint32 a;\r |
132 | uint8 b;\r |
133 | int status;\r |
134 | \r |
135 | selcheat=SendDlgItemMessage(hwndDlg,101,LB_GETCURSEL,0,(LPARAM)(LPSTR)0);\r |
136 | if(selcheat<0) break;\r |
137 | \r |
138 | FCEUI_GetCheat(selcheat,&s,&a,&b,&status);\r |
139 | SetDlgItemText(hwndDlg,102,(LPTSTR)s);\r |
140 | SetDlgItemText(hwndDlg,103,(LPTSTR)U16ToStr(a));\r |
141 | SetDlgItemText(hwndDlg,104,(LPTSTR)U8ToStr(b));\r |
142 | \r |
143 | CheckRadioButton(hwndDlg,107,108,status?107:108);\r |
144 | }\r |
145 | break;\r |
146 | }\r |
147 | \r |
148 | if(!(wParam>>16))\r |
149 | switch(wParam&0xFFFF)\r |
150 | {\r |
151 | case 106:\r |
152 | if(selcheat>=0)\r |
153 | {\r |
154 | FCEUI_DelCheat(selcheat);\r |
155 | SendDlgItemMessage(hwndDlg,101,LB_DELETESTRING,selcheat,0);\r |
156 | selcheat=-1;\r |
157 | SetDlgItemText(hwndDlg,102,(LPTSTR)"");\r |
158 | SetDlgItemText(hwndDlg,103,(LPTSTR)"");\r |
159 | SetDlgItemText(hwndDlg,104,(LPTSTR)"");\r |
160 | CheckRadioButton(hwndDlg,107,108,0); // Is this correct?\r |
161 | }\r |
162 | break;\r |
163 | case 105:\r |
164 | ConfigAddCheat(hwndDlg);\r |
165 | RedoCheatsLB(hwndDlg);\r |
166 | break;\r |
167 | case 1:\r |
168 | gornk:\r |
169 | EndDialog(hwndDlg,0);\r |
170 | break;\r |
171 | }\r |
172 | }\r |
173 | return 0;\r |
174 | }\r |
175 | \r |
176 | \r |
177 | void ConfigCheats(HWND hParent)\r |
178 | {\r |
179 | if(!GI)\r |
180 | {\r |
181 | FCEUD_PrintError("You must have a game loaded before you can manipulate cheats.");\r |
182 | return;\r |
183 | }\r |
184 | \r |
185 | if(GI->type==GIT_NSF)\r |
186 | {\r |
187 | FCEUD_PrintError("Sorry, you can't cheat with NSFs.");\r |
188 | return;\r |
189 | }\r |
190 | \r |
191 | selcheat=-1;\r |
192 | DialogBox(fceu_hInstance,"CHEATS",hParent,CheatsConCallB);\r |
193 | }\r |
194 | \r |
195 | \r |
196 | \r |
197 | \r |
198 | \r |
199 | \r |
200 | HWND cfcallbw;\r |
201 | \r |
202 | int cfcallb(uint32 a, uint8 last, uint8 current)\r |
203 | {\r |
204 | char temp[16];\r |
205 | \r |
206 | sprintf(temp,"%04X:%03d:%03d",(unsigned int)a,last,current);\r |
207 | SendDlgItemMessage(cfcallbw,108,LB_ADDSTRING,0,(LPARAM)(LPSTR)temp);\r |
208 | return(1);\r |
209 | }\r |
210 | \r |
211 | static int scrollindex;\r |
212 | static int scrollnum;\r |
213 | static int scrollmax;\r |
214 | \r |
215 | int cfcallbinsert(uint32 a, uint8 last, uint8 current)\r |
216 | {\r |
217 | char temp[16];\r |
218 | \r |
219 | sprintf(temp,"%04X:%03d:%03d",(unsigned int)a,last,current);\r |
220 | SendDlgItemMessage(cfcallbw,108,LB_INSERTSTRING,13,(LPARAM)(LPSTR)temp);\r |
221 | return(1);\r |
222 | }\r |
223 | \r |
224 | int cfcallbinsertt(uint32 a, uint8 last, uint8 current)\r |
225 | {\r |
226 | char temp[16];\r |
227 | \r |
228 | sprintf(temp,"%04X:%03d:%03d",(unsigned int)a,last,current);\r |
229 | SendDlgItemMessage(cfcallbw,108,LB_INSERTSTRING,0,(LPARAM)(LPSTR)temp);\r |
230 | return(1);\r |
231 | }\r |
232 | \r |
233 | \r |
234 | void AddTheThing(HWND hwndDlg, char *s, int a, int v)\r |
235 | {\r |
236 | if(FCEUI_AddCheat(s,a,v))\r |
237 | MessageBox(hwndDlg,"Cheat Added","Cheat Added",MB_OK);\r |
238 | }\r |
239 | \r |
240 | \r |
241 | static void DoGet(void)\r |
242 | {\r |
243 | int n=FCEUI_CheatSearchGetCount();\r |
244 | int t;\r |
245 | scrollnum=n;\r |
246 | scrollindex=-32768;\r |
247 | \r |
248 | SendDlgItemMessage(cfcallbw,108,LB_RESETCONTENT,0,0);\r |
249 | FCEUI_CheatSearchGetRange(0,13,cfcallb);\r |
250 | \r |
251 | t=-32768+n-1-13;\r |
252 | if(t<-32768)\r |
253 | t=-32768;\r |
254 | scrollmax=t;\r |
255 | SendDlgItemMessage(cfcallbw,120,SBM_SETRANGE,-32768,t);\r |
256 | SendDlgItemMessage(cfcallbw,120,SBM_SETPOS,-32768,1);\r |
257 | }\r |
258 | \r |
259 | \r |
260 | BOOL CALLBACK AddCheatCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r |
261 | {\r |
262 | static int lbfocus;\r |
263 | static HWND hwndLB;\r |
264 | cfcallbw=hwndDlg;\r |
265 | \r |
266 | \r |
267 | switch(uMsg)\r |
268 | { \r |
269 | case WM_VSCROLL:\r |
270 | if(scrollnum>13)\r |
271 | {\r |
272 | switch((int)LOWORD(wParam))\r |
273 | {\r |
274 | case SB_TOP:\r |
275 | scrollindex=-32768;\r |
276 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
277 | SendDlgItemMessage(hwndDlg,108,LB_RESETCONTENT,13,0);\r |
278 | FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+13,cfcallb);\r |
279 | break;\r |
280 | case SB_BOTTOM:\r |
281 | scrollindex=scrollmax;\r |
282 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
283 | SendDlgItemMessage(hwndDlg,108,LB_RESETCONTENT,13,0);\r |
284 | FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+13,cfcallb);\r |
285 | break;\r |
286 | case SB_LINEUP:\r |
287 | if(scrollindex>-32768)\r |
288 | {\r |
289 | scrollindex--;\r |
290 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
291 | SendDlgItemMessage(hwndDlg,108,LB_DELETESTRING,13,0);\r |
292 | FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768,cfcallbinsertt);\r |
293 | }\r |
294 | break;\r |
295 | \r |
296 | case SB_PAGEUP:\r |
297 | scrollindex-=14;\r |
298 | if(scrollindex<-32768) scrollindex=-32768;\r |
299 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
300 | SendDlgItemMessage(hwndDlg,108,LB_RESETCONTENT,13,0);\r |
301 | FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+13,cfcallb);\r |
302 | break;\r |
303 | \r |
304 | case SB_LINEDOWN:\r |
305 | if(scrollindex<scrollmax)\r |
306 | {\r |
307 | scrollindex++;\r |
308 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
309 | SendDlgItemMessage(hwndDlg,108,LB_DELETESTRING,0,0);\r |
310 | FCEUI_CheatSearchGetRange(scrollindex+32768+13,scrollindex+32768+13,cfcallbinsert);\r |
311 | }\r |
312 | break;\r |
313 | \r |
314 | case SB_PAGEDOWN:\r |
315 | scrollindex+=14;\r |
316 | if(scrollindex>scrollmax)\r |
317 | scrollindex=scrollmax;\r |
318 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
319 | SendDlgItemMessage(hwndDlg,108,LB_RESETCONTENT,0,0);\r |
320 | FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+13,cfcallb);\r |
321 | break;\r |
322 | \r |
323 | case SB_THUMBPOSITION:\r |
324 | case SB_THUMBTRACK:\r |
325 | scrollindex=(short int)HIWORD(wParam);\r |
326 | SendDlgItemMessage(hwndDlg,120,SBM_SETPOS,scrollindex,1);\r |
327 | SendDlgItemMessage(hwndDlg,108,LB_RESETCONTENT,0,0);\r |
328 | FCEUI_CheatSearchGetRange(32768+scrollindex,32768+scrollindex+13,cfcallb);\r |
329 | break;\r |
330 | }\r |
331 | \r |
332 | } \r |
333 | break;\r |
334 | \r |
335 | case WM_INITDIALOG:\r |
336 | SetDlgItemText(hwndDlg,110,(LPTSTR)U8ToStr(cheatval1));\r |
337 | SetDlgItemText(hwndDlg,111,(LPTSTR)U8ToStr(cheatval2));\r |
338 | DoGet();\r |
339 | CheckRadioButton(hwndDlg,115,118,scheatmethod+115);\r |
340 | lbfocus=0;\r |
341 | hwndLB=0;\r |
342 | break;\r |
343 | \r |
344 | case WM_VKEYTOITEM:\r |
345 | if(lbfocus)\r |
346 | {\r |
347 | int real;\r |
348 | \r |
349 | real=SendDlgItemMessage(hwndDlg,108,LB_GETCURSEL,0,(LPARAM)(LPSTR)0);\r |
350 | switch((int)LOWORD(wParam))\r |
351 | {\r |
352 | case VK_UP: \r |
353 | /* mmmm....recursive goodness */\r |
354 | if(!real)\r |
355 | SendMessage(hwndDlg,WM_VSCROLL,SB_LINEUP,0);\r |
356 | return(-1);\r |
357 | break;\r |
358 | case VK_DOWN:\r |
359 | if(real==13)\r |
360 | SendMessage(hwndDlg,WM_VSCROLL,SB_LINEDOWN,0);\r |
361 | return(-1);\r |
362 | break;\r |
363 | case VK_PRIOR:\r |
364 | SendMessage(hwndDlg,WM_VSCROLL,SB_PAGEUP,0);\r |
365 | break;\r |
366 | case VK_NEXT:\r |
367 | SendMessage(hwndDlg,WM_VSCROLL,SB_PAGEDOWN,0);\r |
368 | break;\r |
369 | case VK_HOME:\r |
370 | SendMessage(hwndDlg,WM_VSCROLL,SB_TOP,0);\r |
371 | break;\r |
372 | case VK_END:\r |
373 | SendMessage(hwndDlg,WM_VSCROLL,SB_BOTTOM,0);\r |
374 | break;\r |
375 | }\r |
376 | return(-2);\r |
377 | }\r |
378 | break;\r |
379 | \r |
380 | case WM_CLOSE:\r |
381 | case WM_QUIT: goto gornk;\r |
382 | case WM_COMMAND:\r |
383 | switch(LOWORD(wParam))\r |
384 | {\r |
385 | case 108:\r |
386 | switch(HIWORD(wParam))\r |
387 | {\r |
388 | case LBN_SELCHANGE:\r |
389 | {\r |
390 | char TempArray[32];\r |
391 | SendDlgItemMessage(hwndDlg,108,LB_GETTEXT,SendDlgItemMessage(hwndDlg,108,LB_GETCURSEL,0,(LPARAM)(LPSTR)0),(LPARAM)(LPCTSTR)TempArray);\r |
392 | TempArray[4]=0;\r |
393 | SetDlgItemText(hwndDlg,201,(LPTSTR)TempArray); \r |
394 | }\r |
395 | break;\r |
396 | case LBN_SETFOCUS:\r |
397 | lbfocus=1;\r |
398 | break;\r |
399 | case LBN_KILLFOCUS:\r |
400 | lbfocus=0;\r |
401 | break;\r |
402 | }\r |
403 | break;\r |
404 | }\r |
405 | \r |
406 | switch(HIWORD(wParam))\r |
407 | {\r |
408 | case BN_CLICKED:\r |
409 | if(LOWORD(wParam)>=115 && LOWORD(wParam)<=118)\r |
410 | scheatmethod=LOWORD(wParam)-115;\r |
411 | break;\r |
412 | case EN_CHANGE:\r |
413 | {\r |
414 | char TempArray[256];\r |
415 | GetDlgItemText(hwndDlg,LOWORD(wParam),TempArray,256);\r |
416 | switch(LOWORD(wParam))\r |
417 | {\r |
418 | case 110:cheatval1=StrToU8(TempArray);break;\r |
419 | case 111:cheatval2=StrToU8(TempArray);break;\r |
420 | }\r |
421 | }\r |
422 | break;\r |
423 | }\r |
424 | \r |
425 | \r |
426 | if(!(wParam>>16))\r |
427 | switch(wParam&0xFFFF)\r |
428 | {\r |
429 | case 112:\r |
430 | FCEUI_CheatSearchBegin();\r |
431 | DoGet();\r |
432 | break;\r |
433 | case 113:\r |
434 | FCEUI_CheatSearchEnd(scheatmethod,cheatval1,cheatval2);\r |
435 | DoGet();\r |
436 | break;\r |
437 | case 114:\r |
438 | FCEUI_CheatSearchSetCurrentAsOriginal();\r |
439 | DoGet();\r |
440 | break;\r |
441 | case 107:\r |
442 | FCEUI_CheatSearchShowExcluded();\r |
443 | DoGet();\r |
444 | break;\r |
445 | case 105:\r |
446 | {\r |
447 | int a,v;\r |
448 | char temp[256];\r |
449 | \r |
450 | GetDlgItemText(hwndDlg,201,temp,4+1);\r |
451 | a=StrToU16(temp);\r |
452 | GetDlgItemText(hwndDlg,202,temp,3+1);\r |
453 | v=StrToU8(temp);\r |
454 | \r |
455 | GetDlgItemText(hwndDlg,200,temp,256);\r |
456 | AddTheThing(hwndDlg,temp,a,v);\r |
457 | }\r |
458 | break;\r |
459 | case 106:\r |
460 | gornk:\r |
461 | EndDialog(hwndDlg,0);\r |
462 | break;\r |
463 | }\r |
464 | }\r |
465 | return 0;\r |
466 | }\r |
467 | \r |
468 | static void ConfigAddCheat(HWND wnd)\r |
469 | {\r |
470 | DialogBox(fceu_hInstance,"ADDCHEAT",wnd,AddCheatCallB);\r |
471 | }\r |