// Copyright (C) 2003 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 "BreakpointWindow.h" #include "BreakpointView.h" #include "CodeWindow.h" #include "HW/Memmap.h" #include "BreakpointDlg.h" #include "MemoryCheckDlg.h" #include "Host.h" #include "PowerPC/PowerPC.h" #include "FileUtil.h" extern "C" { #include "../../resources/toolbar_add_breakpoint.c" #include "../../resources/toolbar_add_memorycheck.c" #include "../../resources/toolbar_debugger_delete.c" } #define _connect_macro_(id, handler) \ Connect(id, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(handler), (wxObject*)0, (wxEvtHandler*)parent) class CBreakPointBar : public wxAuiToolBar { public: CBreakPointBar(wxWindow* parent, const wxWindowID id) : wxAuiToolBar(parent, id, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_TEXT) { SetToolBitmapSize(wxSize(24, 24)); m_Bitmaps[Toolbar_Delete] = wxBitmap(wxGetBitmapFromMemory(toolbar_delete_png).ConvertToImage().Rescale(24, 24)); m_Bitmaps[Toolbar_Add_BP] = wxBitmap(wxGetBitmapFromMemory(toolbar_add_breakpoint_png).ConvertToImage().Rescale(24, 24)); m_Bitmaps[Toolbar_Add_MC] = wxBitmap(wxGetBitmapFromMemory(toolbar_add_memcheck_png).ConvertToImage().Rescale(24, 24)); AddTool(ID_DELETE, wxT("Delete"), m_Bitmaps[Toolbar_Delete]); _connect_macro_(ID_DELETE, CBreakPointWindow::OnDelete); AddTool(ID_CLEAR, wxT("Clear"), m_Bitmaps[Toolbar_Delete]); _connect_macro_(ID_CLEAR, CBreakPointWindow::OnClear); AddTool(ID_ADDBP, wxT("+BP"), m_Bitmaps[Toolbar_Add_BP]); _connect_macro_(ID_ADDBP, CBreakPointWindow::OnAddBreakPoint); // Add memory breakpoints if you can use them if (Memory::AreMemoryBreakpointsActivated()) { AddTool(ID_ADDMC, wxT("+MC"), m_Bitmaps[Toolbar_Add_MC]); _connect_macro_(ID_ADDMC, CBreakPointWindow::OnAddMemoryCheck); } AddTool(ID_LOAD, wxT("Load"), m_Bitmaps[Toolbar_Delete]); _connect_macro_(ID_LOAD, CBreakPointWindow::LoadAll); AddTool(ID_SAVE, wxT("Save"), m_Bitmaps[Toolbar_Delete]); _connect_macro_(ID_SAVE, CBreakPointWindow::Event_SaveAll); } private: enum { Toolbar_Delete, Toolbar_Add_BP, Toolbar_Add_MC, Num_Bitmaps }; enum { ID_DELETE = 2000, ID_CLEAR, ID_ADDBP, ID_ADDMC, ID_LOAD, ID_SAVE }; wxBitmap m_Bitmaps[Num_Bitmaps]; }; BEGIN_EVENT_TABLE(CBreakPointWindow, wxPanel) EVT_CLOSE(CBreakPointWindow::OnClose) EVT_LIST_ITEM_SELECTED(wxID_ANY, CBreakPointWindow::OnSelectBP) END_EVENT_TABLE() CBreakPointWindow::CBreakPointWindow(CCodeWindow* _pCodeWindow, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) : wxPanel(parent, id, position, size, style, title) , m_pCodeWindow(_pCodeWindow) { m_mgr.SetManagedWindow(this); m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE); m_BreakPointListView = new CBreakPointView(this, wxID_ANY); m_mgr.AddPane(new CBreakPointBar(this, wxID_ANY), wxAuiPaneInfo().ToolbarPane().Top(). LeftDockable(false).RightDockable(false).BottomDockable(false).Floatable(false)); m_mgr.AddPane(m_BreakPointListView, wxAuiPaneInfo().CenterPane()); m_mgr.Update(); } CBreakPointWindow::~CBreakPointWindow() { m_mgr.UnInit(); } void CBreakPointWindow::OnClose(wxCloseEvent& event) { SaveAll(); event.Skip(); } void CBreakPointWindow::NotifyUpdate() { m_BreakPointListView->Update(); } void CBreakPointWindow::OnDelete(wxCommandEvent& WXUNUSED(event)) { m_BreakPointListView->DeleteCurrentSelection(); } // jump to begin addr void CBreakPointWindow::OnSelectBP(wxListEvent& event) { long Index = event.GetIndex(); if (Index >= 0) { u32 Address = (u32)m_BreakPointListView->GetItemData(Index); if (m_pCodeWindow) m_pCodeWindow->JumpToAddress(Address); } } // Clear all breakpoints and memchecks void CBreakPointWindow::OnClear(wxCommandEvent& WXUNUSED(event)) { PowerPC::breakpoints.Clear(); PowerPC::memchecks.Clear(); NotifyUpdate(); } void CBreakPointWindow::OnAddBreakPoint(wxCommandEvent& WXUNUSED(event)) { BreakPointDlg bpDlg(this); bpDlg.ShowModal(); } void CBreakPointWindow::OnAddMemoryCheck(wxCommandEvent& WXUNUSED(event)) { MemoryCheckDlg memDlg(this); memDlg.ShowModal(); } void CBreakPointWindow::Event_SaveAll(wxCommandEvent& WXUNUSED(event)) { SaveAll(); } void CBreakPointWindow::SaveAll() { // simply dump all to bp/mc files in a way we can read again IniFile ini; if (ini.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX))) { ini.SetLines("BreakPoints", PowerPC::breakpoints.GetStrings()); ini.SetLines("MemoryChecks", PowerPC::memchecks.GetStrings()); ini.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); } } void CBreakPointWindow::LoadAll(wxCommandEvent& WXUNUSED(event)) { IniFile ini; BreakPoints::TBreakPointsStr newbps; MemChecks::TMemChecksStr newmcs; if (!ini.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX))) return; if (ini.GetLines("BreakPoints", newbps, false)) PowerPC::breakpoints.AddFromStrings(newbps); if (ini.GetLines("MemoryChecks", newmcs, false)) PowerPC::memchecks.AddFromStrings(newmcs); NotifyUpdate(); }