1
// Copyright 2013 Dolphin Emulator Project
2
// Licensed under GPLv2
3
// Refer to the license.txt file included.
6
#include <wx/textctrl.h>
7
#include <wx/listctrl.h>
9
#include <wx/listctrl.h>
11
#include "../WxUtils.h"
12
#include "MemoryWindow.h"
14
#include "PowerPC/PowerPC.h"
17
#include "Debugger/PPCDebugInterface.h"
18
#include "PowerPC/PPCSymbolDB.h"
21
#include "ConfigManager.h"
22
#include "LogManager.h"
24
#include "HW/Memmap.h"
27
#include "../../DolphinWX/Src/Globals.h"
31
IDM_MEM_ADDRBOX = 350,
46
BEGIN_EVENT_TABLE(CMemoryWindow, wxPanel)
47
EVT_TEXT(IDM_MEM_ADDRBOX, CMemoryWindow::OnAddrBoxChange)
48
EVT_LISTBOX(IDM_SYMBOLLIST, CMemoryWindow::OnSymbolListChange)
49
EVT_HOST_COMMAND(wxID_ANY, CMemoryWindow::OnHostMessage)
50
EVT_BUTTON(IDM_SETVALBUTTON, CMemoryWindow::SetMemoryValue)
51
EVT_BUTTON(IDM_DUMP_MEMORY, CMemoryWindow::OnDumpMemory)
52
EVT_BUTTON(IDM_DUMP_MEM2, CMemoryWindow::OnDumpMem2)
53
EVT_BUTTON(IDM_DUMP_FAKEVMEM, CMemoryWindow::OnDumpFakeVMEM)
54
EVT_CHECKBOX(IDM_U8, CMemoryWindow::U8)
55
EVT_CHECKBOX(IDM_U16, CMemoryWindow::U16)
56
EVT_CHECKBOX(IDM_U32, CMemoryWindow::U32)
57
EVT_BUTTON(IDM_SEARCH, CMemoryWindow::onSearch)
58
EVT_CHECKBOX(IDM_ASCII, CMemoryWindow::onAscii)
59
EVT_CHECKBOX(IDM_HEX, CMemoryWindow::onHex)
62
CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id,
63
const wxPoint& pos, const wxSize& size, long style, const wxString& name)
64
: wxPanel(parent, id, pos, size, style, name)
66
wxBoxSizer* sizerBig = new wxBoxSizer(wxHORIZONTAL);
67
wxBoxSizer* sizerRight = new wxBoxSizer(wxVERTICAL);
68
// Didn't see anything useful in the left part
69
//wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
71
DebugInterface* di = &PowerPC::debug_interface;
73
//symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition,
74
// wxSize(20, 100), 0, NULL, wxLB_SORT);
75
//sizerLeft->Add(symbols, 1, wxEXPAND);
76
memview = new CMemoryView(di, this);
77
memview->dataType = 0;
78
//sizerBig->Add(sizerLeft, 1, wxEXPAND);
79
sizerBig->Add(memview, 20, wxEXPAND);
80
sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3);
81
sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_MEM_ADDRBOX, _T("")));
82
sizerRight->Add(valbox = new wxTextCtrl(this, IDM_VALBOX, _T("")));
83
sizerRight->Add(new wxButton(this, IDM_SETVALBUTTON, _("Set &Value")));
85
sizerRight->AddSpacer(5);
86
sizerRight->Add(new wxButton(this, IDM_DUMP_MEMORY, _("&Dump MRAM")));
87
sizerRight->Add(new wxButton(this, IDM_DUMP_MEM2, _("&Dump EXRAM")));
89
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bTLBHack == true)
90
sizerRight->Add(new wxButton(this, IDM_DUMP_FAKEVMEM, _("&Dump FakeVMEM")));
92
wxStaticBoxSizer* sizerSearchType = new wxStaticBoxSizer(wxVERTICAL, this, _("Search"));
94
sizerSearchType->Add(btnSearch = new wxButton(this, IDM_SEARCH, _("Search")));
95
sizerSearchType->Add(chkAscii = new wxCheckBox(this, IDM_ASCII, _T("&Ascii ")));
96
sizerSearchType->Add(chkHex = new wxCheckBox(this, IDM_HEX, _("&Hex")));
97
sizerRight->Add(sizerSearchType);
98
wxStaticBoxSizer* sizerDataTypes = new wxStaticBoxSizer(wxVERTICAL, this, _("Data Type"));
100
sizerDataTypes->SetMinSize(74, 40);
101
sizerDataTypes->Add(chk8 = new wxCheckBox(this, IDM_U8, _T("&U8")));
102
sizerDataTypes->Add(chk16 = new wxCheckBox(this, IDM_U16, _T("&U16")));
103
sizerDataTypes->Add(chk32 = new wxCheckBox(this, IDM_U32, _T("&U32")));
104
sizerRight->Add(sizerDataTypes);
106
chkHex->SetValue(1); //Set defaults
109
//sizerLeft->Fit(this);
110
sizerRight->Fit(this);
114
void CMemoryWindow::Save(IniFile& _IniFile) const
116
// Prevent these bad values that can happen after a crash or hanging
117
if(GetPosition().x != -32000 && GetPosition().y != -32000)
119
_IniFile.Set("MemoryWindow", "x", GetPosition().x);
120
_IniFile.Set("MemoryWindow", "y", GetPosition().y);
121
_IniFile.Set("MemoryWindow", "w", GetSize().GetWidth());
122
_IniFile.Set("MemoryWindow", "h", GetSize().GetHeight());
126
void CMemoryWindow::Load(IniFile& _IniFile)
129
_IniFile.Get("MemoryWindow", "x", &x, GetPosition().x);
130
_IniFile.Get("MemoryWindow", "y", &y, GetPosition().y);
131
_IniFile.Get("MemoryWindow", "w", &w, GetSize().GetWidth());
132
_IniFile.Get("MemoryWindow", "h", &h, GetSize().GetHeight());
136
void CMemoryWindow::JumpToAddress(u32 _Address)
138
memview->Center(_Address);
141
void CMemoryWindow::SetMemoryValue(wxCommandEvent& event)
143
std::string str_addr = WxStrToStr(addrbox->GetValue());
144
std::string str_val = WxStrToStr(valbox->GetValue());
148
if (!TryParse(std::string("0x") + str_addr, &addr))
150
PanicAlert("Invalid Address: %s", str_addr.c_str());
154
if (!TryParse(std::string("0x") + str_val, &val))
156
PanicAlert("Invalid Value: %s", str_val.c_str());
160
Memory::Write_U32(val, addr);
164
void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event)
166
wxString txt = addrbox->GetValue();
170
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
171
memview->Center(addr & ~3);
177
void CMemoryWindow::Update()
183
void CMemoryWindow::NotifyMapLoaded()
185
symbols->Show(false); // hide it for faster filling
189
const FunctionDB::XFuncMap &syms = g_symbolDB.Symbols();
190
for (FuntionDB::XFuncMap::iterator iter = syms.begin(); iter != syms.end(); ++iter)
192
int idx = symbols->Append(iter->second.name.c_str());
193
symbols->SetClientData(idx, (void*)&iter->second);
201
void CMemoryWindow::OnSymbolListChange(wxCommandEvent& event)
203
int index = symbols->GetSelection();
206
Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
209
memview->Center(pSymbol->address);
214
void CMemoryWindow::OnHostMessage(wxCommandEvent& event)
216
switch (event.GetId())
218
case IDM_NOTIFYMAPLOADED:
224
void DumpArray(const std::string& filename, const u8* data, size_t length)
228
File::IOFile f(filename, "wb");
229
f.WriteBytes(data, length);
233
// Write mram to file
234
void CMemoryWindow::OnDumpMemory( wxCommandEvent& event )
236
DumpArray(File::GetUserPath(F_RAMDUMP_IDX), Memory::m_pRAM, Memory::REALRAM_SIZE);
239
// Write exram (aram or mem2) to file
240
void CMemoryWindow::OnDumpMem2( wxCommandEvent& event )
242
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
244
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), Memory::m_pEXRAM, Memory::EXRAM_SIZE);
248
DumpArray(File::GetUserPath(F_ARAMDUMP_IDX), DSP::GetARAMPtr(), DSP::ARAM_SIZE);
252
// Write fake vmem to file
253
void CMemoryWindow::OnDumpFakeVMEM( wxCommandEvent& event )
255
DumpArray(File::GetUserPath(F_FAKEVMEMDUMP_IDX), Memory::m_pVirtualFakeVMEM, Memory::FAKEVMEM_SIZE);
258
void CMemoryWindow::U8(wxCommandEvent& event)
262
memview->dataType = 0;
266
void CMemoryWindow::U16(wxCommandEvent& event)
270
memview->dataType = 1;
274
void CMemoryWindow::U32(wxCommandEvent& event)
278
memview->dataType = 2;
282
void CMemoryWindow::onSearch(wxCommandEvent& event)
286
switch (memview->GetMemoryType())
292
TheRAM = Memory::m_pRAM;
293
szRAM = Memory::REALRAM_SIZE;
298
u8* aram = DSP::GetARAMPtr();
302
szRAM = DSP::ARAM_SIZE;
307
//Now we have memory to look in
308
//Are we looking for ASCII string, or hex?
310
wxString rawData = valbox->GetValue();
311
std::vector<u8> Dest; //May need a better name
313
int pad = rawData.size()%2; //If it's uneven
318
unsigned char *tmp2 = 0;
321
if (chkHex->GetValue())
323
//We are looking for hex
325
size = (rawData.size()/2) + pad;
326
Dest.resize(size+32);
327
newsize = rawData.size();
331
tmpstr = new char[newsize + 2];
332
memset(tmpstr, 0, newsize + 2);
337
tmpstr = new char[newsize + 1];
338
memset(tmpstr, 0, newsize + 1);
340
sprintf(tmpstr, "%s%s", tmpstr, WxStrToStr(rawData).c_str());
341
tmp2 = &Dest.front();
343
for(i = 0; i < strlen(tmpstr); i++)
346
copy[1] = tmpstr[i+1];
349
sscanf(copy, "%02x", &tmpint);
350
tmp2[count++] = tmpint;
351
// Dest[count] should now be the hex of what the two chars were!
352
// Also should add a check to make sure it's A-F only
353
//sscanf(copy, "%02x", &tmp2[count++]);
360
//Looking for an ascii string
361
size = rawData.size();
363
tmpstr = new char[size+1];
365
tmp2 = &Dest.front();
366
sprintf(tmpstr, "%s", WxStrToStr(rawData).c_str());
368
for(i = 0; i < size; i++)
376
unsigned char* pnt = &Dest.front();
379
wxString txt = addrbox->GetValue();
383
sscanf(WxStrToStr(txt).c_str(), "%08x", &addr);
386
for( ; i < szRAM; i++)
388
for(k = 0; k < size; k++)
390
if(i + k > szRAM) break;
392
if(pnt[k] != TheRAM[i+k])
401
wxMessageBox(_("A match was found. Placing viewer at the offset."));
402
wxChar tmpwxstr[128] = {0};
403
wxSprintf(tmpwxstr, _T("%08x"), i);
404
wxString tmpwx(tmpwxstr);
405
addrbox->SetValue(tmpwx);
406
//memview->curAddress = i;
407
//memview->Refresh();
408
OnAddrBoxChange(event);
412
wxMessageBox(_("No match was found."));
416
void CMemoryWindow::onAscii(wxCommandEvent& event)
421
void CMemoryWindow::onHex(wxCommandEvent& event)
423
chkAscii->SetValue(0);