rlm@1: #include "stdafx.h" rlm@1: #include "VBA.h" rlm@1: #include "resource.h" rlm@1: #include "WinMiscUtil.h" rlm@1: #include "GBACheatsDlg.h" rlm@1: #include "GBCheatsDlg.h" rlm@1: #include "ram_search.h" rlm@1: #include "ramwatch.h" rlm@1: #include "reg.h" rlm@1: #include "Sound.h" rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: rlm@1: /* rlm@1: #include rlm@1: #pragma comment(lib, "comctl32.lib") rlm@1: #include rlm@1: #pragma comment(lib, "shell32.lib") rlm@1: #include rlm@1: #pragma comment(lib, "comdlg32.lib") rlm@1: */ rlm@1: rlm@1: static HMENU ramwatchmenu; rlm@1: static HMENU rwrecentmenu; rlm@1: /*static*/ HACCEL RamWatchAccels = NULL; rlm@1: char rw_recent_files[MAX_RECENT_WATCHES][1024]; rlm@1: //char Watch_Dir[1024]=""; rlm@1: bool RWfileChanged = false; //Keeps track of whether the current watch file has been changed, if so, ramwatch will prompt to save changes rlm@1: bool AutoRWLoad = false; //Keeps track of whether Auto-load is checked rlm@1: bool RWSaveWindowPos = false; //Keeps track of whether Save Window position is checked rlm@1: char currentWatch[1024]; rlm@1: int ramw_x, ramw_y; //Used to store ramwatch dialog window positions rlm@1: AddressWatcher rswatches[MAX_WATCH_COUNT]; rlm@1: int WatchCount=0; rlm@1: static int s_prevSelCount=-1; rlm@1: rlm@1: HWND RamWatchHWnd; rlm@1: #define gamefilename theApp.gameFilename rlm@1: #define hWnd AfxGetMainWnd()->GetSafeHwnd() rlm@1: #define hInst AfxGetInstanceHandle() rlm@1: static char Str_Tmp [1024]; rlm@1: rlm@1: void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths); //initializes the ram search and/or ram watch listbox rlm@1: rlm@1: #define MESSAGEBOXPARENT (RamWatchHWnd ? RamWatchHWnd : hWnd) rlm@1: rlm@1: bool QuickSaveWatches(); rlm@1: bool ResetWatches(); rlm@1: rlm@1: void RefreshWatchListSelectedCountControlStatus(HWND hDlg); rlm@1: rlm@1: unsigned int GetCurrentValue(AddressWatcher& watch) rlm@1: { rlm@1: return ReadValueAtHardwareAddress(watch.Address, watch.Size == 'd' ? 4 : watch.Size == 'w' ? 2 : 1); rlm@1: } rlm@1: rlm@1: bool IsSameWatch(const AddressWatcher& l, const AddressWatcher& r) rlm@1: { rlm@1: if (r.Size == 'S') return false; rlm@1: return ((l.Address == r.Address) && (l.Size == r.Size) && (l.Type == r.Type)/* && (l.WrongEndian == r.WrongEndian)*/); rlm@1: } rlm@1: rlm@1: bool VerifyWatchNotAlreadyAdded(const AddressWatcher& watch) rlm@1: { rlm@1: for (int j = 0; j < WatchCount; j++) rlm@1: { rlm@1: if (IsSameWatch(rswatches[j], watch)) rlm@1: { rlm@1: if(RamWatchHWnd) rlm@1: SetForegroundWindow(RamWatchHWnd); rlm@1: return false; rlm@1: } rlm@1: } rlm@1: return true; rlm@1: } rlm@1: rlm@1: rlm@1: bool InsertWatch(const AddressWatcher& Watch, char *Comment) rlm@1: { rlm@1: if(WatchCount >= MAX_WATCH_COUNT) rlm@1: return false; rlm@1: rlm@1: int i = WatchCount++; rlm@1: AddressWatcher& NewWatch = rswatches[i]; rlm@1: NewWatch = Watch; rlm@1: //if (NewWatch.comment) free(NewWatch.comment); rlm@1: NewWatch.comment = (char *) malloc(strlen(Comment)+2); rlm@1: NewWatch.CurValue = GetCurrentValue(NewWatch); rlm@1: strcpy(NewWatch.comment, Comment); rlm@1: ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); rlm@1: RWfileChanged=true; rlm@1: rlm@1: return true; rlm@1: } rlm@1: rlm@1: LRESULT CALLBACK PromptWatchNameProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets the description of a watched address rlm@1: { rlm@1: RECT r; rlm@1: RECT r2; rlm@1: int dx1, dy1, dx2, dy2; rlm@1: rlm@1: switch(uMsg) rlm@1: { rlm@1: case WM_INITDIALOG: rlm@1: //Clear_Sound_Buffer(); rlm@1: rlm@1: GetWindowRect(hWnd, &r); rlm@1: dx1 = (r.right - r.left) / 2; rlm@1: dy1 = (r.bottom - r.top) / 2; rlm@1: rlm@1: GetWindowRect(hDlg, &r2); rlm@1: dx2 = (r2.right - r2.left) / 2; rlm@1: dy2 = (r2.bottom - r2.top) / 2; rlm@1: rlm@1: //SetWindowPos(hDlg, NULL, max(0, r.left + (dx1 - dx2)), max(0, r.top + (dy1 - dy2)), NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); rlm@1: SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); rlm@1: strcpy(Str_Tmp,"Enter a name for this RAM address."); rlm@1: SendDlgItemMessage(hDlg,IDC_PROMPT_TEXT,WM_SETTEXT,0,(LPARAM)Str_Tmp); rlm@1: strcpy(Str_Tmp,""); rlm@1: SendDlgItemMessage(hDlg,IDC_PROMPT_TEXT2,WM_SETTEXT,0,(LPARAM)Str_Tmp); rlm@1: return true; rlm@1: break; rlm@1: rlm@1: case WM_COMMAND: rlm@1: switch(LOWORD(wParam)) rlm@1: { rlm@1: case IDOK: rlm@1: { rlm@1: GetDlgItemText(hDlg,IDC_PROMPT_EDIT,Str_Tmp,80); rlm@1: InsertWatch(rswatches[WatchCount],Str_Tmp); rlm@1: EndDialog(hDlg, true); rlm@1: return true; rlm@1: break; rlm@1: } rlm@1: case ID_CANCEL: rlm@1: case IDCANCEL: rlm@1: EndDialog(hDlg, false); rlm@1: return false; rlm@1: break; rlm@1: } rlm@1: break; rlm@1: rlm@1: case WM_CLOSE: rlm@1: EndDialog(hDlg, false); rlm@1: return false; rlm@1: break; rlm@1: } rlm@1: rlm@1: return false; rlm@1: } rlm@1: rlm@1: bool InsertWatch(const AddressWatcher& Watch, HWND parent) rlm@1: { rlm@1: if(!VerifyWatchNotAlreadyAdded(Watch)) rlm@1: return false; rlm@1: rlm@1: if(!parent) rlm@1: parent = RamWatchHWnd; rlm@1: if(!parent) rlm@1: parent = hWnd; rlm@1: rlm@1: int prevWatchCount = WatchCount; rlm@1: rlm@1: rswatches[WatchCount] = Watch; rlm@1: rswatches[WatchCount].CurValue = GetCurrentValue(rswatches[WatchCount]); rlm@1: systemSoundClearBuffer(); rlm@1: DialogBox(hInst, MAKEINTRESOURCE(IDD_PROMPT), parent, (DLGPROC) PromptWatchNameProc); rlm@1: rlm@1: return WatchCount > prevWatchCount; rlm@1: } rlm@1: rlm@1: void Update_RAM_Watch() rlm@1: { rlm@1: BOOL watchChanged[MAX_WATCH_COUNT] = {0}; rlm@1: rlm@1: if(WatchCount) rlm@1: { rlm@1: // update cached values and detect changes to displayed listview items rlm@1: rlm@1: for(int i = 0; i < WatchCount; i++) rlm@1: { rlm@1: unsigned int prevCurValue = rswatches[i].CurValue; rlm@1: unsigned int newCurValue = GetCurrentValue(rswatches[i]); rlm@1: if(prevCurValue != newCurValue) rlm@1: { rlm@1: rswatches[i].CurValue = newCurValue; rlm@1: watchChanged[i] = TRUE; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: // refresh any visible parts of the listview box that changed rlm@1: HWND lv = GetDlgItem(RamWatchHWnd,IDC_WATCHLIST); rlm@1: int top = ListView_GetTopIndex(lv); rlm@1: int bottom = top + ListView_GetCountPerPage(lv) + 1; // +1 is so we will update a partially-displayed last item rlm@1: if(top < 0) top = 0; rlm@1: if(bottom > WatchCount) bottom = WatchCount; rlm@1: int start = -1; rlm@1: for(int i = top; i <= bottom; i++) rlm@1: { rlm@1: if(start == -1) rlm@1: { rlm@1: if(i != bottom && watchChanged[i]) rlm@1: { rlm@1: start = i; rlm@1: //somethingChanged = true; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: if(i == bottom || !watchChanged[i]) rlm@1: { rlm@1: ListView_RedrawItems(lv, start, i-1); rlm@1: start = -1; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: bool AskSave() rlm@1: { rlm@1: //This function asks to save changes if the watch file contents have changed rlm@1: //returns false only if a save was attempted but failed or was cancelled rlm@1: if (RWfileChanged) rlm@1: { rlm@1: systemSoundClearBuffer(); rlm@1: int answer = MessageBox(MESSAGEBOXPARENT, "Save Changes?", "Ram Watch", MB_YESNOCANCEL); rlm@1: if(answer == IDYES) rlm@1: if(!QuickSaveWatches()) rlm@1: return false; rlm@1: return (answer != IDCANCEL); rlm@1: } rlm@1: return true; rlm@1: } rlm@1: rlm@1: void WriteRecentRWFiles() rlm@1: { rlm@1: char str[2048]; rlm@1: for (int i = 0; i < MAX_RECENT_WATCHES; i++) rlm@1: { rlm@1: sprintf(str, "recentWatch%d", i+1); rlm@1: regSetStringValue(str, &rw_recent_files[i][0]); rlm@1: } rlm@1: } rlm@1: rlm@1: void UpdateRW_RMenu(HMENU menu, unsigned int mitem, unsigned int baseid) rlm@1: { rlm@1: MENUITEMINFO moo; rlm@1: int x; rlm@1: rlm@1: moo.cbSize = sizeof(moo); rlm@1: moo.fMask = MIIM_SUBMENU | MIIM_STATE; rlm@1: rlm@1: GetMenuItemInfo(GetSubMenu(ramwatchmenu, 0), mitem, FALSE, &moo); rlm@1: moo.hSubMenu = menu; rlm@1: moo.fState = strlen(rw_recent_files[0]) ? MFS_ENABLED : MFS_GRAYED; rlm@1: rlm@1: SetMenuItemInfo(GetSubMenu(ramwatchmenu, 0), mitem, FALSE, &moo); rlm@1: rlm@1: // Remove all recent files submenus rlm@1: for(x = 0; x < MAX_RECENT_WATCHES; x++) rlm@1: { rlm@1: RemoveMenu(menu, baseid + x, MF_BYCOMMAND); rlm@1: } rlm@1: rlm@1: // Recreate the menus rlm@1: for(x = MAX_RECENT_WATCHES - 1; x >= 0; x--) rlm@1: { rlm@1: // Skip empty strings rlm@1: if(!strlen(rw_recent_files[x])) rlm@1: { rlm@1: continue; rlm@1: } rlm@1: rlm@1: moo.cbSize = sizeof(moo); rlm@1: moo.fMask = MIIM_DATA | MIIM_ID | MIIM_TYPE; rlm@1: rlm@1: #if 0 rlm@1: const int TEMP_STRING_LENGTH = 128 + 5; rlm@1: char tmp[TEMP_STRING_LENGTH]; // FIXME? rlm@1: rlm@1: // Fill in the menu text. rlm@1: if(strlen(rw_recent_files[x]) < 128) rlm@1: { rlm@1: sprintf(tmp, "&%d. %s", ( x + 1 ) % 10, rw_recent_files[x]); rlm@1: } rlm@1: else rlm@1: { rlm@1: sprintf(tmp, "&%d. %s", ( x + 1 ) % 10, rw_recent_files[x] + strlen( rw_recent_files[x] ) - 127); rlm@1: } rlm@1: #endif rlm@1: // the ATL way; it is really pain to work out a MBCS-compatible string replace function in the pure c way rlm@1: CString atltmp(rw_recent_files[x]); rlm@1: atltmp.Replace("&", "&&"); rlm@1: char *tmp = atltmp.GetBuffer(0); rlm@1: rlm@1: // Insert the menu item rlm@1: moo.cch = strlen(tmp); rlm@1: moo.fType = 0; rlm@1: moo.wID = baseid + x; rlm@1: moo.dwTypeData = tmp; rlm@1: InsertMenuItem(menu, 0, 1, &moo); rlm@1: rlm@1: // atltmp.ReleaseBuffer(); rlm@1: } rlm@1: rlm@1: // I don't think one function shall do so many things in a row rlm@1: // WriteRecentRWFiles(); // write recent menu to ini rlm@1: } rlm@1: rlm@1: void UpdateRWRecentArray(const char* addString, unsigned int arrayLen, HMENU menu, unsigned int menuItem, unsigned int baseId) rlm@1: { rlm@1: const size_t len = 1024; // Avoid magic numbers rlm@1: rlm@1: // Try to find out if the filename is already in the recent files list. rlm@1: for(unsigned int x = 0; x < arrayLen; x++) rlm@1: { rlm@1: if(strlen(rw_recent_files[x])) rlm@1: { rlm@1: if(!strncmp(rw_recent_files[x], addString, 1024)) // Item is already in list. rlm@1: { rlm@1: // If the filename is in the file list don't add it again. rlm@1: // Move it up in the list instead. rlm@1: rlm@1: int y; rlm@1: char tmp[len]; rlm@1: rlm@1: // Save pointer. rlm@1: strncpy(tmp, rw_recent_files[x], len - 1); // assuming rw_recent_files[n] is 0-terminated rlm@1: rlm@1: for(y = x; y; y--) rlm@1: { rlm@1: // Move items down. rlm@1: strncpy(rw_recent_files[y], rw_recent_files[y - 1], len); rlm@1: } rlm@1: rlm@1: // Put item on top. rlm@1: strncpy(rw_recent_files[0],tmp, len); rlm@1: rlm@1: // Update the recent files menu rlm@1: UpdateRW_RMenu(menu, menuItem, baseId); rlm@1: rlm@1: return; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: // The filename wasn't found in the list. That means we need to add it. rlm@1: rlm@1: // Move the other items down. rlm@1: for(unsigned int x = arrayLen - 1; x; x--) rlm@1: { rlm@1: strncpy(rw_recent_files[x],rw_recent_files[x - 1], len); rlm@1: } rlm@1: rlm@1: // Add the new item. rlm@1: strncpy(rw_recent_files[0], addString, len); rlm@1: rw_recent_files[0][len - 1] = '\0'; // better not assume that rlm@1: rlm@1: // Update the recent files menu rlm@1: UpdateRW_RMenu(menu, menuItem, baseId); rlm@1: } rlm@1: rlm@1: void RWAddRecentFile(const char *filename) rlm@1: { rlm@1: UpdateRWRecentArray(filename, MAX_RECENT_WATCHES, rwrecentmenu, RAMMENU_FILE_RECENT, RW_MENU_FIRST_RECENT_FILE); rlm@1: } rlm@1: rlm@1: void OpenRWRecentFile(int memwRFileNumber) rlm@1: { rlm@1: if(!ResetWatches()) rlm@1: return; rlm@1: rlm@1: int rnum = memwRFileNumber; rlm@1: if ((unsigned int)rnum >= MAX_RECENT_WATCHES) rlm@1: return; //just in case rlm@1: rlm@1: char* x; rlm@1: rlm@1: while(true) rlm@1: { rlm@1: x = rw_recent_files[rnum]; rlm@1: if (!*x) rlm@1: return; //If no recent files exist just return. Useful for Load last file on startup (or if something goes screwy) rlm@1: rlm@1: if (rnum) //Change order of recent files if not most recent rlm@1: { rlm@1: RWAddRecentFile(x); rlm@1: rnum = 0; rlm@1: } rlm@1: else rlm@1: { rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: strcpy(currentWatch,x); rlm@1: strcpy(Str_Tmp,currentWatch); rlm@1: rlm@1: //loadwatches here rlm@1: FILE *WatchFile = fopen(Str_Tmp,"rb"); rlm@1: if (!WatchFile) rlm@1: { rlm@1: systemSoundClearBuffer(); rlm@1: int answer = MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OKCANCEL); rlm@1: if (answer == IDOK) rlm@1: { rlm@1: rw_recent_files[rnum][0] = '\0'; //Clear file from list rlm@1: if (rnum) //Update the ramwatch list rlm@1: RWAddRecentFile(rw_recent_files[0]); rlm@1: else rlm@1: RWAddRecentFile(rw_recent_files[1]); rlm@1: } rlm@1: return; rlm@1: } rlm@1: const char DELIM = '\t'; rlm@1: AddressWatcher Temp; rlm@1: char mode; rlm@1: fgets(Str_Tmp,1024,WatchFile); rlm@1: sscanf(Str_Tmp,"%c%*s",&mode); rlm@1: //if ((mode == '1' && !(SegaCD_Started)) || (mode == '2' && !(_32X_Started))) rlm@1: //{ rlm@1: // char Device[8]; rlm@1: // strcpy(Device,(mode > '1')?"32X":"SegaCD"); rlm@1: // sprintf(Str_Tmp,"Warning: %s not started. \nWatches for %s addresses will be ignored.",Device,Device); rlm@1: // MessageBox(MESSAGEBOXPARENT,Str_Tmp,"Possible Device Mismatch",MB_OK); rlm@1: //} rlm@1: int WatchAdd; rlm@1: fgets(Str_Tmp,1024,WatchFile); rlm@1: sscanf(Str_Tmp,"%d%*s",&WatchAdd); rlm@1: WatchAdd+=WatchCount; rlm@1: for (int i = WatchCount; i < WatchAdd; i++) rlm@1: { rlm@1: while (i < 0) rlm@1: i++; rlm@1: do { rlm@1: fgets(Str_Tmp,1024,WatchFile); rlm@1: } while (Str_Tmp[0] == '\n'); rlm@1: sscanf(Str_Tmp,"%*05X%*c%08X%*c%c%*c%c%*c%d",&(Temp.Address),&(Temp.Size),&(Temp.Type),&(Temp.WrongEndian)); rlm@1: Temp.WrongEndian = 0; rlm@1: char *Comment = strrchr(Str_Tmp,DELIM) + 1; rlm@1: *strrchr(Comment,'\n') = '\0'; rlm@1: InsertWatch(Temp,Comment); rlm@1: } rlm@1: rlm@1: fclose(WatchFile); rlm@1: if (RamWatchHWnd) { rlm@1: ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); rlm@1: RefreshWatchListSelectedCountControlStatus(RamWatchHWnd); rlm@1: } rlm@1: RWfileChanged=false; rlm@1: return; rlm@1: } rlm@1: rlm@1: int Change_File_L(char *Dest, const char *Dir, const char *Titre, const char *Filter, const char *Ext, HWND hwnd) rlm@1: { rlm@1: if (!strcmp(Dest, "")) rlm@1: { rlm@1: strcpy(Dest, "default."); rlm@1: strcat(Dest, Ext); rlm@1: } rlm@1: rlm@1: SetCurrentDirectory(winGetDestDir(IDS_WATCH_DIR)); rlm@1: rlm@1: OPENFILENAME ofn; rlm@1: rlm@1: memset(&ofn, 0, sizeof(OPENFILENAME)); rlm@1: rlm@1: ofn.lStructSize = sizeof(OPENFILENAME); rlm@1: ofn.hwndOwner = hwnd; rlm@1: ofn.hInstance = hInst; rlm@1: ofn.lpstrFile = Dest; rlm@1: ofn.nMaxFile = 2047; rlm@1: ofn.lpstrFilter = Filter; rlm@1: ofn.nFilterIndex = 1; rlm@1: ofn.lpstrInitialDir = Dir; rlm@1: ofn.lpstrTitle = Titre; rlm@1: ofn.lpstrDefExt = Ext; rlm@1: ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; rlm@1: rlm@1: systemSoundClearBuffer(); rlm@1: rlm@1: if (GetOpenFileName(&ofn)) return 1; rlm@1: rlm@1: return 0; rlm@1: } rlm@1: rlm@1: int Change_File_S(char *Dest, const char *Dir, const char *Titre, const char *Filter, const char *Ext, HWND hwnd) rlm@1: { rlm@1: if (!strcmp(Dest, "")) rlm@1: { rlm@1: strcpy(Dest, "default."); rlm@1: strcat(Dest, Ext); rlm@1: } rlm@1: rlm@1: SetCurrentDirectory(winGetDestDir(IDS_WATCH_DIR)); rlm@1: rlm@1: OPENFILENAME ofn; rlm@1: rlm@1: memset(&ofn, 0, sizeof(OPENFILENAME)); rlm@1: rlm@1: ofn.lStructSize = sizeof(OPENFILENAME); rlm@1: ofn.hwndOwner = hwnd; rlm@1: ofn.hInstance = hInst; rlm@1: ofn.lpstrFile = Dest; rlm@1: ofn.nMaxFile = 2047; rlm@1: ofn.lpstrFilter = Filter; rlm@1: ofn.nFilterIndex = 1; rlm@1: ofn.lpstrInitialDir = Dir; rlm@1: ofn.lpstrTitle = Titre; rlm@1: ofn.lpstrDefExt = Ext; rlm@1: ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; rlm@1: rlm@1: if (GetSaveFileName(&ofn)) return 1; rlm@1: rlm@1: return 0; rlm@1: } rlm@1: rlm@1: bool Save_Watches() rlm@1: { rlm@1: const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/'))); rlm@1: strcpy(Str_Tmp,slash ? slash+1 : gamefilename); rlm@1: char* dot = strrchr(Str_Tmp, '.'); rlm@1: if(dot) *dot = 0; rlm@1: strcat(Str_Tmp,".wch"); rlm@1: if(Change_File_S(Str_Tmp, winGetDestDir(IDS_WATCH_DIR), "Save Watches", "Watchlist\0*.wch\0All Files\0*.*\0\0", "wch", RamWatchHWnd)) rlm@1: { rlm@1: FILE *WatchFile = fopen(Str_Tmp,"r+b"); rlm@1: if (!WatchFile) WatchFile = fopen(Str_Tmp,"w+b"); rlm@1: fputc('\n',WatchFile); rlm@1: strcpy(currentWatch,Str_Tmp); rlm@1: RWAddRecentFile(currentWatch); rlm@1: sprintf(Str_Tmp,"%d\n",WatchCount); rlm@1: fputs(Str_Tmp,WatchFile); rlm@1: const char DELIM = '\t'; rlm@1: for (int i = 0; i < WatchCount; i++) rlm@1: { rlm@1: sprintf(Str_Tmp,"%05X%c%08X%c%c%c%c%c%d%c%s\n",i,DELIM,rswatches[i].Address,DELIM,rswatches[i].Size,DELIM,rswatches[i].Type,DELIM,rswatches[i].WrongEndian,DELIM,rswatches[i].comment); rlm@1: fputs(Str_Tmp,WatchFile); rlm@1: } rlm@1: rlm@1: fclose(WatchFile); rlm@1: RWfileChanged=false; rlm@1: //TODO: Add to recent list function call here rlm@1: return true; rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: bool QuickSaveWatches() rlm@1: { rlm@1: if (RWfileChanged==false) return true; //If file has not changed, no need to save changes rlm@1: if (currentWatch[0] == NULL) //If there is no currently loaded file, run to Save as and then return rlm@1: { rlm@1: return Save_Watches(); rlm@1: } rlm@1: rlm@1: strcpy(Str_Tmp,currentWatch); rlm@1: FILE *WatchFile = fopen(Str_Tmp,"r+b"); rlm@1: if (!WatchFile) WatchFile = fopen(Str_Tmp,"w+b"); rlm@1: fputc('\n',WatchFile); rlm@1: sprintf(Str_Tmp,"%d\n",WatchCount); rlm@1: fputs(Str_Tmp,WatchFile); rlm@1: const char DELIM = '\t'; rlm@1: for (int i = 0; i < WatchCount; i++) rlm@1: { rlm@1: sprintf(Str_Tmp,"%05X%c%08X%c%c%c%c%c%d%c%s\n",i,DELIM,rswatches[i].Address,DELIM,rswatches[i].Size,DELIM,rswatches[i].Type,DELIM,rswatches[i].WrongEndian,DELIM,rswatches[i].comment); rlm@1: fputs(Str_Tmp,WatchFile); rlm@1: } rlm@1: fclose(WatchFile); rlm@1: RWfileChanged=false; rlm@1: return true; rlm@1: } rlm@1: rlm@1: bool Load_Watches(bool clear, const char* filename) rlm@1: { rlm@1: const char DELIM = '\t'; rlm@1: FILE* WatchFile = fopen(filename,"rb"); rlm@1: if (!WatchFile) rlm@1: { rlm@1: systemSoundClearBuffer(); rlm@1: MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OK); rlm@1: return false; rlm@1: } rlm@1: if(clear) rlm@1: { rlm@1: if(!ResetWatches()) rlm@1: { rlm@1: fclose(WatchFile); rlm@1: return false; rlm@1: } rlm@1: } rlm@1: strcpy(currentWatch,filename); rlm@1: RWAddRecentFile(currentWatch); rlm@1: AddressWatcher Temp; rlm@1: char mode; rlm@1: fgets(Str_Tmp,1024,WatchFile); rlm@1: sscanf(Str_Tmp,"%c%*s",&mode); rlm@1: int WatchAdd; rlm@1: fgets(Str_Tmp,1024,WatchFile); rlm@1: sscanf(Str_Tmp,"%d%*s",&WatchAdd); rlm@1: WatchAdd+=WatchCount; rlm@1: for (int i = WatchCount; i < WatchAdd; i++) rlm@1: { rlm@1: while (i < 0) rlm@1: i++; rlm@1: do { rlm@1: fgets(Str_Tmp,1024,WatchFile); rlm@1: } while (Str_Tmp[0] == '\n'); rlm@1: sscanf(Str_Tmp,"%*05X%*c%08X%*c%c%*c%c%*c%d",&(Temp.Address),&(Temp.Size),&(Temp.Type),&(Temp.WrongEndian)); rlm@1: Temp.WrongEndian = 0; rlm@1: char *Comment = strrchr(Str_Tmp,DELIM) + 1; rlm@1: *strrchr(Comment,'\n') = '\0'; rlm@1: InsertWatch(Temp,Comment); rlm@1: } rlm@1: rlm@1: fclose(WatchFile); rlm@1: if (RamWatchHWnd) rlm@1: ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); rlm@1: RWfileChanged=false; rlm@1: return true; rlm@1: } rlm@1: rlm@1: bool Load_Watches(bool clear) rlm@1: { rlm@1: const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/'))); rlm@1: strcpy(Str_Tmp,slash ? slash+1 : gamefilename); rlm@1: char* dot = strrchr(Str_Tmp, '.'); rlm@1: if(dot) *dot = 0; rlm@1: strcat(Str_Tmp,".wch"); rlm@1: if(Change_File_L(Str_Tmp, winGetDestDir(IDS_WATCH_DIR), "Load Watches", "Watchlist\0*.wch\0All Files\0*.*\0\0", "wch", RamWatchHWnd)) rlm@1: { rlm@1: return Load_Watches(clear, Str_Tmp); rlm@1: } rlm@1: return false; rlm@1: } rlm@1: rlm@1: bool ResetWatches() rlm@1: { rlm@1: if(!AskSave()) rlm@1: return false; rlm@1: for (;WatchCount>=0;WatchCount--) rlm@1: { rlm@1: free(rswatches[WatchCount].comment); rlm@1: rswatches[WatchCount].comment = NULL; rlm@1: } rlm@1: WatchCount++; rlm@1: if (RamWatchHWnd) { rlm@1: ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); rlm@1: RefreshWatchListSelectedCountControlStatus(RamWatchHWnd); rlm@1: } rlm@1: RWfileChanged = false; rlm@1: currentWatch[0] = NULL; rlm@1: return true; rlm@1: } rlm@1: rlm@1: void RemoveWatch(int watchIndex) rlm@1: { rlm@1: free(rswatches[watchIndex].comment); rlm@1: rswatches[watchIndex].comment = NULL; rlm@1: for (int i = watchIndex; i <= WatchCount; i++) rlm@1: rswatches[i] = rswatches[i+1]; rlm@1: WatchCount--; rlm@1: } rlm@1: rlm@1: LRESULT CALLBACK EditWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets info for a RAM Watch, and then inserts it into the Watch List rlm@1: { rlm@1: RECT r; rlm@1: RECT r2; rlm@1: int dx1, dy1, dx2, dy2; rlm@1: static int index; rlm@1: static char s,t = s = 0; rlm@1: rlm@1: switch(uMsg) rlm@1: { rlm@1: case WM_INITDIALOG: rlm@1: //Clear_Sound_Buffer(); rlm@1: rlm@1: rlm@1: GetWindowRect(hWnd, &r); rlm@1: dx1 = (r.right - r.left) / 2; rlm@1: dy1 = (r.bottom - r.top) / 2; rlm@1: rlm@1: GetWindowRect(hDlg, &r2); rlm@1: dx2 = (r2.right - r2.left) / 2; rlm@1: dy2 = (r2.bottom - r2.top) / 2; rlm@1: rlm@1: //SetWindowPos(hDlg, NULL, max(0, r.left + (dx1 - dx2)), max(0, r.top + (dy1 - dy2)), NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); rlm@1: SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); rlm@1: index = (int)lParam; rlm@1: sprintf(Str_Tmp,"%08X",rswatches[index].Address); rlm@1: SetDlgItemText(hDlg,IDC_EDIT_COMPAREADDRESS,Str_Tmp); rlm@1: if (rswatches[index].comment != NULL) rlm@1: SetDlgItemText(hDlg,IDC_PROMPT_EDIT,rswatches[index].comment); rlm@1: s = rswatches[index].Size; rlm@1: t = rswatches[index].Type; rlm@1: switch (s) rlm@1: { rlm@1: case 'b': rlm@1: SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_CHECKED, 0); rlm@1: break; rlm@1: case 'w': rlm@1: SendDlgItemMessage(hDlg, IDC_2_BYTES, BM_SETCHECK, BST_CHECKED, 0); rlm@1: break; rlm@1: case 'd': rlm@1: SendDlgItemMessage(hDlg, IDC_4_BYTES, BM_SETCHECK, BST_CHECKED, 0); rlm@1: break; rlm@1: default: rlm@1: s = 0; rlm@1: break; rlm@1: } rlm@1: switch (t) rlm@1: { rlm@1: case 's': rlm@1: SendDlgItemMessage(hDlg, IDC_SIGNED, BM_SETCHECK, BST_CHECKED, 0); rlm@1: break; rlm@1: case 'u': rlm@1: SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_SETCHECK, BST_CHECKED, 0); rlm@1: break; rlm@1: case 'h': rlm@1: SendDlgItemMessage(hDlg, IDC_HEX, BM_SETCHECK, BST_CHECKED, 0); rlm@1: break; rlm@1: default: rlm@1: t = 0; rlm@1: break; rlm@1: } rlm@1: rlm@1: return true; rlm@1: break; rlm@1: rlm@1: case WM_COMMAND: rlm@1: switch(LOWORD(wParam)) rlm@1: { rlm@1: case IDC_SIGNED: rlm@1: t='s'; rlm@1: return true; rlm@1: case IDC_UNSIGNED: rlm@1: t='u'; rlm@1: return true; rlm@1: case IDC_HEX: rlm@1: t='h'; rlm@1: return true; rlm@1: case IDC_1_BYTE: rlm@1: s = 'b'; rlm@1: return true; rlm@1: case IDC_2_BYTES: rlm@1: s = 'w'; rlm@1: return true; rlm@1: case IDC_4_BYTES: rlm@1: s = 'd'; rlm@1: return true; rlm@1: case IDOK: rlm@1: { rlm@1: if (s && t) rlm@1: { rlm@1: AddressWatcher Temp; rlm@1: Temp.Size = s; rlm@1: Temp.Type = t; rlm@1: Temp.WrongEndian = false; //replace this when I get little endian working properly rlm@1: GetDlgItemText(hDlg,IDC_EDIT_COMPAREADDRESS,Str_Tmp,1024); rlm@1: char *addrstr = Str_Tmp; rlm@1: if (strlen(Str_Tmp) > 8) addrstr = &(Str_Tmp[strlen(Str_Tmp) - 9]); rlm@1: for(int i = 0; addrstr[i]; i++) {if(toupper(addrstr[i]) == 'O') addrstr[i] = '0';} rlm@1: sscanf(addrstr,"%08X",&(Temp.Address)); rlm@1: rlm@1: if((Temp.Address & ~0xFFFFFF) == ~0xFFFFFF) rlm@1: Temp.Address &= 0xFFFFFF; rlm@1: rlm@1: if(IsHardwareAddressValid(Temp.Address)) rlm@1: { rlm@1: GetDlgItemText(hDlg,IDC_PROMPT_EDIT,Str_Tmp,80); rlm@1: if (index < WatchCount) RemoveWatch(index); rlm@1: InsertWatch(Temp,Str_Tmp); rlm@1: if(RamWatchHWnd) rlm@1: { rlm@1: ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); rlm@1: } rlm@1: EndDialog(hDlg, true); rlm@1: } rlm@1: else rlm@1: { rlm@1: MessageBox(hDlg,"Invalid Address","ERROR",MB_OK); rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: strcpy(Str_Tmp,"Error:"); rlm@1: if (!s) rlm@1: strcat(Str_Tmp," Size must be specified."); rlm@1: if (!t) rlm@1: strcat(Str_Tmp," Type must be specified."); rlm@1: MessageBox(hDlg,Str_Tmp,"ERROR",MB_OK); rlm@1: } rlm@1: RWfileChanged=true; rlm@1: return true; rlm@1: break; rlm@1: } rlm@1: case ID_CANCEL: rlm@1: case IDCANCEL: rlm@1: EndDialog(hDlg, false); rlm@1: return false; rlm@1: break; rlm@1: } rlm@1: break; rlm@1: rlm@1: case WM_CLOSE: rlm@1: EndDialog(hDlg, false); rlm@1: return false; rlm@1: break; rlm@1: } rlm@1: rlm@1: return false; rlm@1: } rlm@1: rlm@1: rlm@1: rlm@1: rlm@1: void RamWatchEnableCommand(HWND hDlg, HMENU hMenu, UINT uIDEnableItem, bool enable) rlm@1: { rlm@1: EnableWindow(GetDlgItem(hDlg, uIDEnableItem), (enable?TRUE:FALSE)); rlm@1: if (hMenu != NULL) { rlm@1: if (uIDEnableItem == ID_WATCHES_UPDOWN) { rlm@1: EnableMenuItem(hMenu, IDC_C_WATCH_UP, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); rlm@1: EnableMenuItem(hMenu, IDC_C_WATCH_DOWN, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); rlm@1: } rlm@1: else rlm@1: EnableMenuItem(hMenu, uIDEnableItem, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); rlm@1: } rlm@1: } rlm@1: rlm@1: void RefreshWatchListSelectedCountControlStatus(HWND hDlg) rlm@1: { rlm@1: int selCount = ListView_GetSelectedCount(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: if(selCount != s_prevSelCount) rlm@1: { rlm@1: if(selCount < 2 || s_prevSelCount < 2) rlm@1: { rlm@1: RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH_EDIT, selCount == 1); rlm@1: RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH_REMOVE, selCount >= 1); rlm@1: RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH, WatchCount < MAX_WATCH_COUNT); rlm@1: RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH_DUPLICATE, selCount == 1 && WatchCount < MAX_WATCH_COUNT); rlm@1: RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_ADDCHEAT, selCount == 1); rlm@1: RamWatchEnableCommand(hDlg, ramwatchmenu, ID_WATCHES_UPDOWN, selCount == 1); rlm@1: } rlm@1: s_prevSelCount = selCount; rlm@1: } rlm@1: } rlm@1: rlm@1: LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) rlm@1: { rlm@1: RECT r; rlm@1: RECT r2; rlm@1: int dx1, dy1, dx2, dy2; rlm@1: static int watchIndex=0; rlm@1: rlm@1: switch(uMsg) rlm@1: { rlm@1: case WM_MOVE: { rlm@1: RECT wrect; rlm@1: GetWindowRect(hDlg,&wrect); rlm@1: ramw_x = wrect.left; rlm@1: ramw_y = wrect.top; rlm@1: regSetDwordValue(RAMWX, ramw_x); rlm@1: regSetDwordValue(RAMWY, ramw_y); rlm@1: } break; rlm@1: rlm@1: case WM_INITDIALOG: { rlm@1: GetWindowRect(hWnd, &r); //Ramwatch window rlm@1: dx1 = (r.right - r.left) / 2; rlm@1: dy1 = (r.bottom - r.top) / 2; rlm@1: rlm@1: GetWindowRect(hDlg, &r2); // TASer window rlm@1: dx2 = (r2.right - r2.left) / 2; rlm@1: dy2 = (r2.bottom - r2.top) / 2; rlm@1: rlm@1: rlm@1: // push it away from the main window if we can rlm@1: const int width = (r.right-r.left); rlm@1: const int height = (r.bottom - r.top); rlm@1: const int width2 = (r2.right-r2.left); rlm@1: if(r.left+width2 + width < GetSystemMetrics(SM_CXSCREEN)) rlm@1: { rlm@1: r.right += width; rlm@1: r.left += width; rlm@1: } rlm@1: else if((int)r.left - (int)width2 > 0) rlm@1: { rlm@1: r.right -= width2; rlm@1: r.left -= width2; rlm@1: } rlm@1: rlm@1: //----------------------------------------------------------------------------------- rlm@1: //If user has Save Window Pos selected, override default positioning rlm@1: if (RWSaveWindowPos) rlm@1: { rlm@1: //If ramwindow is for some reason completely off screen, use default instead rlm@1: if (ramw_x > (-width*2) || ramw_x < (width*2 + GetSystemMetrics(SM_CYSCREEN)) ) rlm@1: r.left = ramw_x; //This also ignores cases of windows -32000 error codes rlm@1: //If ramwindow is for some reason completely off screen, use default instead rlm@1: if (ramw_y > (0-height*2) ||ramw_y < (height*2 + GetSystemMetrics(SM_CYSCREEN)) ) rlm@1: r.top = ramw_y; //This also ignores cases of windows -32000 error codes rlm@1: } rlm@1: //------------------------------------------------------------------------------------- rlm@1: SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); rlm@1: rlm@1: ramwatchmenu=GetMenu(hDlg); rlm@1: rwrecentmenu=CreateMenu(); rlm@1: UpdateRW_RMenu(rwrecentmenu, RAMMENU_FILE_RECENT, RW_MENU_FIRST_RECENT_FILE); rlm@1: rlm@1: const char* names[3] = {"Address","Value","Notes"}; rlm@1: int widths[3] = {62,64,64+51+53}; rlm@1: init_list_box(GetDlgItem(hDlg,IDC_WATCHLIST),names,3,widths); rlm@1: if (!ResultCount) rlm@1: reset_address_info(); rlm@1: else rlm@1: signal_new_frame(); rlm@1: ListView_SetItemCount(GetDlgItem(hDlg,IDC_WATCHLIST),WatchCount); rlm@1: if (!noMisalign) SendDlgItemMessage(hDlg, IDC_MISALIGN, BM_SETCHECK, BST_CHECKED, 0); rlm@1: //if (littleEndian) SendDlgItemMessage(hDlg, IDC_ENDIAN, BM_SETCHECK, BST_CHECKED, 0); rlm@1: rlm@1: RamWatchAccels = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR1)); rlm@1: rlm@1: // due to some bug in windows, the arrow button width from the resource gets ignored, so we have to set it here rlm@1: SetWindowPos(GetDlgItem(hDlg,ID_WATCHES_UPDOWN), 0,0,0, 30,60, SWP_NOMOVE); rlm@1: rlm@1: Update_RAM_Watch(); rlm@1: rlm@1: DragAcceptFiles(hDlg, TRUE); rlm@1: rlm@1: s_prevSelCount = -1; rlm@1: RefreshWatchListSelectedCountControlStatus(hDlg); rlm@1: return false; rlm@1: } break; rlm@1: rlm@1: case WM_INITMENU: rlm@1: CheckMenuItem(ramwatchmenu, RAMMENU_FILE_AUTOLOAD, AutoRWLoad ? MF_CHECKED : MF_UNCHECKED); rlm@1: CheckMenuItem(ramwatchmenu, RAMMENU_FILE_SAVEWINDOW, RWSaveWindowPos ? MF_CHECKED : MF_UNCHECKED); rlm@1: break; rlm@1: rlm@1: case WM_ENTERMENULOOP: rlm@1: systemSoundClearBuffer(); rlm@1: break; rlm@1: rlm@1: case WM_MENUSELECT: rlm@1: case WM_ENTERSIZEMOVE: rlm@1: //Clear_Sound_Buffer(); rlm@1: break; rlm@1: rlm@1: case WM_NOTIFY: rlm@1: { rlm@1: switch(wParam) rlm@1: { rlm@1: case ID_WATCHES_UPDOWN: rlm@1: { rlm@1: switch(((LPNMUPDOWN)lParam)->hdr.code) rlm@1: { rlm@1: case UDN_DELTAPOS: { rlm@1: int delta = ((LPNMUPDOWN)lParam)->iDelta; rlm@1: SendMessage(hDlg, WM_COMMAND, delta<0 ? IDC_C_WATCH_UP : IDC_C_WATCH_DOWN,0); rlm@1: } break; rlm@1: } rlm@1: } break; rlm@1: rlm@1: default: rlm@1: { rlm@1: LPNMHDR lP = (LPNMHDR) lParam; rlm@1: switch (lP->code) rlm@1: { rlm@1: case LVN_ITEMCHANGED: // selection changed event rlm@1: { rlm@1: NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)lP; rlm@1: if(pNMListView->uNewState & LVIS_FOCUSED || rlm@1: (pNMListView->uNewState ^ pNMListView->uOldState) & LVIS_SELECTED) rlm@1: { rlm@1: // disable buttons that we don't have the right number of selected items for rlm@1: RefreshWatchListSelectedCountControlStatus(hDlg); rlm@1: } rlm@1: } break; rlm@1: rlm@1: case LVN_GETDISPINFO: rlm@1: { rlm@1: LV_DISPINFO *Item = (LV_DISPINFO *)lParam; rlm@1: Item->item.mask = LVIF_TEXT; rlm@1: Item->item.state = 0; rlm@1: Item->item.iImage = 0; rlm@1: const unsigned int iNum = Item->item.iItem; rlm@1: static char num[11]; rlm@1: switch (Item->item.iSubItem) rlm@1: { rlm@1: case 0: rlm@1: sprintf(num,"%08X",rswatches[iNum].Address); rlm@1: Item->item.pszText = num; rlm@1: return true; rlm@1: case 1: { rlm@1: int i = rswatches[iNum].CurValue; rlm@1: int t = rswatches[iNum].Type; rlm@1: int size = rswatches[iNum].Size; rlm@1: const char* formatString = ((t=='s') ? "%d" : (t=='u') ? "%u" : (size=='d' ? "%08X" : size=='w' ? "%04X" : "%02X")); rlm@1: switch (size) rlm@1: { rlm@1: case 'b': rlm@1: default: sprintf(num, formatString, t=='s' ? (char)(i&0xff) : (unsigned char)(i&0xff)); break; rlm@1: case 'w': sprintf(num, formatString, t=='s' ? (short)(i&0xffff) : (unsigned short)(i&0xffff)); break; rlm@1: case 'd': sprintf(num, formatString, t=='s' ? (long)(i&0xffffffff) : (unsigned long)(i&0xffffffff)); break; rlm@1: } rlm@1: rlm@1: Item->item.pszText = num; rlm@1: } return true; rlm@1: case 2: rlm@1: Item->item.pszText = rswatches[iNum].comment ? rswatches[iNum].comment : ""; rlm@1: return true; rlm@1: rlm@1: default: rlm@1: return false; rlm@1: } rlm@1: } rlm@1: case LVN_ODFINDITEM: rlm@1: { rlm@1: // disable search by keyboard typing, rlm@1: // because it interferes with some of the accelerators rlm@1: // and it isn't very useful here anyway rlm@1: SetWindowLong(hDlg, DWL_MSGRESULT, ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST))); rlm@1: return 1; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: } break; rlm@1: rlm@1: case WM_COMMAND: rlm@1: switch(LOWORD(wParam)) rlm@1: { rlm@1: case RAMMENU_FILE_SAVE: rlm@1: QuickSaveWatches(); rlm@1: break; rlm@1: rlm@1: case RAMMENU_FILE_SAVEAS: rlm@1: //case IDC_C_SAVE: rlm@1: return Save_Watches(); rlm@1: case RAMMENU_FILE_OPEN: rlm@1: return Load_Watches(true); rlm@1: case RAMMENU_FILE_APPEND: rlm@1: //case IDC_C_LOAD: rlm@1: return Load_Watches(false); rlm@1: case RAMMENU_FILE_NEW: rlm@1: //case IDC_C_RESET: rlm@1: ResetWatches(); rlm@1: return true; rlm@1: case IDC_C_WATCH_REMOVE: rlm@1: { rlm@1: HWND watchListControl = GetDlgItem(hDlg, IDC_WATCHLIST); rlm@1: watchIndex = ListView_GetNextItem(watchListControl, -1, LVNI_ALL | LVNI_SELECTED); rlm@1: while (watchIndex >= 0) rlm@1: { rlm@1: RemoveWatch(watchIndex); rlm@1: ListView_DeleteItem(watchListControl, watchIndex); rlm@1: watchIndex = ListView_GetNextItem(watchListControl, -1, LVNI_ALL | LVNI_SELECTED); rlm@1: } rlm@1: RWfileChanged=true; rlm@1: SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: return true; rlm@1: } rlm@1: case IDC_C_WATCH_EDIT: rlm@1: watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: if(watchIndex != -1) rlm@1: { rlm@1: systemSoundClearBuffer(); rlm@1: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) watchIndex); rlm@1: SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: } rlm@1: return true; rlm@1: case IDC_C_WATCH: rlm@1: rswatches[WatchCount].Address = rswatches[WatchCount].WrongEndian = 0; rlm@1: rswatches[WatchCount].Size = 'b'; rlm@1: rswatches[WatchCount].Type = 's'; rlm@1: systemSoundClearBuffer(); rlm@1: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) WatchCount); rlm@1: SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: return true; rlm@1: case IDC_C_WATCH_DUPLICATE: rlm@1: watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: if(watchIndex != -1) rlm@1: { rlm@1: rswatches[WatchCount].Address = rswatches[watchIndex].Address; rlm@1: rswatches[WatchCount].WrongEndian = rswatches[watchIndex].WrongEndian; rlm@1: rswatches[WatchCount].Size = rswatches[watchIndex].Size; rlm@1: rswatches[WatchCount].Type = rswatches[watchIndex].Type; rlm@1: systemSoundClearBuffer(); rlm@1: DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) WatchCount); rlm@1: SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: } rlm@1: return true; rlm@1: rlm@1: case IDC_C_WATCH_SEPARATE: rlm@1: AddressWatcher separator; rlm@1: separator.Address = 0; rlm@1: separator.WrongEndian = false; rlm@1: separator.Size = 'S'; rlm@1: separator.Type = 'S'; rlm@1: InsertWatch(separator, "----------------------------"); rlm@1: SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: return true; rlm@1: rlm@1: case IDC_C_WATCH_UP: rlm@1: { rlm@1: watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: if (watchIndex == 0 || watchIndex == -1) rlm@1: return true; rlm@1: void *tmp = malloc(sizeof(AddressWatcher)); rlm@1: memcpy(tmp,&(rswatches[watchIndex]),sizeof(AddressWatcher)); rlm@1: memcpy(&(rswatches[watchIndex]),&(rswatches[watchIndex - 1]),sizeof(AddressWatcher)); rlm@1: memcpy(&(rswatches[watchIndex - 1]),tmp,sizeof(AddressWatcher)); rlm@1: free(tmp); rlm@1: ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex,0,LVIS_FOCUSED|LVIS_SELECTED); rlm@1: ListView_SetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex-1); rlm@1: ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex-1,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); rlm@1: ListView_SetItemCount(GetDlgItem(hDlg,IDC_WATCHLIST),WatchCount); rlm@1: RWfileChanged=true; rlm@1: return true; rlm@1: } rlm@1: case IDC_C_WATCH_DOWN: rlm@1: { rlm@1: watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: if (watchIndex >= WatchCount - 1 || watchIndex == -1) rlm@1: return true; rlm@1: void *tmp = malloc(sizeof(AddressWatcher)); rlm@1: memcpy(tmp,&(rswatches[watchIndex]),sizeof(AddressWatcher)); rlm@1: memcpy(&(rswatches[watchIndex]),&(rswatches[watchIndex + 1]),sizeof(AddressWatcher)); rlm@1: memcpy(&(rswatches[watchIndex + 1]),tmp,sizeof(AddressWatcher)); rlm@1: free(tmp); rlm@1: ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex,0,LVIS_FOCUSED|LVIS_SELECTED); rlm@1: ListView_SetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex+1); rlm@1: ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex+1,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); rlm@1: ListView_SetItemCount(GetDlgItem(hDlg,IDC_WATCHLIST),WatchCount); rlm@1: RWfileChanged=true; rlm@1: return true; rlm@1: } rlm@1: case ID_WATCHES_UPDOWN: rlm@1: { rlm@1: int delta = ((LPNMUPDOWN)lParam)->iDelta; rlm@1: SendMessage(hDlg, WM_COMMAND, delta<0 ? IDC_C_WATCH_UP : IDC_C_WATCH_DOWN,0); rlm@1: break; rlm@1: } rlm@1: case RAMMENU_FILE_AUTOLOAD: rlm@1: { rlm@1: AutoRWLoad ^= 1; rlm@1: CheckMenuItem(ramwatchmenu, RAMMENU_FILE_AUTOLOAD, AutoRWLoad ? MF_CHECKED : MF_UNCHECKED); rlm@1: regSetDwordValue(AUTORWLOAD, AutoRWLoad); rlm@1: break; rlm@1: } rlm@1: case RAMMENU_FILE_SAVEWINDOW: rlm@1: { rlm@1: RWSaveWindowPos ^=1; rlm@1: CheckMenuItem(ramwatchmenu, RAMMENU_FILE_SAVEWINDOW, RWSaveWindowPos ? MF_CHECKED : MF_UNCHECKED); rlm@1: regSetDwordValue(RWSAVEPOS, RWSaveWindowPos); rlm@1: break; rlm@1: } rlm@1: case IDC_C_ADDCHEAT: rlm@1: { rlm@1: watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: if(watchIndex >= 0) rlm@1: { rlm@1: unsigned int address = rswatches[watchIndex].Address; rlm@1: rlm@1: int sizeType = -1; rlm@1: if(rswatches[watchIndex].Size == 'b') rlm@1: sizeType = 0; rlm@1: else if(rswatches[watchIndex].Size == 'w') rlm@1: sizeType = 1; rlm@1: else if(rswatches[watchIndex].Size == 'd') rlm@1: sizeType = 2; rlm@1: rlm@1: int numberType = -1; rlm@1: if(rswatches[watchIndex].Type == 's') rlm@1: numberType = 0; rlm@1: else if(rswatches[watchIndex].Type == 'u') rlm@1: numberType = 1; rlm@1: else if(rswatches[watchIndex].Type == 'h') rlm@1: numberType = 2; rlm@1: rlm@1: if(systemCartridgeType == 0) rlm@1: { rlm@1: AddCheat dlg (address/*, hDlg*/); rlm@1: if(sizeType != -1) dlg.sizeType = sizeType; rlm@1: if(numberType != -1) dlg.numberType = numberType; rlm@1: systemSoundClearBuffer(); rlm@1: dlg.DoModal(); rlm@1: } rlm@1: else rlm@1: { rlm@1: AddGBCheat dlg (address/*, hDlg*/); rlm@1: if(sizeType != -1) dlg.sizeType = sizeType; rlm@1: if(numberType != -1) dlg.numberType = numberType; rlm@1: systemSoundClearBuffer(); rlm@1: dlg.DoModal(); rlm@1: } rlm@1: } rlm@1: } rlm@1: break; rlm@1: case IDOK: rlm@1: case IDCANCEL: rlm@1: RamWatchHWnd = NULL; rlm@1: DragAcceptFiles(hDlg, FALSE); rlm@1: EndDialog(hDlg, true); rlm@1: return true; rlm@1: default: rlm@1: if (LOWORD(wParam) >= RW_MENU_FIRST_RECENT_FILE && LOWORD(wParam) < RW_MENU_FIRST_RECENT_FILE+MAX_RECENT_WATCHES && LOWORD(wParam) <= RW_MENU_LAST_RECENT_FILE) rlm@1: OpenRWRecentFile(LOWORD(wParam) - RW_MENU_FIRST_RECENT_FILE); rlm@1: } rlm@1: break; rlm@1: rlm@1: #if 0 rlm@1: // this message is never received rlm@1: case WM_KEYDOWN: // handle accelerator keys rlm@1: { rlm@1: SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); rlm@1: MSG msg; rlm@1: msg.hwnd = hDlg; rlm@1: msg.message = uMsg; rlm@1: msg.wParam = wParam; rlm@1: msg.lParam = lParam; rlm@1: if(RamWatchAccels && TranslateAccelerator(hDlg, RamWatchAccels, &msg)) rlm@1: return true; rlm@1: } break; rlm@1: #endif rlm@1: rlm@1: case WM_CLOSE: rlm@1: SendMessage(RamWatchHWnd, WM_DESTROY, 0, 0); rlm@1: break; rlm@1: rlm@1: case WM_DESTROY: rlm@1: // this is the correct place rlm@1: RamWatchHWnd = NULL; rlm@1: DragAcceptFiles(hDlg, FALSE); rlm@1: WriteRecentRWFiles(); // write recent menu to ini rlm@1: break; rlm@1: rlm@1: case WM_DROPFILES: rlm@1: { rlm@1: HDROP hDrop = (HDROP)wParam; rlm@1: DragQueryFile(hDrop, 0, Str_Tmp, 1024); rlm@1: DragFinish(hDrop); rlm@1: return Load_Watches(true, Str_Tmp); rlm@1: } break; rlm@1: } rlm@1: rlm@1: return false; rlm@1: }