Mercurial > vba-clojure
diff src/win32/ramwatch.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/ramwatch.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,1249 @@ 1.4 +#include "stdafx.h" 1.5 +#include "VBA.h" 1.6 +#include "resource.h" 1.7 +#include "WinMiscUtil.h" 1.8 +#include "GBACheatsDlg.h" 1.9 +#include "GBCheatsDlg.h" 1.10 +#include "ram_search.h" 1.11 +#include "ramwatch.h" 1.12 +#include "reg.h" 1.13 +#include "Sound.h" 1.14 +#include <cassert> 1.15 +#include <windows.h> 1.16 +#include <string> 1.17 + 1.18 +/* 1.19 +#include <commctrl.h> 1.20 +#pragma comment(lib, "comctl32.lib") 1.21 +#include <shellapi.h> 1.22 +#pragma comment(lib, "shell32.lib") 1.23 +#include <commdlg.h> 1.24 +#pragma comment(lib, "comdlg32.lib") 1.25 +*/ 1.26 + 1.27 +static HMENU ramwatchmenu; 1.28 +static HMENU rwrecentmenu; 1.29 +/*static*/ HACCEL RamWatchAccels = NULL; 1.30 +char rw_recent_files[MAX_RECENT_WATCHES][1024]; 1.31 +//char Watch_Dir[1024]=""; 1.32 +bool RWfileChanged = false; //Keeps track of whether the current watch file has been changed, if so, ramwatch will prompt to save changes 1.33 +bool AutoRWLoad = false; //Keeps track of whether Auto-load is checked 1.34 +bool RWSaveWindowPos = false; //Keeps track of whether Save Window position is checked 1.35 +char currentWatch[1024]; 1.36 +int ramw_x, ramw_y; //Used to store ramwatch dialog window positions 1.37 +AddressWatcher rswatches[MAX_WATCH_COUNT]; 1.38 +int WatchCount=0; 1.39 +static int s_prevSelCount=-1; 1.40 + 1.41 +HWND RamWatchHWnd; 1.42 +#define gamefilename theApp.gameFilename 1.43 +#define hWnd AfxGetMainWnd()->GetSafeHwnd() 1.44 +#define hInst AfxGetInstanceHandle() 1.45 +static char Str_Tmp [1024]; 1.46 + 1.47 +void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths); //initializes the ram search and/or ram watch listbox 1.48 + 1.49 +#define MESSAGEBOXPARENT (RamWatchHWnd ? RamWatchHWnd : hWnd) 1.50 + 1.51 +bool QuickSaveWatches(); 1.52 +bool ResetWatches(); 1.53 + 1.54 +void RefreshWatchListSelectedCountControlStatus(HWND hDlg); 1.55 + 1.56 +unsigned int GetCurrentValue(AddressWatcher& watch) 1.57 +{ 1.58 + return ReadValueAtHardwareAddress(watch.Address, watch.Size == 'd' ? 4 : watch.Size == 'w' ? 2 : 1); 1.59 +} 1.60 + 1.61 +bool IsSameWatch(const AddressWatcher& l, const AddressWatcher& r) 1.62 +{ 1.63 + if (r.Size == 'S') return false; 1.64 + return ((l.Address == r.Address) && (l.Size == r.Size) && (l.Type == r.Type)/* && (l.WrongEndian == r.WrongEndian)*/); 1.65 +} 1.66 + 1.67 +bool VerifyWatchNotAlreadyAdded(const AddressWatcher& watch) 1.68 +{ 1.69 + for (int j = 0; j < WatchCount; j++) 1.70 + { 1.71 + if (IsSameWatch(rswatches[j], watch)) 1.72 + { 1.73 + if(RamWatchHWnd) 1.74 + SetForegroundWindow(RamWatchHWnd); 1.75 + return false; 1.76 + } 1.77 + } 1.78 + return true; 1.79 +} 1.80 + 1.81 + 1.82 +bool InsertWatch(const AddressWatcher& Watch, char *Comment) 1.83 +{ 1.84 + if(WatchCount >= MAX_WATCH_COUNT) 1.85 + return false; 1.86 + 1.87 + int i = WatchCount++; 1.88 + AddressWatcher& NewWatch = rswatches[i]; 1.89 + NewWatch = Watch; 1.90 + //if (NewWatch.comment) free(NewWatch.comment); 1.91 + NewWatch.comment = (char *) malloc(strlen(Comment)+2); 1.92 + NewWatch.CurValue = GetCurrentValue(NewWatch); 1.93 + strcpy(NewWatch.comment, Comment); 1.94 + ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); 1.95 + RWfileChanged=true; 1.96 + 1.97 + return true; 1.98 +} 1.99 + 1.100 +LRESULT CALLBACK PromptWatchNameProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets the description of a watched address 1.101 +{ 1.102 + RECT r; 1.103 + RECT r2; 1.104 + int dx1, dy1, dx2, dy2; 1.105 + 1.106 + switch(uMsg) 1.107 + { 1.108 + case WM_INITDIALOG: 1.109 + //Clear_Sound_Buffer(); 1.110 + 1.111 + GetWindowRect(hWnd, &r); 1.112 + dx1 = (r.right - r.left) / 2; 1.113 + dy1 = (r.bottom - r.top) / 2; 1.114 + 1.115 + GetWindowRect(hDlg, &r2); 1.116 + dx2 = (r2.right - r2.left) / 2; 1.117 + dy2 = (r2.bottom - r2.top) / 2; 1.118 + 1.119 + //SetWindowPos(hDlg, NULL, max(0, r.left + (dx1 - dx2)), max(0, r.top + (dy1 - dy2)), NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); 1.120 + SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); 1.121 + strcpy(Str_Tmp,"Enter a name for this RAM address."); 1.122 + SendDlgItemMessage(hDlg,IDC_PROMPT_TEXT,WM_SETTEXT,0,(LPARAM)Str_Tmp); 1.123 + strcpy(Str_Tmp,""); 1.124 + SendDlgItemMessage(hDlg,IDC_PROMPT_TEXT2,WM_SETTEXT,0,(LPARAM)Str_Tmp); 1.125 + return true; 1.126 + break; 1.127 + 1.128 + case WM_COMMAND: 1.129 + switch(LOWORD(wParam)) 1.130 + { 1.131 + case IDOK: 1.132 + { 1.133 + GetDlgItemText(hDlg,IDC_PROMPT_EDIT,Str_Tmp,80); 1.134 + InsertWatch(rswatches[WatchCount],Str_Tmp); 1.135 + EndDialog(hDlg, true); 1.136 + return true; 1.137 + break; 1.138 + } 1.139 + case ID_CANCEL: 1.140 + case IDCANCEL: 1.141 + EndDialog(hDlg, false); 1.142 + return false; 1.143 + break; 1.144 + } 1.145 + break; 1.146 + 1.147 + case WM_CLOSE: 1.148 + EndDialog(hDlg, false); 1.149 + return false; 1.150 + break; 1.151 + } 1.152 + 1.153 + return false; 1.154 +} 1.155 + 1.156 +bool InsertWatch(const AddressWatcher& Watch, HWND parent) 1.157 +{ 1.158 + if(!VerifyWatchNotAlreadyAdded(Watch)) 1.159 + return false; 1.160 + 1.161 + if(!parent) 1.162 + parent = RamWatchHWnd; 1.163 + if(!parent) 1.164 + parent = hWnd; 1.165 + 1.166 + int prevWatchCount = WatchCount; 1.167 + 1.168 + rswatches[WatchCount] = Watch; 1.169 + rswatches[WatchCount].CurValue = GetCurrentValue(rswatches[WatchCount]); 1.170 + systemSoundClearBuffer(); 1.171 + DialogBox(hInst, MAKEINTRESOURCE(IDD_PROMPT), parent, (DLGPROC) PromptWatchNameProc); 1.172 + 1.173 + return WatchCount > prevWatchCount; 1.174 +} 1.175 + 1.176 +void Update_RAM_Watch() 1.177 +{ 1.178 + BOOL watchChanged[MAX_WATCH_COUNT] = {0}; 1.179 + 1.180 + if(WatchCount) 1.181 + { 1.182 + // update cached values and detect changes to displayed listview items 1.183 + 1.184 + for(int i = 0; i < WatchCount; i++) 1.185 + { 1.186 + unsigned int prevCurValue = rswatches[i].CurValue; 1.187 + unsigned int newCurValue = GetCurrentValue(rswatches[i]); 1.188 + if(prevCurValue != newCurValue) 1.189 + { 1.190 + rswatches[i].CurValue = newCurValue; 1.191 + watchChanged[i] = TRUE; 1.192 + } 1.193 + } 1.194 + } 1.195 + 1.196 + // refresh any visible parts of the listview box that changed 1.197 + HWND lv = GetDlgItem(RamWatchHWnd,IDC_WATCHLIST); 1.198 + int top = ListView_GetTopIndex(lv); 1.199 + int bottom = top + ListView_GetCountPerPage(lv) + 1; // +1 is so we will update a partially-displayed last item 1.200 + if(top < 0) top = 0; 1.201 + if(bottom > WatchCount) bottom = WatchCount; 1.202 + int start = -1; 1.203 + for(int i = top; i <= bottom; i++) 1.204 + { 1.205 + if(start == -1) 1.206 + { 1.207 + if(i != bottom && watchChanged[i]) 1.208 + { 1.209 + start = i; 1.210 + //somethingChanged = true; 1.211 + } 1.212 + } 1.213 + else 1.214 + { 1.215 + if(i == bottom || !watchChanged[i]) 1.216 + { 1.217 + ListView_RedrawItems(lv, start, i-1); 1.218 + start = -1; 1.219 + } 1.220 + } 1.221 + } 1.222 +} 1.223 + 1.224 +bool AskSave() 1.225 +{ 1.226 + //This function asks to save changes if the watch file contents have changed 1.227 + //returns false only if a save was attempted but failed or was cancelled 1.228 + if (RWfileChanged) 1.229 + { 1.230 + systemSoundClearBuffer(); 1.231 + int answer = MessageBox(MESSAGEBOXPARENT, "Save Changes?", "Ram Watch", MB_YESNOCANCEL); 1.232 + if(answer == IDYES) 1.233 + if(!QuickSaveWatches()) 1.234 + return false; 1.235 + return (answer != IDCANCEL); 1.236 + } 1.237 + return true; 1.238 +} 1.239 + 1.240 +void WriteRecentRWFiles() 1.241 +{ 1.242 + char str[2048]; 1.243 + for (int i = 0; i < MAX_RECENT_WATCHES; i++) 1.244 + { 1.245 + sprintf(str, "recentWatch%d", i+1); 1.246 + regSetStringValue(str, &rw_recent_files[i][0]); 1.247 + } 1.248 +} 1.249 + 1.250 +void UpdateRW_RMenu(HMENU menu, unsigned int mitem, unsigned int baseid) 1.251 +{ 1.252 + MENUITEMINFO moo; 1.253 + int x; 1.254 + 1.255 + moo.cbSize = sizeof(moo); 1.256 + moo.fMask = MIIM_SUBMENU | MIIM_STATE; 1.257 + 1.258 + GetMenuItemInfo(GetSubMenu(ramwatchmenu, 0), mitem, FALSE, &moo); 1.259 + moo.hSubMenu = menu; 1.260 + moo.fState = strlen(rw_recent_files[0]) ? MFS_ENABLED : MFS_GRAYED; 1.261 + 1.262 + SetMenuItemInfo(GetSubMenu(ramwatchmenu, 0), mitem, FALSE, &moo); 1.263 + 1.264 + // Remove all recent files submenus 1.265 + for(x = 0; x < MAX_RECENT_WATCHES; x++) 1.266 + { 1.267 + RemoveMenu(menu, baseid + x, MF_BYCOMMAND); 1.268 + } 1.269 + 1.270 + // Recreate the menus 1.271 + for(x = MAX_RECENT_WATCHES - 1; x >= 0; x--) 1.272 + { 1.273 + // Skip empty strings 1.274 + if(!strlen(rw_recent_files[x])) 1.275 + { 1.276 + continue; 1.277 + } 1.278 + 1.279 + moo.cbSize = sizeof(moo); 1.280 + moo.fMask = MIIM_DATA | MIIM_ID | MIIM_TYPE; 1.281 + 1.282 +#if 0 1.283 + const int TEMP_STRING_LENGTH = 128 + 5; 1.284 + char tmp[TEMP_STRING_LENGTH]; // FIXME? 1.285 + 1.286 + // Fill in the menu text. 1.287 + if(strlen(rw_recent_files[x]) < 128) 1.288 + { 1.289 + sprintf(tmp, "&%d. %s", ( x + 1 ) % 10, rw_recent_files[x]); 1.290 + } 1.291 + else 1.292 + { 1.293 + sprintf(tmp, "&%d. %s", ( x + 1 ) % 10, rw_recent_files[x] + strlen( rw_recent_files[x] ) - 127); 1.294 + } 1.295 +#endif 1.296 + // the ATL way; it is really pain to work out a MBCS-compatible string replace function in the pure c way 1.297 + CString atltmp(rw_recent_files[x]); 1.298 + atltmp.Replace("&", "&&"); 1.299 + char *tmp = atltmp.GetBuffer(0); 1.300 + 1.301 + // Insert the menu item 1.302 + moo.cch = strlen(tmp); 1.303 + moo.fType = 0; 1.304 + moo.wID = baseid + x; 1.305 + moo.dwTypeData = tmp; 1.306 + InsertMenuItem(menu, 0, 1, &moo); 1.307 + 1.308 + // atltmp.ReleaseBuffer(); 1.309 + } 1.310 + 1.311 + // I don't think one function shall do so many things in a row 1.312 +// WriteRecentRWFiles(); // write recent menu to ini 1.313 +} 1.314 + 1.315 +void UpdateRWRecentArray(const char* addString, unsigned int arrayLen, HMENU menu, unsigned int menuItem, unsigned int baseId) 1.316 +{ 1.317 + const size_t len = 1024; // Avoid magic numbers 1.318 + 1.319 + // Try to find out if the filename is already in the recent files list. 1.320 + for(unsigned int x = 0; x < arrayLen; x++) 1.321 + { 1.322 + if(strlen(rw_recent_files[x])) 1.323 + { 1.324 + if(!strncmp(rw_recent_files[x], addString, 1024)) // Item is already in list. 1.325 + { 1.326 + // If the filename is in the file list don't add it again. 1.327 + // Move it up in the list instead. 1.328 + 1.329 + int y; 1.330 + char tmp[len]; 1.331 + 1.332 + // Save pointer. 1.333 + strncpy(tmp, rw_recent_files[x], len - 1); // assuming rw_recent_files[n] is 0-terminated 1.334 + 1.335 + for(y = x; y; y--) 1.336 + { 1.337 + // Move items down. 1.338 + strncpy(rw_recent_files[y], rw_recent_files[y - 1], len); 1.339 + } 1.340 + 1.341 + // Put item on top. 1.342 + strncpy(rw_recent_files[0],tmp, len); 1.343 + 1.344 + // Update the recent files menu 1.345 + UpdateRW_RMenu(menu, menuItem, baseId); 1.346 + 1.347 + return; 1.348 + } 1.349 + } 1.350 + } 1.351 + 1.352 + // The filename wasn't found in the list. That means we need to add it. 1.353 + 1.354 + // Move the other items down. 1.355 + for(unsigned int x = arrayLen - 1; x; x--) 1.356 + { 1.357 + strncpy(rw_recent_files[x],rw_recent_files[x - 1], len); 1.358 + } 1.359 + 1.360 + // Add the new item. 1.361 + strncpy(rw_recent_files[0], addString, len); 1.362 + rw_recent_files[0][len - 1] = '\0'; // better not assume that 1.363 + 1.364 + // Update the recent files menu 1.365 + UpdateRW_RMenu(menu, menuItem, baseId); 1.366 +} 1.367 + 1.368 +void RWAddRecentFile(const char *filename) 1.369 +{ 1.370 + UpdateRWRecentArray(filename, MAX_RECENT_WATCHES, rwrecentmenu, RAMMENU_FILE_RECENT, RW_MENU_FIRST_RECENT_FILE); 1.371 +} 1.372 + 1.373 +void OpenRWRecentFile(int memwRFileNumber) 1.374 +{ 1.375 + if(!ResetWatches()) 1.376 + return; 1.377 + 1.378 + int rnum = memwRFileNumber; 1.379 + if ((unsigned int)rnum >= MAX_RECENT_WATCHES) 1.380 + return; //just in case 1.381 + 1.382 + char* x; 1.383 + 1.384 + while(true) 1.385 + { 1.386 + x = rw_recent_files[rnum]; 1.387 + if (!*x) 1.388 + return; //If no recent files exist just return. Useful for Load last file on startup (or if something goes screwy) 1.389 + 1.390 + if (rnum) //Change order of recent files if not most recent 1.391 + { 1.392 + RWAddRecentFile(x); 1.393 + rnum = 0; 1.394 + } 1.395 + else 1.396 + { 1.397 + break; 1.398 + } 1.399 + } 1.400 + 1.401 + strcpy(currentWatch,x); 1.402 + strcpy(Str_Tmp,currentWatch); 1.403 + 1.404 + //loadwatches here 1.405 + FILE *WatchFile = fopen(Str_Tmp,"rb"); 1.406 + if (!WatchFile) 1.407 + { 1.408 + systemSoundClearBuffer(); 1.409 + int answer = MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OKCANCEL); 1.410 + if (answer == IDOK) 1.411 + { 1.412 + rw_recent_files[rnum][0] = '\0'; //Clear file from list 1.413 + if (rnum) //Update the ramwatch list 1.414 + RWAddRecentFile(rw_recent_files[0]); 1.415 + else 1.416 + RWAddRecentFile(rw_recent_files[1]); 1.417 + } 1.418 + return; 1.419 + } 1.420 + const char DELIM = '\t'; 1.421 + AddressWatcher Temp; 1.422 + char mode; 1.423 + fgets(Str_Tmp,1024,WatchFile); 1.424 + sscanf(Str_Tmp,"%c%*s",&mode); 1.425 + //if ((mode == '1' && !(SegaCD_Started)) || (mode == '2' && !(_32X_Started))) 1.426 + //{ 1.427 + // char Device[8]; 1.428 + // strcpy(Device,(mode > '1')?"32X":"SegaCD"); 1.429 + // sprintf(Str_Tmp,"Warning: %s not started. \nWatches for %s addresses will be ignored.",Device,Device); 1.430 + // MessageBox(MESSAGEBOXPARENT,Str_Tmp,"Possible Device Mismatch",MB_OK); 1.431 + //} 1.432 + int WatchAdd; 1.433 + fgets(Str_Tmp,1024,WatchFile); 1.434 + sscanf(Str_Tmp,"%d%*s",&WatchAdd); 1.435 + WatchAdd+=WatchCount; 1.436 + for (int i = WatchCount; i < WatchAdd; i++) 1.437 + { 1.438 + while (i < 0) 1.439 + i++; 1.440 + do { 1.441 + fgets(Str_Tmp,1024,WatchFile); 1.442 + } while (Str_Tmp[0] == '\n'); 1.443 + sscanf(Str_Tmp,"%*05X%*c%08X%*c%c%*c%c%*c%d",&(Temp.Address),&(Temp.Size),&(Temp.Type),&(Temp.WrongEndian)); 1.444 + Temp.WrongEndian = 0; 1.445 + char *Comment = strrchr(Str_Tmp,DELIM) + 1; 1.446 + *strrchr(Comment,'\n') = '\0'; 1.447 + InsertWatch(Temp,Comment); 1.448 + } 1.449 + 1.450 + fclose(WatchFile); 1.451 + if (RamWatchHWnd) { 1.452 + ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); 1.453 + RefreshWatchListSelectedCountControlStatus(RamWatchHWnd); 1.454 + } 1.455 + RWfileChanged=false; 1.456 + return; 1.457 +} 1.458 + 1.459 +int Change_File_L(char *Dest, const char *Dir, const char *Titre, const char *Filter, const char *Ext, HWND hwnd) 1.460 +{ 1.461 + if (!strcmp(Dest, "")) 1.462 + { 1.463 + strcpy(Dest, "default."); 1.464 + strcat(Dest, Ext); 1.465 + } 1.466 + 1.467 + SetCurrentDirectory(winGetDestDir(IDS_WATCH_DIR)); 1.468 + 1.469 + OPENFILENAME ofn; 1.470 + 1.471 + memset(&ofn, 0, sizeof(OPENFILENAME)); 1.472 + 1.473 + ofn.lStructSize = sizeof(OPENFILENAME); 1.474 + ofn.hwndOwner = hwnd; 1.475 + ofn.hInstance = hInst; 1.476 + ofn.lpstrFile = Dest; 1.477 + ofn.nMaxFile = 2047; 1.478 + ofn.lpstrFilter = Filter; 1.479 + ofn.nFilterIndex = 1; 1.480 + ofn.lpstrInitialDir = Dir; 1.481 + ofn.lpstrTitle = Titre; 1.482 + ofn.lpstrDefExt = Ext; 1.483 + ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 1.484 + 1.485 + systemSoundClearBuffer(); 1.486 + 1.487 + if (GetOpenFileName(&ofn)) return 1; 1.488 + 1.489 + return 0; 1.490 +} 1.491 + 1.492 +int Change_File_S(char *Dest, const char *Dir, const char *Titre, const char *Filter, const char *Ext, HWND hwnd) 1.493 +{ 1.494 + if (!strcmp(Dest, "")) 1.495 + { 1.496 + strcpy(Dest, "default."); 1.497 + strcat(Dest, Ext); 1.498 + } 1.499 + 1.500 + SetCurrentDirectory(winGetDestDir(IDS_WATCH_DIR)); 1.501 + 1.502 + OPENFILENAME ofn; 1.503 + 1.504 + memset(&ofn, 0, sizeof(OPENFILENAME)); 1.505 + 1.506 + ofn.lStructSize = sizeof(OPENFILENAME); 1.507 + ofn.hwndOwner = hwnd; 1.508 + ofn.hInstance = hInst; 1.509 + ofn.lpstrFile = Dest; 1.510 + ofn.nMaxFile = 2047; 1.511 + ofn.lpstrFilter = Filter; 1.512 + ofn.nFilterIndex = 1; 1.513 + ofn.lpstrInitialDir = Dir; 1.514 + ofn.lpstrTitle = Titre; 1.515 + ofn.lpstrDefExt = Ext; 1.516 + ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; 1.517 + 1.518 + if (GetSaveFileName(&ofn)) return 1; 1.519 + 1.520 + return 0; 1.521 +} 1.522 + 1.523 +bool Save_Watches() 1.524 +{ 1.525 + const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/'))); 1.526 + strcpy(Str_Tmp,slash ? slash+1 : gamefilename); 1.527 + char* dot = strrchr(Str_Tmp, '.'); 1.528 + if(dot) *dot = 0; 1.529 + strcat(Str_Tmp,".wch"); 1.530 + if(Change_File_S(Str_Tmp, winGetDestDir(IDS_WATCH_DIR), "Save Watches", "Watchlist\0*.wch\0All Files\0*.*\0\0", "wch", RamWatchHWnd)) 1.531 + { 1.532 + FILE *WatchFile = fopen(Str_Tmp,"r+b"); 1.533 + if (!WatchFile) WatchFile = fopen(Str_Tmp,"w+b"); 1.534 + fputc('\n',WatchFile); 1.535 + strcpy(currentWatch,Str_Tmp); 1.536 + RWAddRecentFile(currentWatch); 1.537 + sprintf(Str_Tmp,"%d\n",WatchCount); 1.538 + fputs(Str_Tmp,WatchFile); 1.539 + const char DELIM = '\t'; 1.540 + for (int i = 0; i < WatchCount; i++) 1.541 + { 1.542 + 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); 1.543 + fputs(Str_Tmp,WatchFile); 1.544 + } 1.545 + 1.546 + fclose(WatchFile); 1.547 + RWfileChanged=false; 1.548 + //TODO: Add to recent list function call here 1.549 + return true; 1.550 + } 1.551 + return false; 1.552 +} 1.553 + 1.554 +bool QuickSaveWatches() 1.555 +{ 1.556 +if (RWfileChanged==false) return true; //If file has not changed, no need to save changes 1.557 +if (currentWatch[0] == NULL) //If there is no currently loaded file, run to Save as and then return 1.558 + { 1.559 + return Save_Watches(); 1.560 + } 1.561 + 1.562 + strcpy(Str_Tmp,currentWatch); 1.563 + FILE *WatchFile = fopen(Str_Tmp,"r+b"); 1.564 + if (!WatchFile) WatchFile = fopen(Str_Tmp,"w+b"); 1.565 + fputc('\n',WatchFile); 1.566 + sprintf(Str_Tmp,"%d\n",WatchCount); 1.567 + fputs(Str_Tmp,WatchFile); 1.568 + const char DELIM = '\t'; 1.569 + for (int i = 0; i < WatchCount; i++) 1.570 + { 1.571 + 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); 1.572 + fputs(Str_Tmp,WatchFile); 1.573 + } 1.574 + fclose(WatchFile); 1.575 + RWfileChanged=false; 1.576 + return true; 1.577 +} 1.578 + 1.579 +bool Load_Watches(bool clear, const char* filename) 1.580 +{ 1.581 + const char DELIM = '\t'; 1.582 + FILE* WatchFile = fopen(filename,"rb"); 1.583 + if (!WatchFile) 1.584 + { 1.585 + systemSoundClearBuffer(); 1.586 + MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OK); 1.587 + return false; 1.588 + } 1.589 + if(clear) 1.590 + { 1.591 + if(!ResetWatches()) 1.592 + { 1.593 + fclose(WatchFile); 1.594 + return false; 1.595 + } 1.596 + } 1.597 + strcpy(currentWatch,filename); 1.598 + RWAddRecentFile(currentWatch); 1.599 + AddressWatcher Temp; 1.600 + char mode; 1.601 + fgets(Str_Tmp,1024,WatchFile); 1.602 + sscanf(Str_Tmp,"%c%*s",&mode); 1.603 + int WatchAdd; 1.604 + fgets(Str_Tmp,1024,WatchFile); 1.605 + sscanf(Str_Tmp,"%d%*s",&WatchAdd); 1.606 + WatchAdd+=WatchCount; 1.607 + for (int i = WatchCount; i < WatchAdd; i++) 1.608 + { 1.609 + while (i < 0) 1.610 + i++; 1.611 + do { 1.612 + fgets(Str_Tmp,1024,WatchFile); 1.613 + } while (Str_Tmp[0] == '\n'); 1.614 + sscanf(Str_Tmp,"%*05X%*c%08X%*c%c%*c%c%*c%d",&(Temp.Address),&(Temp.Size),&(Temp.Type),&(Temp.WrongEndian)); 1.615 + Temp.WrongEndian = 0; 1.616 + char *Comment = strrchr(Str_Tmp,DELIM) + 1; 1.617 + *strrchr(Comment,'\n') = '\0'; 1.618 + InsertWatch(Temp,Comment); 1.619 + } 1.620 + 1.621 + fclose(WatchFile); 1.622 + if (RamWatchHWnd) 1.623 + ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); 1.624 + RWfileChanged=false; 1.625 + return true; 1.626 +} 1.627 + 1.628 +bool Load_Watches(bool clear) 1.629 +{ 1.630 + const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/'))); 1.631 + strcpy(Str_Tmp,slash ? slash+1 : gamefilename); 1.632 + char* dot = strrchr(Str_Tmp, '.'); 1.633 + if(dot) *dot = 0; 1.634 + strcat(Str_Tmp,".wch"); 1.635 + if(Change_File_L(Str_Tmp, winGetDestDir(IDS_WATCH_DIR), "Load Watches", "Watchlist\0*.wch\0All Files\0*.*\0\0", "wch", RamWatchHWnd)) 1.636 + { 1.637 + return Load_Watches(clear, Str_Tmp); 1.638 + } 1.639 + return false; 1.640 +} 1.641 + 1.642 +bool ResetWatches() 1.643 +{ 1.644 + if(!AskSave()) 1.645 + return false; 1.646 + for (;WatchCount>=0;WatchCount--) 1.647 + { 1.648 + free(rswatches[WatchCount].comment); 1.649 + rswatches[WatchCount].comment = NULL; 1.650 + } 1.651 + WatchCount++; 1.652 + if (RamWatchHWnd) { 1.653 + ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); 1.654 + RefreshWatchListSelectedCountControlStatus(RamWatchHWnd); 1.655 + } 1.656 + RWfileChanged = false; 1.657 + currentWatch[0] = NULL; 1.658 + return true; 1.659 +} 1.660 + 1.661 +void RemoveWatch(int watchIndex) 1.662 +{ 1.663 + free(rswatches[watchIndex].comment); 1.664 + rswatches[watchIndex].comment = NULL; 1.665 + for (int i = watchIndex; i <= WatchCount; i++) 1.666 + rswatches[i] = rswatches[i+1]; 1.667 + WatchCount--; 1.668 +} 1.669 + 1.670 +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 1.671 +{ 1.672 + RECT r; 1.673 + RECT r2; 1.674 + int dx1, dy1, dx2, dy2; 1.675 + static int index; 1.676 + static char s,t = s = 0; 1.677 + 1.678 + switch(uMsg) 1.679 + { 1.680 + case WM_INITDIALOG: 1.681 + //Clear_Sound_Buffer(); 1.682 + 1.683 + 1.684 + GetWindowRect(hWnd, &r); 1.685 + dx1 = (r.right - r.left) / 2; 1.686 + dy1 = (r.bottom - r.top) / 2; 1.687 + 1.688 + GetWindowRect(hDlg, &r2); 1.689 + dx2 = (r2.right - r2.left) / 2; 1.690 + dy2 = (r2.bottom - r2.top) / 2; 1.691 + 1.692 + //SetWindowPos(hDlg, NULL, max(0, r.left + (dx1 - dx2)), max(0, r.top + (dy1 - dy2)), NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); 1.693 + SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); 1.694 + index = (int)lParam; 1.695 + sprintf(Str_Tmp,"%08X",rswatches[index].Address); 1.696 + SetDlgItemText(hDlg,IDC_EDIT_COMPAREADDRESS,Str_Tmp); 1.697 + if (rswatches[index].comment != NULL) 1.698 + SetDlgItemText(hDlg,IDC_PROMPT_EDIT,rswatches[index].comment); 1.699 + s = rswatches[index].Size; 1.700 + t = rswatches[index].Type; 1.701 + switch (s) 1.702 + { 1.703 + case 'b': 1.704 + SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_CHECKED, 0); 1.705 + break; 1.706 + case 'w': 1.707 + SendDlgItemMessage(hDlg, IDC_2_BYTES, BM_SETCHECK, BST_CHECKED, 0); 1.708 + break; 1.709 + case 'd': 1.710 + SendDlgItemMessage(hDlg, IDC_4_BYTES, BM_SETCHECK, BST_CHECKED, 0); 1.711 + break; 1.712 + default: 1.713 + s = 0; 1.714 + break; 1.715 + } 1.716 + switch (t) 1.717 + { 1.718 + case 's': 1.719 + SendDlgItemMessage(hDlg, IDC_SIGNED, BM_SETCHECK, BST_CHECKED, 0); 1.720 + break; 1.721 + case 'u': 1.722 + SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_SETCHECK, BST_CHECKED, 0); 1.723 + break; 1.724 + case 'h': 1.725 + SendDlgItemMessage(hDlg, IDC_HEX, BM_SETCHECK, BST_CHECKED, 0); 1.726 + break; 1.727 + default: 1.728 + t = 0; 1.729 + break; 1.730 + } 1.731 + 1.732 + return true; 1.733 + break; 1.734 + 1.735 + case WM_COMMAND: 1.736 + switch(LOWORD(wParam)) 1.737 + { 1.738 + case IDC_SIGNED: 1.739 + t='s'; 1.740 + return true; 1.741 + case IDC_UNSIGNED: 1.742 + t='u'; 1.743 + return true; 1.744 + case IDC_HEX: 1.745 + t='h'; 1.746 + return true; 1.747 + case IDC_1_BYTE: 1.748 + s = 'b'; 1.749 + return true; 1.750 + case IDC_2_BYTES: 1.751 + s = 'w'; 1.752 + return true; 1.753 + case IDC_4_BYTES: 1.754 + s = 'd'; 1.755 + return true; 1.756 + case IDOK: 1.757 + { 1.758 + if (s && t) 1.759 + { 1.760 + AddressWatcher Temp; 1.761 + Temp.Size = s; 1.762 + Temp.Type = t; 1.763 + Temp.WrongEndian = false; //replace this when I get little endian working properly 1.764 + GetDlgItemText(hDlg,IDC_EDIT_COMPAREADDRESS,Str_Tmp,1024); 1.765 + char *addrstr = Str_Tmp; 1.766 + if (strlen(Str_Tmp) > 8) addrstr = &(Str_Tmp[strlen(Str_Tmp) - 9]); 1.767 + for(int i = 0; addrstr[i]; i++) {if(toupper(addrstr[i]) == 'O') addrstr[i] = '0';} 1.768 + sscanf(addrstr,"%08X",&(Temp.Address)); 1.769 + 1.770 + if((Temp.Address & ~0xFFFFFF) == ~0xFFFFFF) 1.771 + Temp.Address &= 0xFFFFFF; 1.772 + 1.773 + if(IsHardwareAddressValid(Temp.Address)) 1.774 + { 1.775 + GetDlgItemText(hDlg,IDC_PROMPT_EDIT,Str_Tmp,80); 1.776 + if (index < WatchCount) RemoveWatch(index); 1.777 + InsertWatch(Temp,Str_Tmp); 1.778 + if(RamWatchHWnd) 1.779 + { 1.780 + ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); 1.781 + } 1.782 + EndDialog(hDlg, true); 1.783 + } 1.784 + else 1.785 + { 1.786 + MessageBox(hDlg,"Invalid Address","ERROR",MB_OK); 1.787 + } 1.788 + } 1.789 + else 1.790 + { 1.791 + strcpy(Str_Tmp,"Error:"); 1.792 + if (!s) 1.793 + strcat(Str_Tmp," Size must be specified."); 1.794 + if (!t) 1.795 + strcat(Str_Tmp," Type must be specified."); 1.796 + MessageBox(hDlg,Str_Tmp,"ERROR",MB_OK); 1.797 + } 1.798 + RWfileChanged=true; 1.799 + return true; 1.800 + break; 1.801 + } 1.802 + case ID_CANCEL: 1.803 + case IDCANCEL: 1.804 + EndDialog(hDlg, false); 1.805 + return false; 1.806 + break; 1.807 + } 1.808 + break; 1.809 + 1.810 + case WM_CLOSE: 1.811 + EndDialog(hDlg, false); 1.812 + return false; 1.813 + break; 1.814 + } 1.815 + 1.816 + return false; 1.817 +} 1.818 + 1.819 + 1.820 + 1.821 + 1.822 +void RamWatchEnableCommand(HWND hDlg, HMENU hMenu, UINT uIDEnableItem, bool enable) 1.823 +{ 1.824 + EnableWindow(GetDlgItem(hDlg, uIDEnableItem), (enable?TRUE:FALSE)); 1.825 + if (hMenu != NULL) { 1.826 + if (uIDEnableItem == ID_WATCHES_UPDOWN) { 1.827 + EnableMenuItem(hMenu, IDC_C_WATCH_UP, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); 1.828 + EnableMenuItem(hMenu, IDC_C_WATCH_DOWN, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); 1.829 + } 1.830 + else 1.831 + EnableMenuItem(hMenu, uIDEnableItem, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); 1.832 + } 1.833 +} 1.834 + 1.835 +void RefreshWatchListSelectedCountControlStatus(HWND hDlg) 1.836 +{ 1.837 + int selCount = ListView_GetSelectedCount(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.838 + if(selCount != s_prevSelCount) 1.839 + { 1.840 + if(selCount < 2 || s_prevSelCount < 2) 1.841 + { 1.842 + RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH_EDIT, selCount == 1); 1.843 + RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH_REMOVE, selCount >= 1); 1.844 + RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH, WatchCount < MAX_WATCH_COUNT); 1.845 + RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_WATCH_DUPLICATE, selCount == 1 && WatchCount < MAX_WATCH_COUNT); 1.846 + RamWatchEnableCommand(hDlg, ramwatchmenu, IDC_C_ADDCHEAT, selCount == 1); 1.847 + RamWatchEnableCommand(hDlg, ramwatchmenu, ID_WATCHES_UPDOWN, selCount == 1); 1.848 + } 1.849 + s_prevSelCount = selCount; 1.850 + } 1.851 +} 1.852 + 1.853 +LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 1.854 +{ 1.855 + RECT r; 1.856 + RECT r2; 1.857 + int dx1, dy1, dx2, dy2; 1.858 + static int watchIndex=0; 1.859 + 1.860 + switch(uMsg) 1.861 + { 1.862 + case WM_MOVE: { 1.863 + RECT wrect; 1.864 + GetWindowRect(hDlg,&wrect); 1.865 + ramw_x = wrect.left; 1.866 + ramw_y = wrect.top; 1.867 + regSetDwordValue(RAMWX, ramw_x); 1.868 + regSetDwordValue(RAMWY, ramw_y); 1.869 + } break; 1.870 + 1.871 + case WM_INITDIALOG: { 1.872 + GetWindowRect(hWnd, &r); //Ramwatch window 1.873 + dx1 = (r.right - r.left) / 2; 1.874 + dy1 = (r.bottom - r.top) / 2; 1.875 + 1.876 + GetWindowRect(hDlg, &r2); // TASer window 1.877 + dx2 = (r2.right - r2.left) / 2; 1.878 + dy2 = (r2.bottom - r2.top) / 2; 1.879 + 1.880 + 1.881 + // push it away from the main window if we can 1.882 + const int width = (r.right-r.left); 1.883 + const int height = (r.bottom - r.top); 1.884 + const int width2 = (r2.right-r2.left); 1.885 + if(r.left+width2 + width < GetSystemMetrics(SM_CXSCREEN)) 1.886 + { 1.887 + r.right += width; 1.888 + r.left += width; 1.889 + } 1.890 + else if((int)r.left - (int)width2 > 0) 1.891 + { 1.892 + r.right -= width2; 1.893 + r.left -= width2; 1.894 + } 1.895 + 1.896 + //----------------------------------------------------------------------------------- 1.897 + //If user has Save Window Pos selected, override default positioning 1.898 + if (RWSaveWindowPos) 1.899 + { 1.900 + //If ramwindow is for some reason completely off screen, use default instead 1.901 + if (ramw_x > (-width*2) || ramw_x < (width*2 + GetSystemMetrics(SM_CYSCREEN)) ) 1.902 + r.left = ramw_x; //This also ignores cases of windows -32000 error codes 1.903 + //If ramwindow is for some reason completely off screen, use default instead 1.904 + if (ramw_y > (0-height*2) ||ramw_y < (height*2 + GetSystemMetrics(SM_CYSCREEN)) ) 1.905 + r.top = ramw_y; //This also ignores cases of windows -32000 error codes 1.906 + } 1.907 + //------------------------------------------------------------------------------------- 1.908 + SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); 1.909 + 1.910 + ramwatchmenu=GetMenu(hDlg); 1.911 + rwrecentmenu=CreateMenu(); 1.912 + UpdateRW_RMenu(rwrecentmenu, RAMMENU_FILE_RECENT, RW_MENU_FIRST_RECENT_FILE); 1.913 + 1.914 + const char* names[3] = {"Address","Value","Notes"}; 1.915 + int widths[3] = {62,64,64+51+53}; 1.916 + init_list_box(GetDlgItem(hDlg,IDC_WATCHLIST),names,3,widths); 1.917 + if (!ResultCount) 1.918 + reset_address_info(); 1.919 + else 1.920 + signal_new_frame(); 1.921 + ListView_SetItemCount(GetDlgItem(hDlg,IDC_WATCHLIST),WatchCount); 1.922 + if (!noMisalign) SendDlgItemMessage(hDlg, IDC_MISALIGN, BM_SETCHECK, BST_CHECKED, 0); 1.923 + //if (littleEndian) SendDlgItemMessage(hDlg, IDC_ENDIAN, BM_SETCHECK, BST_CHECKED, 0); 1.924 + 1.925 + RamWatchAccels = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR1)); 1.926 + 1.927 + // due to some bug in windows, the arrow button width from the resource gets ignored, so we have to set it here 1.928 + SetWindowPos(GetDlgItem(hDlg,ID_WATCHES_UPDOWN), 0,0,0, 30,60, SWP_NOMOVE); 1.929 + 1.930 + Update_RAM_Watch(); 1.931 + 1.932 + DragAcceptFiles(hDlg, TRUE); 1.933 + 1.934 + s_prevSelCount = -1; 1.935 + RefreshWatchListSelectedCountControlStatus(hDlg); 1.936 + return false; 1.937 + } break; 1.938 + 1.939 + case WM_INITMENU: 1.940 + CheckMenuItem(ramwatchmenu, RAMMENU_FILE_AUTOLOAD, AutoRWLoad ? MF_CHECKED : MF_UNCHECKED); 1.941 + CheckMenuItem(ramwatchmenu, RAMMENU_FILE_SAVEWINDOW, RWSaveWindowPos ? MF_CHECKED : MF_UNCHECKED); 1.942 + break; 1.943 + 1.944 + case WM_ENTERMENULOOP: 1.945 + systemSoundClearBuffer(); 1.946 + break; 1.947 + 1.948 + case WM_MENUSELECT: 1.949 + case WM_ENTERSIZEMOVE: 1.950 + //Clear_Sound_Buffer(); 1.951 + break; 1.952 + 1.953 + case WM_NOTIFY: 1.954 + { 1.955 + switch(wParam) 1.956 + { 1.957 + case ID_WATCHES_UPDOWN: 1.958 + { 1.959 + switch(((LPNMUPDOWN)lParam)->hdr.code) 1.960 + { 1.961 + case UDN_DELTAPOS: { 1.962 + int delta = ((LPNMUPDOWN)lParam)->iDelta; 1.963 + SendMessage(hDlg, WM_COMMAND, delta<0 ? IDC_C_WATCH_UP : IDC_C_WATCH_DOWN,0); 1.964 + } break; 1.965 + } 1.966 + } break; 1.967 + 1.968 + default: 1.969 + { 1.970 + LPNMHDR lP = (LPNMHDR) lParam; 1.971 + switch (lP->code) 1.972 + { 1.973 + case LVN_ITEMCHANGED: // selection changed event 1.974 + { 1.975 + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)lP; 1.976 + if(pNMListView->uNewState & LVIS_FOCUSED || 1.977 + (pNMListView->uNewState ^ pNMListView->uOldState) & LVIS_SELECTED) 1.978 + { 1.979 + // disable buttons that we don't have the right number of selected items for 1.980 + RefreshWatchListSelectedCountControlStatus(hDlg); 1.981 + } 1.982 + } break; 1.983 + 1.984 + case LVN_GETDISPINFO: 1.985 + { 1.986 + LV_DISPINFO *Item = (LV_DISPINFO *)lParam; 1.987 + Item->item.mask = LVIF_TEXT; 1.988 + Item->item.state = 0; 1.989 + Item->item.iImage = 0; 1.990 + const unsigned int iNum = Item->item.iItem; 1.991 + static char num[11]; 1.992 + switch (Item->item.iSubItem) 1.993 + { 1.994 + case 0: 1.995 + sprintf(num,"%08X",rswatches[iNum].Address); 1.996 + Item->item.pszText = num; 1.997 + return true; 1.998 + case 1: { 1.999 + int i = rswatches[iNum].CurValue; 1.1000 + int t = rswatches[iNum].Type; 1.1001 + int size = rswatches[iNum].Size; 1.1002 + const char* formatString = ((t=='s') ? "%d" : (t=='u') ? "%u" : (size=='d' ? "%08X" : size=='w' ? "%04X" : "%02X")); 1.1003 + switch (size) 1.1004 + { 1.1005 + case 'b': 1.1006 + default: sprintf(num, formatString, t=='s' ? (char)(i&0xff) : (unsigned char)(i&0xff)); break; 1.1007 + case 'w': sprintf(num, formatString, t=='s' ? (short)(i&0xffff) : (unsigned short)(i&0xffff)); break; 1.1008 + case 'd': sprintf(num, formatString, t=='s' ? (long)(i&0xffffffff) : (unsigned long)(i&0xffffffff)); break; 1.1009 + } 1.1010 + 1.1011 + Item->item.pszText = num; 1.1012 + } return true; 1.1013 + case 2: 1.1014 + Item->item.pszText = rswatches[iNum].comment ? rswatches[iNum].comment : ""; 1.1015 + return true; 1.1016 + 1.1017 + default: 1.1018 + return false; 1.1019 + } 1.1020 + } 1.1021 + case LVN_ODFINDITEM: 1.1022 + { 1.1023 + // disable search by keyboard typing, 1.1024 + // because it interferes with some of the accelerators 1.1025 + // and it isn't very useful here anyway 1.1026 + SetWindowLong(hDlg, DWL_MSGRESULT, ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST))); 1.1027 + return 1; 1.1028 + } 1.1029 + } 1.1030 + } 1.1031 + } 1.1032 + } break; 1.1033 + 1.1034 + case WM_COMMAND: 1.1035 + switch(LOWORD(wParam)) 1.1036 + { 1.1037 + case RAMMENU_FILE_SAVE: 1.1038 + QuickSaveWatches(); 1.1039 + break; 1.1040 + 1.1041 + case RAMMENU_FILE_SAVEAS: 1.1042 + //case IDC_C_SAVE: 1.1043 + return Save_Watches(); 1.1044 + case RAMMENU_FILE_OPEN: 1.1045 + return Load_Watches(true); 1.1046 + case RAMMENU_FILE_APPEND: 1.1047 + //case IDC_C_LOAD: 1.1048 + return Load_Watches(false); 1.1049 + case RAMMENU_FILE_NEW: 1.1050 + //case IDC_C_RESET: 1.1051 + ResetWatches(); 1.1052 + return true; 1.1053 + case IDC_C_WATCH_REMOVE: 1.1054 + { 1.1055 + HWND watchListControl = GetDlgItem(hDlg, IDC_WATCHLIST); 1.1056 + watchIndex = ListView_GetNextItem(watchListControl, -1, LVNI_ALL | LVNI_SELECTED); 1.1057 + while (watchIndex >= 0) 1.1058 + { 1.1059 + RemoveWatch(watchIndex); 1.1060 + ListView_DeleteItem(watchListControl, watchIndex); 1.1061 + watchIndex = ListView_GetNextItem(watchListControl, -1, LVNI_ALL | LVNI_SELECTED); 1.1062 + } 1.1063 + RWfileChanged=true; 1.1064 + SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1065 + return true; 1.1066 + } 1.1067 + case IDC_C_WATCH_EDIT: 1.1068 + watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1069 + if(watchIndex != -1) 1.1070 + { 1.1071 + systemSoundClearBuffer(); 1.1072 + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) watchIndex); 1.1073 + SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1074 + } 1.1075 + return true; 1.1076 + case IDC_C_WATCH: 1.1077 + rswatches[WatchCount].Address = rswatches[WatchCount].WrongEndian = 0; 1.1078 + rswatches[WatchCount].Size = 'b'; 1.1079 + rswatches[WatchCount].Type = 's'; 1.1080 + systemSoundClearBuffer(); 1.1081 + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) WatchCount); 1.1082 + SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1083 + return true; 1.1084 + case IDC_C_WATCH_DUPLICATE: 1.1085 + watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1086 + if(watchIndex != -1) 1.1087 + { 1.1088 + rswatches[WatchCount].Address = rswatches[watchIndex].Address; 1.1089 + rswatches[WatchCount].WrongEndian = rswatches[watchIndex].WrongEndian; 1.1090 + rswatches[WatchCount].Size = rswatches[watchIndex].Size; 1.1091 + rswatches[WatchCount].Type = rswatches[watchIndex].Type; 1.1092 + systemSoundClearBuffer(); 1.1093 + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) WatchCount); 1.1094 + SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1095 + } 1.1096 + return true; 1.1097 + 1.1098 + case IDC_C_WATCH_SEPARATE: 1.1099 + AddressWatcher separator; 1.1100 + separator.Address = 0; 1.1101 + separator.WrongEndian = false; 1.1102 + separator.Size = 'S'; 1.1103 + separator.Type = 'S'; 1.1104 + InsertWatch(separator, "----------------------------"); 1.1105 + SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1106 + return true; 1.1107 + 1.1108 + case IDC_C_WATCH_UP: 1.1109 + { 1.1110 + watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1111 + if (watchIndex == 0 || watchIndex == -1) 1.1112 + return true; 1.1113 + void *tmp = malloc(sizeof(AddressWatcher)); 1.1114 + memcpy(tmp,&(rswatches[watchIndex]),sizeof(AddressWatcher)); 1.1115 + memcpy(&(rswatches[watchIndex]),&(rswatches[watchIndex - 1]),sizeof(AddressWatcher)); 1.1116 + memcpy(&(rswatches[watchIndex - 1]),tmp,sizeof(AddressWatcher)); 1.1117 + free(tmp); 1.1118 + ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex,0,LVIS_FOCUSED|LVIS_SELECTED); 1.1119 + ListView_SetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex-1); 1.1120 + ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex-1,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); 1.1121 + ListView_SetItemCount(GetDlgItem(hDlg,IDC_WATCHLIST),WatchCount); 1.1122 + RWfileChanged=true; 1.1123 + return true; 1.1124 + } 1.1125 + case IDC_C_WATCH_DOWN: 1.1126 + { 1.1127 + watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1128 + if (watchIndex >= WatchCount - 1 || watchIndex == -1) 1.1129 + return true; 1.1130 + void *tmp = malloc(sizeof(AddressWatcher)); 1.1131 + memcpy(tmp,&(rswatches[watchIndex]),sizeof(AddressWatcher)); 1.1132 + memcpy(&(rswatches[watchIndex]),&(rswatches[watchIndex + 1]),sizeof(AddressWatcher)); 1.1133 + memcpy(&(rswatches[watchIndex + 1]),tmp,sizeof(AddressWatcher)); 1.1134 + free(tmp); 1.1135 + ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex,0,LVIS_FOCUSED|LVIS_SELECTED); 1.1136 + ListView_SetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex+1); 1.1137 + ListView_SetItemState(GetDlgItem(hDlg,IDC_WATCHLIST),watchIndex+1,LVIS_FOCUSED|LVIS_SELECTED,LVIS_FOCUSED|LVIS_SELECTED); 1.1138 + ListView_SetItemCount(GetDlgItem(hDlg,IDC_WATCHLIST),WatchCount); 1.1139 + RWfileChanged=true; 1.1140 + return true; 1.1141 + } 1.1142 + case ID_WATCHES_UPDOWN: 1.1143 + { 1.1144 + int delta = ((LPNMUPDOWN)lParam)->iDelta; 1.1145 + SendMessage(hDlg, WM_COMMAND, delta<0 ? IDC_C_WATCH_UP : IDC_C_WATCH_DOWN,0); 1.1146 + break; 1.1147 + } 1.1148 + case RAMMENU_FILE_AUTOLOAD: 1.1149 + { 1.1150 + AutoRWLoad ^= 1; 1.1151 + CheckMenuItem(ramwatchmenu, RAMMENU_FILE_AUTOLOAD, AutoRWLoad ? MF_CHECKED : MF_UNCHECKED); 1.1152 + regSetDwordValue(AUTORWLOAD, AutoRWLoad); 1.1153 + break; 1.1154 + } 1.1155 + case RAMMENU_FILE_SAVEWINDOW: 1.1156 + { 1.1157 + RWSaveWindowPos ^=1; 1.1158 + CheckMenuItem(ramwatchmenu, RAMMENU_FILE_SAVEWINDOW, RWSaveWindowPos ? MF_CHECKED : MF_UNCHECKED); 1.1159 + regSetDwordValue(RWSAVEPOS, RWSaveWindowPos); 1.1160 + break; 1.1161 + } 1.1162 + case IDC_C_ADDCHEAT: 1.1163 + { 1.1164 + watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1165 + if(watchIndex >= 0) 1.1166 + { 1.1167 + unsigned int address = rswatches[watchIndex].Address; 1.1168 + 1.1169 + int sizeType = -1; 1.1170 + if(rswatches[watchIndex].Size == 'b') 1.1171 + sizeType = 0; 1.1172 + else if(rswatches[watchIndex].Size == 'w') 1.1173 + sizeType = 1; 1.1174 + else if(rswatches[watchIndex].Size == 'd') 1.1175 + sizeType = 2; 1.1176 + 1.1177 + int numberType = -1; 1.1178 + if(rswatches[watchIndex].Type == 's') 1.1179 + numberType = 0; 1.1180 + else if(rswatches[watchIndex].Type == 'u') 1.1181 + numberType = 1; 1.1182 + else if(rswatches[watchIndex].Type == 'h') 1.1183 + numberType = 2; 1.1184 + 1.1185 + if(systemCartridgeType == 0) 1.1186 + { 1.1187 + AddCheat dlg (address/*, hDlg*/); 1.1188 + if(sizeType != -1) dlg.sizeType = sizeType; 1.1189 + if(numberType != -1) dlg.numberType = numberType; 1.1190 + systemSoundClearBuffer(); 1.1191 + dlg.DoModal(); 1.1192 + } 1.1193 + else 1.1194 + { 1.1195 + AddGBCheat dlg (address/*, hDlg*/); 1.1196 + if(sizeType != -1) dlg.sizeType = sizeType; 1.1197 + if(numberType != -1) dlg.numberType = numberType; 1.1198 + systemSoundClearBuffer(); 1.1199 + dlg.DoModal(); 1.1200 + } 1.1201 + } 1.1202 + } 1.1203 + break; 1.1204 + case IDOK: 1.1205 + case IDCANCEL: 1.1206 + RamWatchHWnd = NULL; 1.1207 + DragAcceptFiles(hDlg, FALSE); 1.1208 + EndDialog(hDlg, true); 1.1209 + return true; 1.1210 + default: 1.1211 + 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) 1.1212 + OpenRWRecentFile(LOWORD(wParam) - RW_MENU_FIRST_RECENT_FILE); 1.1213 + } 1.1214 + break; 1.1215 + 1.1216 +#if 0 1.1217 + // this message is never received 1.1218 + case WM_KEYDOWN: // handle accelerator keys 1.1219 + { 1.1220 + SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); 1.1221 + MSG msg; 1.1222 + msg.hwnd = hDlg; 1.1223 + msg.message = uMsg; 1.1224 + msg.wParam = wParam; 1.1225 + msg.lParam = lParam; 1.1226 + if(RamWatchAccels && TranslateAccelerator(hDlg, RamWatchAccels, &msg)) 1.1227 + return true; 1.1228 + } break; 1.1229 +#endif 1.1230 + 1.1231 + case WM_CLOSE: 1.1232 + SendMessage(RamWatchHWnd, WM_DESTROY, 0, 0); 1.1233 + break; 1.1234 + 1.1235 + case WM_DESTROY: 1.1236 + // this is the correct place 1.1237 + RamWatchHWnd = NULL; 1.1238 + DragAcceptFiles(hDlg, FALSE); 1.1239 + WriteRecentRWFiles(); // write recent menu to ini 1.1240 + break; 1.1241 + 1.1242 + case WM_DROPFILES: 1.1243 + { 1.1244 + HDROP hDrop = (HDROP)wParam; 1.1245 + DragQueryFile(hDrop, 0, Str_Tmp, 1024); 1.1246 + DragFinish(hDrop); 1.1247 + return Load_Watches(true, Str_Tmp); 1.1248 + } break; 1.1249 + } 1.1250 + 1.1251 + return false; 1.1252 +}