home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / win32 / GBMemoryViewerDlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  10.0 KB  |  422 lines

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