Mercurial > vba-linux
comparison src/win32/GBCheatsDlg.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // GBCheats.cpp : implementation file | |
2 // | |
3 | |
4 #include "stdafx.h" | |
5 #include "resource.h" | |
6 #include "GBCheatsDlg.h" | |
7 #include "Reg.h" | |
8 #include "StringTokenizer.h" | |
9 #include "WinResUtil.h" | |
10 #include "Sound.h" | |
11 #include "VBA.h" | |
12 | |
13 #include "../common/CheatSearch.h" | |
14 #include "../gb/gbCheats.h" | |
15 #include "../gb/gbGlobals.h" | |
16 | |
17 static inline bool winGbCheatAddVerifyGs(const char *code, const char *desc) | |
18 { | |
19 gbAddGsCheat(code, desc); | |
20 return true; | |
21 } | |
22 | |
23 static inline bool winGbCheatAddVerifyGg(const char *code, const char *desc) | |
24 { | |
25 gbAddGgCheat(code, desc); | |
26 return true; | |
27 } | |
28 | |
29 //////////////////////////////// | |
30 | |
31 bool winGbCheatReaddress() | |
32 { | |
33 if (cheatSearchData.count != 3) | |
34 return false; | |
35 | |
36 CheatSearchBlock *block = &cheatSearchData.blocks[0]; | |
37 if (gbRamSize > 0) | |
38 { | |
39 if (gbRam) | |
40 block->data = gbRam; | |
41 else | |
42 block->data = &gbMemory[0xa000]; | |
43 block->offset = 0xa000; | |
44 block->size = gbRamSize; | |
45 cheatSearchSetSavedAndBits(block); | |
46 } | |
47 else | |
48 { | |
49 cheatSearchZeroBlock(&cheatSearchData.blocks[0]); | |
50 } | |
51 | |
52 block = &cheatSearchData.blocks[1]; | |
53 if (gbCgbMode) | |
54 { | |
55 block->data = &gbMemory[0xc000]; | |
56 block->offset = 0xc000; | |
57 block->size = 0x1000; | |
58 cheatSearchSetSavedAndBits(block); | |
59 | |
60 block = &cheatSearchData.blocks[2]; | |
61 block->data = gbWram; | |
62 block->offset = 0xd000; | |
63 block->size = 0x8000; | |
64 cheatSearchSetSavedAndBits(block); | |
65 } | |
66 else | |
67 { | |
68 block->data = &gbMemory[0xc000]; | |
69 block->offset = 0xc000; | |
70 block->size = 0x2000; | |
71 cheatSearchSetSavedAndBits(block); | |
72 | |
73 cheatSearchZeroBlock(&cheatSearchData.blocks[2]); | |
74 } | |
75 | |
76 cheatSearchData.count = 3; | |
77 return true; | |
78 } | |
79 | |
80 ///////////////////////////////////////////////////////////////////////////// | |
81 // GBCheatSearch dialog | |
82 | |
83 GBCheatSearch::GBCheatSearch(CWnd*pParent /*=NULL*/) | |
84 : CDialog(GBCheatSearch::IDD, pParent) | |
85 { | |
86 //{{AFX_DATA_INIT(GBCheatSearch) | |
87 searchType = -1; | |
88 numberType = -1; | |
89 sizeType = -1; | |
90 updateValues = FALSE; | |
91 valueType = -1; | |
92 //}}AFX_DATA_INIT | |
93 data = NULL; | |
94 } | |
95 | |
96 GBCheatSearch::~GBCheatSearch() | |
97 { | |
98 if (data) | |
99 free(data); | |
100 } | |
101 | |
102 void GBCheatSearch::DoDataExchange(CDataExchange*pDX) | |
103 { | |
104 CDialog::DoDataExchange(pDX); | |
105 //{{AFX_DATA_MAP(GBCheatSearch) | |
106 DDX_Control(pDX, IDC_VALUE, m_value); | |
107 DDX_Control(pDX, IDC_CHEAT_LIST, m_list); | |
108 DDX_Radio(pDX, IDC_EQ, searchType); | |
109 DDX_Radio(pDX, IDC_SIGNED, numberType); | |
110 DDX_Radio(pDX, IDC_SIZE_8, sizeType); | |
111 DDX_Check(pDX, IDC_UPDATE, updateValues); | |
112 DDX_Radio(pDX, IDC_OLD_VALUE, valueType); | |
113 //}}AFX_DATA_MAP | |
114 } | |
115 | |
116 BEGIN_MESSAGE_MAP(GBCheatSearch, CDialog) | |
117 //{{AFX_MSG_MAP(GBCheatSearch) | |
118 ON_BN_CLICKED(ID_OK, OnOk) | |
119 ON_BN_CLICKED(IDC_ADD_CHEAT, OnAddCheat) | |
120 ON_BN_CLICKED(IDC_SEARCH, OnSearch) | |
121 ON_BN_CLICKED(IDC_START, OnStart) | |
122 ON_BN_CLICKED(IDC_UPDATE, OnUpdate) | |
123 ON_NOTIFY(LVN_GETDISPINFO, IDC_CHEAT_LIST, OnGetdispinfoCheatList) | |
124 ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHEAT_LIST, OnItemchangedCheatList) | |
125 ON_CONTROL_RANGE(BN_CLICKED, IDC_OLD_VALUE, IDC_SPECIFIC_VALUE, OnValueType) | |
126 ON_CONTROL_RANGE(BN_CLICKED, IDC_EQ, IDC_GE, OnSearchType) | |
127 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIGNED, IDC_HEXADECIMAL, OnNumberType) | |
128 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIZE_8, IDC_SIZE_32, OnSizeType) | |
129 //}}AFX_MSG_MAP | |
130 ON_WM_CLOSE() | |
131 ON_BN_CLICKED(IDC_CHEATREFRESHBUTTON, OnBnClickedCheatrefreshbutton) | |
132 END_MESSAGE_MAP() | |
133 | |
134 ///////////////////////////////////////////////////////////////////////////// | |
135 // GBCheatSearch message handlers | |
136 | |
137 void GBCheatSearch::OnOk() | |
138 { | |
139 if (data) | |
140 free(data); | |
141 data = NULL; | |
142 | |
143 if (theApp.modelessCheatDialogIsOpen) | |
144 { | |
145 theApp.modelessCheatDialogIsOpen = false; | |
146 DestroyWindow(); | |
147 } | |
148 else | |
149 { | |
150 EndDialog(TRUE); | |
151 } | |
152 } | |
153 | |
154 void GBCheatSearch::OnClose() | |
155 { | |
156 CDialog::OnClose(); | |
157 if (theApp.modelessCheatDialogIsOpen) | |
158 { | |
159 theApp.modelessCheatDialogIsOpen = false; | |
160 DestroyWindow(); | |
161 } | |
162 else | |
163 { | |
164 EndDialog(FALSE); | |
165 } | |
166 } | |
167 | |
168 void GBCheatSearch::OnBnClickedCheatrefreshbutton() | |
169 { | |
170 addChanges(false); | |
171 } | |
172 | |
173 void GBCheatSearch::OnAddCheat() | |
174 { | |
175 int mark = m_list.GetSelectionMark(); | |
176 | |
177 if (mark != -1) | |
178 { | |
179 LVITEM item; | |
180 memset(&item, 0, sizeof(item)); | |
181 item.mask = LVIF_PARAM; | |
182 item.iItem = mark; | |
183 if (m_list.GetItem(&item)) | |
184 { | |
185 AddGBCheat dlg((u32)item.lParam); | |
186 dlg.DoModal(); | |
187 } | |
188 } | |
189 } | |
190 | |
191 void GBCheatSearch::OnSearch() | |
192 { | |
193 CString buffer; | |
194 if (valueType == 0) | |
195 cheatSearch(&cheatSearchData, | |
196 searchType, | |
197 sizeType, | |
198 numberType == 0); | |
199 else | |
200 { | |
201 m_value.GetWindowText(buffer); | |
202 if (buffer.IsEmpty()) | |
203 { | |
204 systemMessage(IDS_NUMBER_CANNOT_BE_EMPTY, "Number cannot be empty"); | |
205 return; | |
206 } | |
207 int value = 0; | |
208 switch (numberType) | |
209 { | |
210 case 0: | |
211 sscanf(buffer, "%d", &value); | |
212 break; | |
213 case 1: | |
214 sscanf(buffer, "%u", &value); | |
215 break; | |
216 default: | |
217 sscanf(buffer, "%x", &value); | |
218 } | |
219 cheatSearchValue(&cheatSearchData, | |
220 searchType, | |
221 sizeType, | |
222 numberType == 0, | |
223 value); | |
224 } | |
225 | |
226 addChanges(true); | |
227 | |
228 if (updateValues) | |
229 cheatSearchUpdateValues(&cheatSearchData); | |
230 | |
231 if (theApp.modelessCheatDialogIsOpen) | |
232 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData, sizeType) == 0 ? FALSE : TRUE); | |
233 | |
234 if (0 == cheatSearchGetCount(&cheatSearchData, sizeType)) | |
235 OnStart(); | |
236 } | |
237 | |
238 void GBCheatSearch::OnStart() | |
239 { | |
240 if (cheatSearchData.count == 0) | |
241 { | |
242 CheatSearchBlock *block = &cheatSearchData.blocks[0]; | |
243 if (gbRamSize > 0) | |
244 { | |
245 if (gbRam) | |
246 block->data = gbRam; | |
247 else | |
248 block->data = &gbMemory[0xa000]; | |
249 block->size = gbRamSize; | |
250 block->offset = 0xa000; | |
251 block->saved = (u8 *)malloc(gbRamSize); | |
252 block->bits = (u8 *)malloc(gbRamSize >> 3); | |
253 } | |
254 else | |
255 { | |
256 cheatSearchZeroBlock(&cheatSearchData.blocks[0]); | |
257 } | |
258 | |
259 block = &cheatSearchData.blocks[1]; | |
260 if (gbCgbMode) | |
261 { | |
262 block->data = &gbMemory[0xc000]; | |
263 block->size = 0x1000; | |
264 block->offset = 0xc000; | |
265 block->saved = (u8 *)malloc(0x1000); | |
266 block->bits = (u8 *)malloc(0x1000 >> 3); | |
267 | |
268 block = &cheatSearchData.blocks[2]; | |
269 block->data = gbWram; | |
270 block->size = 0x8000; | |
271 block->offset = 0xd000; | |
272 block->saved = (u8 *)malloc(0x8000); | |
273 block->bits = (u8 *)malloc(0x8000 >> 3); | |
274 } | |
275 else | |
276 { | |
277 block->data = &gbMemory[0xc000]; | |
278 block->size = 0x2000; | |
279 block->offset = 0xc000; | |
280 block->saved = (u8 *)malloc(0x2000); | |
281 block->bits = (u8 *)malloc(0x2000 >> 3); | |
282 | |
283 cheatSearchZeroBlock(&cheatSearchData.blocks[2]); | |
284 } | |
285 | |
286 cheatSearchData.count = 3; | |
287 } | |
288 | |
289 cheatSearchStart(&cheatSearchData); | |
290 GetDlgItem(IDC_SEARCH)->EnableWindow(TRUE); | |
291 | |
292 if (theApp.modelessCheatDialogIsOpen) | |
293 { | |
294 GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE); | |
295 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE); | |
296 } | |
297 } | |
298 | |
299 void GBCheatSearch::OnUpdate() | |
300 { | |
301 if (GetDlgItem(IDC_UPDATE)->SendMessage(BM_GETCHECK, | |
302 0, | |
303 0) & BST_CHECKED) | |
304 updateValues = true; | |
305 else | |
306 updateValues = false; | |
307 regSetDwordValue("gbCheatsUpdate", updateValues); | |
308 } | |
309 | |
310 BOOL GBCheatSearch::OnInitDialog() | |
311 { | |
312 CDialog::OnInitDialog(); | |
313 | |
314 CString temp = winResLoadString(IDS_ADDRESS); | |
315 | |
316 m_list.InsertColumn(0, temp, LVCFMT_CENTER, 125, 0); | |
317 | |
318 temp = winResLoadString(IDS_OLD_VALUE); | |
319 m_list.InsertColumn(1, temp, LVCFMT_CENTER, 125, 1); | |
320 | |
321 temp = winResLoadString(IDS_NEW_VALUE); | |
322 m_list.InsertColumn(2, temp, LVCFMT_CENTER, 125, 2); | |
323 | |
324 m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)), | |
325 TRUE); | |
326 | |
327 m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT); | |
328 | |
329 if (!cheatSearchData.count) | |
330 { | |
331 GetDlgItem(IDC_SEARCH)->EnableWindow(FALSE); | |
332 GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(FALSE); | |
333 } | |
334 | |
335 valueType = regQueryDwordValue("gbCheatsValueType", 0); | |
336 if (valueType < 0 || valueType > 1) | |
337 valueType = 2; | |
338 | |
339 searchType = regQueryDwordValue("gbCheatsSearchType", | |
340 SEARCH_EQ); | |
341 if (searchType < 0 || searchType > 5) | |
342 searchType = 0; | |
343 | |
344 numberType = regQueryDwordValue("gbCheatsNumberType", 2); | |
345 if (numberType < 0 || numberType > 2) | |
346 numberType = 2; | |
347 | |
348 sizeType = regQueryDwordValue("gbCheatsSizeType", 0); | |
349 if (sizeType < 0 || sizeType > 2) | |
350 sizeType = 0; | |
351 | |
352 updateValues = regQueryDwordValue("gbCheatsUpdate", 0) ? | |
353 true : false; | |
354 | |
355 UpdateData(FALSE); | |
356 | |
357 if (valueType == 0) | |
358 m_value.EnableWindow(FALSE); | |
359 | |
360 CenterWindow(); | |
361 | |
362 if (theApp.modelessCheatDialogIsOpen) | |
363 GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE); | |
364 | |
365 if (cheatSearchData.count) | |
366 { | |
367 addChanges(false); | |
368 if (theApp.modelessCheatDialogIsOpen) | |
369 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData, | |
370 sizeType) == 0 ? FALSE : TRUE); | |
371 } | |
372 else | |
373 { | |
374 if (theApp.modelessCheatDialogIsOpen) | |
375 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE); | |
376 } | |
377 | |
378 return TRUE; // return TRUE unless you set the focus to a control | |
379 // EXCEPTION: OCX Property Pages should return FALSE | |
380 } | |
381 | |
382 void GBCheatSearch::OnGetdispinfoCheatList(NMHDR*pNMHDR, LRESULT*pResult) | |
383 { | |
384 LV_DISPINFO*info = (LV_DISPINFO *)pNMHDR; | |
385 if (info->item.mask & LVIF_TEXT) | |
386 { | |
387 int index = info->item.iItem; | |
388 int col = info->item.iSubItem; | |
389 | |
390 switch (col) | |
391 { | |
392 case 0: | |
393 strcpy(info->item.pszText, data[index].address); | |
394 break; | |
395 case 1: | |
396 strcpy(info->item.pszText, data[index].oldValue); | |
397 break; | |
398 case 2: | |
399 strcpy(info->item.pszText, data[index].newValue); | |
400 break; | |
401 } | |
402 } | |
403 *pResult = TRUE; | |
404 } | |
405 | |
406 void GBCheatSearch::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult) | |
407 { | |
408 GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(m_list.GetSelectionMark() != -1); | |
409 } | |
410 | |
411 int GBCheatSearch::getBank(u16 addr, int j) | |
412 { | |
413 switch (addr >> 12) | |
414 { | |
415 case 0x0a: | |
416 return j / 0x2000; | |
417 case 0x0d: | |
418 return j / 0x1000; | |
419 } | |
420 return 0; | |
421 } | |
422 | |
423 void GBCheatSearch::addChange(int index, int bank, u16 address, int offset, u32 oldValue, u32 newValue) | |
424 { | |
425 data[index].bank = bank; | |
426 if (bank) | |
427 { | |
428 if (address == 0xa000) | |
429 address |= offset & 0x1fff; | |
430 else | |
431 address |= offset & 0xfff; | |
432 } | |
433 else | |
434 address |= offset; | |
435 data[index].addr = address; | |
436 sprintf(data[index].address, "%02x:%04x", bank, address); | |
437 switch (numberType) | |
438 { | |
439 case 0: | |
440 sprintf(data[index].oldValue, "%d", oldValue); | |
441 sprintf(data[index].newValue, "%d", newValue); | |
442 break; | |
443 case 1: | |
444 sprintf(data[index].oldValue, "%u", oldValue); | |
445 sprintf(data[index].newValue, "%u", newValue); | |
446 break; | |
447 case 2: | |
448 switch (sizeType) | |
449 { | |
450 case 0: | |
451 sprintf(data[index].oldValue, "%02x", oldValue); | |
452 sprintf(data[index].newValue, "%02x", newValue); | |
453 break; | |
454 case 1: | |
455 sprintf(data[index].oldValue, "%04x", oldValue); | |
456 sprintf(data[index].newValue, "%04x", newValue); | |
457 break; | |
458 case 2: | |
459 sprintf(data[index].oldValue, "%08x", oldValue); | |
460 sprintf(data[index].newValue, "%08x", newValue); | |
461 break; | |
462 } | |
463 } | |
464 } | |
465 | |
466 void GBCheatSearch::addChanges(bool showMsg) | |
467 { | |
468 int count = cheatSearchGetCount(&cheatSearchData, sizeType); | |
469 | |
470 m_list.DeleteAllItems(); | |
471 | |
472 if (count > 4000) | |
473 { | |
474 if (showMsg) | |
475 systemMessage( | |
476 IDS_SEARCH_PRODUCED_TOO_MANY, | |
477 "Search produced %d results.\nThey have been remembered, but are too many to display.\nPlease refine it better by performing additional searches.", | |
478 count); | |
479 return; | |
480 } | |
481 | |
482 if (count == 0) | |
483 { | |
484 if (showMsg) | |
485 systemMessage(IDS_SEARCH_PRODUCED_NO_RESULTS, "Search produced no results"); | |
486 return; | |
487 } | |
488 | |
489 m_list.SetItemCount(count); | |
490 if (data) | |
491 free(data); | |
492 | |
493 data = (WinGbCheatsData *)calloc(count, sizeof(WinGbCheatsData)); | |
494 | |
495 int inc = 1; | |
496 switch (sizeType) | |
497 { | |
498 case 1: | |
499 inc = 2; | |
500 break; | |
501 case 2: | |
502 inc = 4; | |
503 break; | |
504 } | |
505 | |
506 int index = 0; | |
507 if (numberType == 0) | |
508 { | |
509 for (int i = 0; i < cheatSearchData.count; i++) | |
510 { | |
511 CheatSearchBlock *block = &cheatSearchData.blocks[i]; | |
512 | |
513 for (int j = 0; j < block->size; j += inc) | |
514 { | |
515 if (IS_BIT_SET(block->bits, j)) | |
516 { | |
517 addChange(index++, | |
518 getBank(block->offset|j, j), | |
519 block->offset, | |
520 j, | |
521 cheatSearchSignedRead(block->saved, | |
522 j, | |
523 sizeType), | |
524 cheatSearchSignedRead(block->data, | |
525 j, | |
526 sizeType)); | |
527 } | |
528 } | |
529 } | |
530 } | |
531 else | |
532 { | |
533 for (int i = 0; i < cheatSearchData.count; i++) | |
534 { | |
535 CheatSearchBlock *block = &cheatSearchData.blocks[i]; | |
536 | |
537 for (int j = 0; j < block->size; j += inc) | |
538 { | |
539 if (IS_BIT_SET(block->bits, j)) | |
540 { | |
541 addChange(index++, | |
542 getBank(block->offset|j, j), | |
543 block->offset, | |
544 j, | |
545 cheatSearchRead(block->saved, | |
546 j, | |
547 sizeType), | |
548 cheatSearchRead(block->data, | |
549 j, | |
550 sizeType)); | |
551 } | |
552 } | |
553 } | |
554 } | |
555 | |
556 for (int i = 0; i < count; i++) | |
557 { | |
558 LVITEM item; | |
559 | |
560 item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; | |
561 item.iItem = i; | |
562 item.iSubItem = 0; | |
563 item.lParam = data[i].addr| | |
564 (data[i].bank << 16); | |
565 item.state = 0; | |
566 item.stateMask = 0; | |
567 item.pszText = LPSTR_TEXTCALLBACK; | |
568 m_list.InsertItem(&item); | |
569 | |
570 m_list.SetItemText(i, 1, LPSTR_TEXTCALLBACK); | |
571 m_list.SetItemText(i, 2, LPSTR_TEXTCALLBACK); | |
572 } | |
573 } | |
574 | |
575 void GBCheatSearch::OnValueType(UINT id) | |
576 { | |
577 switch (id) | |
578 { | |
579 case IDC_OLD_VALUE: | |
580 valueType = 0; | |
581 m_value.EnableWindow(FALSE); | |
582 regSetDwordValue("gbCheatsValueType", 0); | |
583 break; | |
584 case IDC_SPECIFIC_VALUE: | |
585 valueType = 1; | |
586 m_value.EnableWindow(TRUE); | |
587 regSetDwordValue("gbCheatsValueType", 1); | |
588 break; | |
589 } | |
590 } | |
591 | |
592 void GBCheatSearch::OnSearchType(UINT id) | |
593 { | |
594 switch (id) | |
595 { | |
596 case IDC_EQ: | |
597 searchType = SEARCH_EQ; | |
598 regSetDwordValue("gbCheatsSearchType", 0); | |
599 break; | |
600 case IDC_NE: | |
601 searchType = SEARCH_NE; | |
602 regSetDwordValue("gbCheatsSearchType", 1); | |
603 break; | |
604 case IDC_LT: | |
605 searchType = SEARCH_LT; | |
606 regSetDwordValue("gbCheatsSearchType", 2); | |
607 break; | |
608 case IDC_LE: | |
609 searchType = SEARCH_LE; | |
610 regSetDwordValue("gbCheatsSearchType", 3); | |
611 break; | |
612 case IDC_GT: | |
613 searchType = SEARCH_GT; | |
614 regSetDwordValue("gbCheatsSearchType", 4); | |
615 break; | |
616 case IDC_GE: | |
617 searchType = SEARCH_GE; | |
618 regSetDwordValue("gbCheatsSearchType", 5); | |
619 break; | |
620 } | |
621 } | |
622 | |
623 void GBCheatSearch::OnNumberType(UINT id) | |
624 { | |
625 switch (id) | |
626 { | |
627 case IDC_SIGNED: | |
628 numberType = 0; | |
629 regSetDwordValue("gbCheatsNumberType", 0); | |
630 if (m_list.GetItemCount()) | |
631 { | |
632 addChanges(false); | |
633 } | |
634 break; | |
635 case IDC_UNSIGNED: | |
636 numberType = 1; | |
637 regSetDwordValue("gbCheatsNumberType", 1); | |
638 if (m_list.GetItemCount()) | |
639 { | |
640 addChanges(false); | |
641 } | |
642 break; | |
643 case IDC_HEXADECIMAL: | |
644 numberType = 2; | |
645 regSetDwordValue("gbCheatsNumberType", 2); | |
646 if (m_list.GetItemCount()) | |
647 { | |
648 addChanges(false); | |
649 } | |
650 break; | |
651 } | |
652 } | |
653 | |
654 void GBCheatSearch::OnSizeType(UINT id) | |
655 { | |
656 switch (id) | |
657 { | |
658 case IDC_SIZE_8: | |
659 sizeType = BITS_8; | |
660 regSetDwordValue("gbCheatsSizeType", 0); | |
661 if (m_list.GetItemCount()) | |
662 { | |
663 addChanges(false); | |
664 } | |
665 break; | |
666 case IDC_SIZE_16: | |
667 sizeType = BITS_16; | |
668 regSetDwordValue("gbCheatsSizeType", 1); | |
669 if (m_list.GetItemCount()) | |
670 { | |
671 addChanges(false); | |
672 } | |
673 break; | |
674 case IDC_SIZE_32: | |
675 sizeType = BITS_32; | |
676 regSetDwordValue("gbCheatsSizeType", 2); | |
677 if (m_list.GetItemCount()) | |
678 { | |
679 addChanges(false); | |
680 } | |
681 break; | |
682 } | |
683 } | |
684 | |
685 ///////////////////////////////////////////////////////////////////////////// | |
686 // AddGBCheat dialog | |
687 | |
688 AddGBCheat::AddGBCheat(u32 addr, CWnd*pParent /*=NULL*/) | |
689 : CDialog(AddGBCheat::IDD, pParent) | |
690 { | |
691 //{{AFX_DATA_INIT(AddGBCheat) | |
692 numberType = regQueryDwordValue("gbCheatsNumberType", 2); | |
693 if (numberType < 0 || numberType > 2) | |
694 numberType = 2; | |
695 sizeType = regQueryDwordValue("gbCheatsSizeType", 0); | |
696 if (sizeType < 0 || sizeType > 2) | |
697 sizeType = 0; | |
698 //}}AFX_DATA_INIT | |
699 address = addr; | |
700 } | |
701 | |
702 void AddGBCheat::DoDataExchange(CDataExchange*pDX) | |
703 { | |
704 CDialog::DoDataExchange(pDX); | |
705 //{{AFX_DATA_MAP(AddGBCheat) | |
706 DDX_Control(pDX, IDC_VALUE, m_value); | |
707 DDX_Control(pDX, IDC_ADDRESS, m_address); | |
708 DDX_Control(pDX, IDC_DESC, m_desc); | |
709 DDX_Radio(pDX, IDC_SIZE_8, sizeType); | |
710 DDX_Radio(pDX, IDC_SIGNED, numberType); | |
711 //}}AFX_DATA_MAP | |
712 } | |
713 | |
714 BEGIN_MESSAGE_MAP(AddGBCheat, CDialog) | |
715 //{{AFX_MSG_MAP(AddGBCheat) | |
716 ON_BN_CLICKED(ID_OK, OnOk) | |
717 ON_BN_CLICKED(ID_CANCEL, OnCancel) | |
718 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIGNED, IDC_HEXADECIMAL, OnNumberType) | |
719 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIZE_8, IDC_SIZE_32, OnSizeType) | |
720 //}}AFX_MSG_MAP | |
721 END_MESSAGE_MAP() | |
722 | |
723 ///////////////////////////////////////////////////////////////////////////// | |
724 // AddGBCheat message handlers | |
725 | |
726 void AddGBCheat::OnCancel() | |
727 { | |
728 EndDialog(FALSE); | |
729 } | |
730 | |
731 void AddGBCheat::OnOk() | |
732 { | |
733 // add cheat | |
734 if (addCheat()) | |
735 { | |
736 EndDialog(TRUE); | |
737 } | |
738 } | |
739 | |
740 bool AddGBCheat::addCheat() | |
741 { | |
742 CString buffer; | |
743 CString code; | |
744 | |
745 u32 value; | |
746 m_value.GetWindowText(buffer); | |
747 | |
748 if (buffer.IsEmpty()) | |
749 { | |
750 systemMessage(IDS_VALUE_CANNOT_BE_EMPTY, "Value cannot be empty"); | |
751 return false; | |
752 } | |
753 | |
754 switch (numberType) | |
755 { | |
756 case 0: | |
757 sscanf(buffer, "%d", &value); | |
758 break; | |
759 case 1: | |
760 sscanf(buffer, "%u", &value); | |
761 break; | |
762 default: | |
763 sscanf(buffer, "%x", &value); | |
764 } | |
765 | |
766 m_desc.GetWindowText(buffer); | |
767 | |
768 int bank = (address >> 16); | |
769 address &= 0xFFFF; | |
770 | |
771 if (address >= 0xd000) | |
772 bank += 0x90; | |
773 else | |
774 bank = 0x01; | |
775 | |
776 switch (sizeType) | |
777 { | |
778 case 0: | |
779 code.Format("%02X%02X%02X%02X", bank, value, address&0xFF, address>>8); | |
780 gbAddGsCheat(code, buffer); | |
781 break; | |
782 case 1: | |
783 code.Format("%02X%02X%02X%02X", bank, value&0xFF, address&0xFF, | |
784 address>>8); | |
785 gbAddGsCheat(code, buffer); | |
786 address++; | |
787 code.Format("%02X%02X%02X%02X", bank, value>>8, address&0xFF, | |
788 address>>8); | |
789 gbAddGsCheat(code, buffer); | |
790 break; | |
791 case 2: | |
792 code.Format("%02X%02X%02X%02X", bank, value&0xFF, address&0xFF, | |
793 address>>8); | |
794 gbAddGsCheat(code, buffer); | |
795 address++; | |
796 code.Format("%02X%02X%02X%02X", bank, (value>>8) & 0xFF, address&0xFF, | |
797 address>>8); | |
798 gbAddGsCheat(code, buffer); | |
799 address++; | |
800 code.Format("%02X%02X%02X%02X", bank, (value>>16)&0xFF, address&0xFF, | |
801 address>>8); | |
802 gbAddGsCheat(code, buffer); | |
803 address++; | |
804 code.Format("%02X%02X%02X%02X", bank, value>>24, address&0xFF, | |
805 address>>8); | |
806 gbAddGsCheat(code, buffer); | |
807 break; | |
808 } | |
809 | |
810 return true; | |
811 } | |
812 | |
813 BOOL AddGBCheat::OnInitDialog() | |
814 { | |
815 CDialog::OnInitDialog(); | |
816 | |
817 CString buffer; | |
818 buffer.Format("%02x:%08x", (address>>16), address&0xFFFF); | |
819 m_address.SetWindowText(buffer); | |
820 m_address.EnableWindow(FALSE); | |
821 ::SetWindowLong(m_address, | |
822 GWL_USERDATA, | |
823 address); | |
824 | |
825 UpdateData(FALSE); | |
826 | |
827 m_desc.LimitText(32); | |
828 | |
829 if (address != 0) | |
830 { | |
831 GetDlgItem(IDC_SIZE_8)->EnableWindow(FALSE); | |
832 GetDlgItem(IDC_SIZE_16)->EnableWindow(FALSE); | |
833 GetDlgItem(IDC_SIZE_32)->EnableWindow(FALSE); | |
834 GetDlgItem(IDC_HEXADECIMAL)->EnableWindow(FALSE); | |
835 GetDlgItem(IDC_UNSIGNED)->EnableWindow(FALSE); | |
836 GetDlgItem(IDC_SIGNED)->EnableWindow(FALSE); | |
837 } | |
838 CenterWindow(); | |
839 | |
840 return TRUE; // return TRUE unless you set the focus to a control | |
841 // EXCEPTION: OCX Property Pages should return FALSE | |
842 } | |
843 | |
844 void AddGBCheat::OnNumberType(UINT id) | |
845 { | |
846 switch (id) | |
847 { | |
848 case IDC_SIGNED: | |
849 numberType = 0; | |
850 regSetDwordValue("gbCheatsNumberType", 0); | |
851 break; | |
852 case IDC_UNSIGNED: | |
853 numberType = 1; | |
854 regSetDwordValue("gbCheatsNumberType", 1); | |
855 break; | |
856 case IDC_HEXADECIMAL: | |
857 numberType = 2; | |
858 regSetDwordValue("gbCheatsNumberType", 2); | |
859 break; | |
860 } | |
861 } | |
862 | |
863 void AddGBCheat::OnSizeType(UINT id) | |
864 { | |
865 switch (id) | |
866 { | |
867 case IDC_SIZE_8: | |
868 sizeType = BITS_8; | |
869 regSetDwordValue("gbCheatsSizeType", 0); | |
870 break; | |
871 case IDC_SIZE_16: | |
872 sizeType = BITS_16; | |
873 regSetDwordValue("gbCheatsSizeType", 1); | |
874 break; | |
875 case IDC_SIZE_32: | |
876 sizeType = BITS_32; | |
877 regSetDwordValue("gbCheatsSizeType", 2); | |
878 break; | |
879 } | |
880 } | |
881 | |
882 ///////////////////////////////////////////////////////////////////////////// | |
883 // GBCheatList dialog | |
884 | |
885 GBCheatList::GBCheatList(CWnd*pParent /*=NULL*/) | |
886 : CDialog(GBCheatList::IDD, pParent) | |
887 { | |
888 //{{AFX_DATA_INIT(GBCheatList) | |
889 // NOTE: the ClassWizard will add member initialization here | |
890 //}}AFX_DATA_INIT | |
891 duringRefresh = false; | |
892 } | |
893 | |
894 void GBCheatList::DoDataExchange(CDataExchange*pDX) | |
895 { | |
896 CDialog::DoDataExchange(pDX); | |
897 //{{AFX_DATA_MAP(GBCheatList) | |
898 DDX_Control(pDX, IDC_CHEAT_LIST, m_list); | |
899 //}}AFX_DATA_MAP | |
900 } | |
901 | |
902 BEGIN_MESSAGE_MAP(GBCheatList, CDialog) | |
903 //{{AFX_MSG_MAP(GBCheatList) | |
904 ON_BN_CLICKED(ID_OK, OnOk) | |
905 ON_BN_CLICKED(IDC_ADD_GG_CHEAT, OnAddGgCheat) | |
906 ON_BN_CLICKED(IDC_ADD_GS_CHEAT, OnAddGsCheat) | |
907 ON_BN_CLICKED(IDC_ENABLE, OnEnable) | |
908 ON_BN_CLICKED(IDC_REMOVE, OnRemove) | |
909 ON_BN_CLICKED(IDC_REMOVE_ALL, OnRemoveAll) | |
910 ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHEAT_LIST, OnItemchangedCheatList) | |
911 //}}AFX_MSG_MAP | |
912 END_MESSAGE_MAP() | |
913 | |
914 ///////////////////////////////////////////////////////////////////////////// | |
915 // GBCheatList message handlers | |
916 | |
917 void GBCheatList::OnOk() | |
918 { | |
919 EndDialog(TRUE); | |
920 } | |
921 | |
922 void GBCheatList::OnAddGgCheat() | |
923 { | |
924 CString temp = winResLoadString(IDS_ADD_GG_CODE); | |
925 AddGBCode dlg(winGbCheatAddVerifyGg, 11, temp); | |
926 dlg.DoModal(); | |
927 refresh(); | |
928 } | |
929 | |
930 void GBCheatList::OnAddGsCheat() | |
931 { | |
932 CString temp = winResLoadString(IDS_ADD_GS_CODE); | |
933 | |
934 AddGBCode dlg(winGbCheatAddVerifyGs, 8, temp); | |
935 dlg.DoModal(); | |
936 refresh(); | |
937 } | |
938 | |
939 void GBCheatList::OnEnable() | |
940 { | |
941 int mark = m_list.GetSelectionMark(); | |
942 | |
943 if (mark != -1) | |
944 { | |
945 LVITEM item; | |
946 memset(&item, 0, sizeof(item)); | |
947 item.mask = LVIF_PARAM; | |
948 item.iItem = mark; | |
949 if (m_list.GetItem(&item)) | |
950 { | |
951 if (gbCheatList[item.lParam].enabled) | |
952 gbCheatDisable(item.lParam); | |
953 else | |
954 gbCheatEnable(item.lParam); | |
955 refresh(); | |
956 } | |
957 } | |
958 } | |
959 | |
960 void GBCheatList::OnRemove() | |
961 { | |
962 int mark = m_list.GetSelectionMark(); | |
963 | |
964 if (mark != -1) | |
965 { | |
966 LVITEM item; | |
967 memset(&item, 0, sizeof(item)); | |
968 item.mask = LVIF_PARAM; | |
969 item.iItem = mark; | |
970 if (m_list.GetItem(&item)) | |
971 { | |
972 gbCheatRemove(item.lParam); | |
973 refresh(); | |
974 } | |
975 } | |
976 } | |
977 | |
978 void GBCheatList::OnRemoveAll() | |
979 { | |
980 gbCheatRemoveAll(); | |
981 refresh(); | |
982 } | |
983 | |
984 void GBCheatList::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult) | |
985 { | |
986 if (m_list.GetSelectionMark() != -1) | |
987 { | |
988 GetDlgItem(IDC_REMOVE)->EnableWindow(TRUE); | |
989 GetDlgItem(IDC_ENABLE)->EnableWindow(TRUE); | |
990 } | |
991 else | |
992 { | |
993 GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE); | |
994 GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE); | |
995 } | |
996 | |
997 if (!duringRefresh) | |
998 { | |
999 LPNMLISTVIEW l = (LPNMLISTVIEW)pNMHDR; | |
1000 if (l->uChanged & LVIF_STATE) | |
1001 { | |
1002 if (((l->uOldState & LVIS_STATEIMAGEMASK)>>12) != | |
1003 (((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) | |
1004 { | |
1005 if (m_list.GetCheck(l->iItem)) | |
1006 gbCheatEnable(l->lParam); | |
1007 else | |
1008 gbCheatDisable(l->lParam); | |
1009 refresh(); | |
1010 } | |
1011 } | |
1012 } | |
1013 } | |
1014 | |
1015 BOOL GBCheatList::OnInitDialog() | |
1016 { | |
1017 CDialog::OnInitDialog(); | |
1018 | |
1019 CString temp = winResLoadString(IDS_CODE); | |
1020 m_list.InsertColumn(0, temp, LVCFMT_LEFT, 120, 0); | |
1021 temp = winResLoadString(IDS_DESCRIPTION); | |
1022 m_list.InsertColumn(1, temp, LVCFMT_LEFT, 200, 1); | |
1023 temp = winResLoadString(IDS_STATUS); | |
1024 m_list.InsertColumn(2, temp, LVCFMT_LEFT, 80, 2); | |
1025 | |
1026 m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)), | |
1027 TRUE); | |
1028 | |
1029 m_list.SetExtendedStyle(LVS_EX_CHECKBOXES | | |
1030 LVS_EX_FULLROWSELECT); | |
1031 | |
1032 refresh(); | |
1033 GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE); | |
1034 GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE); | |
1035 CenterWindow(); | |
1036 | |
1037 return TRUE; // return TRUE unless you set the focus to a control | |
1038 // EXCEPTION: OCX Property Pages should return FALSE | |
1039 } | |
1040 | |
1041 void GBCheatList::refresh() | |
1042 { | |
1043 duringRefresh = true; | |
1044 | |
1045 m_list.DeleteAllItems(); | |
1046 | |
1047 char buffer[2]; | |
1048 | |
1049 for (int i = 0; i < gbCheatNumber; i++) | |
1050 { | |
1051 LVITEM item; | |
1052 | |
1053 item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; | |
1054 item.iItem = i; | |
1055 item.iSubItem = 0; | |
1056 item.lParam = i; | |
1057 item.state = 0; | |
1058 item.stateMask = 0; | |
1059 item.pszText = gbCheatList[i].cheatCode; | |
1060 m_list.InsertItem(&item); | |
1061 | |
1062 m_list.SetCheck(i, (gbCheatList[i].enabled ? TRUE : FALSE)); | |
1063 | |
1064 m_list.SetItemText(i, 1, gbCheatList[i].cheatDesc); | |
1065 | |
1066 buffer[0] = (gbCheatList[i].enabled) ? 'E' : 'D'; | |
1067 buffer[1] = 0; | |
1068 m_list.SetItemText(i, 2, buffer); | |
1069 } | |
1070 duringRefresh = false; | |
1071 } | |
1072 | |
1073 ///////////////////////////////////////////////////////////////////////////// | |
1074 // AddGBCode dialog | |
1075 | |
1076 AddGBCode::AddGBCode(bool(*verify)(const char *, const char *), int len, const char *title, CWnd*pParent /*=NULL*/) | |
1077 : CDialog(AddGBCode::IDD, pParent) | |
1078 { | |
1079 //{{AFX_DATA_INIT(AddGBCode) | |
1080 // NOTE: the ClassWizard will add member initialization here | |
1081 //}}AFX_DATA_INIT | |
1082 addVerify = verify; | |
1083 addLength = len; | |
1084 addTitle = title; | |
1085 } | |
1086 | |
1087 void AddGBCode::DoDataExchange(CDataExchange*pDX) | |
1088 { | |
1089 CDialog::DoDataExchange(pDX); | |
1090 //{{AFX_DATA_MAP(AddGBCode) | |
1091 DDX_Control(pDX, IDC_DESC, m_desc); | |
1092 DDX_Control(pDX, IDC_CODE, m_code); | |
1093 //}}AFX_DATA_MAP | |
1094 } | |
1095 | |
1096 BEGIN_MESSAGE_MAP(AddGBCode, CDialog) | |
1097 //{{AFX_MSG_MAP(AddGBCode) | |
1098 ON_BN_CLICKED(ID_OK, OnOk) | |
1099 ON_BN_CLICKED(ID_CANCEL, OnCancel) | |
1100 //}}AFX_MSG_MAP | |
1101 END_MESSAGE_MAP() | |
1102 | |
1103 ///////////////////////////////////////////////////////////////////////////// | |
1104 // AddGBCode message handlers | |
1105 | |
1106 void AddGBCode::OnOk() | |
1107 { | |
1108 CString desc; | |
1109 CString buffer; | |
1110 m_code.GetWindowText(buffer); | |
1111 m_desc.GetWindowText(desc); | |
1112 | |
1113 StringTokenizer st(buffer, " \t\n\r"); | |
1114 const char * t = st.next(); | |
1115 while (t) | |
1116 { | |
1117 addVerify(t, desc); | |
1118 t = st.next(); | |
1119 } | |
1120 EndDialog(TRUE); | |
1121 } | |
1122 | |
1123 void AddGBCode::OnCancel() | |
1124 { | |
1125 EndDialog(FALSE); | |
1126 } | |
1127 | |
1128 BOOL AddGBCode::OnInitDialog() | |
1129 { | |
1130 CDialog::OnInitDialog(); | |
1131 | |
1132 m_code.LimitText(1024); | |
1133 m_desc.LimitText(32); | |
1134 SetWindowText(addTitle); | |
1135 CenterWindow(); | |
1136 | |
1137 return TRUE; // return TRUE unless you set the focus to a control | |
1138 // EXCEPTION: OCX Property Pages should return FALSE | |
1139 } | |
1140 |