diff options
| author | bushing <bushing@gmail.com> | 2008-12-08 05:30:24 +0000 |
|---|---|---|
| committer | bushing <bushing@gmail.com> | 2008-12-08 05:30:24 +0000 |
| commit | 49cfded60bb5b444d1828190eacc52bbb49a9cb8 (patch) | |
| tree | 0823218c1f2f6eec307dadbdec18c5632625f052 /Source/Core/DebuggerWX | |
| parent | 901fe7c00fec5e2aaf55d184edbcb6d092345d52 (diff) | |
set svn:eol-style=native for **.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1442 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DebuggerWX')
| -rw-r--r-- | Source/Core/DebuggerWX/Src/BreakPointDlg.cpp | 176 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/BreakpointView.cpp | 242 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/BreakpointWindow.cpp | 752 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/CodeView.cpp | 1122 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/CodeWindow.cpp | 2468 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/Debugger.cpp | 38 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/JitWindow.cpp | 422 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/LogWindow.cpp | 1038 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp | 224 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/MemoryView.cpp | 860 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/MemoryWindow.cpp | 442 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/RegisterView.cpp | 316 | ||||
| -rw-r--r-- | Source/Core/DebuggerWX/Src/RegisterWindow.cpp | 194 |
13 files changed, 4147 insertions, 4147 deletions
diff --git a/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp b/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp index 2a13bcb7a3..318b8225ef 100644 --- a/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp +++ b/Source/Core/DebuggerWX/Src/BreakPointDlg.cpp @@ -1,88 +1,88 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "BreakPointDlg.h"
-#include "Common.h"
-#include "Debugger.h"
-#include "StringUtil.h"
-#include "Debugger/Debugger_BreakPoints.h"
-
-
-BEGIN_EVENT_TABLE(BreakPointDlg,wxDialog)
- EVT_CLOSE(BreakPointDlg::OnClose)
- EVT_BUTTON(ID_OK, BreakPointDlg::OnOK)
- EVT_BUTTON(ID_CANCEL, BreakPointDlg::OnCancel)
-END_EVENT_TABLE()
-
-
-BreakPointDlg::BreakPointDlg(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
-: wxDialog(parent, id, title, position, size, style)
-{
- CreateGUIControls();
-}
-
-
-BreakPointDlg::~BreakPointDlg()
-{
-}
-
-
-void BreakPointDlg::CreateGUIControls()
-{
- SetIcon(wxNullIcon);
- SetSize(8,8,279,121);
- Center();
-
-
- wxStaticText* WxStaticText1 = new wxStaticText(this, ID_WXSTATICTEXT1, wxT("Address"), wxPoint(8,24), wxDefaultSize, 0, wxT("WxStaticText1"));
- WxStaticText1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pButtonOK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(192,64), wxSize(73,25), 0, wxDefaultValidator, wxT("OK"));
- m_pButtonOK->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pButtonCancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxPoint(112,64), wxSize(73,25), 0, wxDefaultValidator, wxT("Cancel"));
- m_pButtonCancel->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pEditAddress = new wxTextCtrl(this, ID_ADDRESS, wxT("80000000"), wxPoint(56,24), wxSize(197,20), 0, wxDefaultValidator, wxT("WxEdit1"));
- m_pEditAddress->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- wxStaticBox* WxStaticBox1 = new wxStaticBox(this, ID_WXSTATICBOX1, wxT("Address"), wxPoint(0,0), wxSize(265,57));
- WxStaticBox1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-}
-
-
-void BreakPointDlg::OnClose(wxCloseEvent& /*event*/)
-{
- Destroy();
-}
-
-void BreakPointDlg::OnOK(wxCommandEvent& /*event*/)
-{
- wxString AddressString = m_pEditAddress->GetLineText(0);
- u32 Address = 0;
- if (AsciiToHex(AddressString.mb_str(), Address))
- {
- CBreakPoints::AddBreakPoint(Address);
- CBreakPoints::UpdateBreakPointView();
- Close();
- }
-}
-
-void BreakPointDlg::OnCancel(wxCommandEvent& /*event*/)
-{
- Close();
-}
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "BreakPointDlg.h" +#include "Common.h" +#include "Debugger.h" +#include "StringUtil.h" +#include "Debugger/Debugger_BreakPoints.h" + + +BEGIN_EVENT_TABLE(BreakPointDlg,wxDialog) + EVT_CLOSE(BreakPointDlg::OnClose) + EVT_BUTTON(ID_OK, BreakPointDlg::OnOK) + EVT_BUTTON(ID_CANCEL, BreakPointDlg::OnCancel) +END_EVENT_TABLE() + + +BreakPointDlg::BreakPointDlg(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style) +: wxDialog(parent, id, title, position, size, style) +{ + CreateGUIControls(); +} + + +BreakPointDlg::~BreakPointDlg() +{ +} + + +void BreakPointDlg::CreateGUIControls() +{ + SetIcon(wxNullIcon); + SetSize(8,8,279,121); + Center(); + + + wxStaticText* WxStaticText1 = new wxStaticText(this, ID_WXSTATICTEXT1, wxT("Address"), wxPoint(8,24), wxDefaultSize, 0, wxT("WxStaticText1")); + WxStaticText1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pButtonOK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(192,64), wxSize(73,25), 0, wxDefaultValidator, wxT("OK")); + m_pButtonOK->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pButtonCancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxPoint(112,64), wxSize(73,25), 0, wxDefaultValidator, wxT("Cancel")); + m_pButtonCancel->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pEditAddress = new wxTextCtrl(this, ID_ADDRESS, wxT("80000000"), wxPoint(56,24), wxSize(197,20), 0, wxDefaultValidator, wxT("WxEdit1")); + m_pEditAddress->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + wxStaticBox* WxStaticBox1 = new wxStaticBox(this, ID_WXSTATICBOX1, wxT("Address"), wxPoint(0,0), wxSize(265,57)); + WxStaticBox1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); +} + + +void BreakPointDlg::OnClose(wxCloseEvent& /*event*/) +{ + Destroy(); +} + +void BreakPointDlg::OnOK(wxCommandEvent& /*event*/) +{ + wxString AddressString = m_pEditAddress->GetLineText(0); + u32 Address = 0; + if (AsciiToHex(AddressString.mb_str(), Address)) + { + CBreakPoints::AddBreakPoint(Address); + CBreakPoints::UpdateBreakPointView(); + Close(); + } +} + +void BreakPointDlg::OnCancel(wxCommandEvent& /*event*/) +{ + Close(); +} diff --git a/Source/Core/DebuggerWX/Src/BreakpointView.cpp b/Source/Core/DebuggerWX/Src/BreakpointView.cpp index 2f863af897..c3da612491 100644 --- a/Source/Core/DebuggerWX/Src/BreakpointView.cpp +++ b/Source/Core/DebuggerWX/Src/BreakpointView.cpp @@ -1,121 +1,121 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "Common.h"
-
-#include "BreakpointView.h"
-#include "Debugger/Debugger_BreakPoints.h"
-#include "Debugger/Debugger_SymbolMap.h"
-#include "PowerPC/SymbolDB.h"
-
-BEGIN_EVENT_TABLE(CBreakPointView, wxListCtrl)
-
-END_EVENT_TABLE()
-
-CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
- : wxListCtrl(parent, id, pos, size, style)
-{
- SetFont(wxFont(9, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI")));
-
- Refresh();
-}
-
-
-void CBreakPointView::Update()
-{
- ClearAll();
-
- InsertColumn(0, wxT("Active"), wxLIST_FORMAT_LEFT, 50);
- InsertColumn(1, wxT("Type"), wxLIST_FORMAT_LEFT, 50);
- InsertColumn(2, wxT("Function"), wxLIST_FORMAT_CENTER, 200);
- InsertColumn(3, wxT("Address"), wxLIST_FORMAT_LEFT, 100);
- InsertColumn(4, wxT("Flags"), wxLIST_FORMAT_CENTER, 100);
-
- char szBuffer[64];
- const CBreakPoints::TBreakPoints& rBreakPoints = CBreakPoints::GetBreakPoints();
- for (size_t i = 0; i < rBreakPoints.size(); i++)
- {
- const TBreakPoint& rBP = rBreakPoints[i];
- if (!rBP.bTemporary)
- {
- wxString temp;
- temp = wxString::FromAscii(rBP.bOn ? "on" : " ");
- int Item = InsertItem(0, temp);
- temp = wxString::FromAscii("BP");
- SetItem(Item, 1, temp);
-
- Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rBP.iAddress);
- if (symbol)
- {
- temp = wxString::FromAscii(g_symbolDB.GetDescription(rBP.iAddress));
- SetItem(Item, 2, temp);
- }
-
- sprintf(szBuffer, "0x%08x", rBP.iAddress);
- temp = wxString::FromAscii(szBuffer);
- SetItem(Item, 3, temp);
-
- SetItemData(Item, rBP.iAddress);
- }
- }
-
- const CBreakPoints::TMemChecks& rMemChecks = CBreakPoints::GetMemChecks();
- for (size_t i = 0; i < rMemChecks.size(); i++)
- {
- const TMemCheck& rMemCheck = rMemChecks[i];
-
- wxString temp;
- temp = wxString::FromAscii(rMemCheck.Break ? "on" : " ");
- int Item = InsertItem(0, temp);
- temp = wxString::FromAscii("MC");
- SetItem(Item, 1, temp);
-
- Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.StartAddress);
- if (symbol)
- {
- temp = wxString::FromAscii(g_symbolDB.GetDescription(rMemCheck.StartAddress));
- SetItem(Item, 2, temp);
- }
-
- sprintf(szBuffer, "0x%08x to 0%08x", rMemCheck.StartAddress, rMemCheck.EndAddress);
- temp = wxString::FromAscii(szBuffer);
- SetItem(Item, 3, temp);
-
- size_t c = 0;
- if (rMemCheck.OnRead) szBuffer[c++] = 'r';
- if (rMemCheck.OnWrite) szBuffer[c++] = 'w';
- szBuffer[c] = 0x00;
- temp = wxString::FromAscii(szBuffer);
- SetItem(Item, 4, temp);
-
- SetItemData(Item, rMemCheck.StartAddress);
- }
-
-
- Refresh();
-}
-
-void CBreakPointView::DeleteCurrentSelection()
-{
- int Item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
- if (Item >= 0)
- {
- u32 Address = (u32)GetItemData(Item);
- CBreakPoints::DeleteElementByAddress(Address);
- }
-}
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "Common.h" + +#include "BreakpointView.h" +#include "Debugger/Debugger_BreakPoints.h" +#include "Debugger/Debugger_SymbolMap.h" +#include "PowerPC/SymbolDB.h" + +BEGIN_EVENT_TABLE(CBreakPointView, wxListCtrl) + +END_EVENT_TABLE() + +CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) + : wxListCtrl(parent, id, pos, size, style) +{ + SetFont(wxFont(9, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI"))); + + Refresh(); +} + + +void CBreakPointView::Update() +{ + ClearAll(); + + InsertColumn(0, wxT("Active"), wxLIST_FORMAT_LEFT, 50); + InsertColumn(1, wxT("Type"), wxLIST_FORMAT_LEFT, 50); + InsertColumn(2, wxT("Function"), wxLIST_FORMAT_CENTER, 200); + InsertColumn(3, wxT("Address"), wxLIST_FORMAT_LEFT, 100); + InsertColumn(4, wxT("Flags"), wxLIST_FORMAT_CENTER, 100); + + char szBuffer[64]; + const CBreakPoints::TBreakPoints& rBreakPoints = CBreakPoints::GetBreakPoints(); + for (size_t i = 0; i < rBreakPoints.size(); i++) + { + const TBreakPoint& rBP = rBreakPoints[i]; + if (!rBP.bTemporary) + { + wxString temp; + temp = wxString::FromAscii(rBP.bOn ? "on" : " "); + int Item = InsertItem(0, temp); + temp = wxString::FromAscii("BP"); + SetItem(Item, 1, temp); + + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rBP.iAddress); + if (symbol) + { + temp = wxString::FromAscii(g_symbolDB.GetDescription(rBP.iAddress)); + SetItem(Item, 2, temp); + } + + sprintf(szBuffer, "0x%08x", rBP.iAddress); + temp = wxString::FromAscii(szBuffer); + SetItem(Item, 3, temp); + + SetItemData(Item, rBP.iAddress); + } + } + + const CBreakPoints::TMemChecks& rMemChecks = CBreakPoints::GetMemChecks(); + for (size_t i = 0; i < rMemChecks.size(); i++) + { + const TMemCheck& rMemCheck = rMemChecks[i]; + + wxString temp; + temp = wxString::FromAscii(rMemCheck.Break ? "on" : " "); + int Item = InsertItem(0, temp); + temp = wxString::FromAscii("MC"); + SetItem(Item, 1, temp); + + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.StartAddress); + if (symbol) + { + temp = wxString::FromAscii(g_symbolDB.GetDescription(rMemCheck.StartAddress)); + SetItem(Item, 2, temp); + } + + sprintf(szBuffer, "0x%08x to 0%08x", rMemCheck.StartAddress, rMemCheck.EndAddress); + temp = wxString::FromAscii(szBuffer); + SetItem(Item, 3, temp); + + size_t c = 0; + if (rMemCheck.OnRead) szBuffer[c++] = 'r'; + if (rMemCheck.OnWrite) szBuffer[c++] = 'w'; + szBuffer[c] = 0x00; + temp = wxString::FromAscii(szBuffer); + SetItem(Item, 4, temp); + + SetItemData(Item, rMemCheck.StartAddress); + } + + + Refresh(); +} + +void CBreakPointView::DeleteCurrentSelection() +{ + int Item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (Item >= 0) + { + u32 Address = (u32)GetItemData(Item); + CBreakPoints::DeleteElementByAddress(Address); + } +} diff --git a/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp b/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp index 8dc6913513..bcd812ebfc 100644 --- a/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp +++ b/Source/Core/DebuggerWX/Src/BreakpointWindow.cpp @@ -1,376 +1,376 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "BreakpointWindow.h"
-#include "BreakpointView.h"
-#include "CodeWindow.h"
-#include "HW/Memmap.h"
-#include "BreakPointDlg.h"
-#include "MemoryCheckDlg.h"
-#include "IniFile.h"
-#include "Debugger/Debugger_BreakPoints.h" // for TMemCheck
-
-#include <wx/mstream.h>
-
-extern "C" {
-#include "../resources/toolbar_add_breakpoint.c"
-#include "../resources/toolbar_add_memorycheck.c"
-#include "../resources/toolbar_delete.c"
-}
-
-static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT;
-
-BEGIN_EVENT_TABLE(CBreakPointWindow, wxFrame)
- EVT_CLOSE(CBreakPointWindow::OnClose)
- EVT_MENU(IDM_DELETE, CBreakPointWindow::OnDelete)
- EVT_MENU(IDM_CLEAR, CBreakPointWindow::OnClear)
- EVT_MENU(IDM_ADD_BREAKPOINT, CBreakPointWindow::OnAddBreakPoint)
- EVT_MENU(IDM_ADD_BREAKPOINTMANY, CBreakPointWindow::OnAddBreakPointMany)
- EVT_MENU(IDM_ADD_MEMORYCHECK, CBreakPointWindow::OnAddMemoryCheck)
- EVT_MENU(IDM_ADD_MEMORYCHECKMANY, CBreakPointWindow::OnAddMemoryCheckMany)
- EVT_LIST_ITEM_ACTIVATED(ID_BPS, CBreakPointWindow::OnActivated)
-END_EVENT_TABLE()
-
-
-#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name))
-inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length)
-{
- wxMemoryInputStream is(data, length);
- return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1));
-}
-
-
-CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
- : wxFrame(parent, id, title, position, size, style)
- , m_BreakPointListView(NULL)
- , m_pCodeWindow(_pCodeWindow)
-{
- InitBitmaps();
-
- CreateGUIControls();
-
- // Create the toolbar
- RecreateToolbar();
-
-}
-
-
-CBreakPointWindow::~CBreakPointWindow()
-{}
-
-
-void
-CBreakPointWindow::Save(IniFile& _IniFile) const
-{
- _IniFile.Set("BreakPoint", "x", GetPosition().x);
- _IniFile.Set("BreakPoint", "y", GetPosition().y);
- _IniFile.Set("BreakPoint", "w", GetSize().GetWidth());
- _IniFile.Set("BreakPoint", "h", GetSize().GetHeight());
-}
-
-
-void
-CBreakPointWindow::Load(IniFile& _IniFile)
-{
- int x,y,w,h;
- _IniFile.Get("BreakPoint", "x", &x, GetPosition().x);
- _IniFile.Get("BreakPoint", "y", &y, GetPosition().y);
- _IniFile.Get("BreakPoint", "w", &w, GetSize().GetWidth());
- _IniFile.Get("BreakPoint", "h", &h, GetSize().GetHeight());
- SetSize(x, y, w, h);
-}
-
-
-void
-CBreakPointWindow::CreateGUIControls()
-{
- SetTitle(wxT("Breakpoints"));
- SetIcon(wxNullIcon);
- SetSize(8, 8, 400, 370);
- Center();
-
- m_BreakPointListView = new CBreakPointView(this, ID_BPS, wxDefaultPosition, GetSize(),
- wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
-
- NotifyUpdate();
-}
-
-
-void
-CBreakPointWindow::PopulateToolbar(wxToolBar* toolBar)
-{
- int w = m_Bitmaps[Toolbar_Delete].GetWidth(),
- h = m_Bitmaps[Toolbar_Delete].GetHeight();
-
- toolBar->SetToolBitmapSize(wxSize(w, h));
- toolBar->AddTool(IDM_DELETE, _T("Delete"), m_Bitmaps[Toolbar_Delete], _T("Delete the selected BreakPoint or MemoryCheck"));
- toolBar->AddTool(IDM_CLEAR, _T("Clear all"), m_Bitmaps[Toolbar_Delete], _T("Clear all BreakPoints and MemoryChecks"));
-
- toolBar->AddSeparator();
-
- toolBar->AddTool(IDM_ADD_BREAKPOINT, _T("BP"), m_Bitmaps[Toolbar_Add_BreakPoint], _T("Add BreakPoint..."));
- toolBar->AddTool(IDM_ADD_BREAKPOINTMANY, _T("BPs"), m_Bitmaps[Toolbar_Add_BreakPoint], _T("Add BreakPoints..."));
-
- // just add memory breakpoints if you can use them
- if (Memory::AreMemoryBreakpointsActivated())
- {
- toolBar->AddTool(IDM_ADD_MEMORYCHECK, _T("MC"), m_Bitmaps[Toolbar_Add_Memcheck], _T("Add MemoryCheck..."));
- toolBar->AddTool(IDM_ADD_MEMORYCHECKMANY, _T("MCs"), m_Bitmaps[Toolbar_Add_Memcheck], _T("Add MemoryChecks..."));
- }
-
- // after adding the buttons to the toolbar, must call Realize() to reflect
- // the changes
- toolBar->Realize();
-}
-
-
-void
-CBreakPointWindow::RecreateToolbar()
-{
- // delete and recreate the toolbar
- wxToolBarBase* toolBar = GetToolBar();
- long style = toolBar ? toolBar->GetWindowStyle() : TOOLBAR_STYLE;
-
- delete toolBar;
- SetToolBar(NULL);
-
- style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT | wxTB_TOP);
- wxToolBar* theToolBar = CreateToolBar(style, ID_TOOLBAR);
-
- PopulateToolbar(theToolBar);
- SetToolBar(theToolBar);
-}
-
-
-void
-CBreakPointWindow::InitBitmaps()
-{
- // load orignal size 48x48
- m_Bitmaps[Toolbar_Delete] = wxGetBitmapFromMemory(toolbar_delete_png);
- m_Bitmaps[Toolbar_Add_BreakPoint] = wxGetBitmapFromMemory(toolbar_add_breakpoint_png);
- m_Bitmaps[Toolbar_Add_Memcheck] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
-
- // scale to 24x24 for toolbar
- for (size_t n = Toolbar_Delete; n < WXSIZEOF(m_Bitmaps); n++)
- {
- m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(16, 16));
- }
-}
-
-
-void
-CBreakPointWindow::OnClose(wxCloseEvent& /*event*/)
-{
- Hide();
-}
-
-
-void CBreakPointWindow::NotifyUpdate()
-{
- if (m_BreakPointListView != NULL)
- {
- m_BreakPointListView->Update();
- }
-}
-
-
-void
-CBreakPointWindow::OnDelete(wxCommandEvent& event)
-{
- if (m_BreakPointListView)
- {
- m_BreakPointListView->DeleteCurrentSelection();
- }
-}
-
-
-// ==========================================================================================
-// Clear all breakpoints
-// ------------
-void
-CBreakPointWindow::OnClear(wxCommandEvent& event)
-{
- CBreakPoints::ClearAllBreakPoints();
-}
-// ============
-
-
-void
-CBreakPointWindow::OnAddBreakPoint(wxCommandEvent& event)
-{
- BreakPointDlg bpDlg(this);
- bpDlg.ShowModal();
-}
-
-
-// ==========================================================================================
-// Load breakpoints from file
-// --------------
-void
-CBreakPointWindow::OnAddBreakPointMany(wxCommandEvent& event)
-{
- // load ini
- IniFile ini;
- std::string filename = std::string(FULL_GAMECONFIG_DIR "BreakPoints.ini");
-
- if (ini.Load(filename.c_str())) // check if there is any file there
- {
- // get lines from a certain section
- std::vector<std::string> lines;
- if (!ini.GetLines("BreakPoints", lines))
- {
- wxMessageBox(_T("You have no [BreakPoints] line in your file"));
- return;
- }
-
- for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
- {
- std::string line = StripSpaces(*iter);
- u32 Address = 0;
- if (AsciiToHex(line.c_str(), Address))
- {
- CBreakPoints::AddBreakPoint(Address);
- }
- }
- // only update after we are done with the loop
- CBreakPoints::UpdateBreakPointView();
- }
- else
- {
- wxMessageBox(_T("You have no GameIni/BreakPoints.ini file"));
- }
-
-}
-// =================
-
-
-void
-CBreakPointWindow::OnAddMemoryCheck(wxCommandEvent& event)
-{
- MemoryCheckDlg memDlg(this);
- memDlg.ShowModal();
-}
-
-
-// ==========================================================================================
-// Load memory checks from file
-// --------------
-void
-CBreakPointWindow::OnAddMemoryCheckMany(wxCommandEvent& event)
-{
- // load ini
- IniFile ini;
- std::string filename = std::string(FULL_GAMECONFIG_DIR "MemoryChecks.ini");
-
- if (ini.Load(filename.c_str()))
- {
- // get lines from a certain section
- std::vector<std::string> lines;
- if (!ini.GetLines("MemoryChecks", lines))
- {
- wxMessageBox(_T("You have no [MemoryChecks] line in your file"));
- return;
- }
-
- for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
- {
- std::string line = StripSpaces(*iter);
- std::vector<std::string> pieces;
- SplitString(line, " ", pieces); // split string
-
- TMemCheck MemCheck;
- u32 sAddress = 0;
- u32 eAddress = 0;
- bool doCommon = false;
-
- // ------------------------------------------------------------------------------------------
- // Decide if we have a range or just one address, and if we should break or not
- // --------------
- if (
- pieces.size() == 1
- && AsciiToHex(pieces[0].c_str(), sAddress)
- && pieces[0].size() == 8
- )
- {
- // address range
- MemCheck.StartAddress = sAddress;
- MemCheck.EndAddress = sAddress;
- doCommon = true;
- MemCheck.Break = false;
- }
- else if(
- pieces.size() == 2
- && AsciiToHex(pieces[0].c_str(), sAddress) && AsciiToHex(pieces[1].c_str(), eAddress)
- && pieces[0].size() == 8 && pieces[1].size() == 8
- )
- {
- // address range
- MemCheck.StartAddress = sAddress;
- MemCheck.EndAddress = eAddress;
- doCommon = true;
- MemCheck.Break = false;
- }
- else if(
- pieces.size() == 3
- && AsciiToHex(pieces[0].c_str(), sAddress) && AsciiToHex(pieces[1].c_str(), eAddress)
- && pieces[0].size() == 8 && pieces[1].size() == 8 && pieces[2].size() == 1
- )
- {
- // address range
- MemCheck.StartAddress = sAddress;
- MemCheck.EndAddress = eAddress;
- doCommon = true;
- MemCheck.Break = true;
- }
-
- if(doCommon)
- {
- // settings for the memory check
- MemCheck.OnRead = true;
- MemCheck.OnWrite = true;
- MemCheck.Log = true;
- //MemCheck.Break = false; // this is also what sets Active "on" in the breakpoint window
- // so don't think it's off because we are only writing this to the log
- CBreakPoints::AddMemoryCheck(MemCheck);
- }
- }
- // update after we are done with the loop
- CBreakPoints::UpdateBreakPointView();
- }
- else
- {
- wxMessageBox(_T("You have no " FULL_GAMECONFIG_DIR "MemoryChecks.ini file"));
- }
-}
-// =================
-
-
-void
-CBreakPointWindow::OnActivated(wxListEvent& event)
-{
- long Index = event.GetIndex();
- if (Index >= 0)
- {
- u32 Address = (u32)m_BreakPointListView->GetItemData(Index);
- if (m_pCodeWindow != NULL)
- {
- m_pCodeWindow->JumpToAddress(Address);
- }
- }
-}
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "BreakpointWindow.h" +#include "BreakpointView.h" +#include "CodeWindow.h" +#include "HW/Memmap.h" +#include "BreakPointDlg.h" +#include "MemoryCheckDlg.h" +#include "IniFile.h" +#include "Debugger/Debugger_BreakPoints.h" // for TMemCheck + +#include <wx/mstream.h> + +extern "C" { +#include "../resources/toolbar_add_breakpoint.c" +#include "../resources/toolbar_add_memorycheck.c" +#include "../resources/toolbar_delete.c" +} + +static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT; + +BEGIN_EVENT_TABLE(CBreakPointWindow, wxFrame) + EVT_CLOSE(CBreakPointWindow::OnClose) + EVT_MENU(IDM_DELETE, CBreakPointWindow::OnDelete) + EVT_MENU(IDM_CLEAR, CBreakPointWindow::OnClear) + EVT_MENU(IDM_ADD_BREAKPOINT, CBreakPointWindow::OnAddBreakPoint) + EVT_MENU(IDM_ADD_BREAKPOINTMANY, CBreakPointWindow::OnAddBreakPointMany) + EVT_MENU(IDM_ADD_MEMORYCHECK, CBreakPointWindow::OnAddMemoryCheck) + EVT_MENU(IDM_ADD_MEMORYCHECKMANY, CBreakPointWindow::OnAddMemoryCheckMany) + EVT_LIST_ITEM_ACTIVATED(ID_BPS, CBreakPointWindow::OnActivated) +END_EVENT_TABLE() + + +#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name)) +inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length) +{ + wxMemoryInputStream is(data, length); + return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1)); +} + + +CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) + : wxFrame(parent, id, title, position, size, style) + , m_BreakPointListView(NULL) + , m_pCodeWindow(_pCodeWindow) +{ + InitBitmaps(); + + CreateGUIControls(); + + // Create the toolbar + RecreateToolbar(); + +} + + +CBreakPointWindow::~CBreakPointWindow() +{} + + +void +CBreakPointWindow::Save(IniFile& _IniFile) const +{ + _IniFile.Set("BreakPoint", "x", GetPosition().x); + _IniFile.Set("BreakPoint", "y", GetPosition().y); + _IniFile.Set("BreakPoint", "w", GetSize().GetWidth()); + _IniFile.Set("BreakPoint", "h", GetSize().GetHeight()); +} + + +void +CBreakPointWindow::Load(IniFile& _IniFile) +{ + int x,y,w,h; + _IniFile.Get("BreakPoint", "x", &x, GetPosition().x); + _IniFile.Get("BreakPoint", "y", &y, GetPosition().y); + _IniFile.Get("BreakPoint", "w", &w, GetSize().GetWidth()); + _IniFile.Get("BreakPoint", "h", &h, GetSize().GetHeight()); + SetSize(x, y, w, h); +} + + +void +CBreakPointWindow::CreateGUIControls() +{ + SetTitle(wxT("Breakpoints")); + SetIcon(wxNullIcon); + SetSize(8, 8, 400, 370); + Center(); + + m_BreakPointListView = new CBreakPointView(this, ID_BPS, wxDefaultPosition, GetSize(), + wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING); + + NotifyUpdate(); +} + + +void +CBreakPointWindow::PopulateToolbar(wxToolBar* toolBar) +{ + int w = m_Bitmaps[Toolbar_Delete].GetWidth(), + h = m_Bitmaps[Toolbar_Delete].GetHeight(); + + toolBar->SetToolBitmapSize(wxSize(w, h)); + toolBar->AddTool(IDM_DELETE, _T("Delete"), m_Bitmaps[Toolbar_Delete], _T("Delete the selected BreakPoint or MemoryCheck")); + toolBar->AddTool(IDM_CLEAR, _T("Clear all"), m_Bitmaps[Toolbar_Delete], _T("Clear all BreakPoints and MemoryChecks")); + + toolBar->AddSeparator(); + + toolBar->AddTool(IDM_ADD_BREAKPOINT, _T("BP"), m_Bitmaps[Toolbar_Add_BreakPoint], _T("Add BreakPoint...")); + toolBar->AddTool(IDM_ADD_BREAKPOINTMANY, _T("BPs"), m_Bitmaps[Toolbar_Add_BreakPoint], _T("Add BreakPoints...")); + + // just add memory breakpoints if you can use them + if (Memory::AreMemoryBreakpointsActivated()) + { + toolBar->AddTool(IDM_ADD_MEMORYCHECK, _T("MC"), m_Bitmaps[Toolbar_Add_Memcheck], _T("Add MemoryCheck...")); + toolBar->AddTool(IDM_ADD_MEMORYCHECKMANY, _T("MCs"), m_Bitmaps[Toolbar_Add_Memcheck], _T("Add MemoryChecks...")); + } + + // after adding the buttons to the toolbar, must call Realize() to reflect + // the changes + toolBar->Realize(); +} + + +void +CBreakPointWindow::RecreateToolbar() +{ + // delete and recreate the toolbar + wxToolBarBase* toolBar = GetToolBar(); + long style = toolBar ? toolBar->GetWindowStyle() : TOOLBAR_STYLE; + + delete toolBar; + SetToolBar(NULL); + + style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT | wxTB_TOP); + wxToolBar* theToolBar = CreateToolBar(style, ID_TOOLBAR); + + PopulateToolbar(theToolBar); + SetToolBar(theToolBar); +} + + +void +CBreakPointWindow::InitBitmaps() +{ + // load orignal size 48x48 + m_Bitmaps[Toolbar_Delete] = wxGetBitmapFromMemory(toolbar_delete_png); + m_Bitmaps[Toolbar_Add_BreakPoint] = wxGetBitmapFromMemory(toolbar_add_breakpoint_png); + m_Bitmaps[Toolbar_Add_Memcheck] = wxGetBitmapFromMemory(toolbar_add_memcheck_png); + + // scale to 24x24 for toolbar + for (size_t n = Toolbar_Delete; n < WXSIZEOF(m_Bitmaps); n++) + { + m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(16, 16)); + } +} + + +void +CBreakPointWindow::OnClose(wxCloseEvent& /*event*/) +{ + Hide(); +} + + +void CBreakPointWindow::NotifyUpdate() +{ + if (m_BreakPointListView != NULL) + { + m_BreakPointListView->Update(); + } +} + + +void +CBreakPointWindow::OnDelete(wxCommandEvent& event) +{ + if (m_BreakPointListView) + { + m_BreakPointListView->DeleteCurrentSelection(); + } +} + + +// ========================================================================================== +// Clear all breakpoints +// ------------ +void +CBreakPointWindow::OnClear(wxCommandEvent& event) +{ + CBreakPoints::ClearAllBreakPoints(); +} +// ============ + + +void +CBreakPointWindow::OnAddBreakPoint(wxCommandEvent& event) +{ + BreakPointDlg bpDlg(this); + bpDlg.ShowModal(); +} + + +// ========================================================================================== +// Load breakpoints from file +// -------------- +void +CBreakPointWindow::OnAddBreakPointMany(wxCommandEvent& event) +{ + // load ini + IniFile ini; + std::string filename = std::string(FULL_GAMECONFIG_DIR "BreakPoints.ini"); + + if (ini.Load(filename.c_str())) // check if there is any file there + { + // get lines from a certain section + std::vector<std::string> lines; + if (!ini.GetLines("BreakPoints", lines)) + { + wxMessageBox(_T("You have no [BreakPoints] line in your file")); + return; + } + + for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + std::string line = StripSpaces(*iter); + u32 Address = 0; + if (AsciiToHex(line.c_str(), Address)) + { + CBreakPoints::AddBreakPoint(Address); + } + } + // only update after we are done with the loop + CBreakPoints::UpdateBreakPointView(); + } + else + { + wxMessageBox(_T("You have no GameIni/BreakPoints.ini file")); + } + +} +// ================= + + +void +CBreakPointWindow::OnAddMemoryCheck(wxCommandEvent& event) +{ + MemoryCheckDlg memDlg(this); + memDlg.ShowModal(); +} + + +// ========================================================================================== +// Load memory checks from file +// -------------- +void +CBreakPointWindow::OnAddMemoryCheckMany(wxCommandEvent& event) +{ + // load ini + IniFile ini; + std::string filename = std::string(FULL_GAMECONFIG_DIR "MemoryChecks.ini"); + + if (ini.Load(filename.c_str())) + { + // get lines from a certain section + std::vector<std::string> lines; + if (!ini.GetLines("MemoryChecks", lines)) + { + wxMessageBox(_T("You have no [MemoryChecks] line in your file")); + return; + } + + for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) + { + std::string line = StripSpaces(*iter); + std::vector<std::string> pieces; + SplitString(line, " ", pieces); // split string + + TMemCheck MemCheck; + u32 sAddress = 0; + u32 eAddress = 0; + bool doCommon = false; + + // ------------------------------------------------------------------------------------------ + // Decide if we have a range or just one address, and if we should break or not + // -------------- + if ( + pieces.size() == 1 + && AsciiToHex(pieces[0].c_str(), sAddress) + && pieces[0].size() == 8 + ) + { + // address range + MemCheck.StartAddress = sAddress; + MemCheck.EndAddress = sAddress; + doCommon = true; + MemCheck.Break = false; + } + else if( + pieces.size() == 2 + && AsciiToHex(pieces[0].c_str(), sAddress) && AsciiToHex(pieces[1].c_str(), eAddress) + && pieces[0].size() == 8 && pieces[1].size() == 8 + ) + { + // address range + MemCheck.StartAddress = sAddress; + MemCheck.EndAddress = eAddress; + doCommon = true; + MemCheck.Break = false; + } + else if( + pieces.size() == 3 + && AsciiToHex(pieces[0].c_str(), sAddress) && AsciiToHex(pieces[1].c_str(), eAddress) + && pieces[0].size() == 8 && pieces[1].size() == 8 && pieces[2].size() == 1 + ) + { + // address range + MemCheck.StartAddress = sAddress; + MemCheck.EndAddress = eAddress; + doCommon = true; + MemCheck.Break = true; + } + + if(doCommon) + { + // settings for the memory check + MemCheck.OnRead = true; + MemCheck.OnWrite = true; + MemCheck.Log = true; + //MemCheck.Break = false; // this is also what sets Active "on" in the breakpoint window + // so don't think it's off because we are only writing this to the log + CBreakPoints::AddMemoryCheck(MemCheck); + } + } + // update after we are done with the loop + CBreakPoints::UpdateBreakPointView(); + } + else + { + wxMessageBox(_T("You have no " FULL_GAMECONFIG_DIR "MemoryChecks.ini file")); + } +} +// ================= + + +void +CBreakPointWindow::OnActivated(wxListEvent& event) +{ + long Index = event.GetIndex(); + if (Index >= 0) + { + u32 Address = (u32)m_BreakPointListView->GetItemData(Index); + if (m_pCodeWindow != NULL) + { + m_pCodeWindow->JumpToAddress(Address); + } + } +} + diff --git a/Source/Core/DebuggerWX/Src/CodeView.cpp b/Source/Core/DebuggerWX/Src/CodeView.cpp index ea7d782a5d..1d75cb8283 100644 --- a/Source/Core/DebuggerWX/Src/CodeView.cpp +++ b/Source/Core/DebuggerWX/Src/CodeView.cpp @@ -1,561 +1,561 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "Debugger/PPCDebugInterface.h"
-#include "PowerPC/SymbolDB.h"
-#include "HW/Memmap.h" // for Write_U32
-#include "Common.h"
-#include "StringUtil.h"
-
-#include "Host.h"
-#include "CodeView.h"
-#include "JitWindow.h"
-
-#include <wx/event.h>
-#include <wx/clipbrd.h>
-#include <wx/textdlg.h>
-
-DEFINE_EVENT_TYPE(wxEVT_CODEVIEW_CHANGE);
-
-enum
-{
- IDM_GOTOINMEMVIEW = 12000,
- IDM_COPYADDRESS,
- IDM_COPYHEX,
- IDM_COPYCODE,
- IDM_INSERTBLR,
- IDM_RUNTOHERE,
- IDM_JITRESULTS,
- IDM_FOLLOWBRANCH,
- IDM_RENAMESYMBOL,
- IDM_PATCHALERT,
- IDM_COPYFUNCTION,
-};
-
-
-BEGIN_EVENT_TABLE(CCodeView, wxControl)
- EVT_ERASE_BACKGROUND(CCodeView::OnErase)
- EVT_PAINT(CCodeView::OnPaint)
- EVT_LEFT_DOWN(CCodeView::OnMouseDown)
- EVT_LEFT_UP(CCodeView::OnMouseUpL)
- EVT_MOTION(CCodeView::OnMouseMove)
- EVT_RIGHT_DOWN(CCodeView::OnMouseDown)
- EVT_RIGHT_UP(CCodeView::OnMouseUpR)
- EVT_MENU(-1, CCodeView::OnPopupMenu)
-END_EVENT_TABLE()
-
-CCodeView::CCodeView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id, const wxSize& Size)
- : wxControl(parent, Id, wxDefaultPosition, Size),
- debugger(debuginterface),
- rowHeight(13),
- selection(0),
- oldSelection(0),
- selectionChanged(false),
- selecting(false),
- hasFocus(false),
- showHex(false),
- lx(-1),
- ly(-1)
-{
- rowHeight = 13;
- align = debuginterface->getInstructionSize(0);
- curAddress = debuginterface->getPC();
- selection = 0;
-}
-
-
-wxSize CCodeView::DoGetBestSize() const
-{
- wxSize bestSize;
- bestSize.x = 400;
- bestSize.y = 800;
- return(bestSize);
-}
-
-
-int CCodeView::YToAddress(int y)
-{
- wxRect rc = GetClientRect();
- int ydiff = y - rc.height / 2 - rowHeight / 2;
- ydiff = (int)(floorf((float)ydiff / (float)rowHeight)) + 1;
- return(curAddress + ydiff * align);
-}
-
-
-void CCodeView::OnMouseDown(wxMouseEvent& event)
-{
- int x = event.m_x;
- int y = event.m_y;
-
- if (x > 16)
- {
- oldSelection = selection;
- selection = YToAddress(y);
- // SetCapture(wnd);
- bool oldselecting = selecting;
- selecting = true;
-
- if (!oldselecting || (selection != oldSelection))
- {
- redraw();
- }
- }
- else
- {
- debugger->toggleBreakpoint(YToAddress(y));
- redraw();
- }
-
- event.Skip(true);
-}
-
-
-void CCodeView::OnMouseMove(wxMouseEvent& event)
-{
- wxRect rc = GetClientRect();
-
- if (event.m_leftDown)
- {
- if (event.m_x > 16)
- {
- if (event.m_y < 0)
- {
- curAddress -= align;
- redraw();
- }
- else if (event.m_y > rc.height)
- {
- curAddress += align;
- redraw();
- }
- else
- {
- OnMouseDown(event);
- }
- }
- }
-
- event.Skip(true);
-}
-
-void CCodeView::RaiseEvent()
-{
- wxCommandEvent ev(wxEVT_CODEVIEW_CHANGE, GetId());
- ev.SetEventObject(this);
- ev.SetInt(selection);
- GetEventHandler()->ProcessEvent(ev);
-}
-
-void CCodeView::OnMouseUpL(wxMouseEvent& event)
-{
- if (event.m_x > 16)
- {
- curAddress = YToAddress(event.m_y);
- selecting = false;
- //ReleaseCapture();
- redraw();
- }
- RaiseEvent();
- event.Skip(true);
-}
-
-u32 CCodeView::AddrToBranch(u32 addr)
-{
- const char *temp = debugger->disasm(addr);
- const char *mojs = strstr(temp, "->0x");
- if (mojs)
- {
- u32 dest;
- sscanf(mojs+4,"%08x", &dest);
- return dest;
- }
- return 0;
-}
-
-void CCodeView::OnPopupMenu(wxCommandEvent& event)
-{
-#if wxUSE_CLIPBOARD
- wxTheClipboard->Open();
-#endif
-
- switch (event.GetId())
- {
- case IDM_GOTOINMEMVIEW:
- // CMemoryDlg::Goto(selection);
- break;
-
-#if wxUSE_CLIPBOARD
- case IDM_COPYADDRESS:
- wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%08x"), selection)));
- break;
-
- case IDM_COPYCODE:
- wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(debugger->disasm(selection)))); //Have to manually convert from char* to wxString, don't have to in Windows?
- break;
-
- case IDM_COPYHEX:
- {
- char temp[24];
- sprintf(temp, "%08x", debugger->readInstruction(selection));
- wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(temp)));
- }
- break;
- case IDM_COPYFUNCTION:
- {
- Symbol *symbol = g_symbolDB.GetSymbolFromAddr(selection);
- if (symbol) {
- std::string text;
- text = text + symbol->name + "\r\n";
- // we got a function
- u32 start = symbol->address;
- u32 end = start + symbol->size;
- for (u32 addr = start; addr != end; addr += 4) {
- text = text + StringFromFormat("%08x: ", addr) + debugger->disasm(addr) + "\r\n";
- }
- wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(text.c_str())));
- }
- }
- break;
-#endif
-
- case IDM_RUNTOHERE:
- debugger->setBreakpoint(selection);
- debugger->runToBreakpoint();
- redraw();
- break;
-
- // Insert blr or restore old value
- case IDM_INSERTBLR:
- {
- // Check if this address has been modified
- int find = -1;
- for(u32 i = 0; i < BlrList.size(); i++)
- {
- if(BlrList.at(i).Address == selection)
- { find = i; break; }
- }
-
- // Save the old value
- if(find >= 0)
- {
- Memory::Write_U32(BlrList.at(find).OldValue, selection);
- BlrList.erase(BlrList.begin() + find);
- }
- else
- {
- BlrStruct Temp;
- Temp.Address = selection;
- Temp.OldValue = debugger->readMemory(selection);
- BlrList.push_back(Temp);
- debugger->insertBLR(selection);
- }
- redraw();
- }
- break;
-
- case IDM_JITRESULTS:
- CJitWindow::ViewAddr(selection);
- break;
-
- case IDM_FOLLOWBRANCH:
- {
- u32 dest = AddrToBranch(selection);
- if (dest)
- Center(dest);
- RaiseEvent();
- }
- break;
-
- case IDM_RENAMESYMBOL:
- {
- Symbol *symbol = g_symbolDB.GetSymbolFromAddr(selection);
- if (symbol) {
- wxTextEntryDialog input_symbol(this, wxString::FromAscii("Rename symbol:"), wxGetTextFromUserPromptStr,
- wxString::FromAscii(symbol->name.c_str()));
- if (input_symbol.ShowModal() == wxID_OK) {
- symbol->name = input_symbol.GetValue().mb_str();
- }
-// redraw();
- Host_NotifyMapLoaded();
- }
- }
- break;
-
- case IDM_PATCHALERT:
- {
-
- }
- break;
- }
-
-#if wxUSE_CLIPBOARD
- wxTheClipboard->Close();
-#endif
- event.Skip(true);
-}
-
-
-void CCodeView::OnMouseUpR(wxMouseEvent& event)
-{
- bool isSymbol = g_symbolDB.GetSymbolFromAddr(selection) != 0;
- // popup menu
- wxMenu menu;
- //menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view");
- menu.Append(IDM_FOLLOWBRANCH, wxString::FromAscii("&Follow branch"))->Enable(AddrToBranch(selection) ? true : false);
- menu.AppendSeparator();
-#if wxUSE_CLIPBOARD
- menu.Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address"));
- menu.Append(IDM_COPYFUNCTION, wxString::FromAscii("Copy &function"))->Enable(isSymbol);
- menu.Append(IDM_COPYCODE, wxString::FromAscii("Copy &code line"));
- menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex"));
- menu.AppendSeparator();
-#endif
- menu.Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol"))->Enable(isSymbol);
- menu.AppendSeparator();
- menu.Append(IDM_RUNTOHERE, _T("&Run To Here"));
- menu.Append(IDM_JITRESULTS, wxString::FromAscii("PPC vs X86"));
- menu.Append(IDM_INSERTBLR, wxString::FromAscii("Insert &blr"));
- menu.Append(IDM_PATCHALERT, wxString::FromAscii("Patch alert"));
- PopupMenu(&menu);
- event.Skip(true);
-}
-
-
-void CCodeView::OnErase(wxEraseEvent& event)
-{}
-
-
-void CCodeView::OnPaint(wxPaintEvent& event)
-{
- // --------------------------------------------------------------------
- // General settings
- // -------------------------
- wxPaintDC dc(this);
- wxRect rc = GetClientRect();
- wxFont font(7, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT);
- dc.SetFont(font);
- struct branch
- {
- int src, dst, srcAddr;
- };
-
- branch branches[256];
- int numBranches = 0;
- // TODO: Add any drawing code here...
- int width = rc.width;
- int numRows = (rc.height / rowHeight) / 2 + 2;
- //numRows=(numRows&(~1)) + 1;
- // ------------
-
-
- // --------------------------------------------------------------------
- // Colors and brushes
- // -------------------------
- dc.SetBackgroundMode(wxTRANSPARENT); // the text background
- const wxChar* bgColor = _T("#ffffff");
- wxPen nullPen(bgColor);
- wxPen currentPen(_T("#000000"));
- wxPen selPen(_T("#808080")); // gray
- nullPen.SetStyle(wxTRANSPARENT);
- currentPen.SetStyle(wxSOLID);
- wxBrush currentBrush(_T("#FFEfE8")); // the ... ? ... is light gray
- wxBrush pcBrush(_T("#70FF70")); // the selected code line is green
- wxBrush bpBrush(_T("#FF3311")); // red
-
- wxBrush bgBrush(bgColor);
- wxBrush nullBrush(bgColor);
- nullBrush.SetStyle(wxTRANSPARENT);
-
- dc.SetPen(nullPen);
- dc.SetBrush(bgBrush);
- dc.DrawRectangle(0, 0, 16, rc.height);
- dc.DrawRectangle(0, 0, rc.width, 5);
- // ------------
-
-
- // --------------------------------------------------------------------
- // Walk through all visible rows
- // -------------------------
- for (int i = -numRows; i <= numRows; i++)
- {
- unsigned int address = curAddress + i * align;
-
- int rowY1 = rc.height / 2 + rowHeight * i - rowHeight / 2;
- int rowY2 = rc.height / 2 + rowHeight * i + rowHeight / 2;
-
- wxString temp = wxString::Format(_T("%08x"), address);
- u32 col = debugger->getColor(address);
- wxBrush rowBrush(wxColor(col >> 16, col >> 8, col));
- dc.SetBrush(nullBrush);
- dc.SetPen(nullPen);
- dc.DrawRectangle(0, rowY1, 16, rowY2 - rowY1 + 2);
-
- if (selecting && (address == selection))
- dc.SetPen(selPen);
- else
- dc.SetPen(i == 0 ? currentPen : nullPen);
-
- if (address == debugger->getPC())
- dc.SetBrush(pcBrush);
- else
- dc.SetBrush(rowBrush);
-
- dc.DrawRectangle(16, rowY1, width, rowY2 - rowY1 + 1);
- dc.SetBrush(currentBrush);
- dc.SetTextForeground(_T("#600000")); // the address text is dark red
- dc.DrawText(temp, 17, rowY1);
- dc.SetTextForeground(_T("#000000"));
-
- if (debugger->isAlive())
- {
- char dis[256] = {0};
- strcpy(dis, debugger->disasm(address));
- char* dis2 = strchr(dis, '\t');
- char desc[256] = "";
-
- // If we have a code
- if (dis2)
- {
- *dis2 = 0;
- dis2++;
- const char* mojs = strstr(dis2, "0x8");
-
- // --------------------------------------------------------------------
- // Colors and brushes
- // -------------------------
- if (mojs)
- {
- for (int k = 0; k < 8; k++)
- {
- bool found = false;
-
- for (int j = 0; j < 22; j++)
- {
- if (mojs[k + 2] == "0123456789ABCDEFabcdef"[j])
- {
- found = true;
- }
- }
- if (!found)
- {
- mojs = 0;
- break;
- }
- }
- }
- // ------------
-
-
- // --------------------------------------------------------------------
- // Colors and brushes
- // -------------------------
- if (mojs)
- {
- int offs;
- sscanf(mojs + 2, "%08x", &offs);
- branches[numBranches].src = rowY1 + rowHeight / 2;
- branches[numBranches].srcAddr = address / align;
- branches[numBranches++].dst = (int)(rowY1 + ((s64)(u32)offs - (s64)(u32)address) * rowHeight / align + rowHeight / 2);
- sprintf(desc, "-->%s", debugger->getDescription(offs).c_str());
- dc.SetTextForeground(_T("#600060")); // the -> arrow illustrations are purple
- }
- else
- {
- dc.SetTextForeground(_T("#000000"));
- }
-
- dc.DrawText(wxString::FromAscii(dis2), 126, rowY1);
- // ------------
- }
-
- // Show blr as its' own color
- if (strcmp(dis, "blr"))
- dc.SetTextForeground(_T("#007000")); // dark green
- else
- dc.SetTextForeground(_T("#8000FF")); // purple
-
- dc.DrawText(wxString::FromAscii(dis), 70, rowY1);
-
- if (desc[0] == 0)
- {
- strcpy(desc, debugger->getDescription(address).c_str());
- }
-
- dc.SetTextForeground(_T("#0000FF")); // blue
-
- //char temp[256];
- //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE);
- if (strlen(desc))
- {
- dc.DrawText(wxString::FromAscii(desc), 235, rowY1);
- }
-
- // Show red breakpoint dot
- if (debugger->isBreakpoint(address))
- {
- dc.SetBrush(bpBrush);
- dc.DrawRectangle(2, rowY1, 7, 7);
- //DrawIconEx(hdc, 2, rowY1, breakPoint, 32, 32, 0, 0, DI_NORMAL);
- }
- }
- } // end of for
- // ------------
-
-
- // --------------------------------------------------------------------
- // Colors and brushes
- // -------------------------
- dc.SetPen(currentPen);
-
- for (int i = 0; i < numBranches; i++)
- {
- int x = 300 + (branches[i].srcAddr % 9) * 8;
- _MoveTo(x-2, branches[i].src);
-
- if (branches[i].dst < rc.height + 400 && branches[i].dst > -400)
- {
- _LineTo(dc, x+2, branches[i].src);
- _LineTo(dc, x+2, branches[i].dst);
- _LineTo(dc, x-4, branches[i].dst);
-
- _MoveTo(x, branches[i].dst - 4);
- _LineTo(dc, x-4, branches[i].dst);
- _LineTo(dc, x+1, branches[i].dst+5);
- }
- else
- {
- _LineTo(dc, x+4, branches[i].src);
- //MoveToEx(hdc,x+2,branches[i].dst-4,0);
- //LineTo(hdc,x+6,branches[i].dst);
- //LineTo(hdc,x+1,branches[i].dst+5);
- }
-
- //LineTo(hdc,x,branches[i].dst+4);
- //LineTo(hdc,x-2,branches[i].dst);
- }
- // ------------
-}
-
-
-void CCodeView::_LineTo(wxPaintDC &dc, int x, int y)
-{
- dc.DrawLine(lx, ly, x, y);
- lx = x;
- ly = y;
-}
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "Debugger/PPCDebugInterface.h" +#include "PowerPC/SymbolDB.h" +#include "HW/Memmap.h" // for Write_U32 +#include "Common.h" +#include "StringUtil.h" + +#include "Host.h" +#include "CodeView.h" +#include "JitWindow.h" + +#include <wx/event.h> +#include <wx/clipbrd.h> +#include <wx/textdlg.h> + +DEFINE_EVENT_TYPE(wxEVT_CODEVIEW_CHANGE); + +enum +{ + IDM_GOTOINMEMVIEW = 12000, + IDM_COPYADDRESS, + IDM_COPYHEX, + IDM_COPYCODE, + IDM_INSERTBLR, + IDM_RUNTOHERE, + IDM_JITRESULTS, + IDM_FOLLOWBRANCH, + IDM_RENAMESYMBOL, + IDM_PATCHALERT, + IDM_COPYFUNCTION, +}; + + +BEGIN_EVENT_TABLE(CCodeView, wxControl) + EVT_ERASE_BACKGROUND(CCodeView::OnErase) + EVT_PAINT(CCodeView::OnPaint) + EVT_LEFT_DOWN(CCodeView::OnMouseDown) + EVT_LEFT_UP(CCodeView::OnMouseUpL) + EVT_MOTION(CCodeView::OnMouseMove) + EVT_RIGHT_DOWN(CCodeView::OnMouseDown) + EVT_RIGHT_UP(CCodeView::OnMouseUpR) + EVT_MENU(-1, CCodeView::OnPopupMenu) +END_EVENT_TABLE() + +CCodeView::CCodeView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id, const wxSize& Size) + : wxControl(parent, Id, wxDefaultPosition, Size), + debugger(debuginterface), + rowHeight(13), + selection(0), + oldSelection(0), + selectionChanged(false), + selecting(false), + hasFocus(false), + showHex(false), + lx(-1), + ly(-1) +{ + rowHeight = 13; + align = debuginterface->getInstructionSize(0); + curAddress = debuginterface->getPC(); + selection = 0; +} + + +wxSize CCodeView::DoGetBestSize() const +{ + wxSize bestSize; + bestSize.x = 400; + bestSize.y = 800; + return(bestSize); +} + + +int CCodeView::YToAddress(int y) +{ + wxRect rc = GetClientRect(); + int ydiff = y - rc.height / 2 - rowHeight / 2; + ydiff = (int)(floorf((float)ydiff / (float)rowHeight)) + 1; + return(curAddress + ydiff * align); +} + + +void CCodeView::OnMouseDown(wxMouseEvent& event) +{ + int x = event.m_x; + int y = event.m_y; + + if (x > 16) + { + oldSelection = selection; + selection = YToAddress(y); + // SetCapture(wnd); + bool oldselecting = selecting; + selecting = true; + + if (!oldselecting || (selection != oldSelection)) + { + redraw(); + } + } + else + { + debugger->toggleBreakpoint(YToAddress(y)); + redraw(); + } + + event.Skip(true); +} + + +void CCodeView::OnMouseMove(wxMouseEvent& event) +{ + wxRect rc = GetClientRect(); + + if (event.m_leftDown) + { + if (event.m_x > 16) + { + if (event.m_y < 0) + { + curAddress -= align; + redraw(); + } + else if (event.m_y > rc.height) + { + curAddress += align; + redraw(); + } + else + { + OnMouseDown(event); + } + } + } + + event.Skip(true); +} + +void CCodeView::RaiseEvent() +{ + wxCommandEvent ev(wxEVT_CODEVIEW_CHANGE, GetId()); + ev.SetEventObject(this); + ev.SetInt(selection); + GetEventHandler()->ProcessEvent(ev); +} + +void CCodeView::OnMouseUpL(wxMouseEvent& event) +{ + if (event.m_x > 16) + { + curAddress = YToAddress(event.m_y); + selecting = false; + //ReleaseCapture(); + redraw(); + } + RaiseEvent(); + event.Skip(true); +} + +u32 CCodeView::AddrToBranch(u32 addr) +{ + const char *temp = debugger->disasm(addr); + const char *mojs = strstr(temp, "->0x"); + if (mojs) + { + u32 dest; + sscanf(mojs+4,"%08x", &dest); + return dest; + } + return 0; +} + +void CCodeView::OnPopupMenu(wxCommandEvent& event) +{ +#if wxUSE_CLIPBOARD + wxTheClipboard->Open(); +#endif + + switch (event.GetId()) + { + case IDM_GOTOINMEMVIEW: + // CMemoryDlg::Goto(selection); + break; + +#if wxUSE_CLIPBOARD + case IDM_COPYADDRESS: + wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%08x"), selection))); + break; + + case IDM_COPYCODE: + wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(debugger->disasm(selection)))); //Have to manually convert from char* to wxString, don't have to in Windows? + break; + + case IDM_COPYHEX: + { + char temp[24]; + sprintf(temp, "%08x", debugger->readInstruction(selection)); + wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(temp))); + } + break; + case IDM_COPYFUNCTION: + { + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(selection); + if (symbol) { + std::string text; + text = text + symbol->name + "\r\n"; + // we got a function + u32 start = symbol->address; + u32 end = start + symbol->size; + for (u32 addr = start; addr != end; addr += 4) { + text = text + StringFromFormat("%08x: ", addr) + debugger->disasm(addr) + "\r\n"; + } + wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(text.c_str()))); + } + } + break; +#endif + + case IDM_RUNTOHERE: + debugger->setBreakpoint(selection); + debugger->runToBreakpoint(); + redraw(); + break; + + // Insert blr or restore old value + case IDM_INSERTBLR: + { + // Check if this address has been modified + int find = -1; + for(u32 i = 0; i < BlrList.size(); i++) + { + if(BlrList.at(i).Address == selection) + { find = i; break; } + } + + // Save the old value + if(find >= 0) + { + Memory::Write_U32(BlrList.at(find).OldValue, selection); + BlrList.erase(BlrList.begin() + find); + } + else + { + BlrStruct Temp; + Temp.Address = selection; + Temp.OldValue = debugger->readMemory(selection); + BlrList.push_back(Temp); + debugger->insertBLR(selection); + } + redraw(); + } + break; + + case IDM_JITRESULTS: + CJitWindow::ViewAddr(selection); + break; + + case IDM_FOLLOWBRANCH: + { + u32 dest = AddrToBranch(selection); + if (dest) + Center(dest); + RaiseEvent(); + } + break; + + case IDM_RENAMESYMBOL: + { + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(selection); + if (symbol) { + wxTextEntryDialog input_symbol(this, wxString::FromAscii("Rename symbol:"), wxGetTextFromUserPromptStr, + wxString::FromAscii(symbol->name.c_str())); + if (input_symbol.ShowModal() == wxID_OK) { + symbol->name = input_symbol.GetValue().mb_str(); + } +// redraw(); + Host_NotifyMapLoaded(); + } + } + break; + + case IDM_PATCHALERT: + { + + } + break; + } + +#if wxUSE_CLIPBOARD + wxTheClipboard->Close(); +#endif + event.Skip(true); +} + + +void CCodeView::OnMouseUpR(wxMouseEvent& event) +{ + bool isSymbol = g_symbolDB.GetSymbolFromAddr(selection) != 0; + // popup menu + wxMenu menu; + //menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view"); + menu.Append(IDM_FOLLOWBRANCH, wxString::FromAscii("&Follow branch"))->Enable(AddrToBranch(selection) ? true : false); + menu.AppendSeparator(); +#if wxUSE_CLIPBOARD + menu.Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address")); + menu.Append(IDM_COPYFUNCTION, wxString::FromAscii("Copy &function"))->Enable(isSymbol); + menu.Append(IDM_COPYCODE, wxString::FromAscii("Copy &code line")); + menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex")); + menu.AppendSeparator(); +#endif + menu.Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol"))->Enable(isSymbol); + menu.AppendSeparator(); + menu.Append(IDM_RUNTOHERE, _T("&Run To Here")); + menu.Append(IDM_JITRESULTS, wxString::FromAscii("PPC vs X86")); + menu.Append(IDM_INSERTBLR, wxString::FromAscii("Insert &blr")); + menu.Append(IDM_PATCHALERT, wxString::FromAscii("Patch alert")); + PopupMenu(&menu); + event.Skip(true); +} + + +void CCodeView::OnErase(wxEraseEvent& event) +{} + + +void CCodeView::OnPaint(wxPaintEvent& event) +{ + // -------------------------------------------------------------------- + // General settings + // ------------------------- + wxPaintDC dc(this); + wxRect rc = GetClientRect(); + wxFont font(7, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT); + dc.SetFont(font); + struct branch + { + int src, dst, srcAddr; + }; + + branch branches[256]; + int numBranches = 0; + // TODO: Add any drawing code here... + int width = rc.width; + int numRows = (rc.height / rowHeight) / 2 + 2; + //numRows=(numRows&(~1)) + 1; + // ------------ + + + // -------------------------------------------------------------------- + // Colors and brushes + // ------------------------- + dc.SetBackgroundMode(wxTRANSPARENT); // the text background + const wxChar* bgColor = _T("#ffffff"); + wxPen nullPen(bgColor); + wxPen currentPen(_T("#000000")); + wxPen selPen(_T("#808080")); // gray + nullPen.SetStyle(wxTRANSPARENT); + currentPen.SetStyle(wxSOLID); + wxBrush currentBrush(_T("#FFEfE8")); // the ... ? ... is light gray + wxBrush pcBrush(_T("#70FF70")); // the selected code line is green + wxBrush bpBrush(_T("#FF3311")); // red + + wxBrush bgBrush(bgColor); + wxBrush nullBrush(bgColor); + nullBrush.SetStyle(wxTRANSPARENT); + + dc.SetPen(nullPen); + dc.SetBrush(bgBrush); + dc.DrawRectangle(0, 0, 16, rc.height); + dc.DrawRectangle(0, 0, rc.width, 5); + // ------------ + + + // -------------------------------------------------------------------- + // Walk through all visible rows + // ------------------------- + for (int i = -numRows; i <= numRows; i++) + { + unsigned int address = curAddress + i * align; + + int rowY1 = rc.height / 2 + rowHeight * i - rowHeight / 2; + int rowY2 = rc.height / 2 + rowHeight * i + rowHeight / 2; + + wxString temp = wxString::Format(_T("%08x"), address); + u32 col = debugger->getColor(address); + wxBrush rowBrush(wxColor(col >> 16, col >> 8, col)); + dc.SetBrush(nullBrush); + dc.SetPen(nullPen); + dc.DrawRectangle(0, rowY1, 16, rowY2 - rowY1 + 2); + + if (selecting && (address == selection)) + dc.SetPen(selPen); + else + dc.SetPen(i == 0 ? currentPen : nullPen); + + if (address == debugger->getPC()) + dc.SetBrush(pcBrush); + else + dc.SetBrush(rowBrush); + + dc.DrawRectangle(16, rowY1, width, rowY2 - rowY1 + 1); + dc.SetBrush(currentBrush); + dc.SetTextForeground(_T("#600000")); // the address text is dark red + dc.DrawText(temp, 17, rowY1); + dc.SetTextForeground(_T("#000000")); + + if (debugger->isAlive()) + { + char dis[256] = {0}; + strcpy(dis, debugger->disasm(address)); + char* dis2 = strchr(dis, '\t'); + char desc[256] = ""; + + // If we have a code + if (dis2) + { + *dis2 = 0; + dis2++; + const char* mojs = strstr(dis2, "0x8"); + + // -------------------------------------------------------------------- + // Colors and brushes + // ------------------------- + if (mojs) + { + for (int k = 0; k < 8; k++) + { + bool found = false; + + for (int j = 0; j < 22; j++) + { + if (mojs[k + 2] == "0123456789ABCDEFabcdef"[j]) + { + found = true; + } + } + if (!found) + { + mojs = 0; + break; + } + } + } + // ------------ + + + // -------------------------------------------------------------------- + // Colors and brushes + // ------------------------- + if (mojs) + { + int offs; + sscanf(mojs + 2, "%08x", &offs); + branches[numBranches].src = rowY1 + rowHeight / 2; + branches[numBranches].srcAddr = address / align; + branches[numBranches++].dst = (int)(rowY1 + ((s64)(u32)offs - (s64)(u32)address) * rowHeight / align + rowHeight / 2); + sprintf(desc, "-->%s", debugger->getDescription(offs).c_str()); + dc.SetTextForeground(_T("#600060")); // the -> arrow illustrations are purple + } + else + { + dc.SetTextForeground(_T("#000000")); + } + + dc.DrawText(wxString::FromAscii(dis2), 126, rowY1); + // ------------ + } + + // Show blr as its' own color + if (strcmp(dis, "blr")) + dc.SetTextForeground(_T("#007000")); // dark green + else + dc.SetTextForeground(_T("#8000FF")); // purple + + dc.DrawText(wxString::FromAscii(dis), 70, rowY1); + + if (desc[0] == 0) + { + strcpy(desc, debugger->getDescription(address).c_str()); + } + + dc.SetTextForeground(_T("#0000FF")); // blue + + //char temp[256]; + //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE); + if (strlen(desc)) + { + dc.DrawText(wxString::FromAscii(desc), 235, rowY1); + } + + // Show red breakpoint dot + if (debugger->isBreakpoint(address)) + { + dc.SetBrush(bpBrush); + dc.DrawRectangle(2, rowY1, 7, 7); + //DrawIconEx(hdc, 2, rowY1, breakPoint, 32, 32, 0, 0, DI_NORMAL); + } + } + } // end of for + // ------------ + + + // -------------------------------------------------------------------- + // Colors and brushes + // ------------------------- + dc.SetPen(currentPen); + + for (int i = 0; i < numBranches; i++) + { + int x = 300 + (branches[i].srcAddr % 9) * 8; + _MoveTo(x-2, branches[i].src); + + if (branches[i].dst < rc.height + 400 && branches[i].dst > -400) + { + _LineTo(dc, x+2, branches[i].src); + _LineTo(dc, x+2, branches[i].dst); + _LineTo(dc, x-4, branches[i].dst); + + _MoveTo(x, branches[i].dst - 4); + _LineTo(dc, x-4, branches[i].dst); + _LineTo(dc, x+1, branches[i].dst+5); + } + else + { + _LineTo(dc, x+4, branches[i].src); + //MoveToEx(hdc,x+2,branches[i].dst-4,0); + //LineTo(hdc,x+6,branches[i].dst); + //LineTo(hdc,x+1,branches[i].dst+5); + } + + //LineTo(hdc,x,branches[i].dst+4); + //LineTo(hdc,x-2,branches[i].dst); + } + // ------------ +} + + +void CCodeView::_LineTo(wxPaintDC &dc, int x, int y) +{ + dc.DrawLine(lx, ly, x, y); + lx = x; + ly = y; +} + diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index 42a6ad9376..dfe1489559 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -1,1234 +1,1234 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <wx/button.h>
-#include <wx/textctrl.h>
-#include <wx/textdlg.h>
-#include <wx/listctrl.h>
-#include <wx/thread.h>
-#include <wx/mstream.h>
-
-// ugly that this lib included code from the main
-#include "../../DolphinWX/Src/Globals.h"
-
-#include "IniFile.h"
-#include "Host.h"
-
-#include "Debugger.h"
-
-#include "RegisterWindow.h"
-#include "LogWindow.h"
-#include "BreakpointWindow.h"
-#include "MemoryWindow.h"
-#include "JitWindow.h"
-
-#include "CodeWindow.h"
-#include "CodeView.h"
-
-#include "FileUtil.h"
-#include "Core.h"
-#include "HLE/HLE.h"
-#include "Boot/Boot.h"
-#include "LogManager.h"
-#include "HW/CPU.h"
-#include "PowerPC/PowerPC.h"
-#include "Debugger/PPCDebugInterface.h"
-#include "Debugger/Debugger_SymbolMap.h"
-#include "PowerPC/PPCAnalyst.h"
-#include "PowerPC/Profiler.h"
-#include "PowerPC/SymbolDB.h"
-#include "PowerPC/SignatureDB.h"
-#include "PowerPC/PPCTables.h"
-#include "PowerPC/Jit64/Jit.h"
-#include "PowerPC/Jit64/JitCache.h" // for ClearCache()
-
-#include "Plugins/Plugin_DSP.h" // new stuff, to let us open the DLLDebugger
-#include "Plugins/Plugin_Video.h" // new stuff, to let us open the DLLDebugger
-#include "../../DolphinWX/Src/PluginManager.h"
-#include "../../DolphinWX/Src/Config.h"
-
-// and here are the classes
-class CPluginInfo;
-class CPluginManager;
-//extern DynamicLibrary Common::CPlugin;
-//extern CPluginManager CPluginManager::m_Instance;
-
-extern "C" {
- #include "../resources/toolbar_play.c"
- #include "../resources/toolbar_pause.c"
- #include "../resources/toolbar_add_memorycheck.c"
- #include "../resources/toolbar_delete.c"
- #include "../resources/toolbar_add_breakpoint.c"
-}
-
-static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT;
-
-BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
- EVT_LISTBOX(IDM_SYMBOLLIST, CCodeWindow::OnSymbolListChange)
- EVT_LISTBOX(IDM_CALLSTACKLIST, CCodeWindow::OnCallstackListChange)
- EVT_LISTBOX(IDM_CALLERSLIST, CCodeWindow::OnCallersListChange)
- EVT_LISTBOX(IDM_CALLSLIST, CCodeWindow::OnCallsListChange)
- EVT_HOST_COMMAND(wxID_ANY, CCodeWindow::OnHostMessage)
- EVT_MENU(IDM_LOGWINDOW, CCodeWindow::OnToggleLogWindow)
- EVT_MENU(IDM_REGISTERWINDOW, CCodeWindow::OnToggleRegisterWindow)
- EVT_MENU(IDM_BREAKPOINTWINDOW, CCodeWindow::OnToggleBreakPointWindow)
- EVT_MENU(IDM_MEMORYWINDOW, CCodeWindow::OnToggleMemoryWindow)
- EVT_MENU(IDM_JITWINDOW, CCodeWindow::OnToggleJitWindow)
- EVT_MENU(IDM_SOUNDWINDOW, CCodeWindow::OnToggleSoundWindow)
- EVT_MENU(IDM_VIDEOWINDOW, CCodeWindow::OnToggleVideoWindow)
-
- EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnInterpreter) // CPU Mode
- EVT_MENU(IDM_AUTOMATICSTART, CCodeWindow::OnAutomaticStart) // CPU Mode
- EVT_MENU(IDM_JITUNLIMITED, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITLSLXZOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITLSLWZOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITLSLBZXOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITLSFOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITLSPOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITFPOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITIOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITPOFF, CCodeWindow::OnJITOff)
- EVT_MENU(IDM_JITSROFF, CCodeWindow::OnJITOff)
-
- EVT_MENU(IDM_CLEARSYMBOLS, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_LOADMAPFILE, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_SCANFUNCTIONS, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_SAVEMAPFILE, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_SAVEMAPFILEWITHCODES, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_CREATESIGNATUREFILE, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_USESIGNATUREFILE, CCodeWindow::OnSymbolsMenu)
- EVT_MENU(IDM_PATCHHLEFUNCTIONS, CCodeWindow::OnSymbolsMenu)
-
- EVT_MENU(IDM_CLEARCODECACHE, CCodeWindow::OnJitMenu)
- EVT_MENU(IDM_LOGINSTRUCTIONS, CCodeWindow::OnJitMenu)
-
- EVT_MENU(IDM_PROFILEBLOCKS, CCodeWindow::OnProfilerMenu)
- EVT_MENU(IDM_WRITEPROFILE, CCodeWindow::OnProfilerMenu)
-
- // toolbar
- EVT_MENU(IDM_DEBUG_GO, CCodeWindow::OnCodeStep)
- EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep)
- EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep)
- EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep)
- EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep)
- EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep)
- EVT_TEXT(IDM_ADDRBOX, CCodeWindow::OnAddrBoxChange)
-
- EVT_COMMAND(IDM_CODEVIEW, wxEVT_CODEVIEW_CHANGE, CCodeWindow::OnCodeViewChange)
-END_EVENT_TABLE()
-
-#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name))
-inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length)
-{
- wxMemoryInputStream is(data, length);
- return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1));
-}
-
-// =======================================================================================
-// WARNING: If you create a new dialog window you must add m_dialog(NULL) below otherwise
-// m_dialog = true and things will crash.
-// ----------------
-CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter, wxWindow* parent, wxWindowID id,
- const wxString& title, const wxPoint& pos, const wxSize& size, long style)
- : wxFrame(parent, id, title, pos, size, style)
- , m_LogWindow(NULL)
- , m_RegisterWindow(NULL)
- , m_BreakpointWindow(NULL)
- , m_MemoryWindow(NULL)
- , m_JitWindow(NULL)
-{
- // Load ini settings
- IniFile file;
- file.Load(DEBUGGER_CONFIG_FILE);
- this->Load_(file);
-
- InitBitmaps();
-
- CreateGUIControls(_LocalCoreStartupParameter);
-
- // Create the toolbar
- RecreateToolbar();
-
- UpdateButtonStates();
-
- wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN,
- wxKeyEventHandler(CCodeWindow::OnKeyDown),
- (wxObject*)0, this);
-
- // Load settings for selectable windowses, but only if they have been created
- this->Load(file);
- if (m_BreakpointWindow) m_BreakpointWindow->Load(file);
- if (m_RegisterWindow) m_RegisterWindow->Load(file);
- if (m_MemoryWindow) m_MemoryWindow->Load(file);
- if (m_JitWindow) m_JitWindow->Load(file);
-}
-// ===============
-
-
-CCodeWindow::~CCodeWindow()
-{
- IniFile file;
- file.Load(DEBUGGER_CONFIG_FILE);
-
- this->Save(file);
- if (m_BreakpointWindow) m_BreakpointWindow->Save(file);
- if (m_LogWindow) m_LogWindow->Save(file);
- if (m_RegisterWindow) m_RegisterWindow->Save(file);
- if (m_MemoryWindow) m_MemoryWindow->Save(file);
- if (m_JitWindow) m_JitWindow->Save(file);
-
- file.Save(DEBUGGER_CONFIG_FILE);
-}
-
-
-// =======================================================================================
-// Load before CreateGUIControls()
-// --------------
-void CCodeWindow::Load_( IniFile &ini )
-{
-
- // Decide what windows to use
- ini.Get("ShowOnStart", "LogWindow", &bLogWindow, true);
- ini.Get("ShowOnStart", "RegisterWindow", &bRegisterWindow, true);
- ini.Get("ShowOnStart", "BreakpointWindow", &bBreakpointWindow, true);
- ini.Get("ShowOnStart", "MemoryWindow", &bMemoryWindow, true);
- ini.Get("ShowOnStart", "JitWindow", &bJitWindow, true);
- ini.Get("ShowOnStart", "SoundWindow", &bSoundWindow, false);
- ini.Get("ShowOnStart", "VideoWindow", &bVideoWindow, false);
- // ===============
-
- // Boot to pause or not
- ini.Get("ShowOnStart", "AutomaticStart", &bAutomaticStart, false);
-}
-
-
-void CCodeWindow::Load( IniFile &ini )
-{
- int x,y,w,h;
- ini.Get("CodeWindow", "x", &x, GetPosition().x);
- ini.Get("CodeWindow", "y", &y, GetPosition().y);
- ini.Get("CodeWindow", "w", &w, GetSize().GetWidth());
- ini.Get("CodeWindow", "h", &h, GetSize().GetHeight());
- this->SetSize(x, y, w, h);
-}
-
-
-void CCodeWindow::Save(IniFile &ini) const
-{
- ini.Set("CodeWindow", "x", GetPosition().x);
- ini.Set("CodeWindow", "y", GetPosition().y);
- ini.Set("CodeWindow", "w", GetSize().GetWidth());
- ini.Set("CodeWindow", "h", GetSize().GetHeight());
-
- // Boot to pause or not
- ini.Set("ShowOnStart", "AutomaticStart", GetMenuBar()->IsChecked(IDM_AUTOMATICSTART));
-
- // Save windows settings
- ini.Set("ShowOnStart", "LogWindow", GetMenuBar()->IsChecked(IDM_LOGWINDOW));
- ini.Set("ShowOnStart", "RegisterWindow", GetMenuBar()->IsChecked(IDM_REGISTERWINDOW));
- ini.Set("ShowOnStart", "BreakpointWindow", GetMenuBar()->IsChecked(IDM_BREAKPOINTWINDOW));
- ini.Set("ShowOnStart", "MemoryWindow", GetMenuBar()->IsChecked(IDM_MEMORYWINDOW));
- ini.Set("ShowOnStart", "JitWindow", GetMenuBar()->IsChecked(IDM_JITWINDOW));
- ini.Set("ShowOnStart", "SoundWindow", GetMenuBar()->IsChecked(IDM_SOUNDWINDOW));
- ini.Set("ShowOnStart", "VideoWindow", GetMenuBar()->IsChecked(IDM_VIDEOWINDOW));
-}
-
-
-void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter)
-{
- CreateMenu(_LocalCoreStartupParameter);
-
- // =======================================================================================
- // Configure the code window
- wxBoxSizer* sizerBig = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
-
- DebugInterface* di = new PPCDebugInterface();
-
- codeview = new CCodeView(di, this, IDM_CODEVIEW);
- sizerBig->Add(sizerLeft, 2, wxEXPAND);
- sizerBig->Add(codeview, 5, wxEXPAND);
-
- sizerLeft->Add(callstack = new wxListBox(this, IDM_CALLSTACKLIST, wxDefaultPosition, wxSize(90, 100)), 0, wxEXPAND);
- sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND);
- sizerLeft->Add(calls = new wxListBox(this, IDM_CALLSLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 0, wxEXPAND);
- sizerLeft->Add(callers = new wxListBox(this, IDM_CALLERSLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 0, wxEXPAND);
-
- SetSizer(sizerBig);
-
- sizerLeft->SetSizeHints(this);
- sizerLeft->Fit(this);
- sizerBig->SetSizeHints(this);
- sizerBig->Fit(this);
-
- sync_event.Init();
- // =================
-
-
- // additional dialogs
- if (IsLoggingActivated() && bLogWindow)
- {
- m_LogWindow = new CLogWindow(this);
- m_LogWindow->Show(true);
- }
-
- if (bRegisterWindow)
- {
- m_RegisterWindow = new CRegisterWindow(this);
- m_RegisterWindow->Show(true);
- }
-
- if(bBreakpointWindow)
- {
- m_BreakpointWindow = new CBreakPointWindow(this, this);
- m_BreakpointWindow->Show(true);
- }
-
- if(bMemoryWindow)
- {
- m_MemoryWindow = new CMemoryWindow(this);
- m_MemoryWindow->Show(true);
- }
-
- if(bJitWindow)
- {
- m_JitWindow = new CJitWindow(this);
- m_JitWindow->Show(true);
- }
-
- if(bSoundWindow)
- {
- // possible todo: add some kind of if here to? can it fail?
- CPluginManager::GetInstance().OpenDebug(
- GetHandle(),
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(),
- false, true
- );
- } // don't have any else, just ignore it
-
- if(bVideoWindow)
- {
- // possible todo: add some kind of if here to? can it fail?
- CPluginManager::GetInstance().OpenDebug(
- GetHandle(),
- _LocalCoreStartupParameter.m_strVideoPlugin.c_str(),
- true, true
- );
- } // don't have any else, just ignore it
-}
-
-
-void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter)
-{
-
- // =======================================================================================
- // Windowses
- // ---------------
- wxMenuBar* pMenuBar = new wxMenuBar(wxMB_DOCKABLE);
-
- {
- wxMenu* pCoreMenu = new wxMenu;
-
- wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter core"), wxEmptyString, wxITEM_CHECK);
- interpreter->Check(!_LocalCoreStartupParameter.bUseJIT);
- pCoreMenu->AppendSeparator();
- wxMenuItem* automaticstart = pCoreMenu->Append(IDM_AUTOMATICSTART, _T("&Automatic start"), wxEmptyString, wxITEM_CHECK);
- automaticstart->Check(bAutomaticStart);
- pCoreMenu->AppendSeparator();
-
-#ifdef JIT_OFF_OPTIONS
- jitunlimited = pCoreMenu->Append(IDM_JITUNLIMITED, _T("&Unlimited JIT Cache"), wxEmptyString, wxITEM_CHECK);
- pCoreMenu->AppendSeparator();
- jitoff = pCoreMenu->Append(IDM_JITOFF, _T("&JIT off (JIT core)"), wxEmptyString, wxITEM_CHECK);
- jitlsoff = pCoreMenu->Append(IDM_JITLSOFF, _T("&JIT LoadStore off"), wxEmptyString, wxITEM_CHECK);
- jitlslbzxoff = pCoreMenu->Append(IDM_JITLSLBZXOFF, _T(" &JIT LoadStore lbzx off"), wxEmptyString, wxITEM_CHECK);
- jitlslxzoff = pCoreMenu->Append(IDM_JITLSLXZOFF, _T(" &JIT LoadStore lXz off"), wxEmptyString, wxITEM_CHECK);
- jitlslwzoff = pCoreMenu->Append(IDM_JITLSLWZOFF, _T(" &JIT LoadStore lwz off"), wxEmptyString, wxITEM_CHECK);
- jitlspoff = pCoreMenu->Append(IDM_JITLSFOFF, _T("&JIT LoadStore Floating off"), wxEmptyString, wxITEM_CHECK);
- jitlsfoff = pCoreMenu->Append(IDM_JITLSPOFF, _T("&JIT LoadStore Paired off"), wxEmptyString, wxITEM_CHECK);
- jitfpoff = pCoreMenu->Append(IDM_JITFPOFF, _T("&JIT FloatingPoint off"), wxEmptyString, wxITEM_CHECK);
- jitioff = pCoreMenu->Append(IDM_JITIOFF, _T("&JIT Integer off"), wxEmptyString, wxITEM_CHECK);
- jitpoff = pCoreMenu->Append(IDM_JITPOFF, _T("&JIT Paired off"), wxEmptyString, wxITEM_CHECK);
- jitsroff = pCoreMenu->Append(IDM_JITSROFF, _T("&JIT SystemRegisters off"), wxEmptyString, wxITEM_CHECK);
-#endif
-
-// wxMenuItem* dualcore = pDebugMenu->Append(IDM_DUALCORE, _T("&DualCore"), wxEmptyString, wxITEM_CHECK);
-// dualcore->Check(_LocalCoreStartupParameter.bUseDualCore);
-
- pMenuBar->Append(pCoreMenu, _T("&CPU Mode"));
-
- }
-
- {
- wxMenu* pDebugDialogs = new wxMenu;
-
- if (IsLoggingActivated())
- {
- wxMenuItem* pLogWindow = pDebugDialogs->Append(IDM_LOGWINDOW, _T("&LogManager"), wxEmptyString, wxITEM_CHECK);
- pLogWindow->Check(bLogWindow);
- }
-
- wxMenuItem* pRegister = pDebugDialogs->Append(IDM_REGISTERWINDOW, _T("&Registers"), wxEmptyString, wxITEM_CHECK);
- pRegister->Check(bRegisterWindow);
-
- wxMenuItem* pBreakPoints = pDebugDialogs->Append(IDM_BREAKPOINTWINDOW, _T("&BreakPoints"), wxEmptyString, wxITEM_CHECK);
- pBreakPoints->Check(bBreakpointWindow);
-
- wxMenuItem* pMemory = pDebugDialogs->Append(IDM_MEMORYWINDOW, _T("&Memory"), wxEmptyString, wxITEM_CHECK);
- pMemory->Check(bMemoryWindow);
-
- wxMenuItem* pJit = pDebugDialogs->Append(IDM_JITWINDOW, _T("&Jit"), wxEmptyString, wxITEM_CHECK);
- pJit->Check(bJitWindow);
-
- wxMenuItem* pSound = pDebugDialogs->Append(IDM_SOUNDWINDOW, _T("&Sound"), wxEmptyString, wxITEM_CHECK);
- pSound->Check(bSoundWindow);
-
- wxMenuItem* pVideo = pDebugDialogs->Append(IDM_VIDEOWINDOW, _T("&Video"), wxEmptyString, wxITEM_CHECK);
- pVideo->Check(bVideoWindow);
-
- pMenuBar->Append(pDebugDialogs, _T("&Views"));
- }
- // ===============
-
-
- {
- wxMenu *pSymbolsMenu = new wxMenu;
- pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols"));
- // pSymbolsMenu->Append(IDM_CLEANSYMBOLS, _T("&Clean symbols (zz)"));
- pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map"));
- pSymbolsMenu->AppendSeparator();
- pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map"));
- pSymbolsMenu->Append(IDM_SAVEMAPFILE, _T("&Save symbol map"));
- pSymbolsMenu->AppendSeparator();
- pSymbolsMenu->Append(IDM_SAVEMAPFILEWITHCODES, _T("Save code"));
- pSymbolsMenu->AppendSeparator();
- pSymbolsMenu->Append(IDM_CREATESIGNATUREFILE, _T("&Create signature file..."));
- pSymbolsMenu->Append(IDM_USESIGNATUREFILE, _T("&Use signature file..."));
- pSymbolsMenu->AppendSeparator();
- pSymbolsMenu->Append(IDM_PATCHHLEFUNCTIONS, _T("&Patch HLE functions"));
- pMenuBar->Append(pSymbolsMenu, _T("&Symbols"));
- }
-
- {
- wxMenu *pJitMenu = new wxMenu;
- pJitMenu->Append(IDM_CLEARCODECACHE, _T("&Clear code cache"));
- pJitMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage"));
- pMenuBar->Append(pJitMenu, _T("&JIT"));
- }
-
- {
- wxMenu *pProfilerMenu = new wxMenu;
- pProfilerMenu->Append(IDM_PROFILEBLOCKS, _T("&Profile blocks"), wxEmptyString, wxITEM_CHECK);
- pProfilerMenu->AppendSeparator();
- pProfilerMenu->Append(IDM_WRITEPROFILE, _T("&Write to profile.txt, show"));
- pMenuBar->Append(pProfilerMenu, _T("&Profiler"));
- }
-
-
- SetMenuBar(pMenuBar);
-}
-
-
-bool CCodeWindow::UseInterpreter()
-{
- return GetMenuBar()->IsChecked(IDM_INTERPRETER);
-}
-
-bool CCodeWindow::AutomaticStart()
-{
- return GetMenuBar()->IsChecked(IDM_AUTOMATICSTART);
-}
-
-bool CCodeWindow::UseDualCore()
-{
- return GetMenuBar()->IsChecked(IDM_DUALCORE);
-}
-
-
-// =======================================================================================
-// CPU Mode
-// --------------
-void CCodeWindow::OnInterpreter(wxCommandEvent& event)
-{
- if (Core::GetState() != Core::CORE_RUN) {
- PowerPC::SetMode(UseInterpreter() ? PowerPC::MODE_INTERPRETER : PowerPC::MODE_JIT);
- } else {
- event.Skip();
- wxMessageBox(_T("Please pause the emulator before changing mode."));
- }
-}
-
-
-void CCodeWindow::OnAutomaticStart(wxCommandEvent& event)
-{
- bAutomaticStart = !bAutomaticStart;
-}
-
-
-void CCodeWindow::OnJITOff(wxCommandEvent& event)
-{
- if (Core::GetState() == Core::CORE_UNINITIALIZED)
- {
- // we disallow changing the status here because it will be reset to the defult when BootCore()
- // creates the SCoreStartupParameter as a game is loaded
- GetMenuBar()->Check(event.GetId(),!event.IsChecked());
- wxMessageBox(_T("Please start a game before changing mode."));
- } else {
- if (Core::GetState() != Core::CORE_RUN)
- {
- switch (event.GetId())
- {
- case IDM_JITUNLIMITED:
- Core::g_CoreStartupParameter.bJITUnlimitedCache = event.IsChecked();
- Jit64::ClearCache(); // allow InitCache() even after the game has started
- Jit64::InitCache();
- GetMenuBar()->Enable(event.GetId(),!event.IsChecked());
- break;
- case IDM_JITOFF:
- Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break;
- case IDM_JITLSOFF:
- Core::g_CoreStartupParameter.bJITLoadStoreOff = event.IsChecked(); break;
- case IDM_JITLSLXZOFF:
- Core::g_CoreStartupParameter.bJITLoadStorelXzOff = event.IsChecked(); break;
- case IDM_JITLSLWZOFF:
- Core::g_CoreStartupParameter.bJITLoadStorelwzOff = event.IsChecked(); break;
- case IDM_JITLSLBZXOFF:
- Core::g_CoreStartupParameter.bJITLoadStorelbzxOff = event.IsChecked(); break;
- case IDM_JITLSFOFF:
- Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff = event.IsChecked(); break;
- case IDM_JITLSPOFF:
- Core::g_CoreStartupParameter.bJITLoadStorePairedOff = event.IsChecked(); break;
- case IDM_JITFPOFF:
- Core::g_CoreStartupParameter.bJITFloatingPointOff = event.IsChecked(); break;
- case IDM_JITIOFF:
- Core::g_CoreStartupParameter.bJITIntegerOff = event.IsChecked(); break;
- case IDM_JITPOFF:
- Core::g_CoreStartupParameter.bJITPairedOff = event.IsChecked(); break;
- case IDM_JITSROFF:
- Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break;
- }
- Jit64::ClearCache();
- } else {
- //event.Skip(); // this doesn't work
- GetMenuBar()->Check(event.GetId(),!event.IsChecked());
- wxMessageBox(_T("Please pause the emulator before changing mode."));
- }
- }
-}
-// ==============
-
-
-void CCodeWindow::OnJitMenu(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case IDM_CLEARCODECACHE:
- Jit64::ClearCache();
- break;
- case IDM_LOGINSTRUCTIONS:
- PPCTables::LogCompiledInstructions();
- break;
- }
-}
-
-void CCodeWindow::OnProfilerMenu(wxCommandEvent& event)
-{
- if (Core::GetState() == Core::CORE_RUN) {
- event.Skip();
- return;
- }
- switch (event.GetId())
- {
- case IDM_PROFILEBLOCKS:
- Jit64::ClearCache();
- Profiler::g_ProfileBlocks = GetMenuBar()->IsChecked(IDM_PROFILEBLOCKS);
- break;
- case IDM_WRITEPROFILE:
- Profiler::WriteProfileResults("profiler.txt");
- File::Launch("profiler.txt");
- break;
- }
-}
-
-void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
-{
- if (Core::GetState() == Core::CORE_UNINITIALIZED)
- {
- // TODO: disable menu items instead :P
- return;
- }
- std::string mapfile = CBoot::GenerateMapFilename();
- switch (event.GetId())
- {
- case IDM_CLEARSYMBOLS:
- g_symbolDB.Clear();
- Host_NotifyMapLoaded();
- break;
- case IDM_CLEANSYMBOLS:
- g_symbolDB.Clear("zz");
- Host_NotifyMapLoaded();
- break;
- case IDM_SCANFUNCTIONS:
- {
- PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB);
- SignatureDB db;
- if (db.Load(TOTALDB_FILE))
- db.Apply(&g_symbolDB);
-
- // HLE::PatchFunctions();
- NotifyMapLoaded();
- break;
- }
- case IDM_LOADMAPFILE:
- if (!File::Exists(mapfile.c_str()))
- {
- g_symbolDB.Clear();
- PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB);
- SignatureDB db;
- if (db.Load(TOTALDB_FILE))
- db.Apply(&g_symbolDB);
- } else {
- g_symbolDB.LoadMap(mapfile.c_str());
- }
- NotifyMapLoaded();
- break;
- case IDM_SAVEMAPFILE:
- g_symbolDB.SaveMap(mapfile.c_str());
- break;
- case IDM_SAVEMAPFILEWITHCODES:
- g_symbolDB.SaveMap(mapfile.c_str(), true);
- break;
- case IDM_CREATESIGNATUREFILE:
- {
- wxTextEntryDialog input_prefix(this, wxString::FromAscii("Only export symbols with prefix:"), wxGetTextFromUserPromptStr, _T("."));
- if (input_prefix.ShowModal() == wxID_OK) {
- std::string prefix(input_prefix.GetValue().mb_str());
-
- wxString path = wxFileSelector(
- _T("Save signature as"), wxEmptyString, wxEmptyString, wxEmptyString,
- _T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_SAVE,
- this);
- if (path) {
- SignatureDB db;
- db.Initialize(&g_symbolDB, prefix.c_str());
- std::string filename(path.ToAscii()); // PPCAnalyst::SaveSignatureDB(
- db.Save(path.ToAscii());
- }
- }
- }
- break;
- case IDM_USESIGNATUREFILE:
- {
- wxString path = wxFileSelector(
- _T("Apply signature file"), wxEmptyString, wxEmptyString, wxEmptyString,
- _T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_OPEN | wxFD_FILE_MUST_EXIST,
- this);
- if (path) {
- SignatureDB db;
- db.Load(path.ToAscii());
- db.Apply(&g_symbolDB);
- }
- }
- NotifyMapLoaded();
- break;
- case IDM_PATCHHLEFUNCTIONS:
- HLE::PatchFunctions();
- Update();
- break;
- }
-}
-
-// =======================================================================================
-// The Play, Stop, Step, Skip, Go to PC and Show PC buttons all go here
-// --------------
-void CCodeWindow::OnCodeStep(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case IDM_DEBUG_GO:
- {
- // [F|RES] prolly we should disable the other buttons in go mode too ...
- JumpToAddress(PC);
-
- if (CCPU::IsStepping())
- {
- CCPU::EnableStepping(false);
- }
- else
- {
- CCPU::EnableStepping(true);
- Host_UpdateLogDisplay();
- }
-
- Update();
- }
- break;
-
- case IDM_STEP:
- SingleCPUStep();
-
- break;
-
- case IDM_STEPOVER:
- CCPU::EnableStepping(true);
- break;
-
- case IDM_SKIP:
- PC += 4;
- Update();
- break;
-
- case IDM_SETPC:
- PC = codeview->GetSelection();
- Update();
- break;
-
- case IDM_GOTOPC:
- JumpToAddress(PC);
- break;
- }
-
- UpdateButtonStates();
-}
-
-
-void CCodeWindow::JumpToAddress(u32 _Address)
-{
- codeview->Center(_Address);
- UpdateLists();
-}
-
-
-void CCodeWindow::UpdateLists()
-{
- callers->Clear();
- u32 addr = codeview->GetSelection();
- Symbol *symbol = g_symbolDB.GetSymbolFromAddr(addr);
- if (!symbol)
- return;
- for (int i = 0; i < (int)symbol->callers.size(); i++)
- {
- u32 caller_addr = symbol->callers[i].callAddress;
- Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr);
- if (caller_symbol) {
- int idx = callers->Append(wxString::Format( wxT("< %s (%08x)"), caller_symbol->name.c_str(), caller_addr));
- callers->SetClientData(idx, (void*)caller_addr);
- }
- }
-
- calls->Clear();
- for (int i = 0; i < (int)symbol->calls.size(); i++)
- {
- u32 call_addr = symbol->calls[i].function;
- Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr);
- if (call_symbol) {
- int idx = calls->Append(wxString::Format(_T("> %s (%08x)"), call_symbol->name.c_str(), call_addr));
- calls->SetClientData(idx, (void*)call_addr);
- }
- }
-}
-
-
-void CCodeWindow::OnCodeViewChange(wxCommandEvent &event)
-{
- //PanicAlert("boo");
- UpdateLists();
-}
-
-void CCodeWindow::OnAddrBoxChange(wxCommandEvent& event)
-{
- wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(IDM_ADDRBOX);
- wxString txt = pAddrCtrl->GetValue();
-
- std::string text(txt.mb_str());
- text = StripSpaces(text);
- if (text.size() == 8)
- {
- u32 addr;
- sscanf(text.c_str(), "%08x", &addr);
- JumpToAddress(addr);
- }
-
- event.Skip(1);
-}
-
-void CCodeWindow::OnCallstackListChange(wxCommandEvent& event)
-{
- int index = callstack->GetSelection();
- if (index >= 0) {
- u32 address = (u32)(u64)(callstack->GetClientData(index));
- if (address)
- JumpToAddress(address);
- }
-}
-
-void CCodeWindow::OnCallersListChange(wxCommandEvent& event)
-{
- int index = callers->GetSelection();
- if (index >= 0) {
- u32 address = (u32)(u64)(callers->GetClientData(index));
- if (address)
- JumpToAddress(address);
- }
-}
-
-void CCodeWindow::OnCallsListChange(wxCommandEvent& event)
-{
- int index = calls->GetSelection();
- if (index >= 0) {
- u32 address = (u32)(u64)(calls->GetClientData(index));
- if (address)
- JumpToAddress(address);
- }
-}
-
-void CCodeWindow::Update()
-{
- codeview->Refresh();
- callstack->Clear();
-
- std::vector<Debugger::CallstackEntry> stack;
-
- if (Debugger::GetCallstack(stack))
- {
- for (size_t i = 0; i < stack.size(); i++)
- {
- int idx = callstack->Append(wxString::FromAscii(stack[i].Name.c_str()));
- callstack->SetClientData(idx, (void*)(u64)stack[i].vAddress);
- }
- }
- else
- {
- callstack->Append(wxString::FromAscii("invalid callstack"));
- }
-
- UpdateButtonStates();
-
- /* Automatically show the current PC position when a breakpoint is hit or
- when we pause */
- codeview->Center(PC);
-}
-
-
-void CCodeWindow::NotifyMapLoaded()
-{
- g_symbolDB.FillInCallers();
- symbols->Show(false); // hide it for faster filling
- symbols->Clear();
- for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++)
- {
- int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str()));
- symbols->SetClientData(idx, (void*)&iter->second);
- }
- symbols->Show(true);
- Update();
-}
-
-
-void CCodeWindow::UpdateButtonStates()
-{
- wxToolBar* toolBar = GetToolBar();
- if (Core::GetState() == Core::CORE_UNINITIALIZED)
- {
- toolBar->EnableTool(IDM_DEBUG_GO, false);
- toolBar->EnableTool(IDM_STEP, false);
- toolBar->EnableTool(IDM_STEPOVER, false);
- toolBar->EnableTool(IDM_SKIP, false);
- }
- else
- {
- if (!CCPU::IsStepping())
- {
- toolBar->SetToolShortHelp(IDM_DEBUG_GO, _T("&Pause"));
- toolBar->SetToolNormalBitmap(IDM_DEBUG_GO, m_Bitmaps[Toolbar_Pause]);
- toolBar->EnableTool(IDM_DEBUG_GO, true);
- toolBar->EnableTool(IDM_STEP, false);
- toolBar->EnableTool(IDM_STEPOVER, false);
- toolBar->EnableTool(IDM_SKIP, false);
- }
- else
- {
- toolBar->SetToolShortHelp(IDM_DEBUG_GO, _T("&Play"));
- toolBar->SetToolNormalBitmap(IDM_DEBUG_GO, m_Bitmaps[Toolbar_DebugGo]);
- toolBar->EnableTool(IDM_DEBUG_GO, true);
- toolBar->EnableTool(IDM_STEP, true);
- toolBar->EnableTool(IDM_STEPOVER, true);
- toolBar->EnableTool(IDM_SKIP, true);
- }
- }
-}
-
-
-void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
-{
- int index = symbols->GetSelection();
- if (index >= 0) {
- Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
- if (pSymbol != NULL)
- {
- if(pSymbol->type == Symbol::SYMBOL_DATA)
- {
- if(m_MemoryWindow && m_MemoryWindow->IsVisible())
- m_MemoryWindow->JumpToAddress(pSymbol->address);
- }
- else
- {
- JumpToAddress(pSymbol->address);
- }
- }
- }
-}
-
-void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event)
-{
-}
-
-
-void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event)
-{
- if (IsLoggingActivated())
- {
- bool show = GetMenuBar()->IsChecked(event.GetId());
-
- if (show)
- {
- if (!m_LogWindow)
- {
- m_LogWindow = new CLogWindow(this);
- }
-
- m_LogWindow->Show(true);
- }
- else // hide
- {
- // If m_dialog is NULL, then possibly the system
- // didn't report the checked menu item status correctly.
- // It should be true just after the menu item was selected,
- // if there was no modeless dialog yet.
- wxASSERT(m_LogWindow != NULL);
-
- if (m_LogWindow)
- {
- m_LogWindow->Hide();
- }
- }
- }
-}
-
-
-void CCodeWindow::OnToggleRegisterWindow(wxCommandEvent& event)
-{
- bool show = GetMenuBar()->IsChecked(event.GetId());
-
- if (show)
- {
- if (!m_RegisterWindow)
- {
- m_RegisterWindow = new CRegisterWindow(this);
- }
-
- m_RegisterWindow->Show(true);
- }
- else // hide
- {
- // If m_dialog is NULL, then possibly the system
- // didn't report the checked menu item status correctly.
- // It should be true just after the menu item was selected,
- // if there was no modeless dialog yet.
- wxASSERT(m_RegisterWindow != NULL);
-
- if (m_RegisterWindow)
- {
- m_RegisterWindow->Hide();
- }
- }
-}
-
-
-// =======================================================================================
-// Toggle Sound Debugging Window
-// ------------
-void CCodeWindow::OnToggleSoundWindow(wxCommandEvent& event)
-{
- bool show = GetMenuBar()->IsChecked(event.GetId());
-
- if (show)
- {
- // TODO: add some kind of if() check here to?
- CPluginManager::GetInstance().OpenDebug(
- GetHandle(),
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(),
- false, true // DSP, show
- );
- }
- else // hide
- {
- // Close the sound dll that has an open debugger
- CPluginManager::GetInstance().OpenDebug(
- GetHandle(),
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(),
- false, false // DSP, hide
- );
- }
-}
-// ===========
-
-
-// =======================================================================================
-// Toggle Video Debugging Window
-// ------------
-void CCodeWindow::OnToggleVideoWindow(wxCommandEvent& event)
-{
- bool show = GetMenuBar()->IsChecked(event.GetId());
- //GetMenuBar()->Check(event.GetId(), false); // Turn off
-
- if (show)
- {
- // It works now, but I'll keep this message in case the problem reappears
- /*if(Core::GetState() == Core::CORE_UNINITIALIZED)
- {
- wxMessageBox(_T("Warning, opening this window before a game is started \n\
-may cause a crash when a game is later started. Todo: figure out why and fix it."), wxT("OpenGL Debugging Window"));
- }*/
-
- // TODO: add some kind of if() check here to?
- CPluginManager::GetInstance().OpenDebug(
- GetHandle(),
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(),
- true, true // Video, show
- );
- }
- else // hide
- {
- // Close the video dll that has an open debugger
- CPluginManager::GetInstance().OpenDebug(
- GetHandle(),
- SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(),
- true, false // Video, hide
- );
- }
-}
-// ===========
-
-
-void CCodeWindow::OnToggleJitWindow(wxCommandEvent& event)
-{
- bool show = GetMenuBar()->IsChecked(event.GetId());
-
- if (show)
- {
- if (!m_JitWindow)
- {
- m_JitWindow = new CJitWindow(this);
- }
-
- m_JitWindow->Show(true);
- }
- else // hide
- {
- // If m_dialog is NULL, then possibly the system
- // didn't report the checked menu item status correctly.
- // It should be true just after the menu item was selected,
- // if there was no modeless dialog yet.
- wxASSERT(m_JitWindow != NULL);
-
- if (m_JitWindow)
- {
- m_JitWindow->Hide();
- }
- }
-}
-
-
-void CCodeWindow::OnToggleBreakPointWindow(wxCommandEvent& event)
-{
- bool show = GetMenuBar()->IsChecked(event.GetId());
-
- if (show)
- {
- if (!m_BreakpointWindow)
- {
- m_BreakpointWindow = new CBreakPointWindow(this, this);
- }
-
- m_BreakpointWindow->Show(true);
- }
- else // hide
- {
- // If m_dialog is NULL, then possibly the system
- // didn't report the checked menu item status correctly.
- // It should be true just after the menu item was selected,
- // if there was no modeless dialog yet.
- wxASSERT(m_BreakpointWindow != NULL);
-
- if (m_BreakpointWindow)
- {
- m_BreakpointWindow->Hide();
- }
- }
-}
-
-void CCodeWindow::OnToggleMemoryWindow(wxCommandEvent& event)
-{
- bool show = GetMenuBar()->IsChecked(event.GetId());
-
- if (show)
- {
- if (!m_MemoryWindow)
- {
- m_MemoryWindow = new CMemoryWindow(this);
- }
-
- m_MemoryWindow->Show(true);
- }
- else // hide
- {
- // If m_dialog is NULL, then possibly the system
- // didn't report the checked menu item status correctly.
- // It should be true just after the menu item was selected,
- // if there was no modeless dialog yet.
- wxASSERT(m_MemoryWindow != NULL);
-
- if (m_MemoryWindow)
- {
- m_MemoryWindow->Hide();
- }
- }
-}
-
-void CCodeWindow::OnHostMessage(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case IDM_NOTIFYMAPLOADED:
- NotifyMapLoaded();
- break;
-
- case IDM_UPDATELOGDISPLAY:
-
- if (m_LogWindow)
- {
- m_LogWindow->NotifyUpdate();
- }
-
- break;
-
- case IDM_UPDATEDISASMDIALOG:
- Update();
-
- if (m_RegisterWindow)
- {
- m_RegisterWindow->NotifyUpdate();
- }
- break;
-
- case IDM_UPDATEBREAKPOINTS:
- Update();
-
- if (m_BreakpointWindow)
- {
- m_BreakpointWindow->NotifyUpdate();
- }
- break;
-
- }
-}
-
-void CCodeWindow::PopulateToolbar(wxToolBar* toolBar)
-{
- int w = m_Bitmaps[Toolbar_DebugGo].GetWidth(),
- h = m_Bitmaps[Toolbar_DebugGo].GetHeight();
-
- toolBar->SetToolBitmapSize(wxSize(w, h));
- toolBar->AddTool(IDM_DEBUG_GO, _T("Play"), m_Bitmaps[Toolbar_DebugGo]);
- toolBar->AddTool(IDM_STEP, _T("Step"), m_Bitmaps[Toolbar_Step]);
- toolBar->AddTool(IDM_STEPOVER, _T("Step Over"), m_Bitmaps[Toolbar_StepOver]);
- toolBar->AddTool(IDM_SKIP, _T("Skip"), m_Bitmaps[Toolbar_Skip]);
- toolBar->AddSeparator();
- toolBar->AddTool(IDM_GOTOPC, _T("Show PC"), m_Bitmaps[Toolbar_GotoPC]);
- toolBar->AddTool(IDM_SETPC, _T("Set PC"), m_Bitmaps[Toolbar_SetPC]);
- toolBar->AddSeparator();
- toolBar->AddControl(new wxTextCtrl(toolBar, IDM_ADDRBOX, _T("")));
-
- // after adding the buttons to the toolbar, must call Realize() to reflect
- // the changes
- toolBar->Realize();
-}
-
-
-void CCodeWindow::RecreateToolbar()
-{
- // delete and recreate the toolbar
- wxToolBarBase* toolBar = GetToolBar();
- delete toolBar;
- SetToolBar(NULL);
-
- long style = TOOLBAR_STYLE;
- style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT | wxTB_TOP);
- wxToolBar* theToolBar = CreateToolBar(style, ID_TOOLBAR);
-
- PopulateToolbar(theToolBar);
- SetToolBar(theToolBar);
-}
-
-
-void CCodeWindow::InitBitmaps()
-{
- // load original size 48x48
- m_Bitmaps[Toolbar_DebugGo] = wxGetBitmapFromMemory(toolbar_play_png);
- m_Bitmaps[Toolbar_Step] = wxGetBitmapFromMemory(toolbar_add_breakpoint_png);
- m_Bitmaps[Toolbar_StepOver] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
- m_Bitmaps[Toolbar_Skip] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
- m_Bitmaps[Toolbar_GotoPC] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
- m_Bitmaps[Toolbar_SetPC] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
- m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(toolbar_pause_png);
-
-
- // scale to 16x16 for toolbar
- for (size_t n = Toolbar_DebugGo; n < Bitmaps_max; n++)
- {
- m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(16, 16));
- }
-}
-
-
-void CCodeWindow::OnKeyDown(wxKeyEvent& event)
-{
- if ((event.GetKeyCode() == WXK_SPACE) && IsActive())
- {
- SingleCPUStep();
- }
- else
- {
- event.Skip();
- }
-}
-
-
-void CCodeWindow::SingleCPUStep()
-{
- CCPU::StepOpcode(&sync_event);
- // if (CCPU::IsStepping())
- // sync_event.Wait();
- wxThread::Sleep(20);
- // need a short wait here
- JumpToAddress(PC);
- Update();
- Host_UpdateLogDisplay();
-}
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include <wx/button.h> +#include <wx/textctrl.h> +#include <wx/textdlg.h> +#include <wx/listctrl.h> +#include <wx/thread.h> +#include <wx/mstream.h> + +// ugly that this lib included code from the main +#include "../../DolphinWX/Src/Globals.h" + +#include "IniFile.h" +#include "Host.h" + +#include "Debugger.h" + +#include "RegisterWindow.h" +#include "LogWindow.h" +#include "BreakpointWindow.h" +#include "MemoryWindow.h" +#include "JitWindow.h" + +#include "CodeWindow.h" +#include "CodeView.h" + +#include "FileUtil.h" +#include "Core.h" +#include "HLE/HLE.h" +#include "Boot/Boot.h" +#include "LogManager.h" +#include "HW/CPU.h" +#include "PowerPC/PowerPC.h" +#include "Debugger/PPCDebugInterface.h" +#include "Debugger/Debugger_SymbolMap.h" +#include "PowerPC/PPCAnalyst.h" +#include "PowerPC/Profiler.h" +#include "PowerPC/SymbolDB.h" +#include "PowerPC/SignatureDB.h" +#include "PowerPC/PPCTables.h" +#include "PowerPC/Jit64/Jit.h" +#include "PowerPC/Jit64/JitCache.h" // for ClearCache() + +#include "Plugins/Plugin_DSP.h" // new stuff, to let us open the DLLDebugger +#include "Plugins/Plugin_Video.h" // new stuff, to let us open the DLLDebugger +#include "../../DolphinWX/Src/PluginManager.h" +#include "../../DolphinWX/Src/Config.h" + +// and here are the classes +class CPluginInfo; +class CPluginManager; +//extern DynamicLibrary Common::CPlugin; +//extern CPluginManager CPluginManager::m_Instance; + +extern "C" { + #include "../resources/toolbar_play.c" + #include "../resources/toolbar_pause.c" + #include "../resources/toolbar_add_memorycheck.c" + #include "../resources/toolbar_delete.c" + #include "../resources/toolbar_add_breakpoint.c" +} + +static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT; + +BEGIN_EVENT_TABLE(CCodeWindow, wxFrame) + EVT_LISTBOX(IDM_SYMBOLLIST, CCodeWindow::OnSymbolListChange) + EVT_LISTBOX(IDM_CALLSTACKLIST, CCodeWindow::OnCallstackListChange) + EVT_LISTBOX(IDM_CALLERSLIST, CCodeWindow::OnCallersListChange) + EVT_LISTBOX(IDM_CALLSLIST, CCodeWindow::OnCallsListChange) + EVT_HOST_COMMAND(wxID_ANY, CCodeWindow::OnHostMessage) + EVT_MENU(IDM_LOGWINDOW, CCodeWindow::OnToggleLogWindow) + EVT_MENU(IDM_REGISTERWINDOW, CCodeWindow::OnToggleRegisterWindow) + EVT_MENU(IDM_BREAKPOINTWINDOW, CCodeWindow::OnToggleBreakPointWindow) + EVT_MENU(IDM_MEMORYWINDOW, CCodeWindow::OnToggleMemoryWindow) + EVT_MENU(IDM_JITWINDOW, CCodeWindow::OnToggleJitWindow) + EVT_MENU(IDM_SOUNDWINDOW, CCodeWindow::OnToggleSoundWindow) + EVT_MENU(IDM_VIDEOWINDOW, CCodeWindow::OnToggleVideoWindow) + + EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnInterpreter) // CPU Mode + EVT_MENU(IDM_AUTOMATICSTART, CCodeWindow::OnAutomaticStart) // CPU Mode + EVT_MENU(IDM_JITUNLIMITED, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITLSLXZOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITLSLWZOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITLSLBZXOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITLSFOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITLSPOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITFPOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITIOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITPOFF, CCodeWindow::OnJITOff) + EVT_MENU(IDM_JITSROFF, CCodeWindow::OnJITOff) + + EVT_MENU(IDM_CLEARSYMBOLS, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_LOADMAPFILE, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_SCANFUNCTIONS, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_SAVEMAPFILE, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_SAVEMAPFILEWITHCODES, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_CREATESIGNATUREFILE, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_USESIGNATUREFILE, CCodeWindow::OnSymbolsMenu) + EVT_MENU(IDM_PATCHHLEFUNCTIONS, CCodeWindow::OnSymbolsMenu) + + EVT_MENU(IDM_CLEARCODECACHE, CCodeWindow::OnJitMenu) + EVT_MENU(IDM_LOGINSTRUCTIONS, CCodeWindow::OnJitMenu) + + EVT_MENU(IDM_PROFILEBLOCKS, CCodeWindow::OnProfilerMenu) + EVT_MENU(IDM_WRITEPROFILE, CCodeWindow::OnProfilerMenu) + + // toolbar + EVT_MENU(IDM_DEBUG_GO, CCodeWindow::OnCodeStep) + EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep) + EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep) + EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep) + EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep) + EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep) + EVT_TEXT(IDM_ADDRBOX, CCodeWindow::OnAddrBoxChange) + + EVT_COMMAND(IDM_CODEVIEW, wxEVT_CODEVIEW_CHANGE, CCodeWindow::OnCodeViewChange) +END_EVENT_TABLE() + +#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name)) +inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length) +{ + wxMemoryInputStream is(data, length); + return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1)); +} + +// ======================================================================================= +// WARNING: If you create a new dialog window you must add m_dialog(NULL) below otherwise +// m_dialog = true and things will crash. +// ---------------- +CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter, wxWindow* parent, wxWindowID id, + const wxString& title, const wxPoint& pos, const wxSize& size, long style) + : wxFrame(parent, id, title, pos, size, style) + , m_LogWindow(NULL) + , m_RegisterWindow(NULL) + , m_BreakpointWindow(NULL) + , m_MemoryWindow(NULL) + , m_JitWindow(NULL) +{ + // Load ini settings + IniFile file; + file.Load(DEBUGGER_CONFIG_FILE); + this->Load_(file); + + InitBitmaps(); + + CreateGUIControls(_LocalCoreStartupParameter); + + // Create the toolbar + RecreateToolbar(); + + UpdateButtonStates(); + + wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN, + wxKeyEventHandler(CCodeWindow::OnKeyDown), + (wxObject*)0, this); + + // Load settings for selectable windowses, but only if they have been created + this->Load(file); + if (m_BreakpointWindow) m_BreakpointWindow->Load(file); + if (m_RegisterWindow) m_RegisterWindow->Load(file); + if (m_MemoryWindow) m_MemoryWindow->Load(file); + if (m_JitWindow) m_JitWindow->Load(file); +} +// =============== + + +CCodeWindow::~CCodeWindow() +{ + IniFile file; + file.Load(DEBUGGER_CONFIG_FILE); + + this->Save(file); + if (m_BreakpointWindow) m_BreakpointWindow->Save(file); + if (m_LogWindow) m_LogWindow->Save(file); + if (m_RegisterWindow) m_RegisterWindow->Save(file); + if (m_MemoryWindow) m_MemoryWindow->Save(file); + if (m_JitWindow) m_JitWindow->Save(file); + + file.Save(DEBUGGER_CONFIG_FILE); +} + + +// ======================================================================================= +// Load before CreateGUIControls() +// -------------- +void CCodeWindow::Load_( IniFile &ini ) +{ + + // Decide what windows to use + ini.Get("ShowOnStart", "LogWindow", &bLogWindow, true); + ini.Get("ShowOnStart", "RegisterWindow", &bRegisterWindow, true); + ini.Get("ShowOnStart", "BreakpointWindow", &bBreakpointWindow, true); + ini.Get("ShowOnStart", "MemoryWindow", &bMemoryWindow, true); + ini.Get("ShowOnStart", "JitWindow", &bJitWindow, true); + ini.Get("ShowOnStart", "SoundWindow", &bSoundWindow, false); + ini.Get("ShowOnStart", "VideoWindow", &bVideoWindow, false); + // =============== + + // Boot to pause or not + ini.Get("ShowOnStart", "AutomaticStart", &bAutomaticStart, false); +} + + +void CCodeWindow::Load( IniFile &ini ) +{ + int x,y,w,h; + ini.Get("CodeWindow", "x", &x, GetPosition().x); + ini.Get("CodeWindow", "y", &y, GetPosition().y); + ini.Get("CodeWindow", "w", &w, GetSize().GetWidth()); + ini.Get("CodeWindow", "h", &h, GetSize().GetHeight()); + this->SetSize(x, y, w, h); +} + + +void CCodeWindow::Save(IniFile &ini) const +{ + ini.Set("CodeWindow", "x", GetPosition().x); + ini.Set("CodeWindow", "y", GetPosition().y); + ini.Set("CodeWindow", "w", GetSize().GetWidth()); + ini.Set("CodeWindow", "h", GetSize().GetHeight()); + + // Boot to pause or not + ini.Set("ShowOnStart", "AutomaticStart", GetMenuBar()->IsChecked(IDM_AUTOMATICSTART)); + + // Save windows settings + ini.Set("ShowOnStart", "LogWindow", GetMenuBar()->IsChecked(IDM_LOGWINDOW)); + ini.Set("ShowOnStart", "RegisterWindow", GetMenuBar()->IsChecked(IDM_REGISTERWINDOW)); + ini.Set("ShowOnStart", "BreakpointWindow", GetMenuBar()->IsChecked(IDM_BREAKPOINTWINDOW)); + ini.Set("ShowOnStart", "MemoryWindow", GetMenuBar()->IsChecked(IDM_MEMORYWINDOW)); + ini.Set("ShowOnStart", "JitWindow", GetMenuBar()->IsChecked(IDM_JITWINDOW)); + ini.Set("ShowOnStart", "SoundWindow", GetMenuBar()->IsChecked(IDM_SOUNDWINDOW)); + ini.Set("ShowOnStart", "VideoWindow", GetMenuBar()->IsChecked(IDM_VIDEOWINDOW)); +} + + +void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter) +{ + CreateMenu(_LocalCoreStartupParameter); + + // ======================================================================================= + // Configure the code window + wxBoxSizer* sizerBig = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL); + + DebugInterface* di = new PPCDebugInterface(); + + codeview = new CCodeView(di, this, IDM_CODEVIEW); + sizerBig->Add(sizerLeft, 2, wxEXPAND); + sizerBig->Add(codeview, 5, wxEXPAND); + + sizerLeft->Add(callstack = new wxListBox(this, IDM_CALLSTACKLIST, wxDefaultPosition, wxSize(90, 100)), 0, wxEXPAND); + sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); + sizerLeft->Add(calls = new wxListBox(this, IDM_CALLSLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 0, wxEXPAND); + sizerLeft->Add(callers = new wxListBox(this, IDM_CALLERSLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 0, wxEXPAND); + + SetSizer(sizerBig); + + sizerLeft->SetSizeHints(this); + sizerLeft->Fit(this); + sizerBig->SetSizeHints(this); + sizerBig->Fit(this); + + sync_event.Init(); + // ================= + + + // additional dialogs + if (IsLoggingActivated() && bLogWindow) + { + m_LogWindow = new CLogWindow(this); + m_LogWindow->Show(true); + } + + if (bRegisterWindow) + { + m_RegisterWindow = new CRegisterWindow(this); + m_RegisterWindow->Show(true); + } + + if(bBreakpointWindow) + { + m_BreakpointWindow = new CBreakPointWindow(this, this); + m_BreakpointWindow->Show(true); + } + + if(bMemoryWindow) + { + m_MemoryWindow = new CMemoryWindow(this); + m_MemoryWindow->Show(true); + } + + if(bJitWindow) + { + m_JitWindow = new CJitWindow(this); + m_JitWindow->Show(true); + } + + if(bSoundWindow) + { + // possible todo: add some kind of if here to? can it fail? + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(), + false, true + ); + } // don't have any else, just ignore it + + if(bVideoWindow) + { + // possible todo: add some kind of if here to? can it fail? + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + _LocalCoreStartupParameter.m_strVideoPlugin.c_str(), + true, true + ); + } // don't have any else, just ignore it +} + + +void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter) +{ + + // ======================================================================================= + // Windowses + // --------------- + wxMenuBar* pMenuBar = new wxMenuBar(wxMB_DOCKABLE); + + { + wxMenu* pCoreMenu = new wxMenu; + + wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter core"), wxEmptyString, wxITEM_CHECK); + interpreter->Check(!_LocalCoreStartupParameter.bUseJIT); + pCoreMenu->AppendSeparator(); + wxMenuItem* automaticstart = pCoreMenu->Append(IDM_AUTOMATICSTART, _T("&Automatic start"), wxEmptyString, wxITEM_CHECK); + automaticstart->Check(bAutomaticStart); + pCoreMenu->AppendSeparator(); + +#ifdef JIT_OFF_OPTIONS + jitunlimited = pCoreMenu->Append(IDM_JITUNLIMITED, _T("&Unlimited JIT Cache"), wxEmptyString, wxITEM_CHECK); + pCoreMenu->AppendSeparator(); + jitoff = pCoreMenu->Append(IDM_JITOFF, _T("&JIT off (JIT core)"), wxEmptyString, wxITEM_CHECK); + jitlsoff = pCoreMenu->Append(IDM_JITLSOFF, _T("&JIT LoadStore off"), wxEmptyString, wxITEM_CHECK); + jitlslbzxoff = pCoreMenu->Append(IDM_JITLSLBZXOFF, _T(" &JIT LoadStore lbzx off"), wxEmptyString, wxITEM_CHECK); + jitlslxzoff = pCoreMenu->Append(IDM_JITLSLXZOFF, _T(" &JIT LoadStore lXz off"), wxEmptyString, wxITEM_CHECK); + jitlslwzoff = pCoreMenu->Append(IDM_JITLSLWZOFF, _T(" &JIT LoadStore lwz off"), wxEmptyString, wxITEM_CHECK); + jitlspoff = pCoreMenu->Append(IDM_JITLSFOFF, _T("&JIT LoadStore Floating off"), wxEmptyString, wxITEM_CHECK); + jitlsfoff = pCoreMenu->Append(IDM_JITLSPOFF, _T("&JIT LoadStore Paired off"), wxEmptyString, wxITEM_CHECK); + jitfpoff = pCoreMenu->Append(IDM_JITFPOFF, _T("&JIT FloatingPoint off"), wxEmptyString, wxITEM_CHECK); + jitioff = pCoreMenu->Append(IDM_JITIOFF, _T("&JIT Integer off"), wxEmptyString, wxITEM_CHECK); + jitpoff = pCoreMenu->Append(IDM_JITPOFF, _T("&JIT Paired off"), wxEmptyString, wxITEM_CHECK); + jitsroff = pCoreMenu->Append(IDM_JITSROFF, _T("&JIT SystemRegisters off"), wxEmptyString, wxITEM_CHECK); +#endif + +// wxMenuItem* dualcore = pDebugMenu->Append(IDM_DUALCORE, _T("&DualCore"), wxEmptyString, wxITEM_CHECK); +// dualcore->Check(_LocalCoreStartupParameter.bUseDualCore); + + pMenuBar->Append(pCoreMenu, _T("&CPU Mode")); + + } + + { + wxMenu* pDebugDialogs = new wxMenu; + + if (IsLoggingActivated()) + { + wxMenuItem* pLogWindow = pDebugDialogs->Append(IDM_LOGWINDOW, _T("&LogManager"), wxEmptyString, wxITEM_CHECK); + pLogWindow->Check(bLogWindow); + } + + wxMenuItem* pRegister = pDebugDialogs->Append(IDM_REGISTERWINDOW, _T("&Registers"), wxEmptyString, wxITEM_CHECK); + pRegister->Check(bRegisterWindow); + + wxMenuItem* pBreakPoints = pDebugDialogs->Append(IDM_BREAKPOINTWINDOW, _T("&BreakPoints"), wxEmptyString, wxITEM_CHECK); + pBreakPoints->Check(bBreakpointWindow); + + wxMenuItem* pMemory = pDebugDialogs->Append(IDM_MEMORYWINDOW, _T("&Memory"), wxEmptyString, wxITEM_CHECK); + pMemory->Check(bMemoryWindow); + + wxMenuItem* pJit = pDebugDialogs->Append(IDM_JITWINDOW, _T("&Jit"), wxEmptyString, wxITEM_CHECK); + pJit->Check(bJitWindow); + + wxMenuItem* pSound = pDebugDialogs->Append(IDM_SOUNDWINDOW, _T("&Sound"), wxEmptyString, wxITEM_CHECK); + pSound->Check(bSoundWindow); + + wxMenuItem* pVideo = pDebugDialogs->Append(IDM_VIDEOWINDOW, _T("&Video"), wxEmptyString, wxITEM_CHECK); + pVideo->Check(bVideoWindow); + + pMenuBar->Append(pDebugDialogs, _T("&Views")); + } + // =============== + + + { + wxMenu *pSymbolsMenu = new wxMenu; + pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols")); + // pSymbolsMenu->Append(IDM_CLEANSYMBOLS, _T("&Clean symbols (zz)")); + pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map")); + pSymbolsMenu->AppendSeparator(); + pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map")); + pSymbolsMenu->Append(IDM_SAVEMAPFILE, _T("&Save symbol map")); + pSymbolsMenu->AppendSeparator(); + pSymbolsMenu->Append(IDM_SAVEMAPFILEWITHCODES, _T("Save code")); + pSymbolsMenu->AppendSeparator(); + pSymbolsMenu->Append(IDM_CREATESIGNATUREFILE, _T("&Create signature file...")); + pSymbolsMenu->Append(IDM_USESIGNATUREFILE, _T("&Use signature file...")); + pSymbolsMenu->AppendSeparator(); + pSymbolsMenu->Append(IDM_PATCHHLEFUNCTIONS, _T("&Patch HLE functions")); + pMenuBar->Append(pSymbolsMenu, _T("&Symbols")); + } + + { + wxMenu *pJitMenu = new wxMenu; + pJitMenu->Append(IDM_CLEARCODECACHE, _T("&Clear code cache")); + pJitMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage")); + pMenuBar->Append(pJitMenu, _T("&JIT")); + } + + { + wxMenu *pProfilerMenu = new wxMenu; + pProfilerMenu->Append(IDM_PROFILEBLOCKS, _T("&Profile blocks"), wxEmptyString, wxITEM_CHECK); + pProfilerMenu->AppendSeparator(); + pProfilerMenu->Append(IDM_WRITEPROFILE, _T("&Write to profile.txt, show")); + pMenuBar->Append(pProfilerMenu, _T("&Profiler")); + } + + + SetMenuBar(pMenuBar); +} + + +bool CCodeWindow::UseInterpreter() +{ + return GetMenuBar()->IsChecked(IDM_INTERPRETER); +} + +bool CCodeWindow::AutomaticStart() +{ + return GetMenuBar()->IsChecked(IDM_AUTOMATICSTART); +} + +bool CCodeWindow::UseDualCore() +{ + return GetMenuBar()->IsChecked(IDM_DUALCORE); +} + + +// ======================================================================================= +// CPU Mode +// -------------- +void CCodeWindow::OnInterpreter(wxCommandEvent& event) +{ + if (Core::GetState() != Core::CORE_RUN) { + PowerPC::SetMode(UseInterpreter() ? PowerPC::MODE_INTERPRETER : PowerPC::MODE_JIT); + } else { + event.Skip(); + wxMessageBox(_T("Please pause the emulator before changing mode.")); + } +} + + +void CCodeWindow::OnAutomaticStart(wxCommandEvent& event) +{ + bAutomaticStart = !bAutomaticStart; +} + + +void CCodeWindow::OnJITOff(wxCommandEvent& event) +{ + if (Core::GetState() == Core::CORE_UNINITIALIZED) + { + // we disallow changing the status here because it will be reset to the defult when BootCore() + // creates the SCoreStartupParameter as a game is loaded + GetMenuBar()->Check(event.GetId(),!event.IsChecked()); + wxMessageBox(_T("Please start a game before changing mode.")); + } else { + if (Core::GetState() != Core::CORE_RUN) + { + switch (event.GetId()) + { + case IDM_JITUNLIMITED: + Core::g_CoreStartupParameter.bJITUnlimitedCache = event.IsChecked(); + Jit64::ClearCache(); // allow InitCache() even after the game has started + Jit64::InitCache(); + GetMenuBar()->Enable(event.GetId(),!event.IsChecked()); + break; + case IDM_JITOFF: + Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break; + case IDM_JITLSOFF: + Core::g_CoreStartupParameter.bJITLoadStoreOff = event.IsChecked(); break; + case IDM_JITLSLXZOFF: + Core::g_CoreStartupParameter.bJITLoadStorelXzOff = event.IsChecked(); break; + case IDM_JITLSLWZOFF: + Core::g_CoreStartupParameter.bJITLoadStorelwzOff = event.IsChecked(); break; + case IDM_JITLSLBZXOFF: + Core::g_CoreStartupParameter.bJITLoadStorelbzxOff = event.IsChecked(); break; + case IDM_JITLSFOFF: + Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff = event.IsChecked(); break; + case IDM_JITLSPOFF: + Core::g_CoreStartupParameter.bJITLoadStorePairedOff = event.IsChecked(); break; + case IDM_JITFPOFF: + Core::g_CoreStartupParameter.bJITFloatingPointOff = event.IsChecked(); break; + case IDM_JITIOFF: + Core::g_CoreStartupParameter.bJITIntegerOff = event.IsChecked(); break; + case IDM_JITPOFF: + Core::g_CoreStartupParameter.bJITPairedOff = event.IsChecked(); break; + case IDM_JITSROFF: + Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break; + } + Jit64::ClearCache(); + } else { + //event.Skip(); // this doesn't work + GetMenuBar()->Check(event.GetId(),!event.IsChecked()); + wxMessageBox(_T("Please pause the emulator before changing mode.")); + } + } +} +// ============== + + +void CCodeWindow::OnJitMenu(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case IDM_CLEARCODECACHE: + Jit64::ClearCache(); + break; + case IDM_LOGINSTRUCTIONS: + PPCTables::LogCompiledInstructions(); + break; + } +} + +void CCodeWindow::OnProfilerMenu(wxCommandEvent& event) +{ + if (Core::GetState() == Core::CORE_RUN) { + event.Skip(); + return; + } + switch (event.GetId()) + { + case IDM_PROFILEBLOCKS: + Jit64::ClearCache(); + Profiler::g_ProfileBlocks = GetMenuBar()->IsChecked(IDM_PROFILEBLOCKS); + break; + case IDM_WRITEPROFILE: + Profiler::WriteProfileResults("profiler.txt"); + File::Launch("profiler.txt"); + break; + } +} + +void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) +{ + if (Core::GetState() == Core::CORE_UNINITIALIZED) + { + // TODO: disable menu items instead :P + return; + } + std::string mapfile = CBoot::GenerateMapFilename(); + switch (event.GetId()) + { + case IDM_CLEARSYMBOLS: + g_symbolDB.Clear(); + Host_NotifyMapLoaded(); + break; + case IDM_CLEANSYMBOLS: + g_symbolDB.Clear("zz"); + Host_NotifyMapLoaded(); + break; + case IDM_SCANFUNCTIONS: + { + PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB); + SignatureDB db; + if (db.Load(TOTALDB_FILE)) + db.Apply(&g_symbolDB); + + // HLE::PatchFunctions(); + NotifyMapLoaded(); + break; + } + case IDM_LOADMAPFILE: + if (!File::Exists(mapfile.c_str())) + { + g_symbolDB.Clear(); + PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB); + SignatureDB db; + if (db.Load(TOTALDB_FILE)) + db.Apply(&g_symbolDB); + } else { + g_symbolDB.LoadMap(mapfile.c_str()); + } + NotifyMapLoaded(); + break; + case IDM_SAVEMAPFILE: + g_symbolDB.SaveMap(mapfile.c_str()); + break; + case IDM_SAVEMAPFILEWITHCODES: + g_symbolDB.SaveMap(mapfile.c_str(), true); + break; + case IDM_CREATESIGNATUREFILE: + { + wxTextEntryDialog input_prefix(this, wxString::FromAscii("Only export symbols with prefix:"), wxGetTextFromUserPromptStr, _T(".")); + if (input_prefix.ShowModal() == wxID_OK) { + std::string prefix(input_prefix.GetValue().mb_str()); + + wxString path = wxFileSelector( + _T("Save signature as"), wxEmptyString, wxEmptyString, wxEmptyString, + _T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_SAVE, + this); + if (path) { + SignatureDB db; + db.Initialize(&g_symbolDB, prefix.c_str()); + std::string filename(path.ToAscii()); // PPCAnalyst::SaveSignatureDB( + db.Save(path.ToAscii()); + } + } + } + break; + case IDM_USESIGNATUREFILE: + { + wxString path = wxFileSelector( + _T("Apply signature file"), wxEmptyString, wxEmptyString, wxEmptyString, + _T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_OPEN | wxFD_FILE_MUST_EXIST, + this); + if (path) { + SignatureDB db; + db.Load(path.ToAscii()); + db.Apply(&g_symbolDB); + } + } + NotifyMapLoaded(); + break; + case IDM_PATCHHLEFUNCTIONS: + HLE::PatchFunctions(); + Update(); + break; + } +} + +// ======================================================================================= +// The Play, Stop, Step, Skip, Go to PC and Show PC buttons all go here +// -------------- +void CCodeWindow::OnCodeStep(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case IDM_DEBUG_GO: + { + // [F|RES] prolly we should disable the other buttons in go mode too ... + JumpToAddress(PC); + + if (CCPU::IsStepping()) + { + CCPU::EnableStepping(false); + } + else + { + CCPU::EnableStepping(true); + Host_UpdateLogDisplay(); + } + + Update(); + } + break; + + case IDM_STEP: + SingleCPUStep(); + + break; + + case IDM_STEPOVER: + CCPU::EnableStepping(true); + break; + + case IDM_SKIP: + PC += 4; + Update(); + break; + + case IDM_SETPC: + PC = codeview->GetSelection(); + Update(); + break; + + case IDM_GOTOPC: + JumpToAddress(PC); + break; + } + + UpdateButtonStates(); +} + + +void CCodeWindow::JumpToAddress(u32 _Address) +{ + codeview->Center(_Address); + UpdateLists(); +} + + +void CCodeWindow::UpdateLists() +{ + callers->Clear(); + u32 addr = codeview->GetSelection(); + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(addr); + if (!symbol) + return; + for (int i = 0; i < (int)symbol->callers.size(); i++) + { + u32 caller_addr = symbol->callers[i].callAddress; + Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr); + if (caller_symbol) { + int idx = callers->Append(wxString::Format( wxT("< %s (%08x)"), caller_symbol->name.c_str(), caller_addr)); + callers->SetClientData(idx, (void*)caller_addr); + } + } + + calls->Clear(); + for (int i = 0; i < (int)symbol->calls.size(); i++) + { + u32 call_addr = symbol->calls[i].function; + Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr); + if (call_symbol) { + int idx = calls->Append(wxString::Format(_T("> %s (%08x)"), call_symbol->name.c_str(), call_addr)); + calls->SetClientData(idx, (void*)call_addr); + } + } +} + + +void CCodeWindow::OnCodeViewChange(wxCommandEvent &event) +{ + //PanicAlert("boo"); + UpdateLists(); +} + +void CCodeWindow::OnAddrBoxChange(wxCommandEvent& event) +{ + wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(IDM_ADDRBOX); + wxString txt = pAddrCtrl->GetValue(); + + std::string text(txt.mb_str()); + text = StripSpaces(text); + if (text.size() == 8) + { + u32 addr; + sscanf(text.c_str(), "%08x", &addr); + JumpToAddress(addr); + } + + event.Skip(1); +} + +void CCodeWindow::OnCallstackListChange(wxCommandEvent& event) +{ + int index = callstack->GetSelection(); + if (index >= 0) { + u32 address = (u32)(u64)(callstack->GetClientData(index)); + if (address) + JumpToAddress(address); + } +} + +void CCodeWindow::OnCallersListChange(wxCommandEvent& event) +{ + int index = callers->GetSelection(); + if (index >= 0) { + u32 address = (u32)(u64)(callers->GetClientData(index)); + if (address) + JumpToAddress(address); + } +} + +void CCodeWindow::OnCallsListChange(wxCommandEvent& event) +{ + int index = calls->GetSelection(); + if (index >= 0) { + u32 address = (u32)(u64)(calls->GetClientData(index)); + if (address) + JumpToAddress(address); + } +} + +void CCodeWindow::Update() +{ + codeview->Refresh(); + callstack->Clear(); + + std::vector<Debugger::CallstackEntry> stack; + + if (Debugger::GetCallstack(stack)) + { + for (size_t i = 0; i < stack.size(); i++) + { + int idx = callstack->Append(wxString::FromAscii(stack[i].Name.c_str())); + callstack->SetClientData(idx, (void*)(u64)stack[i].vAddress); + } + } + else + { + callstack->Append(wxString::FromAscii("invalid callstack")); + } + + UpdateButtonStates(); + + /* Automatically show the current PC position when a breakpoint is hit or + when we pause */ + codeview->Center(PC); +} + + +void CCodeWindow::NotifyMapLoaded() +{ + g_symbolDB.FillInCallers(); + symbols->Show(false); // hide it for faster filling + symbols->Clear(); + for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++) + { + int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str())); + symbols->SetClientData(idx, (void*)&iter->second); + } + symbols->Show(true); + Update(); +} + + +void CCodeWindow::UpdateButtonStates() +{ + wxToolBar* toolBar = GetToolBar(); + if (Core::GetState() == Core::CORE_UNINITIALIZED) + { + toolBar->EnableTool(IDM_DEBUG_GO, false); + toolBar->EnableTool(IDM_STEP, false); + toolBar->EnableTool(IDM_STEPOVER, false); + toolBar->EnableTool(IDM_SKIP, false); + } + else + { + if (!CCPU::IsStepping()) + { + toolBar->SetToolShortHelp(IDM_DEBUG_GO, _T("&Pause")); + toolBar->SetToolNormalBitmap(IDM_DEBUG_GO, m_Bitmaps[Toolbar_Pause]); + toolBar->EnableTool(IDM_DEBUG_GO, true); + toolBar->EnableTool(IDM_STEP, false); + toolBar->EnableTool(IDM_STEPOVER, false); + toolBar->EnableTool(IDM_SKIP, false); + } + else + { + toolBar->SetToolShortHelp(IDM_DEBUG_GO, _T("&Play")); + toolBar->SetToolNormalBitmap(IDM_DEBUG_GO, m_Bitmaps[Toolbar_DebugGo]); + toolBar->EnableTool(IDM_DEBUG_GO, true); + toolBar->EnableTool(IDM_STEP, true); + toolBar->EnableTool(IDM_STEPOVER, true); + toolBar->EnableTool(IDM_SKIP, true); + } + } +} + + +void CCodeWindow::OnSymbolListChange(wxCommandEvent& event) +{ + int index = symbols->GetSelection(); + if (index >= 0) { + Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index)); + if (pSymbol != NULL) + { + if(pSymbol->type == Symbol::SYMBOL_DATA) + { + if(m_MemoryWindow && m_MemoryWindow->IsVisible()) + m_MemoryWindow->JumpToAddress(pSymbol->address); + } + else + { + JumpToAddress(pSymbol->address); + } + } + } +} + +void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event) +{ +} + + +void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event) +{ + if (IsLoggingActivated()) + { + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + if (!m_LogWindow) + { + m_LogWindow = new CLogWindow(this); + } + + m_LogWindow->Show(true); + } + else // hide + { + // If m_dialog is NULL, then possibly the system + // didn't report the checked menu item status correctly. + // It should be true just after the menu item was selected, + // if there was no modeless dialog yet. + wxASSERT(m_LogWindow != NULL); + + if (m_LogWindow) + { + m_LogWindow->Hide(); + } + } + } +} + + +void CCodeWindow::OnToggleRegisterWindow(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + if (!m_RegisterWindow) + { + m_RegisterWindow = new CRegisterWindow(this); + } + + m_RegisterWindow->Show(true); + } + else // hide + { + // If m_dialog is NULL, then possibly the system + // didn't report the checked menu item status correctly. + // It should be true just after the menu item was selected, + // if there was no modeless dialog yet. + wxASSERT(m_RegisterWindow != NULL); + + if (m_RegisterWindow) + { + m_RegisterWindow->Hide(); + } + } +} + + +// ======================================================================================= +// Toggle Sound Debugging Window +// ------------ +void CCodeWindow::OnToggleSoundWindow(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + // TODO: add some kind of if() check here to? + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(), + false, true // DSP, show + ); + } + else // hide + { + // Close the sound dll that has an open debugger + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(), + false, false // DSP, hide + ); + } +} +// =========== + + +// ======================================================================================= +// Toggle Video Debugging Window +// ------------ +void CCodeWindow::OnToggleVideoWindow(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + //GetMenuBar()->Check(event.GetId(), false); // Turn off + + if (show) + { + // It works now, but I'll keep this message in case the problem reappears + /*if(Core::GetState() == Core::CORE_UNINITIALIZED) + { + wxMessageBox(_T("Warning, opening this window before a game is started \n\ +may cause a crash when a game is later started. Todo: figure out why and fix it."), wxT("OpenGL Debugging Window")); + }*/ + + // TODO: add some kind of if() check here to? + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(), + true, true // Video, show + ); + } + else // hide + { + // Close the video dll that has an open debugger + CPluginManager::GetInstance().OpenDebug( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(), + true, false // Video, hide + ); + } +} +// =========== + + +void CCodeWindow::OnToggleJitWindow(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + if (!m_JitWindow) + { + m_JitWindow = new CJitWindow(this); + } + + m_JitWindow->Show(true); + } + else // hide + { + // If m_dialog is NULL, then possibly the system + // didn't report the checked menu item status correctly. + // It should be true just after the menu item was selected, + // if there was no modeless dialog yet. + wxASSERT(m_JitWindow != NULL); + + if (m_JitWindow) + { + m_JitWindow->Hide(); + } + } +} + + +void CCodeWindow::OnToggleBreakPointWindow(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + if (!m_BreakpointWindow) + { + m_BreakpointWindow = new CBreakPointWindow(this, this); + } + + m_BreakpointWindow->Show(true); + } + else // hide + { + // If m_dialog is NULL, then possibly the system + // didn't report the checked menu item status correctly. + // It should be true just after the menu item was selected, + // if there was no modeless dialog yet. + wxASSERT(m_BreakpointWindow != NULL); + + if (m_BreakpointWindow) + { + m_BreakpointWindow->Hide(); + } + } +} + +void CCodeWindow::OnToggleMemoryWindow(wxCommandEvent& event) +{ + bool show = GetMenuBar()->IsChecked(event.GetId()); + + if (show) + { + if (!m_MemoryWindow) + { + m_MemoryWindow = new CMemoryWindow(this); + } + + m_MemoryWindow->Show(true); + } + else // hide + { + // If m_dialog is NULL, then possibly the system + // didn't report the checked menu item status correctly. + // It should be true just after the menu item was selected, + // if there was no modeless dialog yet. + wxASSERT(m_MemoryWindow != NULL); + + if (m_MemoryWindow) + { + m_MemoryWindow->Hide(); + } + } +} + +void CCodeWindow::OnHostMessage(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case IDM_NOTIFYMAPLOADED: + NotifyMapLoaded(); + break; + + case IDM_UPDATELOGDISPLAY: + + if (m_LogWindow) + { + m_LogWindow->NotifyUpdate(); + } + + break; + + case IDM_UPDATEDISASMDIALOG: + Update(); + + if (m_RegisterWindow) + { + m_RegisterWindow->NotifyUpdate(); + } + break; + + case IDM_UPDATEBREAKPOINTS: + Update(); + + if (m_BreakpointWindow) + { + m_BreakpointWindow->NotifyUpdate(); + } + break; + + } +} + +void CCodeWindow::PopulateToolbar(wxToolBar* toolBar) +{ + int w = m_Bitmaps[Toolbar_DebugGo].GetWidth(), + h = m_Bitmaps[Toolbar_DebugGo].GetHeight(); + + toolBar->SetToolBitmapSize(wxSize(w, h)); + toolBar->AddTool(IDM_DEBUG_GO, _T("Play"), m_Bitmaps[Toolbar_DebugGo]); + toolBar->AddTool(IDM_STEP, _T("Step"), m_Bitmaps[Toolbar_Step]); + toolBar->AddTool(IDM_STEPOVER, _T("Step Over"), m_Bitmaps[Toolbar_StepOver]); + toolBar->AddTool(IDM_SKIP, _T("Skip"), m_Bitmaps[Toolbar_Skip]); + toolBar->AddSeparator(); + toolBar->AddTool(IDM_GOTOPC, _T("Show PC"), m_Bitmaps[Toolbar_GotoPC]); + toolBar->AddTool(IDM_SETPC, _T("Set PC"), m_Bitmaps[Toolbar_SetPC]); + toolBar->AddSeparator(); + toolBar->AddControl(new wxTextCtrl(toolBar, IDM_ADDRBOX, _T(""))); + + // after adding the buttons to the toolbar, must call Realize() to reflect + // the changes + toolBar->Realize(); +} + + +void CCodeWindow::RecreateToolbar() +{ + // delete and recreate the toolbar + wxToolBarBase* toolBar = GetToolBar(); + delete toolBar; + SetToolBar(NULL); + + long style = TOOLBAR_STYLE; + style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT | wxTB_TOP); + wxToolBar* theToolBar = CreateToolBar(style, ID_TOOLBAR); + + PopulateToolbar(theToolBar); + SetToolBar(theToolBar); +} + + +void CCodeWindow::InitBitmaps() +{ + // load original size 48x48 + m_Bitmaps[Toolbar_DebugGo] = wxGetBitmapFromMemory(toolbar_play_png); + m_Bitmaps[Toolbar_Step] = wxGetBitmapFromMemory(toolbar_add_breakpoint_png); + m_Bitmaps[Toolbar_StepOver] = wxGetBitmapFromMemory(toolbar_add_memcheck_png); + m_Bitmaps[Toolbar_Skip] = wxGetBitmapFromMemory(toolbar_add_memcheck_png); + m_Bitmaps[Toolbar_GotoPC] = wxGetBitmapFromMemory(toolbar_add_memcheck_png); + m_Bitmaps[Toolbar_SetPC] = wxGetBitmapFromMemory(toolbar_add_memcheck_png); + m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(toolbar_pause_png); + + + // scale to 16x16 for toolbar + for (size_t n = Toolbar_DebugGo; n < Bitmaps_max; n++) + { + m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(16, 16)); + } +} + + +void CCodeWindow::OnKeyDown(wxKeyEvent& event) +{ + if ((event.GetKeyCode() == WXK_SPACE) && IsActive()) + { + SingleCPUStep(); + } + else + { + event.Skip(); + } +} + + +void CCodeWindow::SingleCPUStep() +{ + CCPU::StepOpcode(&sync_event); + // if (CCPU::IsStepping()) + // sync_event.Wait(); + wxThread::Sleep(20); + // need a short wait here + JumpToAddress(PC); + Update(); + Host_UpdateLogDisplay(); +} diff --git a/Source/Core/DebuggerWX/Src/Debugger.cpp b/Source/Core/DebuggerWX/Src/Debugger.cpp index 8f263d774d..2bf8df55ff 100644 --- a/Source/Core/DebuggerWX/Src/Debugger.cpp +++ b/Source/Core/DebuggerWX/Src/Debugger.cpp @@ -1,19 +1,19 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" + diff --git a/Source/Core/DebuggerWX/Src/JitWindow.cpp b/Source/Core/DebuggerWX/Src/JitWindow.cpp index aa4d4b5300..7914a3b68a 100644 --- a/Source/Core/DebuggerWX/Src/JitWindow.cpp +++ b/Source/Core/DebuggerWX/Src/JitWindow.cpp @@ -1,211 +1,211 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-
-#include "IniFile.h"
-
-#include <wx/button.h>
-#include <wx/textctrl.h>
-#include <wx/listctrl.h>
-#include <wx/thread.h>
-#include <wx/listctrl.h>
-#include "JitWindow.h"
-#include "HW/CPU.h"
-#include "PowerPC/PowerPC.h"
-#include "PowerPC/Jit64/Jit.h"
-#include "PowerPC/Jit64/JitCache.h"
-#include "Host.h"
-#include "disasm.h"
-
-#include "Debugger/PPCDebugInterface.h"
-#include "Debugger/Debugger_SymbolMap.h"
-
-#include "Core.h"
-#include "StringUtil.h"
-#include "LogManager.h"
-
-// ugly that this lib included code from the main
-#include "../../DolphinWX/Src/Globals.h"
-
-// UGLY
-namespace {
-CJitWindow *the_jit_window;
-}
-
-enum
-{
- IDM_REFRESH_LIST = 23350,
- IDM_PPC_BOX,
- IDM_X86_BOX,
- IDM_NEXT,
- IDM_PREV,
- IDM_BLOCKLIST,
-};
-
-BEGIN_EVENT_TABLE(CJitWindow, wxFrame)
-// EVT_TEXT(IDM_ADDRBOX, CJitWindow::OnAddrBoxChange)
- // EVT_LISTBOX(IDM_SYMBOLLIST, CJitWindow::OnSymbolListChange)
- //EVT_HOST_COMMAND(wxID_ANY, CJitWindow::OnHostMessage)
- EVT_BUTTON(IDM_REFRESH_LIST, CJitWindow::OnRefresh)
-END_EVENT_TABLE()
-
-
-CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id,
- const wxString& title, const wxPoint& pos, const wxSize& size, long style)
- : wxFrame(parent, id, title, pos, size, style)
-{
- the_jit_window = this;
- wxBoxSizer* sizerBig = new wxBoxSizer(wxVERTICAL);
- wxBoxSizer* sizerSplit = new wxBoxSizer(wxHORIZONTAL);
- sizerSplit->Add(ppc_box = new wxTextCtrl(this, IDM_PPC_BOX, _T("(ppc)"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), 1, wxEXPAND);
- sizerSplit->Add(x86_box = new wxTextCtrl(this, IDM_X86_BOX, _T("(x86)"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), 1, wxEXPAND);
- sizerBig->Add(block_list = new JitBlockList(this, IDM_BLOCKLIST,
- wxDefaultPosition, wxSize(100, 140),
- wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING), 0, wxEXPAND);
- sizerBig->Add(sizerSplit, 2, wxEXPAND);
-// sizerBig->Add(memview, 5, wxEXPAND);
-// sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3);
- sizerBig->Add(button_refresh = new wxButton(this, IDM_REFRESH_LIST, _T("&Refresh")));
-// sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_ADDRBOX, _T("")));
-// sizerRight->Add(new wxButton(this, IDM_SETPC, _T("S&et PC")));
-
- SetSizer(sizerBig);
-
- sizerSplit->SetSizeHints(this);
- sizerSplit->Fit(this);
- sizerBig->SetSizeHints(this);
- sizerBig->Fit(this);
-}
-
-
-CJitWindow::~CJitWindow()
-{
-}
-
-
-void CJitWindow::Save(IniFile& _IniFile) const
-{
- _IniFile.Set("JitWindow", "x", GetPosition().x);
- _IniFile.Set("JitWindow", "y", GetPosition().y);
- _IniFile.Set("JitWindow", "w", GetSize().GetWidth());
- _IniFile.Set("JitWindow", "h", GetSize().GetHeight());
-}
-
-
-void CJitWindow::Load(IniFile& _IniFile)
-{
- int x,y,w,h;
- _IniFile.Get("JitWindow", "x", &x, GetPosition().x);
- _IniFile.Get("JitWindow", "y", &y, GetPosition().y);
- _IniFile.Get("JitWindow", "w", &w, GetSize().GetWidth());
- _IniFile.Get("JitWindow", "h", &h, GetSize().GetHeight());
- SetSize(x, y, w, h);
-}
-
-void CJitWindow::OnRefresh(wxCommandEvent& /*event*/) {
- block_list->Update();
-}
-
-void CJitWindow::ViewAddr(u32 em_address)
-{
- the_jit_window->Compare(em_address);
-}
-
-void CJitWindow::Compare(u32 em_address)
-{
- u8 *xDis = new u8[65536];
- memset(xDis, 0, 65536);
-
- disassembler x64disasm;
- x64disasm.set_syntax_intel();
-
- int block_num = Jit64::GetBlockNumberFromAddress(em_address);
- if (block_num < 0)
- {
- ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", em_address).c_str()));
- x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str()));
- return;
- }
- Jit64::JitBlock *block = Jit64::GetBlock(block_num);
- const u8 *code = (const u8 *)Jit64::GetCompiledCodeFromBlock(block_num);
- u64 disasmPtr = (u64)code;
- int size = block->codeSize;
- const u8 *end = code + size;
- char *sptr = (char*)xDis;
-
- while ((u8*)disasmPtr < end)
- {
- disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr);
- sptr += strlen(sptr);
- *sptr++ = 13;
- *sptr++ = 10;
- }
- x86_box->SetValue(wxString::FromAscii((char*)xDis));
- delete [] xDis;
-}
-
-void CJitWindow::Update()
-{
-
-}
-
-void CJitWindow::OnHostMessage(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case IDM_NOTIFYMAPLOADED:
- //NotifyMapLoaded();
- break;
- }
-}
-
-
-
-// JitBlockList
-//================
-
-enum {
- COLUMN_ADDRESS,
- COLUMN_PPCSIZE,
- COLUMN_X86SIZE,
- COLUMN_NAME,
- COLUMN_FLAGS,
- COLUMN_NUMEXEC,
- COLUMN_COST, // (estimated as x86size * numexec)
-};
-
-JitBlockList::JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
- : wxListCtrl(parent, id, pos, size, style) // | wxLC_VIRTUAL)
-{
- Init();
-}
-
-void JitBlockList::Init()
-{
- InsertColumn(COLUMN_ADDRESS, _T("Address"));
- InsertColumn(COLUMN_PPCSIZE, _T("PPC Size"));
- InsertColumn(COLUMN_X86SIZE, _T("x86 Size"));
- InsertColumn(COLUMN_NAME, _T("Symbol"));
- InsertColumn(COLUMN_FLAGS, _T("Flags"));
- InsertColumn(COLUMN_NUMEXEC, _T("NumExec"));
- InsertColumn(COLUMN_COST, _T("Cost"));
-}
-
-void JitBlockList::Update()
-{
-}
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" + +#include "IniFile.h" + +#include <wx/button.h> +#include <wx/textctrl.h> +#include <wx/listctrl.h> +#include <wx/thread.h> +#include <wx/listctrl.h> +#include "JitWindow.h" +#include "HW/CPU.h" +#include "PowerPC/PowerPC.h" +#include "PowerPC/Jit64/Jit.h" +#include "PowerPC/Jit64/JitCache.h" +#include "Host.h" +#include "disasm.h" + +#include "Debugger/PPCDebugInterface.h" +#include "Debugger/Debugger_SymbolMap.h" + +#include "Core.h" +#include "StringUtil.h" +#include "LogManager.h" + +// ugly that this lib included code from the main +#include "../../DolphinWX/Src/Globals.h" + +// UGLY +namespace { +CJitWindow *the_jit_window; +} + +enum +{ + IDM_REFRESH_LIST = 23350, + IDM_PPC_BOX, + IDM_X86_BOX, + IDM_NEXT, + IDM_PREV, + IDM_BLOCKLIST, +}; + +BEGIN_EVENT_TABLE(CJitWindow, wxFrame) +// EVT_TEXT(IDM_ADDRBOX, CJitWindow::OnAddrBoxChange) + // EVT_LISTBOX(IDM_SYMBOLLIST, CJitWindow::OnSymbolListChange) + //EVT_HOST_COMMAND(wxID_ANY, CJitWindow::OnHostMessage) + EVT_BUTTON(IDM_REFRESH_LIST, CJitWindow::OnRefresh) +END_EVENT_TABLE() + + +CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, + const wxString& title, const wxPoint& pos, const wxSize& size, long style) + : wxFrame(parent, id, title, pos, size, style) +{ + the_jit_window = this; + wxBoxSizer* sizerBig = new wxBoxSizer(wxVERTICAL); + wxBoxSizer* sizerSplit = new wxBoxSizer(wxHORIZONTAL); + sizerSplit->Add(ppc_box = new wxTextCtrl(this, IDM_PPC_BOX, _T("(ppc)"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), 1, wxEXPAND); + sizerSplit->Add(x86_box = new wxTextCtrl(this, IDM_X86_BOX, _T("(x86)"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), 1, wxEXPAND); + sizerBig->Add(block_list = new JitBlockList(this, IDM_BLOCKLIST, + wxDefaultPosition, wxSize(100, 140), + wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING), 0, wxEXPAND); + sizerBig->Add(sizerSplit, 2, wxEXPAND); +// sizerBig->Add(memview, 5, wxEXPAND); +// sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3); + sizerBig->Add(button_refresh = new wxButton(this, IDM_REFRESH_LIST, _T("&Refresh"))); +// sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_ADDRBOX, _T(""))); +// sizerRight->Add(new wxButton(this, IDM_SETPC, _T("S&et PC"))); + + SetSizer(sizerBig); + + sizerSplit->SetSizeHints(this); + sizerSplit->Fit(this); + sizerBig->SetSizeHints(this); + sizerBig->Fit(this); +} + + +CJitWindow::~CJitWindow() +{ +} + + +void CJitWindow::Save(IniFile& _IniFile) const +{ + _IniFile.Set("JitWindow", "x", GetPosition().x); + _IniFile.Set("JitWindow", "y", GetPosition().y); + _IniFile.Set("JitWindow", "w", GetSize().GetWidth()); + _IniFile.Set("JitWindow", "h", GetSize().GetHeight()); +} + + +void CJitWindow::Load(IniFile& _IniFile) +{ + int x,y,w,h; + _IniFile.Get("JitWindow", "x", &x, GetPosition().x); + _IniFile.Get("JitWindow", "y", &y, GetPosition().y); + _IniFile.Get("JitWindow", "w", &w, GetSize().GetWidth()); + _IniFile.Get("JitWindow", "h", &h, GetSize().GetHeight()); + SetSize(x, y, w, h); +} + +void CJitWindow::OnRefresh(wxCommandEvent& /*event*/) { + block_list->Update(); +} + +void CJitWindow::ViewAddr(u32 em_address) +{ + the_jit_window->Compare(em_address); +} + +void CJitWindow::Compare(u32 em_address) +{ + u8 *xDis = new u8[65536]; + memset(xDis, 0, 65536); + + disassembler x64disasm; + x64disasm.set_syntax_intel(); + + int block_num = Jit64::GetBlockNumberFromAddress(em_address); + if (block_num < 0) + { + ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", em_address).c_str())); + x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str())); + return; + } + Jit64::JitBlock *block = Jit64::GetBlock(block_num); + const u8 *code = (const u8 *)Jit64::GetCompiledCodeFromBlock(block_num); + u64 disasmPtr = (u64)code; + int size = block->codeSize; + const u8 *end = code + size; + char *sptr = (char*)xDis; + + while ((u8*)disasmPtr < end) + { + disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr); + sptr += strlen(sptr); + *sptr++ = 13; + *sptr++ = 10; + } + x86_box->SetValue(wxString::FromAscii((char*)xDis)); + delete [] xDis; +} + +void CJitWindow::Update() +{ + +} + +void CJitWindow::OnHostMessage(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case IDM_NOTIFYMAPLOADED: + //NotifyMapLoaded(); + break; + } +} + + + +// JitBlockList +//================ + +enum { + COLUMN_ADDRESS, + COLUMN_PPCSIZE, + COLUMN_X86SIZE, + COLUMN_NAME, + COLUMN_FLAGS, + COLUMN_NUMEXEC, + COLUMN_COST, // (estimated as x86size * numexec) +}; + +JitBlockList::JitBlockList(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) + : wxListCtrl(parent, id, pos, size, style) // | wxLC_VIRTUAL) +{ + Init(); +} + +void JitBlockList::Init() +{ + InsertColumn(COLUMN_ADDRESS, _T("Address")); + InsertColumn(COLUMN_PPCSIZE, _T("PPC Size")); + InsertColumn(COLUMN_X86SIZE, _T("x86 Size")); + InsertColumn(COLUMN_NAME, _T("Symbol")); + InsertColumn(COLUMN_FLAGS, _T("Flags")); + InsertColumn(COLUMN_NUMEXEC, _T("NumExec")); + InsertColumn(COLUMN_COST, _T("Cost")); +} + +void JitBlockList::Update() +{ +} diff --git a/Source/Core/DebuggerWX/Src/LogWindow.cpp b/Source/Core/DebuggerWX/Src/LogWindow.cpp index c6f57cf0e2..7c14c96368 100644 --- a/Source/Core/DebuggerWX/Src/LogWindow.cpp +++ b/Source/Core/DebuggerWX/Src/LogWindow.cpp @@ -1,519 +1,519 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "LogManager.h"
-
-#include <wx/button.h>
-#include <wx/textctrl.h>
-#include <wx/listbox.h>
-#include <wx/checklst.h>
-
-#include "Core.h" // for Core::GetState()
-#include "LogWindow.h"
-#include "Console.h"
-#include "IniFile.h"
-
-// declare this now to be able to use it in Load()
-CDebugger_LogSettings* LogManager::m_LogSettings;
-
-BEGIN_EVENT_TABLE(CLogWindow, wxDialog)
- EVT_BUTTON(IDM_SUBMITCMD, CLogWindow::OnSubmit)
- EVT_BUTTON(IDM_UPDATELOG, CLogWindow::OnUpdateLog)
- EVT_BUTTON(IDM_CLEARLOG, CLogWindow::OnClear)
- EVT_BUTTON(IDM_ENABLEALL, CLogWindow::OnEnableAll)
- EVT_CHECKLISTBOX(IDM_OPTIONS, CLogWindow::OnOptionsCheck)
- EVT_CHECKLISTBOX(IDM_LOGCHECKS, CLogWindow::OnLogCheck)
- EVT_RADIOBOX(IDM_RADIO0, CLogWindow::OnRadioChange)
-END_EVENT_TABLE()
-
-
-CLogWindow::CLogWindow(wxWindow* parent)
- : wxDialog(parent, wxID_ANY, _T("Log/Console"), wxPoint(100, 700), wxSize(800, 270),
- wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
-{
- wxBoxSizer* sizerTop = new wxBoxSizer(wxHORIZONTAL), // buttons
- * sizerUber = new wxBoxSizer(wxHORIZONTAL), // whole plane
- * sizerBig = new wxBoxSizer(wxVERTICAL), // RIGHT sizer
- * sizerBottom = new wxBoxSizer(wxHORIZONTAL), // submit row
- * sizerLeft = new wxBoxSizer(wxVERTICAL); // LEFT sizer
-
- // left checkboxes and radio boxes -----------------------------------
- int m_radioBoxNChoices[1];
- wxString m_radioBoxChoices0[] = { wxT("0"), wxT("1"), wxT("2"), wxT("3") };
- m_radioBoxNChoices[0] = sizeof( m_radioBoxChoices0 ) / sizeof( wxString );
- m_RadioBox[0] = new wxRadioBox( this, IDM_RADIO0, wxT("Verbosity"),
- wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[0], m_radioBoxChoices0, 1, wxRA_SPECIFY_ROWS);
-
- wxStaticBoxSizer * m_optionsSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Settings"));
- m_options = new wxCheckListBox(this, IDM_OPTIONS, wxDefaultPosition, wxDefaultSize,
- 0, NULL, wxNO_BORDER);
- m_options->Append(wxT("Unify"));
- m_options->Append(wxT("Resolve symbols"));
- m_options->Append(wxT("Write master"));
- m_options->Append(wxT("Show unique"));
- m_optionsSizer->Add(m_options, 0, 0, 0);
-
- // I could not find any transparency setting and it would not automatically space correctly
- m_options->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
- m_options->SetMinSize(wxSize(m_options->GetSize().GetWidth() - 40,
- m_options->GetCount() * 15));
- #ifdef _WIN32
- for (int i = 0; i < m_options->GetCount(); ++i)
- m_options->GetItem(i)->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
- #endif
-
- m_checks = new wxCheckListBox(this, IDM_LOGCHECKS, wxDefaultPosition, wxSize(120, 280));
-
- // finally add it to the sizer
- sizerLeft->Add(m_RadioBox[0], 0, wxGROW);
- sizerLeft->Add(m_optionsSizer, 0, wxGROW);
- sizerLeft->Add(m_checks, 1, wxGROW);
-
-
- // right windows -----------------------------------------------------
- m_log = new wxTextCtrl(this, IDM_LOG, _T(""), wxDefaultPosition, wxSize(600, 120),
- wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP);
- m_cmdline = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition);
- wxButton* btn = new wxButton(this, IDM_SUBMITCMD, _T("Submit"));
-
- sizerTop->Add(new wxButton(this, IDM_UPDATELOG, _T("Update")));
- sizerTop->Add(new wxButton(this, IDM_CLEARLOG, _T("Clear")));
- sizerTop->Add(new wxButton(this, IDM_ENABLEALL, _T("Enable all")));
-
- sizerBottom->Add(m_cmdline, 8, wxGROW | wxRIGHT, 5);
- sizerBottom->Add(btn, 1, wxGROW, 0);
-
- sizerBig->Add(sizerTop, 0, wxGROW);
- sizerBig->Add(m_log, 1, wxGROW | wxSHRINK);
- sizerBig->Add(sizerBottom, 0, wxGROW);
-
- sizerUber->Add(sizerLeft, 0, wxGROW);
- sizerUber->Add(sizerBig, 1, wxGROW);
-
- SetSizer(sizerUber);
- SetAffirmativeId(IDM_SUBMITCMD);
-
- // declare this now to be able to use it in Load()
- LogManager::m_LogSettings = new CDebugger_LogSettings;
-
- //sizerTop->SetSizeHints(this);
- //sizerTop->Fit(this);
- UpdateChecks();
- m_cmdline->SetFocus();
- m_bCheckDirty = false;
-
- /* Load ini from here instead of from CodeWindow.cpp to make sure that
- settings are loaded if the window is showing */
- IniFile file;
- file.Load(DEBUGGER_CONFIG_FILE);
- Load(file);
-}
-
-
-// =======================================================
-// This is called from the CodeWindow deconstruction function.
-// -------------
-void CLogWindow::Save(IniFile& _IniFile) const
-{
- _IniFile.Set("LogWindow", "x", GetPosition().x);
- _IniFile.Set("LogWindow", "y", GetPosition().y);
- _IniFile.Set("LogWindow", "w", GetSize().GetWidth());
- _IniFile.Set("LogWindow", "h", GetSize().GetHeight());
-}
-
-
-// =======================================================
-// This is called from the class construction function.
-// -------------
-void CLogWindow::Load(IniFile& _IniFile)
-{
- int x,y,w,h;
- _IniFile.Get("LogWindow", "x", &x, GetPosition().x);
- _IniFile.Get("LogWindow", "y", &y, GetPosition().y);
- _IniFile.Get("LogWindow", "w", &w, GetSize().GetWidth());
- _IniFile.Get("LogWindow", "h", &h, GetSize().GetHeight());
- SetSize(x, y, w, h);
-
- // Load verbosity setting
- int v;
- _IniFile.Get("LogWindow", "Verbosity", &v, m_RadioBox[0]->GetSelection());
- m_RadioBox[0]->SetSelection(v);
- LogManager::m_LogSettings->m_iVerbosity = v;
-
- // Load options
- _IniFile.Get("LogWindow", "Unify", &LogManager::m_LogSettings->bUnify, false);
- _IniFile.Get("LogWindow", "ResolveSymbols", &LogManager::m_LogSettings->bResolve, false);
- _IniFile.Get("LogWindow", "WriteMaster", &LogManager::m_LogSettings->bWriteMaster, false);
- _IniFile.Get("LogWindow", "OnlyUnique", &bOnlyUnique, false);
- m_options->Check(0, LogManager::m_LogSettings->bUnify);
- m_options->Check(1, LogManager::m_LogSettings->bResolve);
- m_options->Check(2, LogManager::m_LogSettings->bWriteMaster);
- m_options->Check(3, bOnlyUnique);
-
- // If we use the Unify option
- if(LogManager::m_LogSettings->bUnify)
- {
- m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS);
- LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS;
- m_RadioBox[0]->Disable();
- }
-}
-
-void CLogWindow::OnSubmit(wxCommandEvent& event)
-{
- Console_Submit(m_cmdline->GetValue().To8BitData());
- m_cmdline->SetValue(_T(""));
- NotifyUpdate();
-}
-
-
-void CLogWindow::OnClear(wxCommandEvent& event)
-{
- if (Core::GetState() != Core::CORE_UNINITIALIZED) // avoid crash
- {
- LogManager::Clear();
- LOG(MASTER_LOG, "(log cleared).");
- NotifyUpdate();
- }
-}
-
-
-// ----------------------------------------------------------------------------------------
-// Enable or disable all boxes for the current verbosity level and save the changes.
-// -------------
-void CLogWindow::OnEnableAll(wxCommandEvent& event)
-{
- if (!LogManager::m_Log[0])
- return;
- static bool enable = true;
- int v = LogManager::m_LogSettings->m_iVerbosity;
- IniFile ini;
- ini.Load(DEBUGGER_CONFIG_FILE);
-
- // Unified case. Write the same to all levels.
- if(m_options->IsChecked(0))
- {
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- m_checks->Check(i, enable); // get all from the current selection
- for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
- {
- LogManager::m_Log[i + j*100]->m_bEnable = enable;
- LogManager::m_Log[i + j*100]->m_bShowInLog = enable;
- ini.Set("LogManager", LogManager::m_Log[i + j*100]->m_szShortName, enable);
- }
- }
- }
- else // otherwise only update the current shown level
- {
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- m_checks->Check(i, enable);
- LogManager::m_Log[i + v*100]->m_bEnable = enable;
- LogManager::m_Log[i + v*100]->m_bShowInLog = enable;
- ini.Set("LogManager", LogManager::m_Log[i + v*100]->m_szShortName, enable);
- }
- }
-
-
- ini.Save(DEBUGGER_CONFIG_FILE);
- enable = !enable;
-}
-
-
-// ----------------------------------------------------------------------------------------
-// Append checkboxes and update checked groups.
-// -------------
-void CLogWindow::UpdateChecks()
-{
- if (!LogManager::m_bInitialized)
- {
- return;
- }
-
- // This is only run once to append checkboxes to the wxCheckListBox.
- if (m_checks->GetCount() == 0)
- {
- // [F|RES] hide the window while we fill it... wxwidgets gets trouble if you don't do it
- // (at least the win version)
- m_checks->Show(false);
-
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- m_checks->Append(wxString::FromAscii(LogManager::m_Log[i]->m_szName));
- }
-
- m_checks->Show(true);
- }
-
- // ----------------------------------------------------------------------------------------
- // Load the correct values and enable/disable the right groups
- // -------------
- int v = LogManager::m_LogSettings->m_iVerbosity;
- IniFile ini;
- ini.Load(DEBUGGER_CONFIG_FILE);
-
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
- {
- bool Enabled = false;
- ini.Get("LogManager", LogManager::m_Log[i + j*100]->m_szShortName, &Enabled, false);
- LogManager::m_Log[i + j*100]->m_bEnable = Enabled;
- LogManager::m_Log[i + j*100]->m_bShowInLog = Enabled;
- if(j == v) m_checks->Check(i, Enabled);
- }
- }
-
- m_bCheckDirty = true;
-}
-
-
-// ----------------------------------------------------------------------------------------
-// When an option is changed, save the change
-// ---------------
-void CLogWindow::OnOptionsCheck(wxCommandEvent& event)
-{
- IniFile ini;
- ini.Load(DEBUGGER_CONFIG_FILE);
-
- //PanicAlert("%i", (int)Core::GetState());
-
- // Unified case. If the core is uninitialized we only disable the radio boxes
- if(m_options->IsChecked(0) && Core::GetState() == Core::CORE_UNINITIALIZED)
- {
- m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS);
- LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS;
- m_RadioBox[0]->Disable();
- }
- // otherwise we both disable them and update all blocks
- else if(m_options->IsChecked(0) && Core::GetState() != Core::CORE_UNINITIALIZED)
- {
- m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS);
- LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS;
- m_RadioBox[0]->Disable();
-
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- bool Enabled = m_checks->IsChecked(i); // get all from the current i
- for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
- {
- // update groups to enabled or disabled
- LogManager::m_Log[i + 100*j]->m_bEnable = Enabled;
- LogManager::m_Log[i + 100*j]->m_bShowInLog = Enabled;
-
- // update all verbosity levels to this level's Enabled
- ini.Set("LogManager", LogManager::m_Log[i + 100*j]->m_szShortName, Enabled);
- }
- }
- }
- else
- {
- m_RadioBox[0]->Enable(true);
- }
-
- LogManager::m_LogSettings->bUnify = m_options->IsChecked(0);
- LogManager::m_LogSettings->bResolve = m_options->IsChecked(1);
- LogManager::m_LogSettings->bWriteMaster = m_options->IsChecked(2);
- bOnlyUnique = m_options->IsChecked(3);
-
- ini.Set("LogWindow", "Unify", m_options->IsChecked(0));
- ini.Set("LogWindow", "ResolveSymbols", m_options->IsChecked(1));
- ini.Set("LogWindow", "WriteMaster", m_options->IsChecked(2));
- ini.Set("LogWindow", "OnlyUnique", m_options->IsChecked(3));
- ini.Save(DEBUGGER_CONFIG_FILE);
- if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog();
-}
-
-
-// ----------------------------------------------------------------------------------------
-// When a checkbox is changed
-// ---------------
-void CLogWindow::OnLogCheck(wxCommandEvent& event)
-{
- if (!LogManager::m_bInitialized) return;
-
- IniFile ini;
- ini.Load(DEBUGGER_CONFIG_FILE);
- int v = LogManager::m_LogSettings->m_iVerbosity; // current radio button
- int uni = LogManager::m_LogSettings->bUnify;
-
- // Unified case
- if(uni)
- {
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
- {
- // update groups to enabled or disabled
- bool Enabled = m_checks->IsChecked(i); // get all from the current i
- LogManager::m_Log[i + 100*j]->m_bEnable = Enabled;
- LogManager::m_Log[i + 100*j]->m_bShowInLog = Enabled;
-
- ini.Set("LogManager", LogManager::m_Log[i + 100*j]->m_szShortName, Enabled);
- }
- }
- }
- else
- {
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- // update groups to enabled or disabled
- bool Enabled = m_checks->IsChecked(i);
- LogManager::m_Log[i + 100*v]->m_bEnable = Enabled;
- LogManager::m_Log[i + 100*v]->m_bShowInLog = Enabled;
-
- ini.Set("LogManager", LogManager::m_Log[i + 100*v]->m_szShortName, Enabled);
- }
- }
-
- ini.Save(DEBUGGER_CONFIG_FILE);
-
- m_bCheckDirty = true;
- if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog();
-}
-
-
-// ----------------------------------------------------------------------------------------
-// When the verbosity level is changed
-// -------------
-void CLogWindow::OnRadioChange(wxCommandEvent& event)
-{
- // get selection
- int v = m_RadioBox[0]->GetSelection();
-
- // save it
- LogManager::m_LogSettings->m_iVerbosity = v;
- IniFile ini;
- ini.Load(DEBUGGER_CONFIG_FILE);
- ini.Set("LogWindow", "Verbosity", v);
- ini.Save(DEBUGGER_CONFIG_FILE);
-
- // This check is because we allow this to be changed before a game has been loaded so
- // that the boxes do not exist yet
- if (Core::GetState() != Core::CORE_UNINITIALIZED)
- {
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
- // update groups to enabled or disabled
- bool Enabled;
- ini.Get("LogManager", LogManager::m_Log[i + 100*v]->m_szShortName, &Enabled, false);
- LogManager::m_Log[i + 100*v]->m_bEnable = Enabled;
- LogManager::m_Log[i + 100*v]->m_bShowInLog = Enabled;
- m_checks->Check(i, Enabled);
- }
-
- m_bCheckDirty = true;
- UpdateLog();
- }
-}
-
-
-void CLogWindow::OnUpdateLog(wxCommandEvent& event)
-{
- if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog();
-}
-
-
-void CLogWindow::NotifyUpdate()
-{
- UpdateChecks();
- UpdateLog();
-}
-
-
-void CLogWindow::UpdateLog()
-{
- static int last = -1;
- int v = LogManager::m_LogSettings->m_iVerbosity;
- int i = LogManager::m_nextMessages[v];
-
- // check if the the log has been updated (ie if it's dirty)
- if ((last == i) && !m_bCheckDirty)
- {
- return;
- }
- m_bCheckDirty = false;
- last = i;
-
- // ----------------------------------------------------------------------------------------
- // Prepare a selection of the memory log to show to screen
- // ---------------
- int count = 0;
- char* p = m_logBuffer;
-
- // go through all rows
- while (count < MAX_MESSAGES)
- {
- count++;
- const LogManager::SMessage& message = LogManager::m_Messages[v][i];
-
- if (message.m_bInUse) // check if the line has a value
- {
- int len = message.m_dwMsgLen;
-
- // this is what we use, I'm not sure why we have this option
- if (LogManager::m_activeLog == LogTypes::MASTER_LOG)
- {
- // only show checkboxed logs
- if (LogManager::m_Log[message.m_type]->m_bShowInLog)
- {
- if(bOnlyUnique) /* don't show lower level messages that have fallen through
- to this higher level */
- {
- if(message.m_verbosity == v)
- {
- // memcpy is faster than strcpy
- memcpy(p, message.m_szMessage, len);
- p += len;
- }
- }
- else
- {
- // memcpy is faster than strcpy
- memcpy(p, message.m_szMessage, len);
- p += len;
- }
- }
- }
- else
- {
- if (message.m_type == LogManager::m_activeLog)
- {
- memcpy(p, message.m_szMessage, len);
- p += len;
- }
- }
- }
-
- i++;
-
- if (i >= MAX_MESSAGES)
- {
- i = 0;
- }
- }
- // ---------------
-
- *p = 0; //end the string
- m_log->SetValue(wxString::FromAscii(m_logBuffer));
- m_log->SetInsertionPoint(p - m_logBuffer - 1);
- m_log->ShowPosition( m_log->GetLastPosition()); // show last line
-}
-
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "LogManager.h" + +#include <wx/button.h> +#include <wx/textctrl.h> +#include <wx/listbox.h> +#include <wx/checklst.h> + +#include "Core.h" // for Core::GetState() +#include "LogWindow.h" +#include "Console.h" +#include "IniFile.h" + +// declare this now to be able to use it in Load() +CDebugger_LogSettings* LogManager::m_LogSettings; + +BEGIN_EVENT_TABLE(CLogWindow, wxDialog) + EVT_BUTTON(IDM_SUBMITCMD, CLogWindow::OnSubmit) + EVT_BUTTON(IDM_UPDATELOG, CLogWindow::OnUpdateLog) + EVT_BUTTON(IDM_CLEARLOG, CLogWindow::OnClear) + EVT_BUTTON(IDM_ENABLEALL, CLogWindow::OnEnableAll) + EVT_CHECKLISTBOX(IDM_OPTIONS, CLogWindow::OnOptionsCheck) + EVT_CHECKLISTBOX(IDM_LOGCHECKS, CLogWindow::OnLogCheck) + EVT_RADIOBOX(IDM_RADIO0, CLogWindow::OnRadioChange) +END_EVENT_TABLE() + + +CLogWindow::CLogWindow(wxWindow* parent) + : wxDialog(parent, wxID_ANY, _T("Log/Console"), wxPoint(100, 700), wxSize(800, 270), + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + wxBoxSizer* sizerTop = new wxBoxSizer(wxHORIZONTAL), // buttons + * sizerUber = new wxBoxSizer(wxHORIZONTAL), // whole plane + * sizerBig = new wxBoxSizer(wxVERTICAL), // RIGHT sizer + * sizerBottom = new wxBoxSizer(wxHORIZONTAL), // submit row + * sizerLeft = new wxBoxSizer(wxVERTICAL); // LEFT sizer + + // left checkboxes and radio boxes ----------------------------------- + int m_radioBoxNChoices[1]; + wxString m_radioBoxChoices0[] = { wxT("0"), wxT("1"), wxT("2"), wxT("3") }; + m_radioBoxNChoices[0] = sizeof( m_radioBoxChoices0 ) / sizeof( wxString ); + m_RadioBox[0] = new wxRadioBox( this, IDM_RADIO0, wxT("Verbosity"), + wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[0], m_radioBoxChoices0, 1, wxRA_SPECIFY_ROWS); + + wxStaticBoxSizer * m_optionsSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Settings")); + m_options = new wxCheckListBox(this, IDM_OPTIONS, wxDefaultPosition, wxDefaultSize, + 0, NULL, wxNO_BORDER); + m_options->Append(wxT("Unify")); + m_options->Append(wxT("Resolve symbols")); + m_options->Append(wxT("Write master")); + m_options->Append(wxT("Show unique")); + m_optionsSizer->Add(m_options, 0, 0, 0); + + // I could not find any transparency setting and it would not automatically space correctly + m_options->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); + m_options->SetMinSize(wxSize(m_options->GetSize().GetWidth() - 40, + m_options->GetCount() * 15)); + #ifdef _WIN32 + for (int i = 0; i < m_options->GetCount(); ++i) + m_options->GetItem(i)->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); + #endif + + m_checks = new wxCheckListBox(this, IDM_LOGCHECKS, wxDefaultPosition, wxSize(120, 280)); + + // finally add it to the sizer + sizerLeft->Add(m_RadioBox[0], 0, wxGROW); + sizerLeft->Add(m_optionsSizer, 0, wxGROW); + sizerLeft->Add(m_checks, 1, wxGROW); + + + // right windows ----------------------------------------------------- + m_log = new wxTextCtrl(this, IDM_LOG, _T(""), wxDefaultPosition, wxSize(600, 120), + wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP); + m_cmdline = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition); + wxButton* btn = new wxButton(this, IDM_SUBMITCMD, _T("Submit")); + + sizerTop->Add(new wxButton(this, IDM_UPDATELOG, _T("Update"))); + sizerTop->Add(new wxButton(this, IDM_CLEARLOG, _T("Clear"))); + sizerTop->Add(new wxButton(this, IDM_ENABLEALL, _T("Enable all"))); + + sizerBottom->Add(m_cmdline, 8, wxGROW | wxRIGHT, 5); + sizerBottom->Add(btn, 1, wxGROW, 0); + + sizerBig->Add(sizerTop, 0, wxGROW); + sizerBig->Add(m_log, 1, wxGROW | wxSHRINK); + sizerBig->Add(sizerBottom, 0, wxGROW); + + sizerUber->Add(sizerLeft, 0, wxGROW); + sizerUber->Add(sizerBig, 1, wxGROW); + + SetSizer(sizerUber); + SetAffirmativeId(IDM_SUBMITCMD); + + // declare this now to be able to use it in Load() + LogManager::m_LogSettings = new CDebugger_LogSettings; + + //sizerTop->SetSizeHints(this); + //sizerTop->Fit(this); + UpdateChecks(); + m_cmdline->SetFocus(); + m_bCheckDirty = false; + + /* Load ini from here instead of from CodeWindow.cpp to make sure that + settings are loaded if the window is showing */ + IniFile file; + file.Load(DEBUGGER_CONFIG_FILE); + Load(file); +} + + +// ======================================================= +// This is called from the CodeWindow deconstruction function. +// ------------- +void CLogWindow::Save(IniFile& _IniFile) const +{ + _IniFile.Set("LogWindow", "x", GetPosition().x); + _IniFile.Set("LogWindow", "y", GetPosition().y); + _IniFile.Set("LogWindow", "w", GetSize().GetWidth()); + _IniFile.Set("LogWindow", "h", GetSize().GetHeight()); +} + + +// ======================================================= +// This is called from the class construction function. +// ------------- +void CLogWindow::Load(IniFile& _IniFile) +{ + int x,y,w,h; + _IniFile.Get("LogWindow", "x", &x, GetPosition().x); + _IniFile.Get("LogWindow", "y", &y, GetPosition().y); + _IniFile.Get("LogWindow", "w", &w, GetSize().GetWidth()); + _IniFile.Get("LogWindow", "h", &h, GetSize().GetHeight()); + SetSize(x, y, w, h); + + // Load verbosity setting + int v; + _IniFile.Get("LogWindow", "Verbosity", &v, m_RadioBox[0]->GetSelection()); + m_RadioBox[0]->SetSelection(v); + LogManager::m_LogSettings->m_iVerbosity = v; + + // Load options + _IniFile.Get("LogWindow", "Unify", &LogManager::m_LogSettings->bUnify, false); + _IniFile.Get("LogWindow", "ResolveSymbols", &LogManager::m_LogSettings->bResolve, false); + _IniFile.Get("LogWindow", "WriteMaster", &LogManager::m_LogSettings->bWriteMaster, false); + _IniFile.Get("LogWindow", "OnlyUnique", &bOnlyUnique, false); + m_options->Check(0, LogManager::m_LogSettings->bUnify); + m_options->Check(1, LogManager::m_LogSettings->bResolve); + m_options->Check(2, LogManager::m_LogSettings->bWriteMaster); + m_options->Check(3, bOnlyUnique); + + // If we use the Unify option + if(LogManager::m_LogSettings->bUnify) + { + m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS); + LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS; + m_RadioBox[0]->Disable(); + } +} + +void CLogWindow::OnSubmit(wxCommandEvent& event) +{ + Console_Submit(m_cmdline->GetValue().To8BitData()); + m_cmdline->SetValue(_T("")); + NotifyUpdate(); +} + + +void CLogWindow::OnClear(wxCommandEvent& event) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) // avoid crash + { + LogManager::Clear(); + LOG(MASTER_LOG, "(log cleared)."); + NotifyUpdate(); + } +} + + +// ---------------------------------------------------------------------------------------- +// Enable or disable all boxes for the current verbosity level and save the changes. +// ------------- +void CLogWindow::OnEnableAll(wxCommandEvent& event) +{ + if (!LogManager::m_Log[0]) + return; + static bool enable = true; + int v = LogManager::m_LogSettings->m_iVerbosity; + IniFile ini; + ini.Load(DEBUGGER_CONFIG_FILE); + + // Unified case. Write the same to all levels. + if(m_options->IsChecked(0)) + { + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + m_checks->Check(i, enable); // get all from the current selection + for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++) + { + LogManager::m_Log[i + j*100]->m_bEnable = enable; + LogManager::m_Log[i + j*100]->m_bShowInLog = enable; + ini.Set("LogManager", LogManager::m_Log[i + j*100]->m_szShortName, enable); + } + } + } + else // otherwise only update the current shown level + { + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + m_checks->Check(i, enable); + LogManager::m_Log[i + v*100]->m_bEnable = enable; + LogManager::m_Log[i + v*100]->m_bShowInLog = enable; + ini.Set("LogManager", LogManager::m_Log[i + v*100]->m_szShortName, enable); + } + } + + + ini.Save(DEBUGGER_CONFIG_FILE); + enable = !enable; +} + + +// ---------------------------------------------------------------------------------------- +// Append checkboxes and update checked groups. +// ------------- +void CLogWindow::UpdateChecks() +{ + if (!LogManager::m_bInitialized) + { + return; + } + + // This is only run once to append checkboxes to the wxCheckListBox. + if (m_checks->GetCount() == 0) + { + // [F|RES] hide the window while we fill it... wxwidgets gets trouble if you don't do it + // (at least the win version) + m_checks->Show(false); + + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + m_checks->Append(wxString::FromAscii(LogManager::m_Log[i]->m_szName)); + } + + m_checks->Show(true); + } + + // ---------------------------------------------------------------------------------------- + // Load the correct values and enable/disable the right groups + // ------------- + int v = LogManager::m_LogSettings->m_iVerbosity; + IniFile ini; + ini.Load(DEBUGGER_CONFIG_FILE); + + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++) + { + bool Enabled = false; + ini.Get("LogManager", LogManager::m_Log[i + j*100]->m_szShortName, &Enabled, false); + LogManager::m_Log[i + j*100]->m_bEnable = Enabled; + LogManager::m_Log[i + j*100]->m_bShowInLog = Enabled; + if(j == v) m_checks->Check(i, Enabled); + } + } + + m_bCheckDirty = true; +} + + +// ---------------------------------------------------------------------------------------- +// When an option is changed, save the change +// --------------- +void CLogWindow::OnOptionsCheck(wxCommandEvent& event) +{ + IniFile ini; + ini.Load(DEBUGGER_CONFIG_FILE); + + //PanicAlert("%i", (int)Core::GetState()); + + // Unified case. If the core is uninitialized we only disable the radio boxes + if(m_options->IsChecked(0) && Core::GetState() == Core::CORE_UNINITIALIZED) + { + m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS); + LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS; + m_RadioBox[0]->Disable(); + } + // otherwise we both disable them and update all blocks + else if(m_options->IsChecked(0) && Core::GetState() != Core::CORE_UNINITIALIZED) + { + m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS); + LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS; + m_RadioBox[0]->Disable(); + + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + bool Enabled = m_checks->IsChecked(i); // get all from the current i + for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++) + { + // update groups to enabled or disabled + LogManager::m_Log[i + 100*j]->m_bEnable = Enabled; + LogManager::m_Log[i + 100*j]->m_bShowInLog = Enabled; + + // update all verbosity levels to this level's Enabled + ini.Set("LogManager", LogManager::m_Log[i + 100*j]->m_szShortName, Enabled); + } + } + } + else + { + m_RadioBox[0]->Enable(true); + } + + LogManager::m_LogSettings->bUnify = m_options->IsChecked(0); + LogManager::m_LogSettings->bResolve = m_options->IsChecked(1); + LogManager::m_LogSettings->bWriteMaster = m_options->IsChecked(2); + bOnlyUnique = m_options->IsChecked(3); + + ini.Set("LogWindow", "Unify", m_options->IsChecked(0)); + ini.Set("LogWindow", "ResolveSymbols", m_options->IsChecked(1)); + ini.Set("LogWindow", "WriteMaster", m_options->IsChecked(2)); + ini.Set("LogWindow", "OnlyUnique", m_options->IsChecked(3)); + ini.Save(DEBUGGER_CONFIG_FILE); + if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog(); +} + + +// ---------------------------------------------------------------------------------------- +// When a checkbox is changed +// --------------- +void CLogWindow::OnLogCheck(wxCommandEvent& event) +{ + if (!LogManager::m_bInitialized) return; + + IniFile ini; + ini.Load(DEBUGGER_CONFIG_FILE); + int v = LogManager::m_LogSettings->m_iVerbosity; // current radio button + int uni = LogManager::m_LogSettings->bUnify; + + // Unified case + if(uni) + { + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++) + { + // update groups to enabled or disabled + bool Enabled = m_checks->IsChecked(i); // get all from the current i + LogManager::m_Log[i + 100*j]->m_bEnable = Enabled; + LogManager::m_Log[i + 100*j]->m_bShowInLog = Enabled; + + ini.Set("LogManager", LogManager::m_Log[i + 100*j]->m_szShortName, Enabled); + } + } + } + else + { + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + // update groups to enabled or disabled + bool Enabled = m_checks->IsChecked(i); + LogManager::m_Log[i + 100*v]->m_bEnable = Enabled; + LogManager::m_Log[i + 100*v]->m_bShowInLog = Enabled; + + ini.Set("LogManager", LogManager::m_Log[i + 100*v]->m_szShortName, Enabled); + } + } + + ini.Save(DEBUGGER_CONFIG_FILE); + + m_bCheckDirty = true; + if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog(); +} + + +// ---------------------------------------------------------------------------------------- +// When the verbosity level is changed +// ------------- +void CLogWindow::OnRadioChange(wxCommandEvent& event) +{ + // get selection + int v = m_RadioBox[0]->GetSelection(); + + // save it + LogManager::m_LogSettings->m_iVerbosity = v; + IniFile ini; + ini.Load(DEBUGGER_CONFIG_FILE); + ini.Set("LogWindow", "Verbosity", v); + ini.Save(DEBUGGER_CONFIG_FILE); + + // This check is because we allow this to be changed before a game has been loaded so + // that the boxes do not exist yet + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) + { + // update groups to enabled or disabled + bool Enabled; + ini.Get("LogManager", LogManager::m_Log[i + 100*v]->m_szShortName, &Enabled, false); + LogManager::m_Log[i + 100*v]->m_bEnable = Enabled; + LogManager::m_Log[i + 100*v]->m_bShowInLog = Enabled; + m_checks->Check(i, Enabled); + } + + m_bCheckDirty = true; + UpdateLog(); + } +} + + +void CLogWindow::OnUpdateLog(wxCommandEvent& event) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog(); +} + + +void CLogWindow::NotifyUpdate() +{ + UpdateChecks(); + UpdateLog(); +} + + +void CLogWindow::UpdateLog() +{ + static int last = -1; + int v = LogManager::m_LogSettings->m_iVerbosity; + int i = LogManager::m_nextMessages[v]; + + // check if the the log has been updated (ie if it's dirty) + if ((last == i) && !m_bCheckDirty) + { + return; + } + m_bCheckDirty = false; + last = i; + + // ---------------------------------------------------------------------------------------- + // Prepare a selection of the memory log to show to screen + // --------------- + int count = 0; + char* p = m_logBuffer; + + // go through all rows + while (count < MAX_MESSAGES) + { + count++; + const LogManager::SMessage& message = LogManager::m_Messages[v][i]; + + if (message.m_bInUse) // check if the line has a value + { + int len = message.m_dwMsgLen; + + // this is what we use, I'm not sure why we have this option + if (LogManager::m_activeLog == LogTypes::MASTER_LOG) + { + // only show checkboxed logs + if (LogManager::m_Log[message.m_type]->m_bShowInLog) + { + if(bOnlyUnique) /* don't show lower level messages that have fallen through + to this higher level */ + { + if(message.m_verbosity == v) + { + // memcpy is faster than strcpy + memcpy(p, message.m_szMessage, len); + p += len; + } + } + else + { + // memcpy is faster than strcpy + memcpy(p, message.m_szMessage, len); + p += len; + } + } + } + else + { + if (message.m_type == LogManager::m_activeLog) + { + memcpy(p, message.m_szMessage, len); + p += len; + } + } + } + + i++; + + if (i >= MAX_MESSAGES) + { + i = 0; + } + } + // --------------- + + *p = 0; //end the string + m_log->SetValue(wxString::FromAscii(m_logBuffer)); + m_log->SetInsertionPoint(p - m_logBuffer - 1); + m_log->ShowPosition( m_log->GetLastPosition()); // show last line +} + + diff --git a/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp b/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp index 41e09aec49..2adc1413c7 100644 --- a/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp +++ b/Source/Core/DebuggerWX/Src/MemoryCheckDlg.cpp @@ -1,112 +1,112 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "MemoryCheckDlg.h"
-#include "Common.h"
-#include "Debugger.h"
-#include "StringUtil.h"
-#include "Debugger/Debugger_BreakPoints.h"
-
-BEGIN_EVENT_TABLE(MemoryCheckDlg,wxDialog)
- EVT_CLOSE(MemoryCheckDlg::OnClose)
- EVT_BUTTON(ID_OK, MemoryCheckDlg::OnOK)
- EVT_BUTTON(ID_CANCEL, MemoryCheckDlg::OnCancel)
-END_EVENT_TABLE()
-
-
-MemoryCheckDlg::MemoryCheckDlg(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
-: wxDialog(parent, id, title, position, size, style)
-{
- CreateGUIControls();
-}
-
-MemoryCheckDlg::~MemoryCheckDlg()
-{
-}
-
-void MemoryCheckDlg::CreateGUIControls()
-{
- SetIcon(wxNullIcon);
- SetSize(8,8,415,122);
- Center();
-
- m_pButtonCancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxPoint(248,64), wxSize(73,25), 0, wxDefaultValidator, wxT("Cancel"));
- m_pButtonCancel->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pButtonOK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(328,64), wxSize(73,25), 0, wxDefaultValidator, wxT("OK"));
- m_pButtonOK->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pReadFlag = new wxCheckBox(this, ID_READ_FLAG, wxT("Read"), wxPoint(336,33), wxSize(57,15), 0, wxDefaultValidator, wxT("Read"));
- m_pReadFlag->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pWriteFlag = new wxCheckBox(this, ID_WRITE_FLAG, wxT("Write"), wxPoint(336,16), wxSize(57,17), 0, wxDefaultValidator, wxT("WxCheckBox1"));
- m_pWriteFlag->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- wxStaticBox* WxStaticBox2 = new wxStaticBox(this, ID_WXSTATICBOX2, wxT("Break On"), wxPoint(328,0), wxSize(73,57));
- WxStaticBox2->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- wxStaticText* WxStaticText2 = new wxStaticText(this, ID_WXSTATICTEXT2, wxT("End"), wxPoint(168,24), wxDefaultSize, 0, wxT("WxStaticText2"));
- WxStaticText2->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- wxStaticText* WxStaticText1 = new wxStaticText(this, ID_WXSTATICTEXT1, wxT("Start"), wxPoint(8,24), wxDefaultSize, 0, wxT("WxStaticText1"));
- WxStaticText1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pEditStartAddress = new wxTextCtrl(this, ID_EDIT_START_ADDR, wxT("80000000"), wxPoint(40,24), wxSize(109,20), 0, wxDefaultValidator, wxT("WxEdit1"));
- m_pEditStartAddress->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- m_pEditEndAddress = new wxTextCtrl(this, ID_EDIT_END_ADDRESS, wxT("80000000"), wxPoint(200,24), wxSize(109,20), 0, wxDefaultValidator, wxT("WxEdit2"));
- m_pEditEndAddress->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-
- wxStaticBox* WxStaticBox1 = new wxStaticBox(this, ID_WXSTATICBOX1, wxT("Address Range"), wxPoint(0,0), wxSize(321,57));
- WxStaticBox1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma")));
-}
-
-void MemoryCheckDlg::OnClose(wxCloseEvent& /*event*/)
-{
- Destroy();
-}
-
-void MemoryCheckDlg::OnOK(wxCommandEvent& /*event*/)
-{
- wxString StartAddressString = m_pEditStartAddress->GetLineText(0);
- wxString EndAddressString = m_pEditEndAddress->GetLineText(0);
- bool OnRead = m_pReadFlag->GetValue();
- bool OnWrite = m_pWriteFlag->GetValue();
-
- u32 StartAddress, EndAddress;
- if (AsciiToHex(StartAddressString.mb_str(), StartAddress) &&
- AsciiToHex(EndAddressString.mb_str(), EndAddress))
- {
- TMemCheck MemCheck;
- MemCheck.StartAddress = StartAddress;
- MemCheck.EndAddress = EndAddress;
- MemCheck.OnRead = OnRead;
- MemCheck.OnWrite = OnWrite;
-
- MemCheck.Log = true;
- MemCheck.Break = true;
-
- CBreakPoints::AddMemoryCheck(MemCheck);
- CBreakPoints::UpdateBreakPointView();
- Close();
- }
-}
-
-void MemoryCheckDlg::OnCancel(wxCommandEvent& /*event*/)
-{
- Close();
-}
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "MemoryCheckDlg.h" +#include "Common.h" +#include "Debugger.h" +#include "StringUtil.h" +#include "Debugger/Debugger_BreakPoints.h" + +BEGIN_EVENT_TABLE(MemoryCheckDlg,wxDialog) + EVT_CLOSE(MemoryCheckDlg::OnClose) + EVT_BUTTON(ID_OK, MemoryCheckDlg::OnOK) + EVT_BUTTON(ID_CANCEL, MemoryCheckDlg::OnCancel) +END_EVENT_TABLE() + + +MemoryCheckDlg::MemoryCheckDlg(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style) +: wxDialog(parent, id, title, position, size, style) +{ + CreateGUIControls(); +} + +MemoryCheckDlg::~MemoryCheckDlg() +{ +} + +void MemoryCheckDlg::CreateGUIControls() +{ + SetIcon(wxNullIcon); + SetSize(8,8,415,122); + Center(); + + m_pButtonCancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxPoint(248,64), wxSize(73,25), 0, wxDefaultValidator, wxT("Cancel")); + m_pButtonCancel->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pButtonOK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(328,64), wxSize(73,25), 0, wxDefaultValidator, wxT("OK")); + m_pButtonOK->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pReadFlag = new wxCheckBox(this, ID_READ_FLAG, wxT("Read"), wxPoint(336,33), wxSize(57,15), 0, wxDefaultValidator, wxT("Read")); + m_pReadFlag->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pWriteFlag = new wxCheckBox(this, ID_WRITE_FLAG, wxT("Write"), wxPoint(336,16), wxSize(57,17), 0, wxDefaultValidator, wxT("WxCheckBox1")); + m_pWriteFlag->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + wxStaticBox* WxStaticBox2 = new wxStaticBox(this, ID_WXSTATICBOX2, wxT("Break On"), wxPoint(328,0), wxSize(73,57)); + WxStaticBox2->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + wxStaticText* WxStaticText2 = new wxStaticText(this, ID_WXSTATICTEXT2, wxT("End"), wxPoint(168,24), wxDefaultSize, 0, wxT("WxStaticText2")); + WxStaticText2->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + wxStaticText* WxStaticText1 = new wxStaticText(this, ID_WXSTATICTEXT1, wxT("Start"), wxPoint(8,24), wxDefaultSize, 0, wxT("WxStaticText1")); + WxStaticText1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pEditStartAddress = new wxTextCtrl(this, ID_EDIT_START_ADDR, wxT("80000000"), wxPoint(40,24), wxSize(109,20), 0, wxDefaultValidator, wxT("WxEdit1")); + m_pEditStartAddress->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + m_pEditEndAddress = new wxTextCtrl(this, ID_EDIT_END_ADDRESS, wxT("80000000"), wxPoint(200,24), wxSize(109,20), 0, wxDefaultValidator, wxT("WxEdit2")); + m_pEditEndAddress->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); + + wxStaticBox* WxStaticBox1 = new wxStaticBox(this, ID_WXSTATICBOX1, wxT("Address Range"), wxPoint(0,0), wxSize(321,57)); + WxStaticBox1->SetFont(wxFont(8, wxSWISS, wxNORMAL,wxNORMAL, false, wxT("Tahoma"))); +} + +void MemoryCheckDlg::OnClose(wxCloseEvent& /*event*/) +{ + Destroy(); +} + +void MemoryCheckDlg::OnOK(wxCommandEvent& /*event*/) +{ + wxString StartAddressString = m_pEditStartAddress->GetLineText(0); + wxString EndAddressString = m_pEditEndAddress->GetLineText(0); + bool OnRead = m_pReadFlag->GetValue(); + bool OnWrite = m_pWriteFlag->GetValue(); + + u32 StartAddress, EndAddress; + if (AsciiToHex(StartAddressString.mb_str(), StartAddress) && + AsciiToHex(EndAddressString.mb_str(), EndAddress)) + { + TMemCheck MemCheck; + MemCheck.StartAddress = StartAddress; + MemCheck.EndAddress = EndAddress; + MemCheck.OnRead = OnRead; + MemCheck.OnWrite = OnWrite; + + MemCheck.Log = true; + MemCheck.Break = true; + + CBreakPoints::AddMemoryCheck(MemCheck); + CBreakPoints::UpdateBreakPointView(); + Close(); + } +} + +void MemoryCheckDlg::OnCancel(wxCommandEvent& /*event*/) +{ + Close(); +} diff --git a/Source/Core/DebuggerWX/Src/MemoryView.cpp b/Source/Core/DebuggerWX/Src/MemoryView.cpp index 1aef490c51..b449a0c62c 100644 --- a/Source/Core/DebuggerWX/Src/MemoryView.cpp +++ b/Source/Core/DebuggerWX/Src/MemoryView.cpp @@ -1,430 +1,430 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "Common.h"
-
-#include "MemoryView.h"
-#include <wx/event.h>
-#include <wx/clipbrd.h>
-
-
-enum
-{
- IDM_GOTOINMEMVIEW = 12000,
- IDM_COPYADDRESS,
- IDM_COPYHEX,
- IDM_COPYCODE,
- IDM_RUNTOHERE,
- IDM_DYNARECRESULTS,
-};
-
-
-BEGIN_EVENT_TABLE(CMemoryView, wxControl)
-EVT_ERASE_BACKGROUND(CMemoryView::OnErase)
-EVT_PAINT(CMemoryView::OnPaint)
-EVT_LEFT_DOWN(CMemoryView::OnMouseDown)
-EVT_LEFT_UP(CMemoryView::OnMouseUpL)
-EVT_MOTION(CMemoryView::OnMouseMove)
-EVT_RIGHT_DOWN(CMemoryView::OnMouseDown)
-EVT_RIGHT_UP(CMemoryView::OnMouseUpR)
-EVT_MENU(-1, CMemoryView::OnPopupMenu)
-END_EVENT_TABLE()
-
-CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id, const wxSize& Size)
- : wxControl(parent, Id, wxDefaultPosition, Size),
- debugger(debuginterface),
- rowHeight(13),
- selection(0),
- oldSelection(0),
- selectionChanged(false),
- selecting(false),
- hasFocus(false),
- showHex(false)
-{
- rowHeight = 13;
- align = debuginterface->getInstructionSize(0);
- curAddress = debuginterface->getPC();
-}
-
-
-wxSize CMemoryView::DoGetBestSize() const
-{
- wxSize bestSize;
- bestSize.x = 300;
- bestSize.y = 300;
- return(bestSize);
-}
-
-
-int CMemoryView::YToAddress(int y)
-{
- wxRect rc = GetClientRect();
- int ydiff = y - rc.height / 2 - rowHeight / 2;
- ydiff = (int)(floorf((float)ydiff / (float)rowHeight)) + 1;
- return(curAddress + ydiff * align);
-}
-
-
-void CMemoryView::OnMouseDown(wxMouseEvent& event)
-{
- int x = event.m_x;
- int y = event.m_y;
-
- if (x > 16)
- {
- oldSelection = selection;
- selection = YToAddress(y);
- // SetCapture(wnd);
- bool oldselecting = selecting;
- selecting = true;
-
- if (!oldselecting || (selection != oldSelection))
- {
- redraw();
- }
- }
- else
- {
- debugger->toggleBreakpoint(YToAddress(y));
- redraw();
- }
-
- event.Skip(true);
-}
-
-
-void CMemoryView::OnMouseMove(wxMouseEvent& event)
-{
- wxRect rc = GetClientRect();
-
- if (event.m_leftDown)
- {
- if (event.m_x > 16)
- {
- if (event.m_y < 0)
- {
- curAddress -= align;
- redraw();
- }
- else if (event.m_y > rc.height)
- {
- curAddress += align;
- redraw();
- }
- else
- {
- OnMouseDown(event);
- }
- }
- }
-
- event.Skip(true);
-}
-
-
-void CMemoryView::OnMouseUpL(wxMouseEvent& event)
-{
- if (event.m_x > 16)
- {
- curAddress = YToAddress(event.m_y);
- selecting = false;
- //ReleaseCapture();
- redraw();
- }
-
- event.Skip(true);
-}
-
-
-void CMemoryView::OnPopupMenu(wxCommandEvent& event)
-{
-#if wxUSE_CLIPBOARD
- wxTheClipboard->Open();
-#endif
-
- switch (event.GetId())
- {
- case IDM_GOTOINMEMVIEW:
- // CMemoryDlg::Goto(selection);
- break;
-
-#if wxUSE_CLIPBOARD
- case IDM_COPYADDRESS:
- {
- wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%08x"), selection)));
- }
- break;
-
- case IDM_COPYCODE:
- wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(debugger->disasm(selection)))); //Have to manually convert from char* to wxString, don't have to in Windows?
- break;
-
- case IDM_COPYHEX:
- {
- char temp[24];
- sprintf(temp, "%08x", debugger->readMemory(selection));
- wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(temp)));
- }
- break;
-#endif
-
- case IDM_RUNTOHERE:
- {
- debugger->setBreakpoint(selection);
- debugger->runToBreakpoint();
- redraw();
- }
- break;
-
- case IDM_DYNARECRESULTS:
- {
-// CDynaViewDlg::ViewAddr(selection);
-// CDynaViewDlg::Show(TRUE);
-// MessageBox(NULL, "not impl", "CtrlDisAsmView", MB_OK);
- }
- break;
- }
-
-#if wxUSE_CLIPBOARD
- wxTheClipboard->Close();
-#endif
- event.Skip(true);
-}
-
-
-void CMemoryView::OnMouseUpR(wxMouseEvent& event)
-{
- // popup menu
- wxMenu menu;
- //menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view");
-#if wxUSE_CLIPBOARD
- menu.Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address"));
- menu.Append(IDM_COPYCODE, wxString::FromAscii("Copy &code"));
- menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex"));
-#endif
- menu.Append(IDM_RUNTOHERE, _T("&Run To Here"));
- //menu.Append(IDM_DYNARECRESULTS, "Copy &address");
- PopupMenu(&menu);
- event.Skip(true);
-}
-
-
-void CMemoryView::OnErase(wxEraseEvent& event)
-{}
-
-
-void CMemoryView::OnPaint(wxPaintEvent& event)
-{
- wxPaintDC dc(this);
- int fontSize = 8;
- wxRect rc = GetClientRect();
- wxFont font(fontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT);
- dc.SetFont(font);
- struct branch
- {
- int src, dst, srcAddr;
- };
-
- branch branches[256];
- int numBranches = 0;
- // TODO: Add any drawing code here...
- int width = rc.width;
- int numRows = (rc.height / rowHeight) / 2 + 2;
- //numRows=(numRows&(~1)) + 1;
- dc.SetBackgroundMode(wxTRANSPARENT);
- const wxChar* bgColor = _T("#ffffff");
- wxPen nullPen(bgColor);
- wxPen currentPen(_T("#000000"));
- wxPen selPen(_T("#808080")); // gray
- nullPen.SetStyle(wxTRANSPARENT);
-
- wxBrush currentBrush(_T("#FFEfE8")); // ligh gray
- wxBrush pcBrush(_T("#70FF70")); // green
- wxBrush bpBrush(_T("#FF3311")); // red
- wxBrush bgBrush(bgColor);
- wxBrush nullBrush(bgColor);
- nullBrush.SetStyle(wxTRANSPARENT);
-
- dc.SetPen(nullPen);
- dc.SetBrush(bgBrush);
- dc.DrawRectangle(0, 0, 16, rc.height);
- dc.DrawRectangle(0, 0, rc.width, 5+8);
- // TODO - clean up this freaking mess!!!!!
- int i;
-
- for (i = -numRows; i <= numRows; i++)
- {
- unsigned int address = curAddress + i * align;
-
- int rowY1 = rc.height / 2 + rowHeight * i - rowHeight / 2;
- int rowY2 = rc.height / 2 + rowHeight * i + rowHeight / 2;
-
- wxString temp = wxString::Format(_T("%08x"), address);
- u32 col = debugger->getColor(address);
- wxBrush rowBrush(wxColor(col >> 16, col >> 8, col));
- dc.SetBrush(nullBrush);
- dc.SetPen(nullPen);
- dc.DrawRectangle(0, rowY1, 16, rowY2);
-
- if (selecting && (address == selection))
- {
- dc.SetPen(selPen);
- }
- else
- {
- dc.SetPen(i == 0 ? currentPen : nullPen);
- }
-
- if (address == debugger->getPC())
- {
- dc.SetBrush(pcBrush);
- }
- else
- {
- dc.SetBrush(rowBrush);
- }
-
- dc.DrawRectangle(16, rowY1, width, rowY2 - 1);
- dc.SetBrush(currentBrush);
- dc.SetTextForeground(_T("#600000"));
- dc.DrawText(temp, 17, rowY1);
- char mem[256] = {0};
- strcpy(mem, debugger->getRawMemoryString(address));
- dc.SetTextForeground(_T("#000080"));
- dc.DrawText(wxString::FromAscii(mem), 17+fontSize*(8), rowY1);
- dc.SetTextForeground(_T("#000000"));
-
- if (debugger->isAlive())
- {
- char dis[256] = {0};
- strcpy(dis, debugger->disasm(address));
- char* dis2 = strchr(dis, '\t');
- char desc[256] = "";
-
- if (dis2)
- {
- *dis2 = 0;
- dis2++;
- const char* mojs = strstr(dis2, "0x8");
-
- if (mojs)
- {
- for (int k = 0; k < 8; k++)
- {
- bool found = false;
-
- for (int j = 0; j < 22; j++)
- {
- if (mojs[k + 2] == "0123456789ABCDEFabcdef"[j])
- {
- found = true;
- }
- }
-
-
- if (!found)
- {
- mojs = 0;
- break;
- }
- }
- }
-
- if (mojs)
- {
- int offs;
- sscanf(mojs + 2, "%08x", &offs);
- branches[numBranches].src = rowY1 + rowHeight / 2;
- branches[numBranches].srcAddr = address / align;
- branches[numBranches++].dst = (int)(rowY1 + ((s64)offs - (s64)address) * rowHeight / align + rowHeight / 2);
- sprintf(desc, "-->%s", debugger->getDescription(offs).c_str());
- dc.SetTextForeground(_T("#600060"));
- }
- else
- {
- dc.SetTextForeground(_T("#000000"));
- }
-
- dc.DrawText(wxString::FromAscii(dis2), 17+fontSize*(8+8+8), rowY1);
- }
-
- if (strcmp(dis, "blr"))
- {
- dc.SetTextForeground(_T("#007000"));
- }
- else
- {
- dc.SetTextForeground(_T("#8000FF"));
- }
-
- dc.DrawText(wxString::FromAscii(dis), 17+fontSize*(8+8), rowY1);
-
- if (desc[0] == 0)
- {
- strcpy(desc, debugger->getDescription(address).c_str());
- }
-
- dc.SetTextForeground(_T("#0000FF"));
-
- //char temp[256];
- //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE);
- if (strlen(desc))
- {
- dc.DrawText(wxString::FromAscii(desc), 17+fontSize*(8+8+8+30), rowY1);
- }
-
- if (debugger->isBreakpoint(address))
- {
- dc.SetBrush(bpBrush);
- dc.DrawRectangle(2, rowY1, 7, 7);
-// DrawIconEx(hdc, 2, rowY1, breakPoint, 32, 32, 0, 0, DI_NORMAL);
- }
- }
- }
-
- dc.SetPen(currentPen);
- /*
- for (i = 0; i < numBranches; i++)
- {
- int x = 250 + (branches[i].srcAddr % 9) * 8;
- MoveToEx(hdc, x-2, branches[i].src, 0);
-
- if (branches[i].dst < rect.bottom + 200 && branches[i].dst > -200)
- {
- LineTo(hdc, x+2, branches[i].src);
- LineTo(hdc, x+2, branches[i].dst);
- LineTo(hdc, x-4, branches[i].dst);
-
- MoveToEx(hdc, x, branches[i].dst - 4,0);
- LineTo(hdc, x-4, branches[i].dst);
- LineTo(hdc, x+1, branches[i].dst+5);
- }
- else
- {
- LineTo(hdc, x+4, branches[i].src);
- //MoveToEx(hdc,x+2,branches[i].dst-4,0);
- //LineTo(hdc,x+6,branches[i].dst);
- //LineTo(hdc,x+1,branches[i].dst+5);
- }
- //LineTo(hdc,x,branches[i].dst+4);
-
- //LineTo(hdc,x-2,branches[i].dst);
- }*/
-}
-
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "Common.h" + +#include "MemoryView.h" +#include <wx/event.h> +#include <wx/clipbrd.h> + + +enum +{ + IDM_GOTOINMEMVIEW = 12000, + IDM_COPYADDRESS, + IDM_COPYHEX, + IDM_COPYCODE, + IDM_RUNTOHERE, + IDM_DYNARECRESULTS, +}; + + +BEGIN_EVENT_TABLE(CMemoryView, wxControl) +EVT_ERASE_BACKGROUND(CMemoryView::OnErase) +EVT_PAINT(CMemoryView::OnPaint) +EVT_LEFT_DOWN(CMemoryView::OnMouseDown) +EVT_LEFT_UP(CMemoryView::OnMouseUpL) +EVT_MOTION(CMemoryView::OnMouseMove) +EVT_RIGHT_DOWN(CMemoryView::OnMouseDown) +EVT_RIGHT_UP(CMemoryView::OnMouseUpR) +EVT_MENU(-1, CMemoryView::OnPopupMenu) +END_EVENT_TABLE() + +CMemoryView::CMemoryView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id, const wxSize& Size) + : wxControl(parent, Id, wxDefaultPosition, Size), + debugger(debuginterface), + rowHeight(13), + selection(0), + oldSelection(0), + selectionChanged(false), + selecting(false), + hasFocus(false), + showHex(false) +{ + rowHeight = 13; + align = debuginterface->getInstructionSize(0); + curAddress = debuginterface->getPC(); +} + + +wxSize CMemoryView::DoGetBestSize() const +{ + wxSize bestSize; + bestSize.x = 300; + bestSize.y = 300; + return(bestSize); +} + + +int CMemoryView::YToAddress(int y) +{ + wxRect rc = GetClientRect(); + int ydiff = y - rc.height / 2 - rowHeight / 2; + ydiff = (int)(floorf((float)ydiff / (float)rowHeight)) + 1; + return(curAddress + ydiff * align); +} + + +void CMemoryView::OnMouseDown(wxMouseEvent& event) +{ + int x = event.m_x; + int y = event.m_y; + + if (x > 16) + { + oldSelection = selection; + selection = YToAddress(y); + // SetCapture(wnd); + bool oldselecting = selecting; + selecting = true; + + if (!oldselecting || (selection != oldSelection)) + { + redraw(); + } + } + else + { + debugger->toggleBreakpoint(YToAddress(y)); + redraw(); + } + + event.Skip(true); +} + + +void CMemoryView::OnMouseMove(wxMouseEvent& event) +{ + wxRect rc = GetClientRect(); + + if (event.m_leftDown) + { + if (event.m_x > 16) + { + if (event.m_y < 0) + { + curAddress -= align; + redraw(); + } + else if (event.m_y > rc.height) + { + curAddress += align; + redraw(); + } + else + { + OnMouseDown(event); + } + } + } + + event.Skip(true); +} + + +void CMemoryView::OnMouseUpL(wxMouseEvent& event) +{ + if (event.m_x > 16) + { + curAddress = YToAddress(event.m_y); + selecting = false; + //ReleaseCapture(); + redraw(); + } + + event.Skip(true); +} + + +void CMemoryView::OnPopupMenu(wxCommandEvent& event) +{ +#if wxUSE_CLIPBOARD + wxTheClipboard->Open(); +#endif + + switch (event.GetId()) + { + case IDM_GOTOINMEMVIEW: + // CMemoryDlg::Goto(selection); + break; + +#if wxUSE_CLIPBOARD + case IDM_COPYADDRESS: + { + wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%08x"), selection))); + } + break; + + case IDM_COPYCODE: + wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(debugger->disasm(selection)))); //Have to manually convert from char* to wxString, don't have to in Windows? + break; + + case IDM_COPYHEX: + { + char temp[24]; + sprintf(temp, "%08x", debugger->readMemory(selection)); + wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(temp))); + } + break; +#endif + + case IDM_RUNTOHERE: + { + debugger->setBreakpoint(selection); + debugger->runToBreakpoint(); + redraw(); + } + break; + + case IDM_DYNARECRESULTS: + { +// CDynaViewDlg::ViewAddr(selection); +// CDynaViewDlg::Show(TRUE); +// MessageBox(NULL, "not impl", "CtrlDisAsmView", MB_OK); + } + break; + } + +#if wxUSE_CLIPBOARD + wxTheClipboard->Close(); +#endif + event.Skip(true); +} + + +void CMemoryView::OnMouseUpR(wxMouseEvent& event) +{ + // popup menu + wxMenu menu; + //menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view"); +#if wxUSE_CLIPBOARD + menu.Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address")); + menu.Append(IDM_COPYCODE, wxString::FromAscii("Copy &code")); + menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex")); +#endif + menu.Append(IDM_RUNTOHERE, _T("&Run To Here")); + //menu.Append(IDM_DYNARECRESULTS, "Copy &address"); + PopupMenu(&menu); + event.Skip(true); +} + + +void CMemoryView::OnErase(wxEraseEvent& event) +{} + + +void CMemoryView::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + int fontSize = 8; + wxRect rc = GetClientRect(); + wxFont font(fontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT); + dc.SetFont(font); + struct branch + { + int src, dst, srcAddr; + }; + + branch branches[256]; + int numBranches = 0; + // TODO: Add any drawing code here... + int width = rc.width; + int numRows = (rc.height / rowHeight) / 2 + 2; + //numRows=(numRows&(~1)) + 1; + dc.SetBackgroundMode(wxTRANSPARENT); + const wxChar* bgColor = _T("#ffffff"); + wxPen nullPen(bgColor); + wxPen currentPen(_T("#000000")); + wxPen selPen(_T("#808080")); // gray + nullPen.SetStyle(wxTRANSPARENT); + + wxBrush currentBrush(_T("#FFEfE8")); // ligh gray + wxBrush pcBrush(_T("#70FF70")); // green + wxBrush bpBrush(_T("#FF3311")); // red + wxBrush bgBrush(bgColor); + wxBrush nullBrush(bgColor); + nullBrush.SetStyle(wxTRANSPARENT); + + dc.SetPen(nullPen); + dc.SetBrush(bgBrush); + dc.DrawRectangle(0, 0, 16, rc.height); + dc.DrawRectangle(0, 0, rc.width, 5+8); + // TODO - clean up this freaking mess!!!!! + int i; + + for (i = -numRows; i <= numRows; i++) + { + unsigned int address = curAddress + i * align; + + int rowY1 = rc.height / 2 + rowHeight * i - rowHeight / 2; + int rowY2 = rc.height / 2 + rowHeight * i + rowHeight / 2; + + wxString temp = wxString::Format(_T("%08x"), address); + u32 col = debugger->getColor(address); + wxBrush rowBrush(wxColor(col >> 16, col >> 8, col)); + dc.SetBrush(nullBrush); + dc.SetPen(nullPen); + dc.DrawRectangle(0, rowY1, 16, rowY2); + + if (selecting && (address == selection)) + { + dc.SetPen(selPen); + } + else + { + dc.SetPen(i == 0 ? currentPen : nullPen); + } + + if (address == debugger->getPC()) + { + dc.SetBrush(pcBrush); + } + else + { + dc.SetBrush(rowBrush); + } + + dc.DrawRectangle(16, rowY1, width, rowY2 - 1); + dc.SetBrush(currentBrush); + dc.SetTextForeground(_T("#600000")); + dc.DrawText(temp, 17, rowY1); + char mem[256] = {0}; + strcpy(mem, debugger->getRawMemoryString(address)); + dc.SetTextForeground(_T("#000080")); + dc.DrawText(wxString::FromAscii(mem), 17+fontSize*(8), rowY1); + dc.SetTextForeground(_T("#000000")); + + if (debugger->isAlive()) + { + char dis[256] = {0}; + strcpy(dis, debugger->disasm(address)); + char* dis2 = strchr(dis, '\t'); + char desc[256] = ""; + + if (dis2) + { + *dis2 = 0; + dis2++; + const char* mojs = strstr(dis2, "0x8"); + + if (mojs) + { + for (int k = 0; k < 8; k++) + { + bool found = false; + + for (int j = 0; j < 22; j++) + { + if (mojs[k + 2] == "0123456789ABCDEFabcdef"[j]) + { + found = true; + } + } + + + if (!found) + { + mojs = 0; + break; + } + } + } + + if (mojs) + { + int offs; + sscanf(mojs + 2, "%08x", &offs); + branches[numBranches].src = rowY1 + rowHeight / 2; + branches[numBranches].srcAddr = address / align; + branches[numBranches++].dst = (int)(rowY1 + ((s64)offs - (s64)address) * rowHeight / align + rowHeight / 2); + sprintf(desc, "-->%s", debugger->getDescription(offs).c_str()); + dc.SetTextForeground(_T("#600060")); + } + else + { + dc.SetTextForeground(_T("#000000")); + } + + dc.DrawText(wxString::FromAscii(dis2), 17+fontSize*(8+8+8), rowY1); + } + + if (strcmp(dis, "blr")) + { + dc.SetTextForeground(_T("#007000")); + } + else + { + dc.SetTextForeground(_T("#8000FF")); + } + + dc.DrawText(wxString::FromAscii(dis), 17+fontSize*(8+8), rowY1); + + if (desc[0] == 0) + { + strcpy(desc, debugger->getDescription(address).c_str()); + } + + dc.SetTextForeground(_T("#0000FF")); + + //char temp[256]; + //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE); + if (strlen(desc)) + { + dc.DrawText(wxString::FromAscii(desc), 17+fontSize*(8+8+8+30), rowY1); + } + + if (debugger->isBreakpoint(address)) + { + dc.SetBrush(bpBrush); + dc.DrawRectangle(2, rowY1, 7, 7); +// DrawIconEx(hdc, 2, rowY1, breakPoint, 32, 32, 0, 0, DI_NORMAL); + } + } + } + + dc.SetPen(currentPen); + /* + for (i = 0; i < numBranches; i++) + { + int x = 250 + (branches[i].srcAddr % 9) * 8; + MoveToEx(hdc, x-2, branches[i].src, 0); + + if (branches[i].dst < rect.bottom + 200 && branches[i].dst > -200) + { + LineTo(hdc, x+2, branches[i].src); + LineTo(hdc, x+2, branches[i].dst); + LineTo(hdc, x-4, branches[i].dst); + + MoveToEx(hdc, x, branches[i].dst - 4,0); + LineTo(hdc, x-4, branches[i].dst); + LineTo(hdc, x+1, branches[i].dst+5); + } + else + { + LineTo(hdc, x+4, branches[i].src); + //MoveToEx(hdc,x+2,branches[i].dst-4,0); + //LineTo(hdc,x+6,branches[i].dst); + //LineTo(hdc,x+1,branches[i].dst+5); + } + //LineTo(hdc,x,branches[i].dst+4); + + //LineTo(hdc,x-2,branches[i].dst); + }*/ +} + + diff --git a/Source/Core/DebuggerWX/Src/MemoryWindow.cpp b/Source/Core/DebuggerWX/Src/MemoryWindow.cpp index ccd563ae8b..c406bc1a84 100644 --- a/Source/Core/DebuggerWX/Src/MemoryWindow.cpp +++ b/Source/Core/DebuggerWX/Src/MemoryWindow.cpp @@ -1,221 +1,221 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-
-#include "IniFile.h"
-
-#include <wx/button.h>
-#include <wx/textctrl.h>
-#include <wx/listctrl.h>
-#include <wx/thread.h>
-#include <wx/listctrl.h>
-#include "MemoryWindow.h"
-#include "HW/CPU.h"
-#include "PowerPC/PowerPC.h"
-#include "Host.h"
-
-#include "Debugger/PPCDebugInterface.h"
-#include "PowerPC/SymbolDB.h"
-
-#include "Core.h"
-#include "LogManager.h"
-
-#include "HW/Memmap.h"
-
-// ugly that this lib included code from the main
-#include "../../DolphinWX/Src/Globals.h"
-
-
-enum
-{
- IDM_DEBUG_GO = 350,
- IDM_STEP,
- IDM_STEPOVER,
- IDM_SKIP,
- IDM_SETPC,
- IDM_GOTOPC,
- IDM_ADDRBOX,
- IDM_CALLSTACKLIST,
- IDM_SYMBOLLIST,
- IDM_INTERPRETER,
- IDM_DUALCORE,
- IDM_LOGWINDOW,
- IDM_REGISTERWINDOW,
- IDM_BREAKPOINTWINDOW,
- IDM_VALBOX,
- IDM_SETVALBUTTON
-};
-
-BEGIN_EVENT_TABLE(CMemoryWindow, wxFrame)
- EVT_TEXT(IDM_ADDRBOX, CMemoryWindow::OnAddrBoxChange)
- EVT_LISTBOX(IDM_SYMBOLLIST, CMemoryWindow::OnSymbolListChange)
- EVT_HOST_COMMAND(wxID_ANY, CMemoryWindow::OnHostMessage)
- EVT_BUTTON(IDM_SETVALBUTTON, CMemoryWindow::SetMemoryValue)
-END_EVENT_TABLE()
-
-
-CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id,
- const wxString& title, const wxPoint& pos, const wxSize& size, long style)
- : wxFrame(parent, id, title, pos, size, style)
-{
- wxBoxSizer* sizerBig = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* sizerRight = new wxBoxSizer(wxVERTICAL);
- // didn't see anything usefull in the left part
- //wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
-
- DebugInterface* di = new PPCDebugInterface();
-
- //sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(20, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND);
- memview = new CMemoryView(di, this, wxID_ANY);
- //sizerBig->Add(sizerLeft, 1, wxEXPAND);
- sizerBig->Add(memview, 20, wxEXPAND);
- sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3);
- sizerRight->Add(buttonGo = new wxButton(this, IDM_DEBUG_GO, _T("&Go")));
- sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_ADDRBOX, _T("")));
- sizerRight->Add(new wxButton(this, IDM_SETPC, _T("S&et PC")));
- sizerRight->Add(valbox = new wxTextCtrl(this, IDM_VALBOX, _T("")));
- sizerRight->Add(new wxButton(this, IDM_SETVALBUTTON, _T("Set &Value")));
-
- SetSizer(sizerBig);
-
- //sizerLeft->SetSizeHints(this);
- //sizerLeft->Fit(this);
- sizerRight->SetSizeHints(this);
- sizerRight->Fit(this);
- sizerBig->SetSizeHints(this);
- sizerBig->Fit(this);
-}
-
-
-CMemoryWindow::~CMemoryWindow()
-{
-}
-
-
-void CMemoryWindow::Save(IniFile& _IniFile) const
-{
- // Prevent these bad values that can happen after a crash or hanging
- if(GetPosition().x != -32000 && GetPosition().y != -32000)
- {
- _IniFile.Set("MemoryWindow", "x", GetPosition().x);
- _IniFile.Set("MemoryWindow", "y", GetPosition().y);
- _IniFile.Set("MemoryWindow", "w", GetSize().GetWidth());
- _IniFile.Set("MemoryWindow", "h", GetSize().GetHeight());
- }
-}
-
-
-void CMemoryWindow::Load(IniFile& _IniFile)
-{
- int x,y,w,h;
- _IniFile.Get("MemoryWindow", "x", &x, GetPosition().x);
- _IniFile.Get("MemoryWindow", "y", &y, GetPosition().y);
- _IniFile.Get("MemoryWindow", "w", &w, GetSize().GetWidth());
- _IniFile.Get("MemoryWindow", "h", &h, GetSize().GetHeight());
- SetSize(x, y, w, h);
-}
-
-
-void CMemoryWindow::JumpToAddress(u32 _Address)
-{
- memview->Center(_Address);
-}
-
-
-void CMemoryWindow::SetMemoryValue(wxCommandEvent& event)
-{
- std::string str_addr = std::string(addrbox->GetValue().mb_str());
- std::string str_val = std::string(valbox->GetValue().mb_str());
- u32 addr;
- u32 val;
-
- if (!TryParseUInt(std::string("0x") + str_addr, &addr)) {
- PanicAlert("Invalid Address: %s", str_addr.c_str());
- return;
- }
-
- if (!TryParseUInt(std::string("0x") + str_val, &val)) {
- PanicAlert("Invalid Value: %s", str_val.c_str());
- return;
- }
-
- Memory::Write_U32(val, addr);
- memview->Refresh();
-}
-void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event)
-{
- wxString txt = addrbox->GetValue();
- if (txt.size() == 8)
- {
- u32 addr;
- sscanf(txt.mb_str(), "%08x", &addr);
- memview->Center(addr);
- }
-
- event.Skip(1);
-}
-
-void CMemoryWindow::Update()
-{
- memview->Refresh();
- memview->Center(PC);
-}
-
-void CMemoryWindow::NotifyMapLoaded()
-{
- symbols->Show(false); // hide it for faster filling
- symbols->Clear();
- /*
-#ifdef _WIN32
- const FunctionDB::XFuncMap &syms = g_symbolDB.Symbols();
- for (FuntionDB::XFuncMap::iterator iter = syms.begin(); iter != syms.end(); ++iter)
- {
- int idx = symbols->Append(iter->second.name.c_str());
- symbols->SetClientData(idx, (void*)&iter->second);
- }
-
- //
-#endif
-*/
- symbols->Show(true);
- Update();
-}
-
-void CMemoryWindow::OnSymbolListChange(wxCommandEvent& event)
-{
- int index = symbols->GetSelection();
- if (index >= 0) {
- Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
- if (pSymbol != NULL)
- {
- memview->Center(pSymbol->address);
- }
- }
-}
-
-void CMemoryWindow::OnHostMessage(wxCommandEvent& event)
-{
- switch (event.GetId())
- {
- case IDM_NOTIFYMAPLOADED:
- NotifyMapLoaded();
- break;
- }
-}
-
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" + +#include "IniFile.h" + +#include <wx/button.h> +#include <wx/textctrl.h> +#include <wx/listctrl.h> +#include <wx/thread.h> +#include <wx/listctrl.h> +#include "MemoryWindow.h" +#include "HW/CPU.h" +#include "PowerPC/PowerPC.h" +#include "Host.h" + +#include "Debugger/PPCDebugInterface.h" +#include "PowerPC/SymbolDB.h" + +#include "Core.h" +#include "LogManager.h" + +#include "HW/Memmap.h" + +// ugly that this lib included code from the main +#include "../../DolphinWX/Src/Globals.h" + + +enum +{ + IDM_DEBUG_GO = 350, + IDM_STEP, + IDM_STEPOVER, + IDM_SKIP, + IDM_SETPC, + IDM_GOTOPC, + IDM_ADDRBOX, + IDM_CALLSTACKLIST, + IDM_SYMBOLLIST, + IDM_INTERPRETER, + IDM_DUALCORE, + IDM_LOGWINDOW, + IDM_REGISTERWINDOW, + IDM_BREAKPOINTWINDOW, + IDM_VALBOX, + IDM_SETVALBUTTON +}; + +BEGIN_EVENT_TABLE(CMemoryWindow, wxFrame) + EVT_TEXT(IDM_ADDRBOX, CMemoryWindow::OnAddrBoxChange) + EVT_LISTBOX(IDM_SYMBOLLIST, CMemoryWindow::OnSymbolListChange) + EVT_HOST_COMMAND(wxID_ANY, CMemoryWindow::OnHostMessage) + EVT_BUTTON(IDM_SETVALBUTTON, CMemoryWindow::SetMemoryValue) +END_EVENT_TABLE() + + +CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id, + const wxString& title, const wxPoint& pos, const wxSize& size, long style) + : wxFrame(parent, id, title, pos, size, style) +{ + wxBoxSizer* sizerBig = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizerRight = new wxBoxSizer(wxVERTICAL); + // didn't see anything usefull in the left part + //wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL); + + DebugInterface* di = new PPCDebugInterface(); + + //sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(20, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); + memview = new CMemoryView(di, this, wxID_ANY); + //sizerBig->Add(sizerLeft, 1, wxEXPAND); + sizerBig->Add(memview, 20, wxEXPAND); + sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3); + sizerRight->Add(buttonGo = new wxButton(this, IDM_DEBUG_GO, _T("&Go"))); + sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_ADDRBOX, _T(""))); + sizerRight->Add(new wxButton(this, IDM_SETPC, _T("S&et PC"))); + sizerRight->Add(valbox = new wxTextCtrl(this, IDM_VALBOX, _T(""))); + sizerRight->Add(new wxButton(this, IDM_SETVALBUTTON, _T("Set &Value"))); + + SetSizer(sizerBig); + + //sizerLeft->SetSizeHints(this); + //sizerLeft->Fit(this); + sizerRight->SetSizeHints(this); + sizerRight->Fit(this); + sizerBig->SetSizeHints(this); + sizerBig->Fit(this); +} + + +CMemoryWindow::~CMemoryWindow() +{ +} + + +void CMemoryWindow::Save(IniFile& _IniFile) const +{ + // Prevent these bad values that can happen after a crash or hanging + if(GetPosition().x != -32000 && GetPosition().y != -32000) + { + _IniFile.Set("MemoryWindow", "x", GetPosition().x); + _IniFile.Set("MemoryWindow", "y", GetPosition().y); + _IniFile.Set("MemoryWindow", "w", GetSize().GetWidth()); + _IniFile.Set("MemoryWindow", "h", GetSize().GetHeight()); + } +} + + +void CMemoryWindow::Load(IniFile& _IniFile) +{ + int x,y,w,h; + _IniFile.Get("MemoryWindow", "x", &x, GetPosition().x); + _IniFile.Get("MemoryWindow", "y", &y, GetPosition().y); + _IniFile.Get("MemoryWindow", "w", &w, GetSize().GetWidth()); + _IniFile.Get("MemoryWindow", "h", &h, GetSize().GetHeight()); + SetSize(x, y, w, h); +} + + +void CMemoryWindow::JumpToAddress(u32 _Address) +{ + memview->Center(_Address); +} + + +void CMemoryWindow::SetMemoryValue(wxCommandEvent& event) +{ + std::string str_addr = std::string(addrbox->GetValue().mb_str()); + std::string str_val = std::string(valbox->GetValue().mb_str()); + u32 addr; + u32 val; + + if (!TryParseUInt(std::string("0x") + str_addr, &addr)) { + PanicAlert("Invalid Address: %s", str_addr.c_str()); + return; + } + + if (!TryParseUInt(std::string("0x") + str_val, &val)) { + PanicAlert("Invalid Value: %s", str_val.c_str()); + return; + } + + Memory::Write_U32(val, addr); + memview->Refresh(); +} +void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event) +{ + wxString txt = addrbox->GetValue(); + if (txt.size() == 8) + { + u32 addr; + sscanf(txt.mb_str(), "%08x", &addr); + memview->Center(addr); + } + + event.Skip(1); +} + +void CMemoryWindow::Update() +{ + memview->Refresh(); + memview->Center(PC); +} + +void CMemoryWindow::NotifyMapLoaded() +{ + symbols->Show(false); // hide it for faster filling + symbols->Clear(); + /* +#ifdef _WIN32 + const FunctionDB::XFuncMap &syms = g_symbolDB.Symbols(); + for (FuntionDB::XFuncMap::iterator iter = syms.begin(); iter != syms.end(); ++iter) + { + int idx = symbols->Append(iter->second.name.c_str()); + symbols->SetClientData(idx, (void*)&iter->second); + } + + // +#endif +*/ + symbols->Show(true); + Update(); +} + +void CMemoryWindow::OnSymbolListChange(wxCommandEvent& event) +{ + int index = symbols->GetSelection(); + if (index >= 0) { + Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index)); + if (pSymbol != NULL) + { + memview->Center(pSymbol->address); + } + } +} + +void CMemoryWindow::OnHostMessage(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case IDM_NOTIFYMAPLOADED: + NotifyMapLoaded(); + break; + } +} + + diff --git a/Source/Core/DebuggerWX/Src/RegisterView.cpp b/Source/Core/DebuggerWX/Src/RegisterView.cpp index fb52b52eac..148c69228a 100644 --- a/Source/Core/DebuggerWX/Src/RegisterView.cpp +++ b/Source/Core/DebuggerWX/Src/RegisterView.cpp @@ -1,158 +1,158 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "RegisterView.h"
-#include "PowerPC/PowerPC.h"
-
-extern const char* GetGRPName(unsigned int index);
-
-
-BEGIN_EVENT_TABLE(CRegisterView, wxListCtrl)
-END_EVENT_TABLE()
-
-CRegisterView::CRegisterView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
- : wxListCtrl(parent, id, pos, size, style)
-{
- InsertColumn(1, wxT("Reg 16-31"), wxLIST_FORMAT_LEFT, 100);
- InsertColumn(0, wxT("Value"), wxLIST_FORMAT_CENTER, 80);
- InsertColumn(0, wxT("Reg 0-15"), wxLIST_FORMAT_LEFT, 100);
- InsertColumn(0, wxT("Value"), wxLIST_FORMAT_CENTER, 80);
-
- SetFont(wxFont(9, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI")));
-
- for (int i = 0; i < 16; i++)
- {
- // 0-15
- int Item = InsertItem(0, wxString::FromAscii(GetGRPName(i)));
-
- // 16-31
- SetItem(Item, 2, wxString::FromAscii(GetGRPName(16 + i)));
-
- // just for easy sort
-
- wxListItem item;
- item.SetId(Item);
- item.SetBackgroundColour(0xFFFFFF);
- item.SetData(i);
- SetItem(item);
- }
-
- Refresh();
-}
-
-
-void
-CRegisterView::Update()
-{
- for (size_t i = 0; i < 16; i++)
- {
- // 0-15
- if (m_CachedRegs[i] != GPR(i))
- {
- m_CachedRegHasChanged[i] = true;
- }
- else
- {
- m_CachedRegHasChanged[i] = false;
- }
-
- m_CachedRegs[i] = GPR(i);
-
- // 16-31
- if (m_CachedRegs[16 + i] != GPR(16 + i))
- {
- m_CachedRegHasChanged[16 + i] = true;
- }
- else
- {
- m_CachedRegHasChanged[16 + i] = false;
- }
-
- m_CachedRegs[16 + i] = GPR(16 + i);
- }
-
- Refresh();
-}
-
-void CRegisterView::Refresh()
-{
- for (size_t i = 0; i < 16; i++)
- {
- wxListItem item;
- item.SetId(i);
- item.SetColumn(1);
- char temp[16];
- sprintf(temp, "0x%08x",m_CachedRegs[i]);
- item.SetText(wxString::FromAscii(temp));
- SetItem(item);
- }
- for (size_t i = 0; i < 16; i++)
- {
- wxListItem item;
- item.SetId(i);
- item.SetColumn(3);
- char temp[16];
- sprintf(temp, "0x%08x",m_CachedRegs[16 + i]);
- item.SetText(wxString::FromAscii(temp));
- SetItem(item);
- }
-}
-#ifdef _WIN32
-bool
-CRegisterView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem)
-{
- bool Result = false;
-
-#ifdef __WXMSW__
- switch (subitem)
- {
- case 1:
- case 3:
- {
- int Register = (subitem == 1) ? item : item + 16;
-
- const wxChar* bgColor = _T("#ffffff");
- wxBrush bgBrush(bgColor);
- wxPen bgPen(bgColor);
-
- wxRect SubItemRect;
- this->GetSubItemRect(item, subitem, SubItemRect);
- rPainDC.SetBrush(bgBrush);
- rPainDC.SetPen(bgPen);
- rPainDC.DrawRectangle(SubItemRect);
-
- if (m_CachedRegHasChanged[Register])
- {
- rPainDC.SetTextForeground(_T("#FF0000"));
- }
- else
- {
- rPainDC.SetTextForeground(_T("#000000"));
- }
-
- wxString text;
- text.Printf(wxT("0x%08x"), m_CachedRegs[Register]);
- rPainDC.DrawText(text, SubItemRect.GetLeft() + 10, SubItemRect.GetTop() + 4);
- return(true);
- }
- break;
- }
-#endif
- return(Result);
-}
-#endif
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "RegisterView.h" +#include "PowerPC/PowerPC.h" + +extern const char* GetGRPName(unsigned int index); + + +BEGIN_EVENT_TABLE(CRegisterView, wxListCtrl) +END_EVENT_TABLE() + +CRegisterView::CRegisterView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) + : wxListCtrl(parent, id, pos, size, style) +{ + InsertColumn(1, wxT("Reg 16-31"), wxLIST_FORMAT_LEFT, 100); + InsertColumn(0, wxT("Value"), wxLIST_FORMAT_CENTER, 80); + InsertColumn(0, wxT("Reg 0-15"), wxLIST_FORMAT_LEFT, 100); + InsertColumn(0, wxT("Value"), wxLIST_FORMAT_CENTER, 80); + + SetFont(wxFont(9, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI"))); + + for (int i = 0; i < 16; i++) + { + // 0-15 + int Item = InsertItem(0, wxString::FromAscii(GetGRPName(i))); + + // 16-31 + SetItem(Item, 2, wxString::FromAscii(GetGRPName(16 + i))); + + // just for easy sort + + wxListItem item; + item.SetId(Item); + item.SetBackgroundColour(0xFFFFFF); + item.SetData(i); + SetItem(item); + } + + Refresh(); +} + + +void +CRegisterView::Update() +{ + for (size_t i = 0; i < 16; i++) + { + // 0-15 + if (m_CachedRegs[i] != GPR(i)) + { + m_CachedRegHasChanged[i] = true; + } + else + { + m_CachedRegHasChanged[i] = false; + } + + m_CachedRegs[i] = GPR(i); + + // 16-31 + if (m_CachedRegs[16 + i] != GPR(16 + i)) + { + m_CachedRegHasChanged[16 + i] = true; + } + else + { + m_CachedRegHasChanged[16 + i] = false; + } + + m_CachedRegs[16 + i] = GPR(16 + i); + } + + Refresh(); +} + +void CRegisterView::Refresh() +{ + for (size_t i = 0; i < 16; i++) + { + wxListItem item; + item.SetId(i); + item.SetColumn(1); + char temp[16]; + sprintf(temp, "0x%08x",m_CachedRegs[i]); + item.SetText(wxString::FromAscii(temp)); + SetItem(item); + } + for (size_t i = 0; i < 16; i++) + { + wxListItem item; + item.SetId(i); + item.SetColumn(3); + char temp[16]; + sprintf(temp, "0x%08x",m_CachedRegs[16 + i]); + item.SetText(wxString::FromAscii(temp)); + SetItem(item); + } +} +#ifdef _WIN32 +bool +CRegisterView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem) +{ + bool Result = false; + +#ifdef __WXMSW__ + switch (subitem) + { + case 1: + case 3: + { + int Register = (subitem == 1) ? item : item + 16; + + const wxChar* bgColor = _T("#ffffff"); + wxBrush bgBrush(bgColor); + wxPen bgPen(bgColor); + + wxRect SubItemRect; + this->GetSubItemRect(item, subitem, SubItemRect); + rPainDC.SetBrush(bgBrush); + rPainDC.SetPen(bgPen); + rPainDC.DrawRectangle(SubItemRect); + + if (m_CachedRegHasChanged[Register]) + { + rPainDC.SetTextForeground(_T("#FF0000")); + } + else + { + rPainDC.SetTextForeground(_T("#000000")); + } + + wxString text; + text.Printf(wxT("0x%08x"), m_CachedRegs[Register]); + rPainDC.DrawText(text, SubItemRect.GetLeft() + 10, SubItemRect.GetTop() + 4); + return(true); + } + break; + } +#endif + return(Result); +} +#endif diff --git a/Source/Core/DebuggerWX/Src/RegisterWindow.cpp b/Source/Core/DebuggerWX/Src/RegisterWindow.cpp index 1c14a3de6c..32124a377a 100644 --- a/Source/Core/DebuggerWX/Src/RegisterWindow.cpp +++ b/Source/Core/DebuggerWX/Src/RegisterWindow.cpp @@ -1,97 +1,97 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include "Debugger.h"
-#include "RegisterWindow.h"
-#include "PowerPC/PowerPC.h"
-#include "RegisterView.h"
-#include "IniFile.h"
-
-extern const char* GetGRPName(unsigned int index);
-
-BEGIN_EVENT_TABLE(CRegisterWindow, wxDialog)
- EVT_CLOSE(CRegisterWindow::OnClose)
- EVT_MENU(wxID_REFRESH, CRegisterWindow::OnRefresh)
-END_EVENT_TABLE()
-
-CRegisterWindow::CRegisterWindow(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
- : wxDialog(parent, id, title, position, size, style)
- , m_GPRListView(NULL)
-{
- CreateGUIControls();
-}
-
-
-CRegisterWindow::~CRegisterWindow()
-{}
-
-
-void CRegisterWindow::Save(IniFile& _IniFile) const
-{
- _IniFile.Set("RegisterWindow", "x", GetPosition().x);
- _IniFile.Set("RegisterWindow", "y", GetPosition().y);
- _IniFile.Set("RegisterWindow", "w", GetSize().GetWidth());
- _IniFile.Set("RegisterWindow", "h", GetSize().GetHeight());
-}
-
-
-void CRegisterWindow::Load(IniFile& _IniFile)
-{
- int x,y,w,h;
- _IniFile.Get("RegisterWindow", "x", &x, GetPosition().x);
- _IniFile.Get("RegisterWindow", "y", &y, GetPosition().y);
- _IniFile.Get("RegisterWindow", "w", &w, GetSize().GetWidth());
- _IniFile.Get("RegisterWindow", "h", &h, GetSize().GetHeight());
- SetSize(x, y, w, h);
-}
-
-
-void CRegisterWindow::CreateGUIControls()
-{
- SetTitle(wxT("Registers"));
- SetIcon(wxNullIcon);
- SetSize(8, 8, 400, 370);
- Center();
-
- m_GPRListView = new CRegisterView(this, ID_GPR, wxDefaultPosition, GetSize(),
- wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
-
- NotifyUpdate();
-}
-
-
-void CRegisterWindow::OnClose(wxCloseEvent& /*event*/)
-{
- Hide();
-}
-
-void CRegisterWindow::OnRefresh(wxCommandEvent& WXUNUSED (event))
-{
- m_GPRListView->Refresh();
- m_GPRListView->Update();
-}
-
-
-void CRegisterWindow::NotifyUpdate()
-{
- if (m_GPRListView != NULL)
- {
- m_GPRListView->Update();
- }
-}
-
-
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Debugger.h" +#include "RegisterWindow.h" +#include "PowerPC/PowerPC.h" +#include "RegisterView.h" +#include "IniFile.h" + +extern const char* GetGRPName(unsigned int index); + +BEGIN_EVENT_TABLE(CRegisterWindow, wxDialog) + EVT_CLOSE(CRegisterWindow::OnClose) + EVT_MENU(wxID_REFRESH, CRegisterWindow::OnRefresh) +END_EVENT_TABLE() + +CRegisterWindow::CRegisterWindow(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) + : wxDialog(parent, id, title, position, size, style) + , m_GPRListView(NULL) +{ + CreateGUIControls(); +} + + +CRegisterWindow::~CRegisterWindow() +{} + + +void CRegisterWindow::Save(IniFile& _IniFile) const +{ + _IniFile.Set("RegisterWindow", "x", GetPosition().x); + _IniFile.Set("RegisterWindow", "y", GetPosition().y); + _IniFile.Set("RegisterWindow", "w", GetSize().GetWidth()); + _IniFile.Set("RegisterWindow", "h", GetSize().GetHeight()); +} + + +void CRegisterWindow::Load(IniFile& _IniFile) +{ + int x,y,w,h; + _IniFile.Get("RegisterWindow", "x", &x, GetPosition().x); + _IniFile.Get("RegisterWindow", "y", &y, GetPosition().y); + _IniFile.Get("RegisterWindow", "w", &w, GetSize().GetWidth()); + _IniFile.Get("RegisterWindow", "h", &h, GetSize().GetHeight()); + SetSize(x, y, w, h); +} + + +void CRegisterWindow::CreateGUIControls() +{ + SetTitle(wxT("Registers")); + SetIcon(wxNullIcon); + SetSize(8, 8, 400, 370); + Center(); + + m_GPRListView = new CRegisterView(this, ID_GPR, wxDefaultPosition, GetSize(), + wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING); + + NotifyUpdate(); +} + + +void CRegisterWindow::OnClose(wxCloseEvent& /*event*/) +{ + Hide(); +} + +void CRegisterWindow::OnRefresh(wxCommandEvent& WXUNUSED (event)) +{ + m_GPRListView->Refresh(); + m_GPRListView->Update(); +} + + +void CRegisterWindow::NotifyUpdate() +{ + if (m_GPRListView != NULL) + { + m_GPRListView->Update(); + } +} + + |
