rlm@1: // GBMemoryViewerDlg.cpp : implementation file rlm@1: // rlm@1: rlm@1: #include "stdafx.h" rlm@1: #include "resource.h" rlm@1: #include "GBMemoryViewerDlg.h" rlm@1: #include "FileDlg.h" rlm@1: #include "MemoryViewerAddressSize.h" rlm@1: #include "Reg.h" rlm@1: #include "WinResUtil.h" rlm@1: #include "VBA.h" rlm@1: rlm@1: //#include "../common/System.h" rlm@1: #include "../gb/gbGlobals.h" rlm@1: rlm@1: GBMemoryViewer::GBMemoryViewer() rlm@1: : MemoryViewer() rlm@1: { rlm@1: setAddressSize(1); rlm@1: } rlm@1: rlm@1: void GBMemoryViewer::readData(u32 address, int len, u8 *data) rlm@1: { rlm@1: u16 addr = address & 0xffff; rlm@1: if (emulating && gbRom != NULL) rlm@1: { rlm@1: for (int i = 0; i < len; i++) rlm@1: { rlm@1: *data++ = gbReadMemoryQuick(addr); rlm@1: addr++; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: for (int i = 0; i < len; i++) rlm@1: { rlm@1: *data++ = 0; rlm@1: addr++; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void GBMemoryViewer::editData(u32 address, int size, int mask, u32 value) rlm@1: { rlm@1: u32 oldValue; rlm@1: u16 addr = (u16)address & 0xffff; rlm@1: switch (size) rlm@1: { rlm@1: case 8: rlm@1: oldValue = gbReadMemoryQuick(addr); rlm@1: oldValue &= mask; rlm@1: oldValue |= (u8)value; rlm@1: gbWriteMemoryQuick(addr, oldValue); rlm@1: break; rlm@1: case 16: rlm@1: oldValue = gbReadMemoryQuick(addr) | rlm@1: (gbReadMemoryQuick(addr + 1) << 8); rlm@1: oldValue &= mask; rlm@1: oldValue |= (u16)value; rlm@1: gbWriteMemoryQuick(addr, (oldValue & 255)); rlm@1: gbWriteMemoryQuick(addr+1, (oldValue >> 8)); rlm@1: break; rlm@1: case 32: rlm@1: oldValue = gbReadMemoryQuick(addr) | rlm@1: (gbReadMemoryQuick(addr + 1) << 8) | rlm@1: (gbReadMemoryQuick(addr + 2) << 16) | rlm@1: (gbReadMemoryQuick(addr + 3) << 24); rlm@1: oldValue &= mask; rlm@1: oldValue |= (u32)value; rlm@1: gbWriteMemoryQuick(addr, (oldValue & 255)); rlm@1: gbWriteMemoryQuick(addr+1, (oldValue >> 8)); rlm@1: gbWriteMemoryQuick(addr+2, (oldValue >> 16)); rlm@1: gbWriteMemoryQuick(addr+3, (oldValue >> 24)); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBMemoryViewerDlg dialog rlm@1: rlm@1: GBMemoryViewerDlg::GBMemoryViewerDlg(CWnd*pParent /*=NULL*/) rlm@1: : ResizeDlg(GBMemoryViewerDlg::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(GBMemoryViewerDlg) rlm@1: m_size = -1; rlm@1: //}}AFX_DATA_INIT rlm@1: autoUpdate = false; rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(GBMemoryViewerDlg) rlm@1: DDX_Control(pDX, IDC_CURRENT_ADDRESS, m_current); rlm@1: DDX_Control(pDX, IDC_ADDRESS, m_address); rlm@1: DDX_Control(pDX, IDC_ADDRESSES, m_addresses); rlm@1: DDX_Radio(pDX, IDC_8_BIT, m_size); rlm@1: //}}AFX_DATA_MAP rlm@1: DDX_Control(pDX, IDC_VIEWER, m_viewer); rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(GBMemoryViewerDlg, CDialog) rlm@1: //{{AFX_MSG_MAP(GBMemoryViewerDlg) rlm@1: ON_BN_CLICKED(IDC_CLOSE, OnClose) rlm@1: ON_BN_CLICKED(IDC_REFRESH, OnRefresh) rlm@1: ON_BN_CLICKED(IDC_8_BIT, On8Bit) rlm@1: ON_BN_CLICKED(IDC_16_BIT, On16Bit) rlm@1: ON_BN_CLICKED(IDC_32_BIT, On32Bit) rlm@1: ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate) rlm@1: ON_BN_CLICKED(IDC_DECIMAL_DISPLAY, OnDecimalDisplay) rlm@1: ON_BN_CLICKED(IDC_ALIGN, OnAlign) rlm@1: ON_BN_CLICKED(IDC_GO, OnGo) rlm@1: ON_CBN_SELCHANGE(IDC_ADDRESSES, OnSelchangeAddresses) rlm@1: ON_BN_CLICKED(IDC_SAVE, OnSave) rlm@1: ON_BN_CLICKED(IDC_LOAD, OnLoad) rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBMemoryViewerDlg message handlers rlm@1: rlm@1: BOOL GBMemoryViewerDlg::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: autoUpdate = !regQueryDwordValue("memViewerAutoUpdate", 1); rlm@1: OnAutoUpdate(); // inverts and update dialog rlm@1: rlm@1: decimalDisplay = !regQueryDwordValue("memViewerDecimalDisplay", 0); rlm@1: OnDecimalDisplay(); rlm@1: rlm@1: align = !regQueryDwordValue("memViewerAlign", 0); rlm@1: OnAlign(); rlm@1: rlm@1: DIALOG_SIZER_START(sz) rlm@1: DIALOG_SIZER_ENTRY(IDC_VIEWER, DS_SizeX | DS_SizeY) rlm@1: DIALOG_SIZER_ENTRY(IDC_REFRESH, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_CLOSE, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_LOAD, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_SAVE, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_AUTO_UPDATE, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_DECIMAL_DISPLAY, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_ALIGN, DS_MoveY) rlm@1: DIALOG_SIZER_ENTRY(IDC_CURRENT_ADDRESS_LABEL, DS_MoveY | DS_MoveX) rlm@1: DIALOG_SIZER_ENTRY(IDC_CURRENT_ADDRESS, DS_MoveY | DS_MoveX) rlm@1: DIALOG_SIZER_END() rlm@1: SetData(sz, rlm@1: TRUE, rlm@1: HKEY_CURRENT_USER, rlm@1: "Software\\Emulators\\VisualBoyAdvance\\Viewer\\GBMemoryView", rlm@1: NULL); rlm@1: rlm@1: m_viewer.setDialog(this); rlm@1: m_viewer.ShowScrollBar(SB_VERT, TRUE); rlm@1: m_viewer.EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH); rlm@1: rlm@1: LPCTSTR s[] = { rlm@1: "0x0000 - ROM", rlm@1: "0x4000 - ROM", rlm@1: "0x8000 - VRAM", rlm@1: "0xA000 - SRAM", rlm@1: "0xC000 - RAM", rlm@1: "0xD000 - WRAM", rlm@1: "0xFF00 - I/O", rlm@1: "0xFF80 - RAM" rlm@1: }; rlm@1: rlm@1: for (int i = 0; i < 8; i++) rlm@1: m_addresses.AddString(s[i]); rlm@1: rlm@1: m_addresses.SetCurSel(0); rlm@1: rlm@1: RECT cbSize; rlm@1: int Height; rlm@1: rlm@1: m_addresses.GetClientRect(&cbSize); rlm@1: Height = m_addresses.GetItemHeight(-1); rlm@1: Height += m_addresses.GetItemHeight(0) * (9); rlm@1: rlm@1: // Note: The use of SM_CYEDGE assumes that we're using Windows '95 rlm@1: // Now add on the height of the border of the edit box rlm@1: Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges rlm@1: rlm@1: // The height of the border of the drop-down box rlm@1: Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges rlm@1: rlm@1: // now set the size of the window rlm@1: m_addresses.SetWindowPos(NULL, rlm@1: 0, 0, rlm@1: cbSize.right, Height, rlm@1: SWP_NOMOVE | SWP_NOZORDER); rlm@1: rlm@1: m_address.LimitText(8); rlm@1: rlm@1: m_size = regQueryDwordValue("memViewerDataSize", 0); rlm@1: if (m_size < 0 || m_size > 2) rlm@1: m_size = 0; rlm@1: m_viewer.setSize(m_size); rlm@1: UpdateData(FALSE); rlm@1: rlm@1: m_current.SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT))); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnClose() rlm@1: { rlm@1: theApp.winRemoveUpdateListener(this); rlm@1: rlm@1: DestroyWindow(); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnRefresh() rlm@1: { rlm@1: m_viewer.Invalidate(); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::update() rlm@1: { rlm@1: OnRefresh(); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::On8Bit() rlm@1: { rlm@1: m_viewer.setSize(0); rlm@1: regSetDwordValue("memViewerDataSize", 0); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::On16Bit() rlm@1: { rlm@1: m_viewer.setSize(1); rlm@1: regSetDwordValue("memViewerDataSize", 1); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::On32Bit() rlm@1: { rlm@1: m_viewer.setSize(2); rlm@1: regSetDwordValue("memViewerDataSize", 2); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnAutoUpdate() rlm@1: { rlm@1: autoUpdate = !autoUpdate; rlm@1: if (autoUpdate) rlm@1: { rlm@1: theApp.winAddUpdateListener(this); rlm@1: } rlm@1: else rlm@1: { rlm@1: theApp.winRemoveUpdateListener(this); rlm@1: } rlm@1: if (GetDlgItem(IDC_AUTO_UPDATE)) rlm@1: ((CButton *)GetDlgItem(IDC_AUTO_UPDATE))->SetCheck(autoUpdate ? TRUE : FALSE); rlm@1: regSetDwordValue("memViewerAutoUpdate", autoUpdate); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnDecimalDisplay() rlm@1: { rlm@1: decimalDisplay = !decimalDisplay; rlm@1: m_viewer.setDecimal(decimalDisplay ? true : false); rlm@1: if (GetDlgItem(IDC_DECIMAL_DISPLAY)) rlm@1: ((CButton *)GetDlgItem(IDC_DECIMAL_DISPLAY))->SetCheck(decimalDisplay ? TRUE : FALSE); rlm@1: rlm@1: regSetDwordValue("memViewerDecimalDisplay", decimalDisplay); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnAlign() rlm@1: { rlm@1: align = !align; rlm@1: if (GetDlgItem(IDC_ALIGN)) rlm@1: ((CButton *)GetDlgItem(IDC_ALIGN))->SetCheck(align ? TRUE : FALSE); rlm@1: rlm@1: regSetDwordValue("memViewerAlign", align); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnGo() rlm@1: { rlm@1: CString buffer; rlm@1: rlm@1: m_address.GetWindowText(buffer); rlm@1: rlm@1: u32 address; rlm@1: sscanf(buffer, "%x", &address); rlm@1: if (align) rlm@1: address &= ~0xF; rlm@1: else rlm@1: { rlm@1: if (m_viewer.getSize() == 1) rlm@1: address &= ~1; rlm@1: else if (m_viewer.getSize() == 2) rlm@1: address &= ~3; rlm@1: } rlm@1: m_viewer.setAddress(address); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnSelchangeAddresses() rlm@1: { rlm@1: int cur = m_addresses.GetCurSel(); rlm@1: rlm@1: switch (cur) rlm@1: { rlm@1: case 0: rlm@1: m_viewer.setAddress(0x0000); rlm@1: break; rlm@1: case 1: rlm@1: m_viewer.setAddress(0x4000); rlm@1: break; rlm@1: case 2: rlm@1: m_viewer.setAddress(0x8000); rlm@1: break; rlm@1: case 3: rlm@1: m_viewer.setAddress(0xa000); rlm@1: break; rlm@1: case 4: rlm@1: m_viewer.setAddress(0xc000); rlm@1: break; rlm@1: case 5: rlm@1: m_viewer.setAddress(0xd000); rlm@1: break; rlm@1: case 6: rlm@1: m_viewer.setAddress(0xff00); rlm@1: break; rlm@1: case 7: rlm@1: m_viewer.setAddress(0xff80); rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::setCurrentAddress(u32 address) rlm@1: { rlm@1: CString buffer; rlm@1: rlm@1: buffer.Format("0x%08X", address); rlm@1: m_current.SetWindowText(buffer); rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnSave() rlm@1: { rlm@1: MemoryViewerAddressSize dlg; rlm@1: rlm@1: dlg.setAddress(m_viewer.getCurrentAddress()); rlm@1: rlm@1: LPCTSTR exts[] = { ".dmp", NULL }; rlm@1: rlm@1: CString filter = winResLoadFilter(IDS_FILTER_DUMP); rlm@1: CString title = winResLoadString(IDS_SELECT_DUMP_FILE); rlm@1: rlm@1: if (dlg.DoModal() == IDOK) rlm@1: { rlm@1: CString buffer; rlm@1: FileDlg file(this, rlm@1: buffer, rlm@1: filter, rlm@1: 0, rlm@1: "DMP", rlm@1: exts, rlm@1: "", rlm@1: title, rlm@1: true); rlm@1: if (file.DoModal() == IDOK) rlm@1: { rlm@1: buffer = file.GetPathName(); rlm@1: FILE *f = fopen(buffer, "wb"); rlm@1: rlm@1: if (f == NULL) rlm@1: { rlm@1: systemMessage(IDS_ERROR_CREATING_FILE, buffer); rlm@1: return; rlm@1: } rlm@1: rlm@1: int size = dlg.getSize(); rlm@1: u16 addr = dlg.getAddress() & 0xffff; rlm@1: rlm@1: for (int i = 0; i < size; i++) rlm@1: { rlm@1: fputc(gbReadMemoryQuick(addr), f); rlm@1: addr++; rlm@1: } rlm@1: rlm@1: fclose(f); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::OnLoad() rlm@1: { rlm@1: CString buffer; rlm@1: LPCTSTR exts[] = { ".dmp", NULL }; rlm@1: CString filter = winResLoadFilter(IDS_FILTER_DUMP); rlm@1: CString title = winResLoadString(IDS_SELECT_DUMP_FILE); rlm@1: rlm@1: FileDlg file(this, rlm@1: buffer, rlm@1: filter, rlm@1: 0, rlm@1: "DMP", rlm@1: exts, rlm@1: "", rlm@1: title, rlm@1: false); rlm@1: rlm@1: if (file.DoModal() == IDOK) rlm@1: { rlm@1: buffer = file.GetPathName(); rlm@1: FILE *f = fopen(buffer, "rb"); rlm@1: if (f == NULL) rlm@1: { rlm@1: systemMessage(IDS_CANNOT_OPEN_FILE, rlm@1: "Cannot open file %s", rlm@1: buffer); rlm@1: return; rlm@1: } rlm@1: rlm@1: MemoryViewerAddressSize dlg; rlm@1: rlm@1: fseek(f, 0, SEEK_END); rlm@1: int size = ftell(f); rlm@1: rlm@1: fseek(f, 0, SEEK_SET); rlm@1: rlm@1: dlg.setAddress(m_viewer.getCurrentAddress()); rlm@1: dlg.setSize(size); rlm@1: rlm@1: if (dlg.DoModal() == IDOK) rlm@1: { rlm@1: int size = dlg.getSize(); rlm@1: u16 addr = dlg.getAddress() & 0xffff; rlm@1: rlm@1: for (int i = 0; i < size; i++) rlm@1: { rlm@1: int c = fgetc(f); rlm@1: if (c == -1) rlm@1: break; rlm@1: gbWriteMemoryQuick(addr, c); rlm@1: addr++; rlm@1: } rlm@1: OnRefresh(); rlm@1: } rlm@1: fclose(f); rlm@1: } rlm@1: } rlm@1: rlm@1: void GBMemoryViewerDlg::PostNcDestroy() rlm@1: { rlm@1: delete this; rlm@1: } rlm@1: