diff --git a/bml.cpp b/bml.cpp index f6c7fa92..3f597b72 100644 --- a/bml.cpp +++ b/bml.cpp @@ -1,11 +1,27 @@ -#include #include #include #include +#include "port.h" #include "bml.h" -static inline bml_node *bml_node_new(void) +static char *strndup_p(char *str, int len) +{ + char *buffer; + int n; + + buffer = (char *) malloc (len + 1); + + if (buffer) + { + for (n = 0; ((n < len) && (str[n] != 0)); n++) buffer[n] = str[n]; + buffer[n] = '\0'; + } + + return buffer; +} + +static inline bml_node *bml_node_new (void) { bml_node *node = new bml_node; @@ -16,6 +32,28 @@ static inline bml_node *bml_node_new(void) return node; } +static inline int islf(char c) +{ + return (c == '\r' || c == '\n'); +} + +static inline int isblank(char c) +{ + return (c == ' ' || c == '\t'); +} + +static inline int isalnum(char c) +{ + return ((c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9')); +} + +static inline int bml_valid (char c) +{ + return (isalnum (c) || c == '-'); +} + static char *strndup_trim (char *str, int len) { int start; @@ -27,17 +65,7 @@ static char *strndup_trim (char *str, int len) for (end = len - 1; isblank (str[end]) || str[end] == '\n' || str[end] == '\r'; end--) {} - return strndup (str + start, end - start + 1); -} - -static inline int bml_valid (char c) -{ - return (isalnum (c) || c == '-'); -} - -static inline int islf(char c) -{ - return (c == '\r' || c == '\n'); + return strndup_p (str + start, end - start + 1); } static inline unsigned int bml_read_depth (char *data) @@ -77,7 +105,7 @@ static void bml_parse_data (bml_node *node, char **data) if (p[len] != '\"') return; - node->data = strndup (p + 2, len - 2); + node->data = strndup_p (p + 2, len - 2); *data += len + 1; } else if (*p == '=') diff --git a/cheats.h b/cheats.h index 2ba29589..a651a63b 100644 --- a/cheats.h +++ b/cheats.h @@ -272,6 +272,7 @@ void S9xUpdateCheatsInMemory (void); bool8 S9xImportCheatsFromDatabase (const char *filename); void S9xCheatsDisable (void); void S9xCheatsEnable (void); +char *S9xCheatValidate (char *cheat); void S9xInitCheatData (void); void S9xInitWatchedAddress (void); diff --git a/cheats2.cpp b/cheats2.cpp index 003be910..47ee1b44 100644 --- a/cheats2.cpp +++ b/cheats2.cpp @@ -613,6 +613,9 @@ int S9xAddCheatGroup (const char *name, const char *cheat) int S9xModifyCheatGroup (uint32 num, const char *name, const char *cheat) { + if (num >= Cheat.g.size()) + return -1; + S9xDisableCheatGroup (num); delete[] Cheat.g[num].name; @@ -639,21 +642,46 @@ char *S9xCheatToText (SCheat *c) return text; } +char *S9xCheatGroupToText(SCheatGroup *g) +{ + std::string text = ""; + unsigned int i; + + if (g->c.size() == 0) + return NULL; + + for (i = 0; i < g->c.size(); i++) + { + char *tmp = S9xCheatToText(&g->c[i]); + if (i != 0) + text += '+'; + text += tmp; + delete[] tmp; + } + + return strdup(text.c_str()); +} + +char *S9xCheatValidate(char *code_string) +{ + SCheatGroup g = S9xCreateCheatGroup ("temp", code_string); + + delete[] g.name; + + if (g.c.size() > 0) + { + return S9xCheatGroupToText(&g); + } + + return NULL; +} + char *S9xCheatGroupToText (uint32 num) { - std::string text = ""; - unsigned int i; + if (num >= Cheat.g.size()) + return NULL; - for (i = 0; i < Cheat.g[num].c.size (); i++) - { - char *tmp = S9xCheatToText (&Cheat.g[num].c[i]); - if (i != 0) - text += '+'; - text += tmp; - delete[] tmp; - } - - return strdup (text.c_str ()); + return S9xCheatGroupToText(&Cheat.g[num]); } void S9xUpdateCheatsInMemory (void) diff --git a/memmap.cpp b/memmap.cpp index 1509e291..a522179a 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -1787,6 +1787,8 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize) S9xReset(); + S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); + return (TRUE); } @@ -1951,6 +1953,7 @@ bool8 CMemory::LoadMultiCartInt () S9xReset(); S9xInitCheatData(); + S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); return (TRUE); } diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index 607188a1..2b94b81b 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -246,7 +246,7 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,168,131,10 END -IDD_CHEATER DIALOGEX 0, 0, 262, 218 +IDD_CHEATER DIALOGEX 0, 0, 262, 194 STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU CAPTION "Cheat Entry and Editor" FONT 8, "MS Sans Serif", 0, 0, 0x1 @@ -258,14 +258,10 @@ BEGIN PUSHBUTTON "C&lear",IDC_CLEAR_CHEATS,215,65,40,15 EDITTEXT IDC_CHEAT_CODE,86,134,118,15,ES_UPPERCASE | ES_AUTOHSCROLL EDITTEXT IDC_CHEAT_DESCRIPTION,85,154,119,15,ES_AUTOHSCROLL - EDITTEXT IDC_CHEAT_ADDRESS,85,175,44,15,ES_UPPERCASE | ES_AUTOHSCROLL - EDITTEXT IDC_CHEAT_BYTE,215,175,26,15,ES_UPPERCASE | ES_AUTOHSCROLL - PUSHBUTTON "&OK",IDOK,93,196,50,15 - PUSHBUTTON "&Cancel",IDCANCEL,151,196,50,15 + PUSHBUTTON "&OK",IDOK,99,174,50,15 + PUSHBUTTON "&Cancel",IDCANCEL,154,174,50,15 RTEXT "Enter Cheat Code:",IDC_LABEL_CHEAT_CODE,23,134,59,15,SS_CENTERIMAGE RTEXT "Cheat Description",IDC_LABEL_CHEAT_DESCRIPTION,19,154,61,15,SS_CENTERIMAGE - RTEXT "Cheat Address (hex)",IDC_LABEL_CHEAT_ADDRESS,18,175,64,15,SS_CENTERIMAGE - RTEXT "New Value (dec or hex)",IDC_LABEL_CHEAT_BYTE,134,175,74,15,SS_CENTERIMAGE END IDD_NETPLAYPROGRESS DIALOG 0, 0, 186, 61 diff --git a/win32/snes9xw.vcxproj b/win32/snes9xw.vcxproj index efc7ba58..29d57c3d 100644 --- a/win32/snes9xw.vcxproj +++ b/win32/snes9xw.vcxproj @@ -389,6 +389,7 @@ + @@ -519,6 +520,7 @@ + diff --git a/win32/snes9xw.vcxproj.filters b/win32/snes9xw.vcxproj.filters index 36ead7cc..687b5ab2 100644 --- a/win32/snes9xw.vcxproj.filters +++ b/win32/snes9xw.vcxproj.filters @@ -51,6 +51,9 @@ Emu + + Emu + UnZip @@ -404,6 +407,9 @@ Emu + + Emu + Emu diff --git a/win32/wlanguage.h b/win32/wlanguage.h index 40e6add9..5201e616 100644 --- a/win32/wlanguage.h +++ b/win32/wlanguage.h @@ -546,6 +546,7 @@ Nintendo is a trade mark.") the current value. This value is used when a cheat is unapplied.\n\ (If left blank, no value is restored when the cheat is unapplied)") #define SEARCH_ERR_INVALIDSEARCHVALUE TEXT("Please enter a valid value for a search!") +#define SEARCH_COLUMN_CODE TEXT("Code") #define SEARCH_COLUMN_ADDRESS TEXT("Address") #define SEARCH_COLUMN_VALUE TEXT("Value") #define SEARCH_COLUMN_DESCRIPTION TEXT("Description") diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index ffc883f2..41fb3543 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -231,6 +231,7 @@ #include "AVIOutput.h" #include "InputCustom.h" #include +#include #if (((defined(_MSC_VER) && _MSC_VER >= 1300)) || defined(__MINGW32__)) // both MINGW and VS.NET use fstream instead of fstream.h which is deprecated @@ -2305,10 +2306,10 @@ LRESULT CALLBACK WinProc( break; case ID_CHEAT_ENTER: RestoreGUIDisplay (); - S9xRemoveCheats (); + S9xCheatsDisable (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_CHEATER), hWnd, DlgCheater); S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); - S9xApplyCheats (); + S9xCheatsEnable (); RestoreSNESDisplay (); break; case ID_CHEAT_SEARCH: @@ -2333,14 +2334,14 @@ LRESULT CALLBACK WinProc( case ID_CHEAT_APPLY: Settings.ApplyCheats = !Settings.ApplyCheats; if (!Settings.ApplyCheats){ - S9xRemoveCheats (); + S9xCheatsDisable (); S9xMessage (S9X_INFO, S9X_GAME_GENIE_CODE_ERROR, CHEATS_INFO_DISABLED); }else{ - S9xApplyCheats (); + S9xCheatsEnable (); bool on = false; extern struct SCheatData Cheat; - for (uint32 i = 0; i < Cheat.num_cheats && !on; i++) - if (Cheat.c [i].enabled) + for (uint32 i = 0; i < Cheat.g.size() && !on; i++) + if (Cheat.g [i].enabled) on = true; S9xMessage (S9X_INFO, S9X_GAME_GENIE_CODE_ERROR, on ? CHEATS_INFO_ENABLED : CHEATS_INFO_ENABLED_NONE); } @@ -4061,8 +4062,10 @@ static bool LoadROMPlain(const TCHAR *filename) if (Memory.LoadROM (_tToChar(filename))) { S9xStartCheatSearch (&Cheat); + if (Settings.ApplyCheats) + S9xCheatsEnable(); ReInitSound(); - ResetFrameTimer (); + ResetFrameTimer(); return (TRUE); } return (FALSE); @@ -4074,6 +4077,8 @@ static bool LoadROMMulti(const TCHAR *filename, const TCHAR *filename2) if (Memory.LoadMultiCart(_tToChar(filename), _tToChar(filename2))) { S9xStartCheatSearch(&Cheat); + if (Settings.ApplyCheats) + S9xCheatsEnable(); ReInitSound(); ResetFrameTimer(); return (TRUE); @@ -8490,6 +8495,7 @@ DWORD* state; a.pszText=d; \ a.cchTextMax=e; \ ListView_GetItem(GetDlgItem(hDlg, b), &a); +#define CHEAT_SIZE 1024 INT_PTR CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -8505,64 +8511,52 @@ INT_PTR CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_CHEAT_LIST), LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES); - SendDlgItemMessage(hDlg, IDC_CHEAT_CODE, EM_LIMITTEXT, 14, 0); - SendDlgItemMessage(hDlg, IDC_CHEAT_DESCRIPTION, EM_LIMITTEXT, 22, 0); - SendDlgItemMessage(hDlg, IDC_CHEAT_ADDRESS, EM_LIMITTEXT, 6, 0); - SendDlgItemMessage(hDlg, IDC_CHEAT_BYTE, EM_LIMITTEXT, 3, 0); + SendDlgItemMessage(hDlg, IDC_CHEAT_CODE, EM_LIMITTEXT, CHEAT_SIZE, 0); + SendDlgItemMessage(hDlg, IDC_CHEAT_DESCRIPTION, EM_LIMITTEXT, CHEAT_SIZE, 0); LVCOLUMN col; TCHAR temp[32]; - lstrcpy(temp,SEARCH_COLUMN_ADDRESS); + lstrcpy(temp, SEARCH_COLUMN_CODE); memset(&col, 0, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH; col.fmt=LVCFMT_LEFT; col.iOrder=0; col.cx=70; - col.cchTextMax=7; col.pszText=temp; ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 0, &col); - lstrcpy(temp,SEARCH_COLUMN_VALUE); - memset(&col, 0, sizeof(LVCOLUMN)); - col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; - col.fmt=LVCFMT_LEFT; - col.iOrder=1; - col.cx=43; - col.cchTextMax=3; - col.pszText=temp; - col.iSubItem=1; - - ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 1, &col); - lstrcpy(temp,SEARCH_COLUMN_DESCRIPTION); memset(&col, 0, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=2; col.cx=165; - col.cchTextMax=32; col.pszText=temp; col.iSubItem=2; - ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 2, &col); + ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 1, &col); - ct.index=new int[Cheat.num_cheats]; - ct.state=new DWORD[Cheat.num_cheats]; + ct.index=new int[Cheat.g.size()]; + ct.state=new DWORD[Cheat.g.size()]; uint32 counter; - for(counter=0; counter=curr_idx) - ct.index[k]++; - } - - - _stprintf(buffer, TEXT("%02X"), byte[j]); - memset(&lvi, 0, sizeof(LVITEM)); - lvi.iItem=curr_idx; - lvi.iSubItem=1; - lvi.mask=LVIF_TEXT; - lvi.pszText=buffer; - lvi.cchTextMax=2; - SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); - - - GetDlgItemText(hDlg, IDC_CHEAT_DESCRIPTION, tempDesc, 23); - - memset(&lvi, 0, sizeof(LVITEM)); - lvi.iItem=curr_idx; - lvi.iSubItem=2; - lvi.mask=LVIF_TEXT; - lvi.pszText=tempDesc; - lvi.cchTextMax=23; - SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); - - addy++; - - - } - } - else - { - uint8 byte; - TCHAR buffer[7]; - TCHAR buffer2[7]; - - GetDlgItemText(hDlg, IDC_CHEAT_ADDRESS, buffer, 7); - GetDlgItemText(hDlg, IDC_CHEAT_BYTE, buffer2, 7); + delete[] valid_cheat; int curr_idx=-1; + LVITEM lvi; memset(&lvi, 0, sizeof(LVITEM)); lvi.mask=LVIF_TEXT; - lvi.pszText=buffer; - lvi.cchTextMax=6; - lvi.iItem=0; + lvi.pszText=*wstring; + lvi.iItem=ListView_GetItemCount(GetDlgItem(hDlg,IDC_CHEAT_LIST)); curr_idx=ListView_InsertItem(GetDlgItem(hDlg,IDC_CHEAT_LIST), &lvi); - int scanres; - if(buffer2[0]=='$') - _stscanf(buffer2,TEXT("$%2X"), (unsigned int*)&scanres); - else _stscanf(buffer2,TEXT("%d"), &scanres); - byte = (uint8)(scanres & 0xff); + SetDlgItemText(hDlg, IDC_CHEAT_CODE, *wstring); - _stprintf(buffer2, TEXT("%02X"), byte); + unsigned int k; + for(k=0;k=curr_idx) + ct.index[k]++; + } memset(&lvi, 0, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=1; lvi.mask=LVIF_TEXT; - lvi.pszText=buffer2; - lvi.cchTextMax=2; - SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); - - GetDlgItemText(hDlg, IDC_CHEAT_DESCRIPTION, tempDesc, 23); - - memset(&lvi, 0, sizeof(LVITEM)); - lvi.iItem=curr_idx; - lvi.iSubItem=2; - lvi.mask=LVIF_TEXT; lvi.pszText=tempDesc; - lvi.cchTextMax=23; + lvi.cchTextMax=CHEAT_SIZE; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); + + delete wstring; } } break; case IDC_UPDATE_CHEAT: { - TCHAR temp[24]; - char code[24]; - GetDlgItemText(hDlg, IDC_CHEAT_CODE, temp, 23); - strcpy(code,_tToChar(temp)); - if(strcmp(code, "")) + unsigned int j; + TCHAR temp[CHEAT_SIZE]; + char code[CHEAT_SIZE]; + GetDlgItemTextA(hDlg, IDC_CHEAT_CODE, code, CHEAT_SIZE); + + char *valid_cheat = S9xCheatValidate(code); + + if(valid_cheat) { - int j; - bool skip=false; - int count=1; - uint32 addy; - uint8 byte[3]; - //test game genie - if (NULL==S9xGameGenieToRaw (code, addy, byte[0])) - skip=true; - //test goldfinger + Utf8ToWide *wstring; - // if(!skip - - //test PAR - - if(!skip) - { - if(NULL==S9xProActionReplayToRaw(code, addy, byte[0])) - skip=true; - } - - if(!skip) - return 0; - - for(j=0;j<(int)Cheat.num_cheats;j++) + for(j=0;j<(int)Cheat.g.size();j++) { if(ct.index[j]==sel_idx) ct.state[j]=Modified; } - for(j=0; jsel_idx) - ct.index[j]--; - } + for(j=0;jsel_idx) + ct.index[j]--; + } } ListView_DeleteItem(GetDlgItem(hDlg, IDC_CHEAT_LIST), sel_idx); @@ -8945,8 +8765,6 @@ INT_PTR CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) case IDC_CLEAR_CHEATS: internal_change = true; SetDlgItemText(hDlg,IDC_CHEAT_CODE,TEXT("")); - SetDlgItemText(hDlg,IDC_CHEAT_ADDRESS,TEXT("")); - SetDlgItemText(hDlg,IDC_CHEAT_BYTE,TEXT("")); SetDlgItemText(hDlg,IDC_CHEAT_DESCRIPTION,TEXT("")); ListView_SetItemState(GetDlgItem(hDlg, IDC_CHEAT_LIST),sel_idx, 0, LVIS_SELECTED|LVIS_FOCUSED); ListView_SetSelectionMark(GetDlgItem(hDlg, IDC_CHEAT_LIST), -1); @@ -8963,52 +8781,18 @@ INT_PTR CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch(HIWORD(wParam)) { case EN_CHANGE: - if(internal_change) + + char temp[CHEAT_SIZE]; + char *valid_cheat = NULL; + GetDlgItemTextA(hDlg, IDC_CHEAT_CODE, temp, CHEAT_SIZE); + + if (temp && temp[0] && (valid_cheat = S9xCheatValidate(temp))) { - internal_change=false; - return true; - } - SendMessageA((HWND)lParam, WM_GETTEXT, 15,(LPARAM)buffer); - GetCaretPos(&point); - - index = SendMessageA((HWND)lParam,(UINT) EM_CHARFROMPOS, 0, (LPARAM) ((point.x&0x0000FFFF) | (((point.y&0x0000FFFF))<<16))); - - k=0; - for(j=0; j='0' && buffer[j]<='9') || (buffer[j]>='A' && buffer[j]<='F') || buffer[j]=='-' || buffer[j]=='X') - { - buffer2[k]=buffer[j]; - k++; - } - else index --; - } - buffer2[k]='\0'; - - if(has_sel&&!new_sel&&strlen(buffer2)!=0) - { - SetDlgItemTextA(hDlg, IDC_CHEAT_ADDRESS, ""); - SetDlgItemTextA(hDlg, IDC_CHEAT_BYTE, ""); - - } - - if(new_sel!=0) - new_sel--; - - internal_change=true; - SendMessageA((HWND)lParam, WM_SETTEXT, 0,(LPARAM)buffer2); - SendMessageA((HWND)lParam, (UINT) EM_SETSEL, (WPARAM) (index), index); - - uint32 addy; - uint8 val; - bool8 sram; - uint8 bytes[3]; - if(NULL==S9xGameGenieToRaw(buffer2, addy, val)||NULL==S9xProActionReplayToRaw(buffer2, addy, val)||NULL==S9xGoldFingerToRaw(buffer2, addy, sram, val, bytes)) - { - if(has_sel) + if (has_sel) EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); else EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), true); + delete[] valid_cheat; } else { @@ -9016,130 +8800,6 @@ INT_PTR CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); } - // SetDlgItemText(hDlg, IDC_CHEAT_ADDRESS, ""); - // SetDlgItemText(hDlg, IDC_CHEAT_BYTE, ""); - break; - } - break; - } - case IDC_CHEAT_ADDRESS: - { - uint32 j, k; - long index; - char buffer[7]; - char buffer2[7]; - POINT point; - switch(HIWORD(wParam)) - { - case EN_CHANGE: - if(internal_change) - { - internal_change=false; - return true; - } - SendMessageA((HWND)lParam, WM_GETTEXT, 7,(LPARAM)buffer); - GetCaretPos(&point); - - index = SendMessageA((HWND)lParam,(UINT) EM_CHARFROMPOS, 0, (LPARAM) ((point.x&0x0000FFFF) | (((point.y&0x0000FFFF))<<16))); - - k=0; - for(j=0; j='0' && buffer[j]<='9') || (buffer[j]>='A' && buffer[j]<='F')) - { - buffer2[k]=buffer[j]; - k++; - } - else index --; - } - buffer2[k]='\0'; - - - internal_change=true; - SendMessageA((HWND)lParam, WM_SETTEXT, 0,(LPARAM)buffer2); - SendMessageA((HWND)lParam, (UINT) EM_SETSEL, (WPARAM) (index), index); - - SendMessageA(GetDlgItem(hDlg, IDC_CHEAT_BYTE), WM_GETTEXT, 4,(LPARAM)buffer); - - if(has_sel&&!new_sel&&0!=strlen(buffer2)) - SetDlgItemTextA(hDlg, IDC_CHEAT_CODE, ""); - - if(new_sel!=0) - new_sel--; - - if(strlen(buffer2)!=0 && strlen(buffer) !=0) - { - if(has_sel) - EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); - else EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); - EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), true); - } - else - { - EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), false); - EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); - } - - break; - } - break; - } - case IDC_CHEAT_BYTE: - { - uint32 j, k; - long index; - char buffer[4]; - char buffer2[4]; - POINT point; - switch(HIWORD(wParam)) - { - case EN_CHANGE: - if(internal_change) - { - internal_change=false; - return true; - } - SendMessageA((HWND)lParam, WM_GETTEXT, 4,(LPARAM)buffer); - GetCaretPos(&point); - - index = SendMessageA((HWND)lParam,(UINT) EM_CHARFROMPOS, 0, (LPARAM) ((point.x&0x0000FFFF) | (((point.y&0x0000FFFF))<<16))); - - k=0; - for(j=0; j='0' && buffer[j]<='9') || (buffer[j]>='A' && buffer[j]<='F') || buffer[j]=='$') - { - buffer2[k]=buffer[j]; - k++; - } - else index --; - } - buffer2[k]='\0'; - - if(has_sel&&!new_sel&&0!=strlen(buffer2)) - SetDlgItemTextA(hDlg, IDC_CHEAT_CODE, ""); - - if(new_sel!=0) - new_sel--; - - internal_change=true; - SendMessageA((HWND)lParam, WM_SETTEXT, 0,(LPARAM)buffer2); - SendMessageA((HWND)lParam, (UINT) EM_SETSEL, (WPARAM) (index), index); - - SendMessageA(GetDlgItem(hDlg, IDC_CHEAT_ADDRESS), WM_GETTEXT, 7,(LPARAM)buffer); - if(strlen(buffer2)!=0 && strlen(buffer) !=0) - { - if(has_sel) - EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); - else EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); - EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), true); - } - else - { - EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), false); - EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); - } - //SetDlgItemText(hDlg, IDC_CHEAT_CODE, ""); break; } break; @@ -9152,119 +8812,86 @@ INT_PTR CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) for(k=0;k= 0) + if (ListView_GetCheckState(GetDlgItem(hDlg, IDC_CHEAT_LIST), k)) + S9xEnableCheatGroup(index); } } - for(l=(int)Cheat.num_cheats-1;l>=0;l--) + for(l=(int)Cheat.g.size()-1; l>=0; l--) { if(ct.state[l]==Deleted) { - S9xDeleteCheat(l); + S9xDeleteCheatGroup(l); } } } @@ -10426,12 +10053,19 @@ INT_PTR CALLBACK DlgCheatSearchAdd(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP GetDlgItemText(hDlg, IDC_NC_DESC, tempBuf, 22); strncpy(new_cheat->name,_tToChar(tempBuf),22); - new_cheat->enabled=TRUE; - for(int byteIndex = 0; byteIndex < new_cheat->size; byteIndex++) + std::string code_string; + char code[10]; + for (int byteIndex = 0; byteIndex < new_cheat->size; byteIndex++) { - S9xAddCheat(new_cheat->enabled,new_cheat->saved_val,new_cheat->address+byteIndex,(new_cheat->new_val>>(8*byteIndex))&0xFF); - strcpy(Cheat.c[Cheat.num_cheats-1].name,new_cheat->name); + if (byteIndex > 0) + code_string += '+'; + snprintf(code, 10, "%x=%x", new_cheat->address + byteIndex, (new_cheat->new_val >> (8 * byteIndex)) & 0xFF); + code_string += code; } + + S9xAddCheatGroup(new_cheat->name, code_string.c_str()); + S9xEnableCheatGroup(Cheat.g.size() - 1); + ret=0; } } @@ -11049,9 +10683,9 @@ void S9xPostRomInit() if (Settings.ApplyCheats) { extern struct SCheatData Cheat; - for (uint32 i = 0; i < Cheat.num_cheats; i++) + for (uint32 i = 0; i < Cheat.g.size(); i++) { - if (Cheat.c [i].enabled) + if (Cheat.g [i].enabled) { char String2 [1024]; sprintf(String2, "(CHEATS ARE ON!) %s", String);