view 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
line wrap: on
line source
1 // GBCheats.cpp : implementation file
2 //
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"
13 #include "../common/CheatSearch.h"
14 #include "../gb/gbCheats.h"
15 #include "../gb/gbGlobals.h"
17 static inline bool winGbCheatAddVerifyGs(const char *code, const char *desc)
18 {
19 gbAddGsCheat(code, desc);
20 return true;
21 }
23 static inline bool winGbCheatAddVerifyGg(const char *code, const char *desc)
24 {
25 gbAddGgCheat(code, desc);
26 return true;
27 }
29 ////////////////////////////////
31 bool winGbCheatReaddress()
32 {
33 if (cheatSearchData.count != 3)
34 return false;
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 }
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);
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);
73 cheatSearchZeroBlock(&cheatSearchData.blocks[2]);
74 }
76 cheatSearchData.count = 3;
77 return true;
78 }
80 /////////////////////////////////////////////////////////////////////////////
81 // GBCheatSearch dialog
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 }
96 GBCheatSearch::~GBCheatSearch()
97 {
98 if (data)
99 free(data);
100 }
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 }
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()
134 /////////////////////////////////////////////////////////////////////////////
135 // GBCheatSearch message handlers
137 void GBCheatSearch::OnOk()
138 {
139 if (data)
140 free(data);
141 data = NULL;
143 if (theApp.modelessCheatDialogIsOpen)
144 {
145 theApp.modelessCheatDialogIsOpen = false;
146 DestroyWindow();
147 }
148 else
149 {
150 EndDialog(TRUE);
151 }
152 }
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 }
168 void GBCheatSearch::OnBnClickedCheatrefreshbutton()
169 {
170 addChanges(false);
171 }
173 void GBCheatSearch::OnAddCheat()
174 {
175 int mark = m_list.GetSelectionMark();
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 }
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 }
226 addChanges(true);
228 if (updateValues)
229 cheatSearchUpdateValues(&cheatSearchData);
231 if (theApp.modelessCheatDialogIsOpen)
232 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData, sizeType) == 0 ? FALSE : TRUE);
234 if (0 == cheatSearchGetCount(&cheatSearchData, sizeType))
235 OnStart();
236 }
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 }
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);
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);
283 cheatSearchZeroBlock(&cheatSearchData.blocks[2]);
284 }
286 cheatSearchData.count = 3;
287 }
289 cheatSearchStart(&cheatSearchData);
290 GetDlgItem(IDC_SEARCH)->EnableWindow(TRUE);
292 if (theApp.modelessCheatDialogIsOpen)
293 {
294 GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE);
295 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE);
296 }
297 }
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 }
310 BOOL GBCheatSearch::OnInitDialog()
311 {
312 CDialog::OnInitDialog();
314 CString temp = winResLoadString(IDS_ADDRESS);
316 m_list.InsertColumn(0, temp, LVCFMT_CENTER, 125, 0);
318 temp = winResLoadString(IDS_OLD_VALUE);
319 m_list.InsertColumn(1, temp, LVCFMT_CENTER, 125, 1);
321 temp = winResLoadString(IDS_NEW_VALUE);
322 m_list.InsertColumn(2, temp, LVCFMT_CENTER, 125, 2);
324 m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)),
325 TRUE);
327 m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
329 if (!cheatSearchData.count)
330 {
331 GetDlgItem(IDC_SEARCH)->EnableWindow(FALSE);
332 GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(FALSE);
333 }
335 valueType = regQueryDwordValue("gbCheatsValueType", 0);
336 if (valueType < 0 || valueType > 1)
337 valueType = 2;
339 searchType = regQueryDwordValue("gbCheatsSearchType",
340 SEARCH_EQ);
341 if (searchType < 0 || searchType > 5)
342 searchType = 0;
344 numberType = regQueryDwordValue("gbCheatsNumberType", 2);
345 if (numberType < 0 || numberType > 2)
346 numberType = 2;
348 sizeType = regQueryDwordValue("gbCheatsSizeType", 0);
349 if (sizeType < 0 || sizeType > 2)
350 sizeType = 0;
352 updateValues = regQueryDwordValue("gbCheatsUpdate", 0) ?
353 true : false;
355 UpdateData(FALSE);
357 if (valueType == 0)
358 m_value.EnableWindow(FALSE);
360 CenterWindow();
362 if (theApp.modelessCheatDialogIsOpen)
363 GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE);
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 }
378 return TRUE; // return TRUE unless you set the focus to a control
379 // EXCEPTION: OCX Property Pages should return FALSE
380 }
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;
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 }
406 void GBCheatSearch::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult)
407 {
408 GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(m_list.GetSelectionMark() != -1);
409 }
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 }
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 }
466 void GBCheatSearch::addChanges(bool showMsg)
467 {
468 int count = cheatSearchGetCount(&cheatSearchData, sizeType);
470 m_list.DeleteAllItems();
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 }
482 if (count == 0)
483 {
484 if (showMsg)
485 systemMessage(IDS_SEARCH_PRODUCED_NO_RESULTS, "Search produced no results");
486 return;
487 }
489 m_list.SetItemCount(count);
490 if (data)
491 free(data);
493 data = (WinGbCheatsData *)calloc(count, sizeof(WinGbCheatsData));
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 }
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];
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];
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 }
556 for (int i = 0; i < count; i++)
557 {
558 LVITEM item;
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);
570 m_list.SetItemText(i, 1, LPSTR_TEXTCALLBACK);
571 m_list.SetItemText(i, 2, LPSTR_TEXTCALLBACK);
572 }
573 }
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 }
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 }
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 }
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 }
685 /////////////////////////////////////////////////////////////////////////////
686 // AddGBCheat dialog
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 }
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 }
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()
723 /////////////////////////////////////////////////////////////////////////////
724 // AddGBCheat message handlers
726 void AddGBCheat::OnCancel()
727 {
728 EndDialog(FALSE);
729 }
731 void AddGBCheat::OnOk()
732 {
733 // add cheat
734 if (addCheat())
735 {
736 EndDialog(TRUE);
737 }
738 }
740 bool AddGBCheat::addCheat()
741 {
742 CString buffer;
743 CString code;
745 u32 value;
746 m_value.GetWindowText(buffer);
748 if (buffer.IsEmpty())
749 {
750 systemMessage(IDS_VALUE_CANNOT_BE_EMPTY, "Value cannot be empty");
751 return false;
752 }
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 }
766 m_desc.GetWindowText(buffer);
768 int bank = (address >> 16);
769 address &= 0xFFFF;
771 if (address >= 0xd000)
772 bank += 0x90;
773 else
774 bank = 0x01;
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 }
810 return true;
811 }
813 BOOL AddGBCheat::OnInitDialog()
814 {
815 CDialog::OnInitDialog();
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);
825 UpdateData(FALSE);
827 m_desc.LimitText(32);
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();
840 return TRUE; // return TRUE unless you set the focus to a control
841 // EXCEPTION: OCX Property Pages should return FALSE
842 }
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 }
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 }
882 /////////////////////////////////////////////////////////////////////////////
883 // GBCheatList dialog
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 }
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 }
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()
914 /////////////////////////////////////////////////////////////////////////////
915 // GBCheatList message handlers
917 void GBCheatList::OnOk()
918 {
919 EndDialog(TRUE);
920 }
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 }
930 void GBCheatList::OnAddGsCheat()
931 {
932 CString temp = winResLoadString(IDS_ADD_GS_CODE);
934 AddGBCode dlg(winGbCheatAddVerifyGs, 8, temp);
935 dlg.DoModal();
936 refresh();
937 }
939 void GBCheatList::OnEnable()
940 {
941 int mark = m_list.GetSelectionMark();
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 }
960 void GBCheatList::OnRemove()
961 {
962 int mark = m_list.GetSelectionMark();
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 }
978 void GBCheatList::OnRemoveAll()
979 {
980 gbCheatRemoveAll();
981 refresh();
982 }
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 }
997 if (!duringRefresh)
998 {
999 LPNMLISTVIEW l = (LPNMLISTVIEW)pNMHDR;
1000 if (l->uChanged & LVIF_STATE)
1002 if (((l->uOldState & LVIS_STATEIMAGEMASK)>>12) !=
1003 (((l->uNewState & LVIS_STATEIMAGEMASK)>>12)))
1005 if (m_list.GetCheck(l->iItem))
1006 gbCheatEnable(l->lParam);
1007 else
1008 gbCheatDisable(l->lParam);
1009 refresh();
1015 BOOL GBCheatList::OnInitDialog()
1017 CDialog::OnInitDialog();
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);
1026 m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)),
1027 TRUE);
1029 m_list.SetExtendedStyle(LVS_EX_CHECKBOXES |
1030 LVS_EX_FULLROWSELECT);
1032 refresh();
1033 GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE);
1034 GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE);
1035 CenterWindow();
1037 return TRUE; // return TRUE unless you set the focus to a control
1038 // EXCEPTION: OCX Property Pages should return FALSE
1041 void GBCheatList::refresh()
1043 duringRefresh = true;
1045 m_list.DeleteAllItems();
1047 char buffer[2];
1049 for (int i = 0; i < gbCheatNumber; i++)
1051 LVITEM item;
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);
1062 m_list.SetCheck(i, (gbCheatList[i].enabled ? TRUE : FALSE));
1064 m_list.SetItemText(i, 1, gbCheatList[i].cheatDesc);
1066 buffer[0] = (gbCheatList[i].enabled) ? 'E' : 'D';
1067 buffer[1] = 0;
1068 m_list.SetItemText(i, 2, buffer);
1070 duringRefresh = false;
1073 /////////////////////////////////////////////////////////////////////////////
1074 // AddGBCode dialog
1076 AddGBCode::AddGBCode(bool(*verify)(const char *, const char *), int len, const char *title, CWnd*pParent /*=NULL*/)
1077 : CDialog(AddGBCode::IDD, pParent)
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;
1087 void AddGBCode::DoDataExchange(CDataExchange*pDX)
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
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()
1103 /////////////////////////////////////////////////////////////////////////////
1104 // AddGBCode message handlers
1106 void AddGBCode::OnOk()
1108 CString desc;
1109 CString buffer;
1110 m_code.GetWindowText(buffer);
1111 m_desc.GetWindowText(desc);
1113 StringTokenizer st(buffer, " \t\n\r");
1114 const char * t = st.next();
1115 while (t)
1117 addVerify(t, desc);
1118 t = st.next();
1120 EndDialog(TRUE);
1123 void AddGBCode::OnCancel()
1125 EndDialog(FALSE);
1128 BOOL AddGBCode::OnInitDialog()
1130 CDialog::OnInitDialog();
1132 m_code.LimitText(1024);
1133 m_desc.LimitText(32);
1134 SetWindowText(addTitle);
1135 CenterWindow();
1137 return TRUE; // return TRUE unless you set the focus to a control
1138 // EXCEPTION: OCX Property Pages should return FALSE