view src/win32/GBACheatsDlg.cpp @ 5:8fe0c57e53d2

concentrating on lua first
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:39:40 -0600
parents f9f4f1b99eed
children
line wrap: on
line source
1 // GBACheats.cpp : implementation file
2 //
4 #include "stdafx.h"
5 #include "resource.h"
6 #include "GBACheatsDlg.h"
7 #include "Reg.h"
8 #include "StringTokenizer.h"
9 #include "WinResUtil.h"
10 #include "Sound.h"
11 #include "VBA.h"
13 #include "../gba/GBACheats.h"
14 #include "../gba/GBAGlobals.h"
15 #include "../common/CheatSearch.h"
17 ////////////////////////////////
19 bool winGbaCheatReaddress()
20 {
21 if (cheatSearchData.count != 2)
22 return false;
24 CheatSearchBlock *block = &cheatSearchData.blocks[0];
25 block->data = workRAM;
27 block = &cheatSearchData.blocks[1];
28 block->data = internalRAM;
30 cheatSearchData.count = 2;
31 return true;
32 }
34 /////////////////////////////////////////////////////////////////////////////
35 // GBACheatSearch dialog
37 GBACheatSearch::GBACheatSearch(CWnd*pParent /*=NULL*/)
38 : CDialog(GBACheatSearch::IDD, pParent)
39 {
40 //{{AFX_DATA_INIT(GBACheatSearch)
41 valueType = -1;
42 sizeType = -1;
43 searchType = -1;
44 numberType = -1;
45 updateValues = FALSE;
46 //}}AFX_DATA_INIT
47 data = NULL;
48 }
50 GBACheatSearch::~GBACheatSearch()
51 {
52 if (data)
53 free(data);
54 }
56 void GBACheatSearch::DoDataExchange(CDataExchange*pDX)
57 {
58 CDialog::DoDataExchange(pDX);
59 //{{AFX_DATA_MAP(GBACheatSearch)
60 DDX_Control(pDX, IDC_VALUE, m_value);
61 DDX_Control(pDX, IDC_CHEAT_LIST, m_list);
62 DDX_Radio(pDX, IDC_OLD_VALUE, valueType);
63 DDX_Radio(pDX, IDC_SIZE_8, sizeType);
64 DDX_Radio(pDX, IDC_EQ, searchType);
65 DDX_Radio(pDX, IDC_SIGNED, numberType);
66 DDX_Check(pDX, IDC_UPDATE, updateValues);
67 //}}AFX_DATA_MAP
68 }
70 BEGIN_MESSAGE_MAP(GBACheatSearch, CDialog)
71 //{{AFX_MSG_MAP(GBACheatSearch)
72 ON_BN_CLICKED(ID_OK, OnOk)
73 ON_BN_CLICKED(IDC_START, OnStart)
74 ON_BN_CLICKED(IDC_SEARCH, OnSearch)
75 ON_BN_CLICKED(IDC_ADD_CHEAT, OnAddCheat)
76 ON_BN_CLICKED(IDC_UPDATE, OnUpdate)
77 ON_NOTIFY(LVN_GETDISPINFO, IDC_CHEAT_LIST, OnGetdispinfoCheatList)
78 ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHEAT_LIST, OnItemchangedCheatList)
79 ON_CONTROL_RANGE(BN_CLICKED, IDC_OLD_VALUE, IDC_SPECIFIC_VALUE, OnValueType)
80 ON_CONTROL_RANGE(BN_CLICKED, IDC_EQ, IDC_GE, OnSearchType)
81 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIGNED, IDC_HEXADECIMAL, OnNumberType)
82 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIZE_8, IDC_SIZE_32, OnSizeType)
83 //}}AFX_MSG_MAP
84 ON_WM_CLOSE()
85 ON_BN_CLICKED(IDC_CHEATREFRESHBUTTON, OnBnClickedCheatrefreshbutton)
86 //ON_WM_DESTROY()
87 //ON_WM_NCDESTROY()
88 //ON_WM_SYSCOMMAND()
89 //ON_WM_ACTIVATE()
90 END_MESSAGE_MAP()
92 /////////////////////////////////////////////////////////////////////////////
93 // GBACheatSearch message handlers
95 void GBACheatSearch::OnOk()
96 {
97 if (theApp.modelessCheatDialogIsOpen)
98 {
99 theApp.modelessCheatDialogIsOpen = false;
100 DestroyWindow();
101 }
102 else
103 {
104 EndDialog(TRUE);
105 }
106 }
108 void GBACheatSearch::OnClose()
109 {
110 CDialog::OnClose();
111 if (theApp.modelessCheatDialogIsOpen)
112 {
113 theApp.modelessCheatDialogIsOpen = false;
114 DestroyWindow();
115 }
116 else
117 {
118 EndDialog(FALSE);
119 }
120 }
122 void GBACheatSearch::OnStart()
123 {
124 if (cheatSearchData.count == 0)
125 {
126 CheatSearchBlock *block = &cheatSearchData.blocks[0];
127 block->data = workRAM;
128 block->offset = 0x2000000;
129 block->size = 0x40000;
130 block->saved = (u8 *)malloc(0x40000);
131 block->bits = (u8 *)malloc(0x40000>>3);
133 block = &cheatSearchData.blocks[1];
134 block->data = internalRAM;
135 block->offset = 0x3000000;
136 block->size = 0x8000;
137 block->saved = (u8 *)malloc(0x8000);
138 block->bits = (u8 *)malloc(0x8000>>3);
140 cheatSearchData.count = 2;
141 }
143 cheatSearchStart(&cheatSearchData);
144 GetDlgItem(IDC_SEARCH)->EnableWindow(TRUE);
146 if (theApp.modelessCheatDialogIsOpen)
147 {
148 GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE);
149 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE);
150 }
151 }
153 void GBACheatSearch::OnSearch()
154 {
155 CString buffer;
157 if (valueType == 0)
158 cheatSearch(&cheatSearchData,
159 searchType,
160 sizeType,
161 numberType == 0);
162 else
163 {
164 m_value.GetWindowText(buffer);
165 if (buffer.IsEmpty())
166 {
167 systemMessage(IDS_NUMBER_CANNOT_BE_EMPTY, "Number cannot be empty");
168 return;
169 }
170 int value = 0;
171 switch (numberType)
172 {
173 case 0:
174 sscanf(buffer, "%d", &value);
175 break;
176 case 1:
177 sscanf(buffer, "%u", &value);
178 break;
179 default:
180 sscanf(buffer, "%x", &value);
181 }
182 cheatSearchValue(&cheatSearchData,
183 searchType,
184 sizeType,
185 numberType == 0,
186 value);
187 }
189 addChanges(true);
191 if (updateValues)
192 cheatSearchUpdateValues(&cheatSearchData);
194 if (theApp.modelessCheatDialogIsOpen)
195 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData, sizeType) == 0 ? FALSE : TRUE);
197 if (0 == cheatSearchGetCount(&cheatSearchData, sizeType))
198 OnStart();
199 }
201 void GBACheatSearch::OnAddCheat()
202 {
203 int mark = m_list.GetSelectionMark();
205 if (mark != -1)
206 {
207 LVITEM item;
208 memset(&item, 0, sizeof(item));
209 item.mask = LVIF_PARAM;
210 item.iItem = mark;
211 if (m_list.GetItem(&item))
212 {
213 AddCheat dlg((u32)item.lParam);
214 dlg.DoModal();
215 }
216 }
217 }
219 void GBACheatSearch::OnUpdate()
220 {
221 if (GetDlgItem(IDC_UPDATE)->SendMessage(BM_GETCHECK,
222 0,
223 0) & BST_CHECKED)
224 updateValues = true;
225 else
226 updateValues = false;
227 regSetDwordValue("cheatsUpdate", updateValues);
228 }
230 void GBACheatSearch::OnGetdispinfoCheatList(NMHDR*pNMHDR, LRESULT*pResult)
231 {
232 LV_DISPINFO*info = (LV_DISPINFO *)pNMHDR;
233 if (info->item.mask & LVIF_TEXT)
234 {
235 int index = info->item.iItem;
236 int col = info->item.iSubItem;
238 switch (col)
239 {
240 case 0:
241 strcpy(info->item.pszText, data[index].address);
242 break;
243 case 1:
244 strcpy(info->item.pszText, data[index].oldValue);
245 break;
246 case 2:
247 strcpy(info->item.pszText, data[index].newValue);
248 break;
249 }
250 }
251 *pResult = TRUE;
252 }
254 void GBACheatSearch::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult)
255 {
256 GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(m_list.GetSelectionMark() != -1);
257 *pResult = TRUE;
258 }
260 BOOL GBACheatSearch::OnInitDialog()
261 {
262 CDialog::OnInitDialog();
264 CString temp = winResLoadString(IDS_ADDRESS);
266 m_list.InsertColumn(0, temp, LVCFMT_CENTER, 125, 0);
268 temp = winResLoadString(IDS_OLD_VALUE);
269 m_list.InsertColumn(1, temp, LVCFMT_CENTER, 125, 1);
271 temp = winResLoadString(IDS_NEW_VALUE);
272 m_list.InsertColumn(2, temp, LVCFMT_CENTER, 125, 2);
274 m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)),
275 TRUE);
277 m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
279 if (!cheatSearchData.count)
280 {
281 GetDlgItem(IDC_SEARCH)->EnableWindow(FALSE);
282 GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(FALSE);
283 }
285 valueType = regQueryDwordValue("cheatsValueType", 0);
286 if (valueType < 0 || valueType > 1)
287 valueType = 0;
289 searchType = regQueryDwordValue("cheatsSearchType", SEARCH_EQ);
290 if (searchType > 5 || searchType < 0)
291 searchType = 0;
293 numberType = regQueryDwordValue("cheatsNumberType", 2);
294 if (numberType < 0 || numberType > 2)
295 numberType = 2;
297 sizeType = regQueryDwordValue("cheatsSizeType", 0);
298 if (sizeType < 0 || sizeType > 2)
299 sizeType = 0;
301 updateValues = regQueryDwordValue("cheatsUpdate", 0) ?
302 true : false;
304 UpdateData(FALSE);
306 if (valueType == 0)
307 m_value.EnableWindow(FALSE);
308 CenterWindow();
310 if (theApp.modelessCheatDialogIsOpen)
311 GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE);
313 if (cheatSearchData.count)
314 {
315 addChanges(false);
316 if (theApp.modelessCheatDialogIsOpen)
317 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData,
318 sizeType) == 0 ? FALSE : TRUE);
319 }
320 else
321 {
322 if (theApp.modelessCheatDialogIsOpen)
323 GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE);
324 }
326 return TRUE; // return TRUE unless you set the focus to a control
327 // EXCEPTION: OCX Property Pages should return FALSE
328 }
330 void GBACheatSearch::addChanges(bool showMsgs)
331 {
332 int count = cheatSearchGetCount(&cheatSearchData, sizeType);
334 m_list.DeleteAllItems();
336 if (count > 4000)
337 {
338 if (showMsgs)
339 systemMessage(
340 IDS_SEARCH_PRODUCED_TOO_MANY,
341 "Search produced %d results.\nThey have been remembered, but are too many to display.\nPlease refine it better by performing additional searches.",
342 count);
343 return;
344 }
346 if (count == 0)
347 {
348 if (showMsgs)
349 systemMessage(IDS_SEARCH_PRODUCED_NO_RESULTS, "Search produced no results.");
350 return;
351 }
353 m_list.SetItemCount(count);
354 if (data)
355 free(data);
357 data = (WinCheatsData *)calloc(count, sizeof(WinCheatsData));
359 int inc = 1;
360 switch (sizeType)
361 {
362 case 1:
363 inc = 2;
364 break;
365 case 2:
366 inc = 4;
367 break;
368 }
370 int index = 0;
371 if (numberType == 0)
372 {
373 for (int i = 0; i < cheatSearchData.count; i++)
374 {
375 CheatSearchBlock *block = &cheatSearchData.blocks[i];
377 for (int j = 0; j < block->size; j += inc)
378 {
379 if (IS_BIT_SET(block->bits, j))
380 {
381 addChange(index++,
382 block->offset | j,
383 cheatSearchSignedRead(block->saved,
384 j,
385 sizeType),
386 cheatSearchSignedRead(block->data,
387 j,
388 sizeType));
389 }
390 }
391 }
392 }
393 else
394 {
395 for (int i = 0; i < cheatSearchData.count; i++)
396 {
397 CheatSearchBlock *block = &cheatSearchData.blocks[i];
399 for (int j = 0; j < block->size; j += inc)
400 {
401 if (IS_BIT_SET(block->bits, j))
402 {
403 addChange(index++,
404 block->offset | j,
405 cheatSearchRead(block->saved,
406 j,
407 sizeType),
408 cheatSearchRead(block->data,
409 j,
410 sizeType));
411 }
412 }
413 }
414 }
416 for (int i = 0; i < count; i++)
417 {
418 LVITEM item;
420 item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
421 item.iItem = i;
422 item.iSubItem = 0;
423 item.lParam = data[i].addr;
424 item.state = 0;
425 item.stateMask = 0;
426 item.pszText = LPSTR_TEXTCALLBACK;
427 m_list.InsertItem(&item);
429 m_list.SetItemText(i, 1, LPSTR_TEXTCALLBACK);
430 m_list.SetItemText(i, 2, LPSTR_TEXTCALLBACK);
431 }
432 }
434 void GBACheatSearch::addChange(int index, u32 address, u32 oldValue, u32 newValue)
435 {
436 data[index].addr = address;
437 sprintf(data[index].address, "%08x", address);
438 switch (numberType)
439 {
440 case 0:
441 sprintf(data[index].oldValue, "%d", oldValue);
442 sprintf(data[index].newValue, "%d", newValue);
443 break;
444 case 1:
445 sprintf(data[index].oldValue, "%u", oldValue);
446 sprintf(data[index].newValue, "%u", newValue);
447 break;
448 case 2:
449 switch (sizeType)
450 {
451 case 0:
452 sprintf(data[index].oldValue, "%02x", oldValue);
453 sprintf(data[index].newValue, "%02x", newValue);
454 break;
455 case 1:
456 sprintf(data[index].oldValue, "%04x", oldValue);
457 sprintf(data[index].newValue, "%04x", newValue);
458 break;
459 case 2:
460 sprintf(data[index].oldValue, "%08x", oldValue);
461 sprintf(data[index].newValue, "%08x", newValue);
462 break;
463 }
464 }
465 }
467 void GBACheatSearch::OnValueType(UINT id)
468 {
469 switch (id)
470 {
471 case IDC_OLD_VALUE:
472 valueType = 0;
473 m_value.EnableWindow(FALSE);
474 regSetDwordValue("cheatsValueType", 0);
475 break;
476 case IDC_SPECIFIC_VALUE:
477 valueType = 1;
478 m_value.EnableWindow(TRUE);
479 regSetDwordValue("cheatsValueType", 1);
480 break;
481 }
482 }
484 void GBACheatSearch::OnSearchType(UINT id)
485 {
486 switch (id)
487 {
488 case IDC_EQ:
489 searchType = SEARCH_EQ;
490 regSetDwordValue("cheatsSearchType", 0);
491 break;
492 case IDC_NE:
493 searchType = SEARCH_NE;
494 regSetDwordValue("cheatsSearchType", 1);
495 break;
496 case IDC_LT:
497 searchType = SEARCH_LT;
498 regSetDwordValue("cheatsSearchType", 2);
499 break;
500 case IDC_LE:
501 searchType = SEARCH_LE;
502 regSetDwordValue("cheatsSearchType", 3);
503 break;
504 case IDC_GT:
505 searchType = SEARCH_GT;
506 regSetDwordValue("cheatsSearchType", 4);
507 break;
508 case IDC_GE:
509 searchType = SEARCH_GE;
510 regSetDwordValue("cheatsSearchType", 5);
511 break;
512 }
513 }
515 void GBACheatSearch::OnNumberType(UINT id)
516 {
517 switch (id)
518 {
519 case IDC_SIGNED:
520 numberType = 0;
521 regSetDwordValue("cheatsNumberType", 0);
522 if (m_list.GetItemCount())
523 {
524 addChanges(false);
525 }
526 break;
527 case IDC_UNSIGNED:
528 numberType = 1;
529 regSetDwordValue("cheatsNumberType", 1);
530 if (m_list.GetItemCount())
531 {
532 addChanges(false);
533 }
534 break;
535 case IDC_HEXADECIMAL:
536 numberType = 2;
537 regSetDwordValue("cheatsNumberType", 2);
538 if (m_list.GetItemCount())
539 {
540 addChanges(false);
541 }
542 break;
543 }
544 }
546 void GBACheatSearch::OnSizeType(UINT id)
547 {
548 switch (id)
549 {
550 case IDC_SIZE_8:
551 sizeType = BITS_8;
552 regSetDwordValue("cheatsSizeType", 0);
553 if (m_list.GetItemCount())
554 {
555 addChanges(false);
556 }
557 break;
558 case IDC_SIZE_16:
559 sizeType = BITS_16;
560 regSetDwordValue("cheatsSizeType", 1);
561 if (m_list.GetItemCount())
562 {
563 addChanges(false);
564 }
565 break;
566 case IDC_SIZE_32:
567 sizeType = BITS_32;
568 regSetDwordValue("cheatsSizeType", 2);
569 if (m_list.GetItemCount())
570 {
571 addChanges(false);
572 }
573 break;
574 }
575 }
577 /////////////////////////////////////////////////////////////////////////////
578 // AddCheat dialog
580 AddCheat::AddCheat(u32 address, CWnd*pParent /*=NULL*/)
581 : CDialog(AddCheat::IDD, pParent)
582 {
583 //{{AFX_DATA_INIT(AddCheat)
584 numberType = regQueryDwordValue("cheatsNumberType", 2);
585 if (numberType < 0 || numberType > 2)
586 numberType = 2;
587 sizeType = regQueryDwordValue("cheatsSizeType", 0);
588 if (sizeType < 0 || sizeType > 2)
589 sizeType = 0;
590 //}}AFX_DATA_INIT
591 this->address = address;
592 }
594 void AddCheat::DoDataExchange(CDataExchange*pDX)
595 {
596 CDialog::DoDataExchange(pDX);
597 //{{AFX_DATA_MAP(AddCheat)
598 DDX_Control(pDX, IDC_VALUE, m_value);
599 DDX_Control(pDX, IDC_DESC, m_desc);
600 DDX_Control(pDX, IDC_ADDRESS, m_address);
601 DDX_Radio(pDX, IDC_SIZE_8, sizeType);
602 DDX_Radio(pDX, IDC_SIGNED, numberType);
603 //}}AFX_DATA_MAP
604 }
606 BEGIN_MESSAGE_MAP(AddCheat, CDialog)
607 //{{AFX_MSG_MAP(AddCheat)
608 ON_BN_CLICKED(ID_OK, OnOk)
609 ON_BN_CLICKED(ID_CANCEL, OnCancel)
610 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIGNED, IDC_HEXADECIMAL, OnNumberType)
611 ON_CONTROL_RANGE(BN_CLICKED, IDC_SIZE_8, IDC_SIZE_32, OnSizeType)
612 //}}AFX_MSG_MAP
613 END_MESSAGE_MAP()
615 /////////////////////////////////////////////////////////////////////////////
616 // AddCheat message handlers
618 void AddCheat::OnOk()
619 {
620 // add cheat
621 if (addCheat())
622 {
623 EndDialog(TRUE);
624 }
625 }
627 void AddCheat::OnCancel()
628 {
629 EndDialog(FALSE);
630 }
632 BOOL AddCheat::OnInitDialog()
633 {
634 CDialog::OnInitDialog();
636 if (address != 0)
637 {
638 CString buffer;
639 buffer.Format("%08x", address);
640 m_address.SetWindowText(buffer);
641 m_address.EnableWindow(FALSE);
642 }
644 UpdateData(FALSE);
646 GetDlgItem(IDC_DESC)->SendMessage(EM_LIMITTEXT,
647 32,
648 0);
649 if (address != 0)
650 {
651 GetDlgItem(IDC_SIZE_8)->EnableWindow(FALSE);
652 GetDlgItem(IDC_SIZE_16)->EnableWindow(FALSE);
653 GetDlgItem(IDC_SIZE_32)->EnableWindow(FALSE);
654 GetDlgItem(IDC_HEXADECIMAL)->EnableWindow(FALSE);
655 GetDlgItem(IDC_UNSIGNED)->EnableWindow(FALSE);
656 GetDlgItem(IDC_SIGNED)->EnableWindow(FALSE);
657 }
659 CenterWindow();
661 return TRUE; // return TRUE unless you set the focus to a control
662 // EXCEPTION: OCX Property Pages should return FALSE
663 }
665 void AddCheat::OnNumberType(UINT id)
666 {
667 switch (id)
668 {
669 case IDC_SIGNED:
670 numberType = 0;
671 regSetDwordValue("cheatsNumberType", 0);
672 break;
673 case IDC_UNSIGNED:
674 numberType = 1;
675 regSetDwordValue("cheatsNumberType", 1);
676 break;
677 case IDC_HEXADECIMAL:
678 numberType = 2;
679 regSetDwordValue("cheatsNumberType", 2);
680 break;
681 }
682 }
684 void AddCheat::OnSizeType(UINT id)
685 {
686 switch (id)
687 {
688 case IDC_SIZE_8:
689 sizeType = BITS_8;
690 regSetDwordValue("cheatsSizeType", 0);
691 break;
692 case IDC_SIZE_16:
693 sizeType = BITS_16;
694 regSetDwordValue("cheatsSizeType", 1);
695 break;
696 case IDC_SIZE_32:
697 sizeType = BITS_32;
698 regSetDwordValue("cheatsSizeType", 2);
699 break;
700 }
701 }
703 bool AddCheat::addCheat()
704 {
705 CString buffer;
706 CString code;
708 m_address.GetWindowText(buffer);
709 u32 address = 0;
710 sscanf(buffer, "%x", &address);
711 if ((address >= 0x02000000 && address < 0x02040000) ||
712 (address >= 0x03000000 && address < 0x03008000))
713 {}
714 else
715 {
716 systemMessage(IDS_INVALID_ADDRESS, "Invalid address: %08x", address);
717 return false;
718 }
719 if (sizeType != 0)
720 {
721 if (sizeType == 1 && address & 1)
722 {
723 systemMessage(IDS_MISALIGNED_HALFWORD, "Misaligned half-word address: %08x", address);
724 return false;
725 }
726 if (sizeType == 2 && address & 3)
727 {
728 systemMessage(IDS_MISALIGNED_WORD, "Misaligned word address: %08x", address);
729 return false;
730 }
731 }
732 u32 value;
733 m_value.GetWindowText(buffer);
735 if (buffer.IsEmpty())
736 {
737 systemMessage(IDS_VALUE_CANNOT_BE_EMPTY, "Value cannot be empty");
738 return false;
739 }
741 switch (numberType)
742 {
743 case 0:
744 sscanf(buffer, "%d", &value);
745 break;
746 case 1:
747 sscanf(buffer, "%u", &value);
748 break;
749 default:
750 sscanf(buffer, "%x", &value);
751 }
753 m_desc.GetWindowText(buffer);
755 switch (sizeType)
756 {
757 case 0:
758 code.Format("%08x:%02x", address, value);
759 break;
760 case 1:
761 code.Format("%08x:%04x", address, value);
762 break;
763 case 2:
764 code.Format("%08x:%08x", address, value);
765 break;
766 }
768 cheatsAdd(code, buffer, address, value, -1, sizeType);
769 return true;
770 }
772 /////////////////////////////////////////////////////////////////////////////
773 // GBACheatList dialog
775 GBACheatList::GBACheatList(CWnd*pParent /*=NULL*/)
776 : CDialog(GBACheatList::IDD, pParent)
777 {
778 //{{AFX_DATA_INIT(GBACheatList)
779 // NOTE: the ClassWizard will add member initialization here
780 //}}AFX_DATA_INIT
781 }
783 void GBACheatList::DoDataExchange(CDataExchange*pDX)
784 {
785 CDialog::DoDataExchange(pDX);
786 //{{AFX_DATA_MAP(GBACheatList)
787 DDX_Control(pDX, IDC_RESTORE, m_restore);
788 DDX_Control(pDX, IDC_CHEAT_LIST, m_list);
789 //}}AFX_DATA_MAP
790 }
792 BEGIN_MESSAGE_MAP(GBACheatList, CDialog)
793 //{{AFX_MSG_MAP(GBACheatList)
794 ON_BN_CLICKED(IDC_ADD_CHEAT, OnAddCheat)
795 ON_BN_CLICKED(IDC_ADD_CODE, OnAddCode)
796 ON_BN_CLICKED(IDC_ADD_CODEBREAKER, OnAddCodebreaker)
797 ON_BN_CLICKED(IDC_ADD_GAMESHARK, OnAddGameshark)
798 ON_BN_CLICKED(IDC_ENABLE, OnEnable)
799 ON_BN_CLICKED(IDC_REMOVE, OnRemove)
800 ON_BN_CLICKED(IDC_REMOVE_ALL, OnRemoveAll)
801 ON_BN_CLICKED(IDC_RESTORE, OnRestore)
802 ON_BN_CLICKED(ID_OK, OnOk)
803 ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHEAT_LIST, OnItemchangedCheatList)
804 //}}AFX_MSG_MAP
805 END_MESSAGE_MAP()
807 /////////////////////////////////////////////////////////////////////////////
808 // GBACheatList message handlers
810 void GBACheatList::OnAddCheat()
811 {
812 AddCheat dlg(0);
813 dlg.DoModal();
814 refresh();
815 }
817 void GBACheatList::OnAddCode()
818 {
819 AddCheatCode dlg;
820 dlg.DoModal();
821 refresh();
822 }
824 void GBACheatList::OnAddCodebreaker()
825 {
826 AddCBACode dlg;
827 dlg.DoModal();
828 refresh();
829 }
831 void GBACheatList::OnAddGameshark()
832 {
833 AddGSACode dlg;
834 dlg.DoModal();
835 refresh();
836 }
838 void GBACheatList::OnEnable()
839 {
840 int mark = m_list.GetSelectionMark();
841 int count = m_list.GetItemCount();
843 if (mark != -1)
844 {
845 LVITEM item;
846 for (int i = 0; i < count; i++)
847 {
848 memset(&item, 0, sizeof(item));
849 item.mask = LVIF_PARAM|LVIF_STATE;
850 item.stateMask = LVIS_SELECTED;
851 item.iItem = i;
852 if (m_list.GetItem(&item))
853 {
854 if (item.state & LVIS_SELECTED)
855 {
856 if (cheatsList[item.lParam].enabled)
857 cheatsDisable(item.lParam);
858 else
859 cheatsEnable(item.lParam);
860 }
861 }
862 }
863 refresh();
864 }
865 }
867 void GBACheatList::OnRemove()
868 {
869 int mark = m_list.GetSelectionMark();
870 int count = m_list.GetItemCount();
872 if (mark != -1)
873 {
874 for (int i = count - 1; i >= 0; i--)
875 {
876 LVITEM item;
877 memset(&item, 0, sizeof(item));
878 item.mask = LVIF_PARAM|LVIF_STATE;
879 item.iItem = i;
880 item.stateMask = LVIS_SELECTED;
881 if (m_list.GetItem(&item))
882 {
883 if (item.state & LVIS_SELECTED)
884 {
885 cheatsDelete(item.lParam, restoreValues);
886 }
887 }
888 }
889 refresh();
890 }
891 }
893 void GBACheatList::OnRemoveAll()
894 {
895 cheatsDeleteAll(restoreValues);
896 refresh();
897 }
899 void GBACheatList::OnRestore()
900 {
901 restoreValues = !restoreValues;
902 regSetDwordValue("cheatsRestore", restoreValues);
903 }
905 void GBACheatList::OnOk()
906 {
907 EndDialog(TRUE);
908 }
910 void GBACheatList::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult)
911 {
912 if (m_list.GetSelectionMark() != -1)
913 {
914 GetDlgItem(IDC_REMOVE)->EnableWindow(TRUE);
915 GetDlgItem(IDC_ENABLE)->EnableWindow(TRUE);
916 }
917 else
918 {
919 GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE);
920 GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE);
921 }
923 if (!duringRefresh)
924 {
925 LPNMLISTVIEW l = (LPNMLISTVIEW)pNMHDR;
926 if (l->uChanged & LVIF_STATE)
927 {
928 if (((l->uOldState & LVIS_STATEIMAGEMASK)>>12) !=
929 (((l->uNewState & LVIS_STATEIMAGEMASK)>>12)))
930 {
931 if (m_list.GetCheck(l->iItem))
932 cheatsEnable(l->lParam);
933 else
934 cheatsDisable(l->lParam);
935 refresh();
936 }
937 }
938 }
940 *pResult = 0;
941 }
943 BOOL GBACheatList::OnInitDialog()
944 {
945 CDialog::OnInitDialog();
947 CString temp = winResLoadString(IDS_CODE);
948 m_list.InsertColumn(0, temp, LVCFMT_LEFT, 170, 0);
949 temp = winResLoadString(IDS_DESCRIPTION);
950 m_list.InsertColumn(1, temp, LVCFMT_LEFT, 150, 1);
951 temp = winResLoadString(IDS_STATUS);
952 m_list.InsertColumn(2, temp, LVCFMT_LEFT, 80, 1);
954 m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)),
955 TRUE);
957 m_list.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
959 duringRefresh = false;
961 restoreValues = regQueryDwordValue("cheatsRestore", 0) ?
962 true : false;
964 m_restore.SetCheck(restoreValues);
966 refresh();
967 GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE);
968 GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE);
969 CenterWindow();
971 return TRUE; // return TRUE unless you set the focus to a control
972 // EXCEPTION: OCX Property Pages should return FALSE
973 }
975 void GBACheatList::refresh()
976 {
977 duringRefresh = true;
978 m_list.DeleteAllItems();
980 CString buffer;
982 for (int i = 0; i < cheatsNumber; i++)
983 {
984 LVITEM item;
986 item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
987 item.iItem = i;
988 item.iSubItem = 0;
989 item.lParam = i;
990 item.state = 0;
991 item.stateMask = 0;
992 item.pszText = cheatsList[i].codestring;
993 m_list.InsertItem(&item);
995 m_list.SetCheck(i, (cheatsList[i].enabled) ? TRUE : FALSE);
997 m_list.SetItemText(i, 1, cheatsList[i].desc);
999 buffer = (cheatsList[i].enabled) ? 'E' : 'D';
1000 m_list.SetItemText(i, 2, buffer);
1002 duringRefresh = false;
1005 /////////////////////////////////////////////////////////////////////////////
1006 // AddGSACode dialog
1008 AddGSACode::AddGSACode(CWnd*pParent /*=NULL*/)
1009 : CDialog(AddGSACode::IDD, pParent)
1011 //{{AFX_DATA_INIT(AddGSACode)
1012 // NOTE: the ClassWizard will add member initialization here
1013 //}}AFX_DATA_INIT
1016 void AddGSACode::DoDataExchange(CDataExchange*pDX)
1018 CDialog::DoDataExchange(pDX);
1019 //{{AFX_DATA_MAP(AddGSACode)
1020 DDX_Control(pDX, IDC_DESC, m_desc);
1021 DDX_Control(pDX, IDC_CODE, m_code);
1022 //}}AFX_DATA_MAP
1025 BEGIN_MESSAGE_MAP(AddGSACode, CDialog)
1026 //{{AFX_MSG_MAP(AddGSACode)
1027 ON_BN_CLICKED(ID_OK, OnOk)
1028 ON_BN_CLICKED(ID_CANCEL, OnCancel)
1029 //}}AFX_MSG_MAP
1030 END_MESSAGE_MAP()
1032 /////////////////////////////////////////////////////////////////////////////
1033 // AddGSACode message handlers
1035 void AddGSACode::OnOk()
1037 CString desc;
1038 CString buffer;
1039 CString part1;
1040 CString code;
1041 CString token;
1043 m_code.GetWindowText(buffer);
1044 m_desc.GetWindowText(desc);
1046 StringTokenizer st(buffer, " \t\n\r");
1047 part1.Empty();
1048 const char *t = st.next();
1049 while (t)
1051 token = t;
1052 token.MakeUpper();
1053 if (token.GetLength() == 16)
1054 cheatsAddGSACode(token, desc, false);
1055 else if (token.GetLength() == 12)
1057 code = token.Left(8);
1058 code += " ";
1059 code += token.Right(4);
1060 cheatsAddCBACode(code, desc);
1062 else if (part1.IsEmpty())
1063 part1 = token;
1064 else
1066 if (token.GetLength() == 4)
1068 code = part1;
1069 code += " ";
1070 code += token;
1071 cheatsAddCBACode(code, desc);
1073 else
1075 code = part1 + token;
1076 cheatsAddGSACode(code, desc, true);
1078 part1.Empty();
1081 t = st.next();
1083 EndDialog(TRUE);
1086 void AddGSACode::OnCancel()
1088 EndDialog(FALSE);
1091 BOOL AddGSACode::OnInitDialog()
1093 CDialog::OnInitDialog();
1095 m_code.LimitText(1024);
1096 m_desc.LimitText(32);
1097 CString title = winResLoadString(IDS_ADD_GSA_CODE);
1098 SetWindowText(title);
1099 CenterWindow();
1101 return TRUE; // return TRUE unless you set the focus to a control
1102 // EXCEPTION: OCX Property Pages should return FALSE
1105 /////////////////////////////////////////////////////////////////////////////
1106 // AddCBACode dialog
1108 AddCBACode::AddCBACode(CWnd*pParent /*=NULL*/)
1109 : CDialog(AddCBACode::IDD, pParent)
1111 //{{AFX_DATA_INIT(AddCBACode)
1112 // NOTE: the ClassWizard will add member initialization here
1113 //}}AFX_DATA_INIT
1116 void AddCBACode::DoDataExchange(CDataExchange*pDX)
1118 CDialog::DoDataExchange(pDX);
1119 //{{AFX_DATA_MAP(AddCBACode)
1120 DDX_Control(pDX, IDC_DESC, m_desc);
1121 DDX_Control(pDX, IDC_CODE, m_code);
1122 //}}AFX_DATA_MAP
1125 BEGIN_MESSAGE_MAP(AddCBACode, CDialog)
1126 //{{AFX_MSG_MAP(AddCBACode)
1127 ON_BN_CLICKED(ID_OK, OnOk)
1128 ON_BN_CLICKED(ID_CANCEL, OnCancel)
1129 //}}AFX_MSG_MAP
1130 END_MESSAGE_MAP()
1132 /////////////////////////////////////////////////////////////////////////////
1133 // AddCBACode message handlers
1135 void AddCBACode::OnOk()
1137 CString desc;
1138 CString buffer;
1139 CString part1;
1140 CString code;
1141 CString token;
1143 m_code.GetWindowText(buffer);
1144 m_desc.GetWindowText(desc);
1146 StringTokenizer st(buffer, " \t\n\r");
1147 part1.Empty();
1148 const char *t = st.next();
1149 while (t)
1151 token = t;
1152 token.MakeUpper();
1153 if (token.GetLength() == 16)
1154 cheatsAddGSACode(token, desc, false);
1155 else if (token.GetLength() == 12)
1157 code = token.Left(8);
1158 code += " ";
1159 code += token.Right(4);
1160 cheatsAddCBACode(code, desc);
1162 else if (part1.IsEmpty())
1163 part1 = token;
1164 else
1166 if (token.GetLength() == 4)
1168 code = part1;
1169 code += " ";
1170 code += token;
1171 cheatsAddCBACode(code, desc);
1173 else
1175 code = part1 + token;
1176 cheatsAddGSACode(code, desc, true);
1178 part1.Empty();
1181 t = st.next();
1183 EndDialog(TRUE);
1186 void AddCBACode::OnCancel()
1188 EndDialog(FALSE);
1191 BOOL AddCBACode::OnInitDialog()
1193 CDialog::OnInitDialog();
1195 m_code.LimitText(1024);
1196 m_desc.LimitText(32);
1197 CString title = winResLoadString(IDS_ADD_CBA_CODE);
1198 SetWindowText(title);
1199 CenterWindow();
1201 return TRUE; // return TRUE unless you set the focus to a control
1202 // EXCEPTION: OCX Property Pages should return FALSE
1205 /////////////////////////////////////////////////////////////////////////////
1206 // AddCheatCode dialog
1208 AddCheatCode::AddCheatCode(CWnd*pParent /*=NULL*/)
1209 : CDialog(AddCheatCode::IDD, pParent)
1211 //{{AFX_DATA_INIT(AddCheatCode)
1212 // NOTE: the ClassWizard will add member initialization here
1213 //}}AFX_DATA_INIT
1216 void AddCheatCode::DoDataExchange(CDataExchange*pDX)
1218 CDialog::DoDataExchange(pDX);
1219 //{{AFX_DATA_MAP(AddCheatCode)
1220 DDX_Control(pDX, IDC_DESC, m_desc);
1221 DDX_Control(pDX, IDC_CODE, m_code);
1222 //}}AFX_DATA_MAP
1225 BEGIN_MESSAGE_MAP(AddCheatCode, CDialog)
1226 //{{AFX_MSG_MAP(AddCheatCode)
1227 ON_BN_CLICKED(ID_OK, OnOk)
1228 ON_BN_CLICKED(ID_CANCEL, OnCancel)
1229 //}}AFX_MSG_MAP
1230 END_MESSAGE_MAP()
1232 /////////////////////////////////////////////////////////////////////////////
1233 // AddCheatCode message handlers
1235 void AddCheatCode::OnOk()
1237 CString desc;
1238 CString buffer;
1239 CString token;
1241 m_code.GetWindowText(buffer);
1242 m_desc.GetWindowText(desc);
1244 StringTokenizer st(buffer, " \t\n\r");
1245 const char * t = st.next();
1246 while (t)
1248 token = t;
1249 token.MakeUpper();
1250 cheatsAddCheatCode(token, desc);
1251 t = st.next();
1253 EndDialog(TRUE);
1256 void AddCheatCode::OnCancel()
1258 EndDialog(FALSE);
1261 BOOL AddCheatCode::OnInitDialog()
1263 CDialog::OnInitDialog();
1265 m_code.LimitText(1024);
1266 m_desc.LimitText(32);
1267 CString title = winResLoadString(IDS_ADD_CHEAT_CODE);
1268 SetWindowText(title);
1269 CenterWindow();
1271 return TRUE; // return TRUE unless you set the focus to a control
1272 // EXCEPTION: OCX Property Pages should return FALSE
1275 void GBACheatSearch::OnBnClickedCheatrefreshbutton()
1277 addChanges(false);