rlm@1: // GBCheats.cpp : implementation file rlm@1: // rlm@1: rlm@1: #include "stdafx.h" rlm@1: #include "resource.h" rlm@1: #include "GBCheatsDlg.h" rlm@1: #include "Reg.h" rlm@1: #include "StringTokenizer.h" rlm@1: #include "WinResUtil.h" rlm@1: #include "Sound.h" rlm@1: #include "VBA.h" rlm@1: rlm@1: #include "../common/CheatSearch.h" rlm@1: #include "../gb/gbCheats.h" rlm@1: #include "../gb/gbGlobals.h" rlm@1: rlm@1: static inline bool winGbCheatAddVerifyGs(const char *code, const char *desc) rlm@1: { rlm@1: gbAddGsCheat(code, desc); rlm@1: return true; rlm@1: } rlm@1: rlm@1: static inline bool winGbCheatAddVerifyGg(const char *code, const char *desc) rlm@1: { rlm@1: gbAddGgCheat(code, desc); rlm@1: return true; rlm@1: } rlm@1: rlm@1: //////////////////////////////// rlm@1: rlm@1: bool winGbCheatReaddress() rlm@1: { rlm@1: if (cheatSearchData.count != 3) rlm@1: return false; rlm@1: rlm@1: CheatSearchBlock *block = &cheatSearchData.blocks[0]; rlm@1: if (gbRamSize > 0) rlm@1: { rlm@1: if (gbRam) rlm@1: block->data = gbRam; rlm@1: else rlm@1: block->data = &gbMemory[0xa000]; rlm@1: block->offset = 0xa000; rlm@1: block->size = gbRamSize; rlm@1: cheatSearchSetSavedAndBits(block); rlm@1: } rlm@1: else rlm@1: { rlm@1: cheatSearchZeroBlock(&cheatSearchData.blocks[0]); rlm@1: } rlm@1: rlm@1: block = &cheatSearchData.blocks[1]; rlm@1: if (gbCgbMode) rlm@1: { rlm@1: block->data = &gbMemory[0xc000]; rlm@1: block->offset = 0xc000; rlm@1: block->size = 0x1000; rlm@1: cheatSearchSetSavedAndBits(block); rlm@1: rlm@1: block = &cheatSearchData.blocks[2]; rlm@1: block->data = gbWram; rlm@1: block->offset = 0xd000; rlm@1: block->size = 0x8000; rlm@1: cheatSearchSetSavedAndBits(block); rlm@1: } rlm@1: else rlm@1: { rlm@1: block->data = &gbMemory[0xc000]; rlm@1: block->offset = 0xc000; rlm@1: block->size = 0x2000; rlm@1: cheatSearchSetSavedAndBits(block); rlm@1: rlm@1: cheatSearchZeroBlock(&cheatSearchData.blocks[2]); rlm@1: } rlm@1: rlm@1: cheatSearchData.count = 3; rlm@1: return true; rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBCheatSearch dialog rlm@1: rlm@1: GBCheatSearch::GBCheatSearch(CWnd*pParent /*=NULL*/) rlm@1: : CDialog(GBCheatSearch::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(GBCheatSearch) rlm@1: searchType = -1; rlm@1: numberType = -1; rlm@1: sizeType = -1; rlm@1: updateValues = FALSE; rlm@1: valueType = -1; rlm@1: //}}AFX_DATA_INIT rlm@1: data = NULL; rlm@1: } rlm@1: rlm@1: GBCheatSearch::~GBCheatSearch() rlm@1: { rlm@1: if (data) rlm@1: free(data); rlm@1: } rlm@1: rlm@1: void GBCheatSearch::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(GBCheatSearch) rlm@1: DDX_Control(pDX, IDC_VALUE, m_value); rlm@1: DDX_Control(pDX, IDC_CHEAT_LIST, m_list); rlm@1: DDX_Radio(pDX, IDC_EQ, searchType); rlm@1: DDX_Radio(pDX, IDC_SIGNED, numberType); rlm@1: DDX_Radio(pDX, IDC_SIZE_8, sizeType); rlm@1: DDX_Check(pDX, IDC_UPDATE, updateValues); rlm@1: DDX_Radio(pDX, IDC_OLD_VALUE, valueType); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(GBCheatSearch, CDialog) rlm@1: //{{AFX_MSG_MAP(GBCheatSearch) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: ON_BN_CLICKED(IDC_ADD_CHEAT, OnAddCheat) rlm@1: ON_BN_CLICKED(IDC_SEARCH, OnSearch) rlm@1: ON_BN_CLICKED(IDC_START, OnStart) rlm@1: ON_BN_CLICKED(IDC_UPDATE, OnUpdate) rlm@1: ON_NOTIFY(LVN_GETDISPINFO, IDC_CHEAT_LIST, OnGetdispinfoCheatList) rlm@1: ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHEAT_LIST, OnItemchangedCheatList) rlm@1: ON_CONTROL_RANGE(BN_CLICKED, IDC_OLD_VALUE, IDC_SPECIFIC_VALUE, OnValueType) rlm@1: ON_CONTROL_RANGE(BN_CLICKED, IDC_EQ, IDC_GE, OnSearchType) rlm@1: ON_CONTROL_RANGE(BN_CLICKED, IDC_SIGNED, IDC_HEXADECIMAL, OnNumberType) rlm@1: ON_CONTROL_RANGE(BN_CLICKED, IDC_SIZE_8, IDC_SIZE_32, OnSizeType) rlm@1: //}}AFX_MSG_MAP rlm@1: ON_WM_CLOSE() rlm@1: ON_BN_CLICKED(IDC_CHEATREFRESHBUTTON, OnBnClickedCheatrefreshbutton) rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBCheatSearch message handlers rlm@1: rlm@1: void GBCheatSearch::OnOk() rlm@1: { rlm@1: if (data) rlm@1: free(data); rlm@1: data = NULL; rlm@1: rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: { rlm@1: theApp.modelessCheatDialogIsOpen = false; rlm@1: DestroyWindow(); rlm@1: } rlm@1: else rlm@1: { rlm@1: EndDialog(TRUE); rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnClose() rlm@1: { rlm@1: CDialog::OnClose(); rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: { rlm@1: theApp.modelessCheatDialogIsOpen = false; rlm@1: DestroyWindow(); rlm@1: } rlm@1: else rlm@1: { rlm@1: EndDialog(FALSE); rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnBnClickedCheatrefreshbutton() rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnAddCheat() rlm@1: { rlm@1: int mark = m_list.GetSelectionMark(); rlm@1: rlm@1: if (mark != -1) rlm@1: { rlm@1: LVITEM item; rlm@1: memset(&item, 0, sizeof(item)); rlm@1: item.mask = LVIF_PARAM; rlm@1: item.iItem = mark; rlm@1: if (m_list.GetItem(&item)) rlm@1: { rlm@1: AddGBCheat dlg((u32)item.lParam); rlm@1: dlg.DoModal(); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnSearch() rlm@1: { rlm@1: CString buffer; rlm@1: if (valueType == 0) rlm@1: cheatSearch(&cheatSearchData, rlm@1: searchType, rlm@1: sizeType, rlm@1: numberType == 0); rlm@1: else rlm@1: { rlm@1: m_value.GetWindowText(buffer); rlm@1: if (buffer.IsEmpty()) rlm@1: { rlm@1: systemMessage(IDS_NUMBER_CANNOT_BE_EMPTY, "Number cannot be empty"); rlm@1: return; rlm@1: } rlm@1: int value = 0; rlm@1: switch (numberType) rlm@1: { rlm@1: case 0: rlm@1: sscanf(buffer, "%d", &value); rlm@1: break; rlm@1: case 1: rlm@1: sscanf(buffer, "%u", &value); rlm@1: break; rlm@1: default: rlm@1: sscanf(buffer, "%x", &value); rlm@1: } rlm@1: cheatSearchValue(&cheatSearchData, rlm@1: searchType, rlm@1: sizeType, rlm@1: numberType == 0, rlm@1: value); rlm@1: } rlm@1: rlm@1: addChanges(true); rlm@1: rlm@1: if (updateValues) rlm@1: cheatSearchUpdateValues(&cheatSearchData); rlm@1: rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData, sizeType) == 0 ? FALSE : TRUE); rlm@1: rlm@1: if (0 == cheatSearchGetCount(&cheatSearchData, sizeType)) rlm@1: OnStart(); rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnStart() rlm@1: { rlm@1: if (cheatSearchData.count == 0) rlm@1: { rlm@1: CheatSearchBlock *block = &cheatSearchData.blocks[0]; rlm@1: if (gbRamSize > 0) rlm@1: { rlm@1: if (gbRam) rlm@1: block->data = gbRam; rlm@1: else rlm@1: block->data = &gbMemory[0xa000]; rlm@1: block->size = gbRamSize; rlm@1: block->offset = 0xa000; rlm@1: block->saved = (u8 *)malloc(gbRamSize); rlm@1: block->bits = (u8 *)malloc(gbRamSize >> 3); rlm@1: } rlm@1: else rlm@1: { rlm@1: cheatSearchZeroBlock(&cheatSearchData.blocks[0]); rlm@1: } rlm@1: rlm@1: block = &cheatSearchData.blocks[1]; rlm@1: if (gbCgbMode) rlm@1: { rlm@1: block->data = &gbMemory[0xc000]; rlm@1: block->size = 0x1000; rlm@1: block->offset = 0xc000; rlm@1: block->saved = (u8 *)malloc(0x1000); rlm@1: block->bits = (u8 *)malloc(0x1000 >> 3); rlm@1: rlm@1: block = &cheatSearchData.blocks[2]; rlm@1: block->data = gbWram; rlm@1: block->size = 0x8000; rlm@1: block->offset = 0xd000; rlm@1: block->saved = (u8 *)malloc(0x8000); rlm@1: block->bits = (u8 *)malloc(0x8000 >> 3); rlm@1: } rlm@1: else rlm@1: { rlm@1: block->data = &gbMemory[0xc000]; rlm@1: block->size = 0x2000; rlm@1: block->offset = 0xc000; rlm@1: block->saved = (u8 *)malloc(0x2000); rlm@1: block->bits = (u8 *)malloc(0x2000 >> 3); rlm@1: rlm@1: cheatSearchZeroBlock(&cheatSearchData.blocks[2]); rlm@1: } rlm@1: rlm@1: cheatSearchData.count = 3; rlm@1: } rlm@1: rlm@1: cheatSearchStart(&cheatSearchData); rlm@1: GetDlgItem(IDC_SEARCH)->EnableWindow(TRUE); rlm@1: rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: { rlm@1: GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE); rlm@1: GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE); rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnUpdate() rlm@1: { rlm@1: if (GetDlgItem(IDC_UPDATE)->SendMessage(BM_GETCHECK, rlm@1: 0, rlm@1: 0) & BST_CHECKED) rlm@1: updateValues = true; rlm@1: else rlm@1: updateValues = false; rlm@1: regSetDwordValue("gbCheatsUpdate", updateValues); rlm@1: } rlm@1: rlm@1: BOOL GBCheatSearch::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: CString temp = winResLoadString(IDS_ADDRESS); rlm@1: rlm@1: m_list.InsertColumn(0, temp, LVCFMT_CENTER, 125, 0); rlm@1: rlm@1: temp = winResLoadString(IDS_OLD_VALUE); rlm@1: m_list.InsertColumn(1, temp, LVCFMT_CENTER, 125, 1); rlm@1: rlm@1: temp = winResLoadString(IDS_NEW_VALUE); rlm@1: m_list.InsertColumn(2, temp, LVCFMT_CENTER, 125, 2); rlm@1: rlm@1: m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)), rlm@1: TRUE); rlm@1: rlm@1: m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT); rlm@1: rlm@1: if (!cheatSearchData.count) rlm@1: { rlm@1: GetDlgItem(IDC_SEARCH)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(FALSE); rlm@1: } rlm@1: rlm@1: valueType = regQueryDwordValue("gbCheatsValueType", 0); rlm@1: if (valueType < 0 || valueType > 1) rlm@1: valueType = 2; rlm@1: rlm@1: searchType = regQueryDwordValue("gbCheatsSearchType", rlm@1: SEARCH_EQ); rlm@1: if (searchType < 0 || searchType > 5) rlm@1: searchType = 0; rlm@1: rlm@1: numberType = regQueryDwordValue("gbCheatsNumberType", 2); rlm@1: if (numberType < 0 || numberType > 2) rlm@1: numberType = 2; rlm@1: rlm@1: sizeType = regQueryDwordValue("gbCheatsSizeType", 0); rlm@1: if (sizeType < 0 || sizeType > 2) rlm@1: sizeType = 0; rlm@1: rlm@1: updateValues = regQueryDwordValue("gbCheatsUpdate", 0) ? rlm@1: true : false; rlm@1: rlm@1: UpdateData(FALSE); rlm@1: rlm@1: if (valueType == 0) rlm@1: m_value.EnableWindow(FALSE); rlm@1: rlm@1: CenterWindow(); rlm@1: rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: GetDlgItem(IDC_CHEATREFRESHBUTTON)->ShowWindow(TRUE); rlm@1: rlm@1: if (cheatSearchData.count) rlm@1: { rlm@1: addChanges(false); rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(cheatSearchGetCount(&cheatSearchData, rlm@1: sizeType) == 0 ? FALSE : TRUE); rlm@1: } rlm@1: else rlm@1: { rlm@1: if (theApp.modelessCheatDialogIsOpen) rlm@1: GetDlgItem(IDC_CHEATREFRESHBUTTON)->EnableWindow(FALSE); rlm@1: } rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnGetdispinfoCheatList(NMHDR*pNMHDR, LRESULT*pResult) rlm@1: { rlm@1: LV_DISPINFO*info = (LV_DISPINFO *)pNMHDR; rlm@1: if (info->item.mask & LVIF_TEXT) rlm@1: { rlm@1: int index = info->item.iItem; rlm@1: int col = info->item.iSubItem; rlm@1: rlm@1: switch (col) rlm@1: { rlm@1: case 0: rlm@1: strcpy(info->item.pszText, data[index].address); rlm@1: break; rlm@1: case 1: rlm@1: strcpy(info->item.pszText, data[index].oldValue); rlm@1: break; rlm@1: case 2: rlm@1: strcpy(info->item.pszText, data[index].newValue); rlm@1: break; rlm@1: } rlm@1: } rlm@1: *pResult = TRUE; rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult) rlm@1: { rlm@1: GetDlgItem(IDC_ADD_CHEAT)->EnableWindow(m_list.GetSelectionMark() != -1); rlm@1: } rlm@1: rlm@1: int GBCheatSearch::getBank(u16 addr, int j) rlm@1: { rlm@1: switch (addr >> 12) rlm@1: { rlm@1: case 0x0a: rlm@1: return j / 0x2000; rlm@1: case 0x0d: rlm@1: return j / 0x1000; rlm@1: } rlm@1: return 0; rlm@1: } rlm@1: rlm@1: void GBCheatSearch::addChange(int index, int bank, u16 address, int offset, u32 oldValue, u32 newValue) rlm@1: { rlm@1: data[index].bank = bank; rlm@1: if (bank) rlm@1: { rlm@1: if (address == 0xa000) rlm@1: address |= offset & 0x1fff; rlm@1: else rlm@1: address |= offset & 0xfff; rlm@1: } rlm@1: else rlm@1: address |= offset; rlm@1: data[index].addr = address; rlm@1: sprintf(data[index].address, "%02x:%04x", bank, address); rlm@1: switch (numberType) rlm@1: { rlm@1: case 0: rlm@1: sprintf(data[index].oldValue, "%d", oldValue); rlm@1: sprintf(data[index].newValue, "%d", newValue); rlm@1: break; rlm@1: case 1: rlm@1: sprintf(data[index].oldValue, "%u", oldValue); rlm@1: sprintf(data[index].newValue, "%u", newValue); rlm@1: break; rlm@1: case 2: rlm@1: switch (sizeType) rlm@1: { rlm@1: case 0: rlm@1: sprintf(data[index].oldValue, "%02x", oldValue); rlm@1: sprintf(data[index].newValue, "%02x", newValue); rlm@1: break; rlm@1: case 1: rlm@1: sprintf(data[index].oldValue, "%04x", oldValue); rlm@1: sprintf(data[index].newValue, "%04x", newValue); rlm@1: break; rlm@1: case 2: rlm@1: sprintf(data[index].oldValue, "%08x", oldValue); rlm@1: sprintf(data[index].newValue, "%08x", newValue); rlm@1: break; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::addChanges(bool showMsg) rlm@1: { rlm@1: int count = cheatSearchGetCount(&cheatSearchData, sizeType); rlm@1: rlm@1: m_list.DeleteAllItems(); rlm@1: rlm@1: if (count > 4000) rlm@1: { rlm@1: if (showMsg) rlm@1: systemMessage( rlm@1: IDS_SEARCH_PRODUCED_TOO_MANY, rlm@1: "Search produced %d results.\nThey have been remembered, but are too many to display.\nPlease refine it better by performing additional searches.", rlm@1: count); rlm@1: return; rlm@1: } rlm@1: rlm@1: if (count == 0) rlm@1: { rlm@1: if (showMsg) rlm@1: systemMessage(IDS_SEARCH_PRODUCED_NO_RESULTS, "Search produced no results"); rlm@1: return; rlm@1: } rlm@1: rlm@1: m_list.SetItemCount(count); rlm@1: if (data) rlm@1: free(data); rlm@1: rlm@1: data = (WinGbCheatsData *)calloc(count, sizeof(WinGbCheatsData)); rlm@1: rlm@1: int inc = 1; rlm@1: switch (sizeType) rlm@1: { rlm@1: case 1: rlm@1: inc = 2; rlm@1: break; rlm@1: case 2: rlm@1: inc = 4; rlm@1: break; rlm@1: } rlm@1: rlm@1: int index = 0; rlm@1: if (numberType == 0) rlm@1: { rlm@1: for (int i = 0; i < cheatSearchData.count; i++) rlm@1: { rlm@1: CheatSearchBlock *block = &cheatSearchData.blocks[i]; rlm@1: rlm@1: for (int j = 0; j < block->size; j += inc) rlm@1: { rlm@1: if (IS_BIT_SET(block->bits, j)) rlm@1: { rlm@1: addChange(index++, rlm@1: getBank(block->offset|j, j), rlm@1: block->offset, rlm@1: j, rlm@1: cheatSearchSignedRead(block->saved, rlm@1: j, rlm@1: sizeType), rlm@1: cheatSearchSignedRead(block->data, rlm@1: j, rlm@1: sizeType)); rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: for (int i = 0; i < cheatSearchData.count; i++) rlm@1: { rlm@1: CheatSearchBlock *block = &cheatSearchData.blocks[i]; rlm@1: rlm@1: for (int j = 0; j < block->size; j += inc) rlm@1: { rlm@1: if (IS_BIT_SET(block->bits, j)) rlm@1: { rlm@1: addChange(index++, rlm@1: getBank(block->offset|j, j), rlm@1: block->offset, rlm@1: j, rlm@1: cheatSearchRead(block->saved, rlm@1: j, rlm@1: sizeType), rlm@1: cheatSearchRead(block->data, rlm@1: j, rlm@1: sizeType)); rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: for (int i = 0; i < count; i++) rlm@1: { rlm@1: LVITEM item; rlm@1: rlm@1: item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; rlm@1: item.iItem = i; rlm@1: item.iSubItem = 0; rlm@1: item.lParam = data[i].addr| rlm@1: (data[i].bank << 16); rlm@1: item.state = 0; rlm@1: item.stateMask = 0; rlm@1: item.pszText = LPSTR_TEXTCALLBACK; rlm@1: m_list.InsertItem(&item); rlm@1: rlm@1: m_list.SetItemText(i, 1, LPSTR_TEXTCALLBACK); rlm@1: m_list.SetItemText(i, 2, LPSTR_TEXTCALLBACK); rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnValueType(UINT id) rlm@1: { rlm@1: switch (id) rlm@1: { rlm@1: case IDC_OLD_VALUE: rlm@1: valueType = 0; rlm@1: m_value.EnableWindow(FALSE); rlm@1: regSetDwordValue("gbCheatsValueType", 0); rlm@1: break; rlm@1: case IDC_SPECIFIC_VALUE: rlm@1: valueType = 1; rlm@1: m_value.EnableWindow(TRUE); rlm@1: regSetDwordValue("gbCheatsValueType", 1); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnSearchType(UINT id) rlm@1: { rlm@1: switch (id) rlm@1: { rlm@1: case IDC_EQ: rlm@1: searchType = SEARCH_EQ; rlm@1: regSetDwordValue("gbCheatsSearchType", 0); rlm@1: break; rlm@1: case IDC_NE: rlm@1: searchType = SEARCH_NE; rlm@1: regSetDwordValue("gbCheatsSearchType", 1); rlm@1: break; rlm@1: case IDC_LT: rlm@1: searchType = SEARCH_LT; rlm@1: regSetDwordValue("gbCheatsSearchType", 2); rlm@1: break; rlm@1: case IDC_LE: rlm@1: searchType = SEARCH_LE; rlm@1: regSetDwordValue("gbCheatsSearchType", 3); rlm@1: break; rlm@1: case IDC_GT: rlm@1: searchType = SEARCH_GT; rlm@1: regSetDwordValue("gbCheatsSearchType", 4); rlm@1: break; rlm@1: case IDC_GE: rlm@1: searchType = SEARCH_GE; rlm@1: regSetDwordValue("gbCheatsSearchType", 5); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnNumberType(UINT id) rlm@1: { rlm@1: switch (id) rlm@1: { rlm@1: case IDC_SIGNED: rlm@1: numberType = 0; rlm@1: regSetDwordValue("gbCheatsNumberType", 0); rlm@1: if (m_list.GetItemCount()) rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: break; rlm@1: case IDC_UNSIGNED: rlm@1: numberType = 1; rlm@1: regSetDwordValue("gbCheatsNumberType", 1); rlm@1: if (m_list.GetItemCount()) rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: break; rlm@1: case IDC_HEXADECIMAL: rlm@1: numberType = 2; rlm@1: regSetDwordValue("gbCheatsNumberType", 2); rlm@1: if (m_list.GetItemCount()) rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatSearch::OnSizeType(UINT id) rlm@1: { rlm@1: switch (id) rlm@1: { rlm@1: case IDC_SIZE_8: rlm@1: sizeType = BITS_8; rlm@1: regSetDwordValue("gbCheatsSizeType", 0); rlm@1: if (m_list.GetItemCount()) rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: break; rlm@1: case IDC_SIZE_16: rlm@1: sizeType = BITS_16; rlm@1: regSetDwordValue("gbCheatsSizeType", 1); rlm@1: if (m_list.GetItemCount()) rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: break; rlm@1: case IDC_SIZE_32: rlm@1: sizeType = BITS_32; rlm@1: regSetDwordValue("gbCheatsSizeType", 2); rlm@1: if (m_list.GetItemCount()) rlm@1: { rlm@1: addChanges(false); rlm@1: } rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // AddGBCheat dialog rlm@1: rlm@1: AddGBCheat::AddGBCheat(u32 addr, CWnd*pParent /*=NULL*/) rlm@1: : CDialog(AddGBCheat::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(AddGBCheat) rlm@1: numberType = regQueryDwordValue("gbCheatsNumberType", 2); rlm@1: if (numberType < 0 || numberType > 2) rlm@1: numberType = 2; rlm@1: sizeType = regQueryDwordValue("gbCheatsSizeType", 0); rlm@1: if (sizeType < 0 || sizeType > 2) rlm@1: sizeType = 0; rlm@1: //}}AFX_DATA_INIT rlm@1: address = addr; rlm@1: } rlm@1: rlm@1: void AddGBCheat::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(AddGBCheat) rlm@1: DDX_Control(pDX, IDC_VALUE, m_value); rlm@1: DDX_Control(pDX, IDC_ADDRESS, m_address); rlm@1: DDX_Control(pDX, IDC_DESC, m_desc); rlm@1: DDX_Radio(pDX, IDC_SIZE_8, sizeType); rlm@1: DDX_Radio(pDX, IDC_SIGNED, numberType); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(AddGBCheat, CDialog) rlm@1: //{{AFX_MSG_MAP(AddGBCheat) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: ON_BN_CLICKED(ID_CANCEL, OnCancel) rlm@1: ON_CONTROL_RANGE(BN_CLICKED, IDC_SIGNED, IDC_HEXADECIMAL, OnNumberType) rlm@1: ON_CONTROL_RANGE(BN_CLICKED, IDC_SIZE_8, IDC_SIZE_32, OnSizeType) rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // AddGBCheat message handlers rlm@1: rlm@1: void AddGBCheat::OnCancel() rlm@1: { rlm@1: EndDialog(FALSE); rlm@1: } rlm@1: rlm@1: void AddGBCheat::OnOk() rlm@1: { rlm@1: // add cheat rlm@1: if (addCheat()) rlm@1: { rlm@1: EndDialog(TRUE); rlm@1: } rlm@1: } rlm@1: rlm@1: bool AddGBCheat::addCheat() rlm@1: { rlm@1: CString buffer; rlm@1: CString code; rlm@1: rlm@1: u32 value; rlm@1: m_value.GetWindowText(buffer); rlm@1: rlm@1: if (buffer.IsEmpty()) rlm@1: { rlm@1: systemMessage(IDS_VALUE_CANNOT_BE_EMPTY, "Value cannot be empty"); rlm@1: return false; rlm@1: } rlm@1: rlm@1: switch (numberType) rlm@1: { rlm@1: case 0: rlm@1: sscanf(buffer, "%d", &value); rlm@1: break; rlm@1: case 1: rlm@1: sscanf(buffer, "%u", &value); rlm@1: break; rlm@1: default: rlm@1: sscanf(buffer, "%x", &value); rlm@1: } rlm@1: rlm@1: m_desc.GetWindowText(buffer); rlm@1: rlm@1: int bank = (address >> 16); rlm@1: address &= 0xFFFF; rlm@1: rlm@1: if (address >= 0xd000) rlm@1: bank += 0x90; rlm@1: else rlm@1: bank = 0x01; rlm@1: rlm@1: switch (sizeType) rlm@1: { rlm@1: case 0: rlm@1: code.Format("%02X%02X%02X%02X", bank, value, address&0xFF, address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: break; rlm@1: case 1: rlm@1: code.Format("%02X%02X%02X%02X", bank, value&0xFF, address&0xFF, rlm@1: address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: address++; rlm@1: code.Format("%02X%02X%02X%02X", bank, value>>8, address&0xFF, rlm@1: address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: break; rlm@1: case 2: rlm@1: code.Format("%02X%02X%02X%02X", bank, value&0xFF, address&0xFF, rlm@1: address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: address++; rlm@1: code.Format("%02X%02X%02X%02X", bank, (value>>8) & 0xFF, address&0xFF, rlm@1: address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: address++; rlm@1: code.Format("%02X%02X%02X%02X", bank, (value>>16)&0xFF, address&0xFF, rlm@1: address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: address++; rlm@1: code.Format("%02X%02X%02X%02X", bank, value>>24, address&0xFF, rlm@1: address>>8); rlm@1: gbAddGsCheat(code, buffer); rlm@1: break; rlm@1: } rlm@1: rlm@1: return true; rlm@1: } rlm@1: rlm@1: BOOL AddGBCheat::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: CString buffer; rlm@1: buffer.Format("%02x:%08x", (address>>16), address&0xFFFF); rlm@1: m_address.SetWindowText(buffer); rlm@1: m_address.EnableWindow(FALSE); rlm@1: ::SetWindowLong(m_address, rlm@1: GWL_USERDATA, rlm@1: address); rlm@1: rlm@1: UpdateData(FALSE); rlm@1: rlm@1: m_desc.LimitText(32); rlm@1: rlm@1: if (address != 0) rlm@1: { rlm@1: GetDlgItem(IDC_SIZE_8)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_SIZE_16)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_SIZE_32)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_HEXADECIMAL)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_UNSIGNED)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_SIGNED)->EnableWindow(FALSE); rlm@1: } rlm@1: CenterWindow(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void AddGBCheat::OnNumberType(UINT id) rlm@1: { rlm@1: switch (id) rlm@1: { rlm@1: case IDC_SIGNED: rlm@1: numberType = 0; rlm@1: regSetDwordValue("gbCheatsNumberType", 0); rlm@1: break; rlm@1: case IDC_UNSIGNED: rlm@1: numberType = 1; rlm@1: regSetDwordValue("gbCheatsNumberType", 1); rlm@1: break; rlm@1: case IDC_HEXADECIMAL: rlm@1: numberType = 2; rlm@1: regSetDwordValue("gbCheatsNumberType", 2); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void AddGBCheat::OnSizeType(UINT id) rlm@1: { rlm@1: switch (id) rlm@1: { rlm@1: case IDC_SIZE_8: rlm@1: sizeType = BITS_8; rlm@1: regSetDwordValue("gbCheatsSizeType", 0); rlm@1: break; rlm@1: case IDC_SIZE_16: rlm@1: sizeType = BITS_16; rlm@1: regSetDwordValue("gbCheatsSizeType", 1); rlm@1: break; rlm@1: case IDC_SIZE_32: rlm@1: sizeType = BITS_32; rlm@1: regSetDwordValue("gbCheatsSizeType", 2); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBCheatList dialog rlm@1: rlm@1: GBCheatList::GBCheatList(CWnd*pParent /*=NULL*/) rlm@1: : CDialog(GBCheatList::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(GBCheatList) rlm@1: // NOTE: the ClassWizard will add member initialization here rlm@1: //}}AFX_DATA_INIT rlm@1: duringRefresh = false; rlm@1: } rlm@1: rlm@1: void GBCheatList::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(GBCheatList) rlm@1: DDX_Control(pDX, IDC_CHEAT_LIST, m_list); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(GBCheatList, CDialog) rlm@1: //{{AFX_MSG_MAP(GBCheatList) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: ON_BN_CLICKED(IDC_ADD_GG_CHEAT, OnAddGgCheat) rlm@1: ON_BN_CLICKED(IDC_ADD_GS_CHEAT, OnAddGsCheat) rlm@1: ON_BN_CLICKED(IDC_ENABLE, OnEnable) rlm@1: ON_BN_CLICKED(IDC_REMOVE, OnRemove) rlm@1: ON_BN_CLICKED(IDC_REMOVE_ALL, OnRemoveAll) rlm@1: ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHEAT_LIST, OnItemchangedCheatList) rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBCheatList message handlers rlm@1: rlm@1: void GBCheatList::OnOk() rlm@1: { rlm@1: EndDialog(TRUE); rlm@1: } rlm@1: rlm@1: void GBCheatList::OnAddGgCheat() rlm@1: { rlm@1: CString temp = winResLoadString(IDS_ADD_GG_CODE); rlm@1: AddGBCode dlg(winGbCheatAddVerifyGg, 11, temp); rlm@1: dlg.DoModal(); rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void GBCheatList::OnAddGsCheat() rlm@1: { rlm@1: CString temp = winResLoadString(IDS_ADD_GS_CODE); rlm@1: rlm@1: AddGBCode dlg(winGbCheatAddVerifyGs, 8, temp); rlm@1: dlg.DoModal(); rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void GBCheatList::OnEnable() rlm@1: { rlm@1: int mark = m_list.GetSelectionMark(); rlm@1: rlm@1: if (mark != -1) rlm@1: { rlm@1: LVITEM item; rlm@1: memset(&item, 0, sizeof(item)); rlm@1: item.mask = LVIF_PARAM; rlm@1: item.iItem = mark; rlm@1: if (m_list.GetItem(&item)) rlm@1: { rlm@1: if (gbCheatList[item.lParam].enabled) rlm@1: gbCheatDisable(item.lParam); rlm@1: else rlm@1: gbCheatEnable(item.lParam); rlm@1: refresh(); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatList::OnRemove() rlm@1: { rlm@1: int mark = m_list.GetSelectionMark(); rlm@1: rlm@1: if (mark != -1) rlm@1: { rlm@1: LVITEM item; rlm@1: memset(&item, 0, sizeof(item)); rlm@1: item.mask = LVIF_PARAM; rlm@1: item.iItem = mark; rlm@1: if (m_list.GetItem(&item)) rlm@1: { rlm@1: gbCheatRemove(item.lParam); rlm@1: refresh(); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void GBCheatList::OnRemoveAll() rlm@1: { rlm@1: gbCheatRemoveAll(); rlm@1: refresh(); rlm@1: } rlm@1: rlm@1: void GBCheatList::OnItemchangedCheatList(NMHDR*pNMHDR, LRESULT*pResult) rlm@1: { rlm@1: if (m_list.GetSelectionMark() != -1) rlm@1: { rlm@1: GetDlgItem(IDC_REMOVE)->EnableWindow(TRUE); rlm@1: GetDlgItem(IDC_ENABLE)->EnableWindow(TRUE); rlm@1: } rlm@1: else rlm@1: { rlm@1: GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE); rlm@1: } rlm@1: rlm@1: if (!duringRefresh) rlm@1: { rlm@1: LPNMLISTVIEW l = (LPNMLISTVIEW)pNMHDR; rlm@1: if (l->uChanged & LVIF_STATE) rlm@1: { rlm@1: if (((l->uOldState & LVIS_STATEIMAGEMASK)>>12) != rlm@1: (((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) rlm@1: { rlm@1: if (m_list.GetCheck(l->iItem)) rlm@1: gbCheatEnable(l->lParam); rlm@1: else rlm@1: gbCheatDisable(l->lParam); rlm@1: refresh(); rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: BOOL GBCheatList::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: CString temp = winResLoadString(IDS_CODE); rlm@1: m_list.InsertColumn(0, temp, LVCFMT_LEFT, 120, 0); rlm@1: temp = winResLoadString(IDS_DESCRIPTION); rlm@1: m_list.InsertColumn(1, temp, LVCFMT_LEFT, 200, 1); rlm@1: temp = winResLoadString(IDS_STATUS); rlm@1: m_list.InsertColumn(2, temp, LVCFMT_LEFT, 80, 2); rlm@1: rlm@1: m_list.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)), rlm@1: TRUE); rlm@1: rlm@1: m_list.SetExtendedStyle(LVS_EX_CHECKBOXES | rlm@1: LVS_EX_FULLROWSELECT); rlm@1: rlm@1: refresh(); rlm@1: GetDlgItem(IDC_REMOVE)->EnableWindow(FALSE); rlm@1: GetDlgItem(IDC_ENABLE)->EnableWindow(FALSE); rlm@1: CenterWindow(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void GBCheatList::refresh() rlm@1: { rlm@1: duringRefresh = true; rlm@1: rlm@1: m_list.DeleteAllItems(); rlm@1: rlm@1: char buffer[2]; rlm@1: rlm@1: for (int i = 0; i < gbCheatNumber; i++) rlm@1: { rlm@1: LVITEM item; rlm@1: rlm@1: item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; rlm@1: item.iItem = i; rlm@1: item.iSubItem = 0; rlm@1: item.lParam = i; rlm@1: item.state = 0; rlm@1: item.stateMask = 0; rlm@1: item.pszText = gbCheatList[i].cheatCode; rlm@1: m_list.InsertItem(&item); rlm@1: rlm@1: m_list.SetCheck(i, (gbCheatList[i].enabled ? TRUE : FALSE)); rlm@1: rlm@1: m_list.SetItemText(i, 1, gbCheatList[i].cheatDesc); rlm@1: rlm@1: buffer[0] = (gbCheatList[i].enabled) ? 'E' : 'D'; rlm@1: buffer[1] = 0; rlm@1: m_list.SetItemText(i, 2, buffer); rlm@1: } rlm@1: duringRefresh = false; rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // AddGBCode dialog rlm@1: rlm@1: AddGBCode::AddGBCode(bool(*verify)(const char *, const char *), int len, const char *title, CWnd*pParent /*=NULL*/) rlm@1: : CDialog(AddGBCode::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(AddGBCode) rlm@1: // NOTE: the ClassWizard will add member initialization here rlm@1: //}}AFX_DATA_INIT rlm@1: addVerify = verify; rlm@1: addLength = len; rlm@1: addTitle = title; rlm@1: } rlm@1: rlm@1: void AddGBCode::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(AddGBCode) rlm@1: DDX_Control(pDX, IDC_DESC, m_desc); rlm@1: DDX_Control(pDX, IDC_CODE, m_code); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(AddGBCode, CDialog) rlm@1: //{{AFX_MSG_MAP(AddGBCode) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: ON_BN_CLICKED(ID_CANCEL, OnCancel) rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // AddGBCode message handlers rlm@1: rlm@1: void AddGBCode::OnOk() rlm@1: { rlm@1: CString desc; rlm@1: CString buffer; rlm@1: m_code.GetWindowText(buffer); rlm@1: m_desc.GetWindowText(desc); rlm@1: rlm@1: StringTokenizer st(buffer, " \t\n\r"); rlm@1: const char * t = st.next(); rlm@1: while (t) rlm@1: { rlm@1: addVerify(t, desc); rlm@1: t = st.next(); rlm@1: } rlm@1: EndDialog(TRUE); rlm@1: } rlm@1: rlm@1: void AddGBCode::OnCancel() rlm@1: { rlm@1: EndDialog(FALSE); rlm@1: } rlm@1: rlm@1: BOOL AddGBCode::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: m_code.LimitText(1024); rlm@1: m_desc.LimitText(32); rlm@1: SetWindowText(addTitle); rlm@1: CenterWindow(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: