annotate src/win32/GBMemoryViewerDlg.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 // GBMemoryViewerDlg.cpp : implementation file
rlm@1 2 //
rlm@1 3
rlm@1 4 #include "stdafx.h"
rlm@1 5 #include "resource.h"
rlm@1 6 #include "GBMemoryViewerDlg.h"
rlm@1 7 #include "FileDlg.h"
rlm@1 8 #include "MemoryViewerAddressSize.h"
rlm@1 9 #include "Reg.h"
rlm@1 10 #include "WinResUtil.h"
rlm@1 11 #include "VBA.h"
rlm@1 12
rlm@1 13 //#include "../common/System.h"
rlm@1 14 #include "../gb/gbGlobals.h"
rlm@1 15
rlm@1 16 GBMemoryViewer::GBMemoryViewer()
rlm@1 17 : MemoryViewer()
rlm@1 18 {
rlm@1 19 setAddressSize(1);
rlm@1 20 }
rlm@1 21
rlm@1 22 void GBMemoryViewer::readData(u32 address, int len, u8 *data)
rlm@1 23 {
rlm@1 24 u16 addr = address & 0xffff;
rlm@1 25 if (emulating && gbRom != NULL)
rlm@1 26 {
rlm@1 27 for (int i = 0; i < len; i++)
rlm@1 28 {
rlm@1 29 *data++ = gbReadMemoryQuick(addr);
rlm@1 30 addr++;
rlm@1 31 }
rlm@1 32 }
rlm@1 33 else
rlm@1 34 {
rlm@1 35 for (int i = 0; i < len; i++)
rlm@1 36 {
rlm@1 37 *data++ = 0;
rlm@1 38 addr++;
rlm@1 39 }
rlm@1 40 }
rlm@1 41 }
rlm@1 42
rlm@1 43 void GBMemoryViewer::editData(u32 address, int size, int mask, u32 value)
rlm@1 44 {
rlm@1 45 u32 oldValue;
rlm@1 46 u16 addr = (u16)address & 0xffff;
rlm@1 47 switch (size)
rlm@1 48 {
rlm@1 49 case 8:
rlm@1 50 oldValue = gbReadMemoryQuick(addr);
rlm@1 51 oldValue &= mask;
rlm@1 52 oldValue |= (u8)value;
rlm@1 53 gbWriteMemoryQuick(addr, oldValue);
rlm@1 54 break;
rlm@1 55 case 16:
rlm@1 56 oldValue = gbReadMemoryQuick(addr) |
rlm@1 57 (gbReadMemoryQuick(addr + 1) << 8);
rlm@1 58 oldValue &= mask;
rlm@1 59 oldValue |= (u16)value;
rlm@1 60 gbWriteMemoryQuick(addr, (oldValue & 255));
rlm@1 61 gbWriteMemoryQuick(addr+1, (oldValue >> 8));
rlm@1 62 break;
rlm@1 63 case 32:
rlm@1 64 oldValue = gbReadMemoryQuick(addr) |
rlm@1 65 (gbReadMemoryQuick(addr + 1) << 8) |
rlm@1 66 (gbReadMemoryQuick(addr + 2) << 16) |
rlm@1 67 (gbReadMemoryQuick(addr + 3) << 24);
rlm@1 68 oldValue &= mask;
rlm@1 69 oldValue |= (u32)value;
rlm@1 70 gbWriteMemoryQuick(addr, (oldValue & 255));
rlm@1 71 gbWriteMemoryQuick(addr+1, (oldValue >> 8));
rlm@1 72 gbWriteMemoryQuick(addr+2, (oldValue >> 16));
rlm@1 73 gbWriteMemoryQuick(addr+3, (oldValue >> 24));
rlm@1 74 break;
rlm@1 75 }
rlm@1 76 }
rlm@1 77
rlm@1 78 /////////////////////////////////////////////////////////////////////////////
rlm@1 79 // GBMemoryViewerDlg dialog
rlm@1 80
rlm@1 81 GBMemoryViewerDlg::GBMemoryViewerDlg(CWnd*pParent /*=NULL*/)
rlm@1 82 : ResizeDlg(GBMemoryViewerDlg::IDD, pParent)
rlm@1 83 {
rlm@1 84 //{{AFX_DATA_INIT(GBMemoryViewerDlg)
rlm@1 85 m_size = -1;
rlm@1 86 //}}AFX_DATA_INIT
rlm@1 87 autoUpdate = false;
rlm@1 88 }
rlm@1 89
rlm@1 90 void GBMemoryViewerDlg::DoDataExchange(CDataExchange*pDX)
rlm@1 91 {
rlm@1 92 CDialog::DoDataExchange(pDX);
rlm@1 93 //{{AFX_DATA_MAP(GBMemoryViewerDlg)
rlm@1 94 DDX_Control(pDX, IDC_CURRENT_ADDRESS, m_current);
rlm@1 95 DDX_Control(pDX, IDC_ADDRESS, m_address);
rlm@1 96 DDX_Control(pDX, IDC_ADDRESSES, m_addresses);
rlm@1 97 DDX_Radio(pDX, IDC_8_BIT, m_size);
rlm@1 98 //}}AFX_DATA_MAP
rlm@1 99 DDX_Control(pDX, IDC_VIEWER, m_viewer);
rlm@1 100 }
rlm@1 101
rlm@1 102 BEGIN_MESSAGE_MAP(GBMemoryViewerDlg, CDialog)
rlm@1 103 //{{AFX_MSG_MAP(GBMemoryViewerDlg)
rlm@1 104 ON_BN_CLICKED(IDC_CLOSE, OnClose)
rlm@1 105 ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
rlm@1 106 ON_BN_CLICKED(IDC_8_BIT, On8Bit)
rlm@1 107 ON_BN_CLICKED(IDC_16_BIT, On16Bit)
rlm@1 108 ON_BN_CLICKED(IDC_32_BIT, On32Bit)
rlm@1 109 ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate)
rlm@1 110 ON_BN_CLICKED(IDC_DECIMAL_DISPLAY, OnDecimalDisplay)
rlm@1 111 ON_BN_CLICKED(IDC_ALIGN, OnAlign)
rlm@1 112 ON_BN_CLICKED(IDC_GO, OnGo)
rlm@1 113 ON_CBN_SELCHANGE(IDC_ADDRESSES, OnSelchangeAddresses)
rlm@1 114 ON_BN_CLICKED(IDC_SAVE, OnSave)
rlm@1 115 ON_BN_CLICKED(IDC_LOAD, OnLoad)
rlm@1 116 //}}AFX_MSG_MAP
rlm@1 117 END_MESSAGE_MAP()
rlm@1 118
rlm@1 119 /////////////////////////////////////////////////////////////////////////////
rlm@1 120 // GBMemoryViewerDlg message handlers
rlm@1 121
rlm@1 122 BOOL GBMemoryViewerDlg::OnInitDialog()
rlm@1 123 {
rlm@1 124 CDialog::OnInitDialog();
rlm@1 125
rlm@1 126 autoUpdate = !regQueryDwordValue("memViewerAutoUpdate", 1);
rlm@1 127 OnAutoUpdate(); // inverts and update dialog
rlm@1 128
rlm@1 129 decimalDisplay = !regQueryDwordValue("memViewerDecimalDisplay", 0);
rlm@1 130 OnDecimalDisplay();
rlm@1 131
rlm@1 132 align = !regQueryDwordValue("memViewerAlign", 0);
rlm@1 133 OnAlign();
rlm@1 134
rlm@1 135 DIALOG_SIZER_START(sz)
rlm@1 136 DIALOG_SIZER_ENTRY(IDC_VIEWER, DS_SizeX | DS_SizeY)
rlm@1 137 DIALOG_SIZER_ENTRY(IDC_REFRESH, DS_MoveY)
rlm@1 138 DIALOG_SIZER_ENTRY(IDC_CLOSE, DS_MoveY)
rlm@1 139 DIALOG_SIZER_ENTRY(IDC_LOAD, DS_MoveY)
rlm@1 140 DIALOG_SIZER_ENTRY(IDC_SAVE, DS_MoveY)
rlm@1 141 DIALOG_SIZER_ENTRY(IDC_AUTO_UPDATE, DS_MoveY)
rlm@1 142 DIALOG_SIZER_ENTRY(IDC_DECIMAL_DISPLAY, DS_MoveY)
rlm@1 143 DIALOG_SIZER_ENTRY(IDC_ALIGN, DS_MoveY)
rlm@1 144 DIALOG_SIZER_ENTRY(IDC_CURRENT_ADDRESS_LABEL, DS_MoveY | DS_MoveX)
rlm@1 145 DIALOG_SIZER_ENTRY(IDC_CURRENT_ADDRESS, DS_MoveY | DS_MoveX)
rlm@1 146 DIALOG_SIZER_END()
rlm@1 147 SetData(sz,
rlm@1 148 TRUE,
rlm@1 149 HKEY_CURRENT_USER,
rlm@1 150 "Software\\Emulators\\VisualBoyAdvance\\Viewer\\GBMemoryView",
rlm@1 151 NULL);
rlm@1 152
rlm@1 153 m_viewer.setDialog(this);
rlm@1 154 m_viewer.ShowScrollBar(SB_VERT, TRUE);
rlm@1 155 m_viewer.EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);
rlm@1 156
rlm@1 157 LPCTSTR s[] = {
rlm@1 158 "0x0000 - ROM",
rlm@1 159 "0x4000 - ROM",
rlm@1 160 "0x8000 - VRAM",
rlm@1 161 "0xA000 - SRAM",
rlm@1 162 "0xC000 - RAM",
rlm@1 163 "0xD000 - WRAM",
rlm@1 164 "0xFF00 - I/O",
rlm@1 165 "0xFF80 - RAM"
rlm@1 166 };
rlm@1 167
rlm@1 168 for (int i = 0; i < 8; i++)
rlm@1 169 m_addresses.AddString(s[i]);
rlm@1 170
rlm@1 171 m_addresses.SetCurSel(0);
rlm@1 172
rlm@1 173 RECT cbSize;
rlm@1 174 int Height;
rlm@1 175
rlm@1 176 m_addresses.GetClientRect(&cbSize);
rlm@1 177 Height = m_addresses.GetItemHeight(-1);
rlm@1 178 Height += m_addresses.GetItemHeight(0) * (9);
rlm@1 179
rlm@1 180 // Note: The use of SM_CYEDGE assumes that we're using Windows '95
rlm@1 181 // Now add on the height of the border of the edit box
rlm@1 182 Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges
rlm@1 183
rlm@1 184 // The height of the border of the drop-down box
rlm@1 185 Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges
rlm@1 186
rlm@1 187 // now set the size of the window
rlm@1 188 m_addresses.SetWindowPos(NULL,
rlm@1 189 0, 0,
rlm@1 190 cbSize.right, Height,
rlm@1 191 SWP_NOMOVE | SWP_NOZORDER);
rlm@1 192
rlm@1 193 m_address.LimitText(8);
rlm@1 194
rlm@1 195 m_size = regQueryDwordValue("memViewerDataSize", 0);
rlm@1 196 if (m_size < 0 || m_size > 2)
rlm@1 197 m_size = 0;
rlm@1 198 m_viewer.setSize(m_size);
rlm@1 199 UpdateData(FALSE);
rlm@1 200
rlm@1 201 m_current.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)));
rlm@1 202
rlm@1 203 return TRUE; // return TRUE unless you set the focus to a control
rlm@1 204 // EXCEPTION: OCX Property Pages should return FALSE
rlm@1 205 }
rlm@1 206
rlm@1 207 void GBMemoryViewerDlg::OnClose()
rlm@1 208 {
rlm@1 209 theApp.winRemoveUpdateListener(this);
rlm@1 210
rlm@1 211 DestroyWindow();
rlm@1 212 }
rlm@1 213
rlm@1 214 void GBMemoryViewerDlg::OnRefresh()
rlm@1 215 {
rlm@1 216 m_viewer.Invalidate();
rlm@1 217 }
rlm@1 218
rlm@1 219 void GBMemoryViewerDlg::update()
rlm@1 220 {
rlm@1 221 OnRefresh();
rlm@1 222 }
rlm@1 223
rlm@1 224 void GBMemoryViewerDlg::On8Bit()
rlm@1 225 {
rlm@1 226 m_viewer.setSize(0);
rlm@1 227 regSetDwordValue("memViewerDataSize", 0);
rlm@1 228 }
rlm@1 229
rlm@1 230 void GBMemoryViewerDlg::On16Bit()
rlm@1 231 {
rlm@1 232 m_viewer.setSize(1);
rlm@1 233 regSetDwordValue("memViewerDataSize", 1);
rlm@1 234 }
rlm@1 235
rlm@1 236 void GBMemoryViewerDlg::On32Bit()
rlm@1 237 {
rlm@1 238 m_viewer.setSize(2);
rlm@1 239 regSetDwordValue("memViewerDataSize", 2);
rlm@1 240 }
rlm@1 241
rlm@1 242 void GBMemoryViewerDlg::OnAutoUpdate()
rlm@1 243 {
rlm@1 244 autoUpdate = !autoUpdate;
rlm@1 245 if (autoUpdate)
rlm@1 246 {
rlm@1 247 theApp.winAddUpdateListener(this);
rlm@1 248 }
rlm@1 249 else
rlm@1 250 {
rlm@1 251 theApp.winRemoveUpdateListener(this);
rlm@1 252 }
rlm@1 253 if (GetDlgItem(IDC_AUTO_UPDATE))
rlm@1 254 ((CButton *)GetDlgItem(IDC_AUTO_UPDATE))->SetCheck(autoUpdate ? TRUE : FALSE);
rlm@1 255 regSetDwordValue("memViewerAutoUpdate", autoUpdate);
rlm@1 256 }
rlm@1 257
rlm@1 258 void GBMemoryViewerDlg::OnDecimalDisplay()
rlm@1 259 {
rlm@1 260 decimalDisplay = !decimalDisplay;
rlm@1 261 m_viewer.setDecimal(decimalDisplay ? true : false);
rlm@1 262 if (GetDlgItem(IDC_DECIMAL_DISPLAY))
rlm@1 263 ((CButton *)GetDlgItem(IDC_DECIMAL_DISPLAY))->SetCheck(decimalDisplay ? TRUE : FALSE);
rlm@1 264
rlm@1 265 regSetDwordValue("memViewerDecimalDisplay", decimalDisplay);
rlm@1 266 }
rlm@1 267
rlm@1 268 void GBMemoryViewerDlg::OnAlign()
rlm@1 269 {
rlm@1 270 align = !align;
rlm@1 271 if (GetDlgItem(IDC_ALIGN))
rlm@1 272 ((CButton *)GetDlgItem(IDC_ALIGN))->SetCheck(align ? TRUE : FALSE);
rlm@1 273
rlm@1 274 regSetDwordValue("memViewerAlign", align);
rlm@1 275 }
rlm@1 276
rlm@1 277 void GBMemoryViewerDlg::OnGo()
rlm@1 278 {
rlm@1 279 CString buffer;
rlm@1 280
rlm@1 281 m_address.GetWindowText(buffer);
rlm@1 282
rlm@1 283 u32 address;
rlm@1 284 sscanf(buffer, "%x", &address);
rlm@1 285 if (align)
rlm@1 286 address &= ~0xF;
rlm@1 287 else
rlm@1 288 {
rlm@1 289 if (m_viewer.getSize() == 1)
rlm@1 290 address &= ~1;
rlm@1 291 else if (m_viewer.getSize() == 2)
rlm@1 292 address &= ~3;
rlm@1 293 }
rlm@1 294 m_viewer.setAddress(address);
rlm@1 295 }
rlm@1 296
rlm@1 297 void GBMemoryViewerDlg::OnSelchangeAddresses()
rlm@1 298 {
rlm@1 299 int cur = m_addresses.GetCurSel();
rlm@1 300
rlm@1 301 switch (cur)
rlm@1 302 {
rlm@1 303 case 0:
rlm@1 304 m_viewer.setAddress(0x0000);
rlm@1 305 break;
rlm@1 306 case 1:
rlm@1 307 m_viewer.setAddress(0x4000);
rlm@1 308 break;
rlm@1 309 case 2:
rlm@1 310 m_viewer.setAddress(0x8000);
rlm@1 311 break;
rlm@1 312 case 3:
rlm@1 313 m_viewer.setAddress(0xa000);
rlm@1 314 break;
rlm@1 315 case 4:
rlm@1 316 m_viewer.setAddress(0xc000);
rlm@1 317 break;
rlm@1 318 case 5:
rlm@1 319 m_viewer.setAddress(0xd000);
rlm@1 320 break;
rlm@1 321 case 6:
rlm@1 322 m_viewer.setAddress(0xff00);
rlm@1 323 break;
rlm@1 324 case 7:
rlm@1 325 m_viewer.setAddress(0xff80);
rlm@1 326 break;
rlm@1 327 }
rlm@1 328 }
rlm@1 329
rlm@1 330 void GBMemoryViewerDlg::setCurrentAddress(u32 address)
rlm@1 331 {
rlm@1 332 CString buffer;
rlm@1 333
rlm@1 334 buffer.Format("0x%08X", address);
rlm@1 335 m_current.SetWindowText(buffer);
rlm@1 336 }
rlm@1 337
rlm@1 338 void GBMemoryViewerDlg::OnSave()
rlm@1 339 {
rlm@1 340 MemoryViewerAddressSize dlg;
rlm@1 341
rlm@1 342 dlg.setAddress(m_viewer.getCurrentAddress());
rlm@1 343
rlm@1 344 LPCTSTR exts[] = { ".dmp", NULL };
rlm@1 345
rlm@1 346 CString filter = winResLoadFilter(IDS_FILTER_DUMP);
rlm@1 347 CString title = winResLoadString(IDS_SELECT_DUMP_FILE);
rlm@1 348
rlm@1 349 if (dlg.DoModal() == IDOK)
rlm@1 350 {
rlm@1 351 CString buffer;
rlm@1 352 FileDlg file(this,
rlm@1 353 buffer,
rlm@1 354 filter,
rlm@1 355 0,
rlm@1 356 "DMP",
rlm@1 357 exts,
rlm@1 358 "",
rlm@1 359 title,
rlm@1 360 true);
rlm@1 361 if (file.DoModal() == IDOK)
rlm@1 362 {
rlm@1 363 buffer = file.GetPathName();
rlm@1 364 FILE *f = fopen(buffer, "wb");
rlm@1 365
rlm@1 366 if (f == NULL)
rlm@1 367 {
rlm@1 368 systemMessage(IDS_ERROR_CREATING_FILE, buffer);
rlm@1 369 return;
rlm@1 370 }
rlm@1 371
rlm@1 372 int size = dlg.getSize();
rlm@1 373 u16 addr = dlg.getAddress() & 0xffff;
rlm@1 374
rlm@1 375 for (int i = 0; i < size; i++)
rlm@1 376 {
rlm@1 377 fputc(gbReadMemoryQuick(addr), f);
rlm@1 378 addr++;
rlm@1 379 }
rlm@1 380
rlm@1 381 fclose(f);
rlm@1 382 }
rlm@1 383 }
rlm@1 384 }
rlm@1 385
rlm@1 386 void GBMemoryViewerDlg::OnLoad()
rlm@1 387 {
rlm@1 388 CString buffer;
rlm@1 389 LPCTSTR exts[] = { ".dmp", NULL };
rlm@1 390 CString filter = winResLoadFilter(IDS_FILTER_DUMP);
rlm@1 391 CString title = winResLoadString(IDS_SELECT_DUMP_FILE);
rlm@1 392
rlm@1 393 FileDlg file(this,
rlm@1 394 buffer,
rlm@1 395 filter,
rlm@1 396 0,
rlm@1 397 "DMP",
rlm@1 398 exts,
rlm@1 399 "",
rlm@1 400 title,
rlm@1 401 false);
rlm@1 402
rlm@1 403 if (file.DoModal() == IDOK)
rlm@1 404 {
rlm@1 405 buffer = file.GetPathName();
rlm@1 406 FILE *f = fopen(buffer, "rb");
rlm@1 407 if (f == NULL)
rlm@1 408 {
rlm@1 409 systemMessage(IDS_CANNOT_OPEN_FILE,
rlm@1 410 "Cannot open file %s",
rlm@1 411 buffer);
rlm@1 412 return;
rlm@1 413 }
rlm@1 414
rlm@1 415 MemoryViewerAddressSize dlg;
rlm@1 416
rlm@1 417 fseek(f, 0, SEEK_END);
rlm@1 418 int size = ftell(f);
rlm@1 419
rlm@1 420 fseek(f, 0, SEEK_SET);
rlm@1 421
rlm@1 422 dlg.setAddress(m_viewer.getCurrentAddress());
rlm@1 423 dlg.setSize(size);
rlm@1 424
rlm@1 425 if (dlg.DoModal() == IDOK)
rlm@1 426 {
rlm@1 427 int size = dlg.getSize();
rlm@1 428 u16 addr = dlg.getAddress() & 0xffff;
rlm@1 429
rlm@1 430 for (int i = 0; i < size; i++)
rlm@1 431 {
rlm@1 432 int c = fgetc(f);
rlm@1 433 if (c == -1)
rlm@1 434 break;
rlm@1 435 gbWriteMemoryQuick(addr, c);
rlm@1 436 addr++;
rlm@1 437 }
rlm@1 438 OnRefresh();
rlm@1 439 }
rlm@1 440 fclose(f);
rlm@1 441 }
rlm@1 442 }
rlm@1 443
rlm@1 444 void GBMemoryViewerDlg::PostNcDestroy()
rlm@1 445 {
rlm@1 446 delete this;
rlm@1 447 }
rlm@1 448