PsfPlayer updates.

git-svn-id: http://svn.purei.org/purei/trunk@432 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2008-12-02 23:55:03 +00:00
parent d827527939
commit 23fe44a91e
12 changed files with 217 additions and 120 deletions

View File

@ -2,16 +2,22 @@
#define _DEBUGGABLE_H_
#include "MIPS.h"
#include "MIPSModule.h"
#include <list>
#include <functional>
class CDebuggable
{
public:
typedef std::list<MIPSMODULE> ModuleList;
typedef std::tr1::function<CMIPS& ()> GetCpuFuncType;
typedef std::tr1::function<void ()> StepFuncType;
typedef std::tr1::function<ModuleList ()> GetModulesFuncType;
GetCpuFuncType GetCpu;
StepFuncType Step;
GetModulesFuncType GetModules;
};
#endif

View File

@ -1,28 +1,28 @@
#include <stdio.h>
#include <boost/bind.hpp>
#include "FunctionsView.h"
#include "layout/HorizontalLayout.h"
#include "layout/LayoutStretch.h"
#include "win32/LayoutWindow.h"
#include "win32/InputBox.h"
#include "string_cast.h"
#include "lexical_cast_ex.h"
#include "layout/LayoutStretch.h"
#include "layout/LayoutEngine.h"
#include "PtrMacro.h"
#define CLSNAME _T("FunctionsView")
#define DEFAULT_GROUPID (1)
#define DEFAULT_GROUPNAME _T("Global")
using namespace Framework;
using namespace std;
using namespace boost;
using namespace std::tr1;
CFunctionsView::CFunctionsView(HWND hParent, CMIPS* pCtx)
CFunctionsView::CFunctionsView(HWND hParent) :
m_pCtx(NULL),
m_pELF(NULL)
{
RECT rc;
m_pCtx = pCtx;
m_pELF = NULL;
if(!DoesWindowClassExist(CLSNAME))
{
WNDCLASSEX wc;
@ -38,7 +38,11 @@ CFunctionsView::CFunctionsView(HWND hParent, CMIPS* pCtx)
SetRect(&rc, 0, 0, 320, 240);
Create(NULL, CLSNAME, _T("Functions"), WS_CLIPCHILDREN | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX, &rc, hParent, NULL);
unsigned long windowStyle = WS_CLIPCHILDREN | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX;
#ifndef FUNCTIONSVIEW_STANDALONE
windowStyle |= WS_CHILD;
#endif
Create(NULL, CLSNAME, _T("Functions"), windowStyle, &rc, hParent, NULL);
SetClassPtr();
SetRect(&rc, 0, 0, 0, 0);
@ -64,8 +68,6 @@ CFunctionsView::CFunctionsView(HWND hParent, CMIPS* pCtx)
m_pLayout->InsertObject(Win32::CLayoutWindow::CreateCustomBehavior(1, 1, 1, 1, m_pList));
m_pLayout->InsertObject(pSubLayout0);
m_pCtx->m_Functions.m_OnTagListChanged.connect(bind(&CFunctionsView::Refresh, this));
SetSize(469, 612);
SetELF(NULL);
@ -93,8 +95,7 @@ long CFunctionsView::OnNotify(WPARAM wParam, NMHDR* pH)
{
if(pH->hwndFrom == m_pList->m_hWnd)
{
NMLISTVIEW* pN;
pN = (NMLISTVIEW*)pH;
NMLISTVIEW* pN = reinterpret_cast<NMLISTVIEW*>(pH);
switch(pN->hdr.code)
{
case NM_DBLCLK:
@ -183,11 +184,29 @@ void CFunctionsView::RefreshLayout()
void CFunctionsView::RefreshList()
{
unsigned int nCount;
uint32 nAddress;
m_pList->SetRedraw(false);
m_pList->DeleteAllItems();
if(m_pCtx == NULL) return;
if(m_moduleListProvider)
{
m_modules = m_moduleListProvider();
}
else
{
m_modules.clear();
}
bool groupingEnabled = m_modules.size() != 0;
if(groupingEnabled)
{
InitializeModuleGrouper();
}
else
{
m_pList->EnableGroupView(false);
}
for(CMIPSTags::TagIterator itTag(m_pCtx->m_Functions.GetTagsBegin());
itTag != m_pCtx->m_Functions.GetTagsEnd(); itTag++)
{
@ -199,16 +218,49 @@ void CFunctionsView::RefreshList()
it.pszText = const_cast<LPWSTR>(sTag.c_str());
it.lParam = itTag->first;
it.mask = LVIF_PARAM | LVIF_TEXT;
if(groupingEnabled)
{
it.iGroupId = GetFunctionGroupId(itTag->first);
it.mask |= LVIF_GROUPID;
}
m_pList->InsertItem(&it);
}
nCount = m_pList->GetItemCount();
unsigned int nCount = m_pList->GetItemCount();
for(unsigned int i = 0; i < nCount; i++)
{
nAddress = m_pList->GetItemData(i);
uint32 nAddress = m_pList->GetItemData(i);
m_pList->SetItemText(i, 1, (_T("0x") + lexical_cast_hex<tstring>(nAddress, 8)).c_str());
}
m_pList->SetRedraw(true);
}
void CFunctionsView::InitializeModuleGrouper()
{
m_pList->RemoveAllGroups();
m_pList->EnableGroupView(true);
m_pList->InsertGroup(DEFAULT_GROUPNAME, DEFAULT_GROUPID);
for(ModuleList::const_iterator moduleIterator(m_modules.begin());
m_modules.end() != moduleIterator; moduleIterator++)
{
const MIPSMODULE& module(*moduleIterator);
m_pList->InsertGroup(
string_cast<tstring>(module.name.c_str()).c_str(),
module.begin);
}
}
uint32 CFunctionsView::GetFunctionGroupId(uint32 address)
{
for(ModuleList::const_iterator moduleIterator(m_modules.begin());
m_modules.end() != moduleIterator; moduleIterator++)
{
const MIPSMODULE& module(*moduleIterator);
if(address >= module.begin && address < module.end) return module.begin;
}
return DEFAULT_GROUPID;
}
void CFunctionsView::SetELF(CELF* pELF)
@ -224,6 +276,21 @@ void CFunctionsView::SetELF(CELF* pELF)
}
}
void CFunctionsView::SetContext(CMIPS* context, const ModuleListProvider& moduleListProvider)
{
if(m_functionTagsChangeConnection.connected())
{
m_functionTagsChangeConnection.disconnect();
}
m_pCtx = context;
m_moduleListProvider = moduleListProvider;
m_functionTagsChangeConnection = m_pCtx->m_Functions.m_OnTagListChanged.connect(
bind(&CFunctionsView::RefreshList, this));
RefreshList();
}
void CFunctionsView::OnListDblClick()
{
int nItem;
@ -236,42 +303,32 @@ void CFunctionsView::OnListDblClick()
void CFunctionsView::OnNewClick()
{
Win32::CInputBox* pInput;
bool bQuit;
if(m_pCtx == NULL) return;
TCHAR sNameX[256];
const TCHAR* sValue;
uint32 nAddress;
pInput = new Win32::CInputBox(_T("New Function"), _T("New Function Name:"), _T(""));
sValue = pInput->GetValue(m_hWnd);
bQuit = (sValue == NULL);
if(sValue != NULL)
{
Win32::CInputBox inputBox(_T("New Function"), _T("New Function Name:"), _T(""));
const TCHAR* sValue = inputBox.GetValue(m_hWnd);
if(sValue == NULL) return;
_tcsncpy(sNameX, sValue, 255);
}
delete pInput;
if(bQuit) return;
pInput = new Win32::CInputBox(_T("New Function"), _T("New Function Address:"), _T("00000000"));
sValue = pInput->GetValue(m_hWnd);
bQuit = (sValue == NULL);
{
Win32::CInputBox inputBox(_T("New Function"), _T("New Function Address:"), _T("00000000"));
const TCHAR* sValue = inputBox.GetValue(m_hWnd);
if(sValue == NULL) return;
if(sValue != NULL)
{
_stscanf(sValue, _T("%x"), &nAddress);
if((nAddress & 0x3) != 0x0)
{
MessageBox(m_hWnd, _T("Invalid address."), NULL, 16);
bQuit = true;
return;
}
}
}
delete pInput;
if(bQuit) return;
m_pCtx->m_Functions.InsertTag(nAddress, string_cast<string>(sNameX).c_str());
@ -281,16 +338,13 @@ void CFunctionsView::OnNewClick()
void CFunctionsView::OnRenameClick()
{
int nItem;
uint32 nAddress;
const char* sName;
const TCHAR* sNewNameX;
if(m_pCtx == NULL) return;
nItem = m_pList->GetSelection();
int nItem = m_pList->GetSelection();
if(nItem == -1) return;
nAddress = m_pList->GetItemData(nItem);
sName = m_pCtx->m_Functions.Find(nAddress);
uint32 nAddress = m_pList->GetItemData(nItem);
const char* sName = m_pCtx->m_Functions.Find(nAddress);
if(sName == NULL)
{
@ -299,7 +353,7 @@ void CFunctionsView::OnRenameClick()
}
Win32::CInputBox RenameInput(_T("Rename Function"), _T("New Function Name:"), string_cast<tstring>(sName).c_str());
sNewNameX = RenameInput.GetValue(m_hWnd);
const TCHAR* sNewNameX = RenameInput.GetValue(m_hWnd);
if(sNewNameX == NULL) return;
@ -311,23 +365,19 @@ void CFunctionsView::OnRenameClick()
void CFunctionsView::OnImportClick()
{
unsigned int i, nCount;
ELFSYMBOL* pSym;
ELFSECTIONHEADER* pSymTab;
const char* pStrTab;
if(m_pCtx == NULL) return;
if(m_pELF == NULL) return;
pSymTab = m_pELF->FindSection(".symtab");
ELFSECTIONHEADER* pSymTab = m_pELF->FindSection(".symtab");
if(pSymTab == NULL) return;
pStrTab = (const char*)m_pELF->GetSectionData(pSymTab->nIndex);
const char* pStrTab = (const char*)m_pELF->GetSectionData(pSymTab->nIndex);
if(pStrTab == NULL) return;
pSym = (ELFSYMBOL*)m_pELF->FindSectionData(".symtab");
nCount = pSymTab->nSize / sizeof(ELFSYMBOL);
ELFSYMBOL* pSym = (ELFSYMBOL*)m_pELF->FindSectionData(".symtab");
unsigned int nCount = pSymTab->nSize / sizeof(ELFSYMBOL);
for(i = 0; i < nCount; i++)
for(unsigned int i = 0; i < nCount; i++)
{
if((pSym[i].nInfo & 0x0F) != 0x02) continue;
m_pCtx->m_Functions.InsertTag(pSym[i].nValue, (char*)pStrTab + pSym[i].nName);
@ -342,17 +392,16 @@ void CFunctionsView::OnImportClick()
void CFunctionsView::OnDeleteClick()
{
int nItem;
uint32 nAddress;
if(m_pCtx == NULL) return;
nItem = m_pList->GetSelection();
int nItem = m_pList->GetSelection();
if(nItem == -1) return;
if(MessageBox(m_hWnd, _T("Delete this function?"), NULL, MB_ICONQUESTION | MB_YESNO) != IDYES)
{
return;
}
nAddress = m_pList->GetItemData(nItem);
uint32 nAddress = m_pList->GetItemData(nItem);
m_pCtx->m_Functions.InsertTag(nAddress, NULL);
RefreshList();

View File

@ -2,19 +2,34 @@
#define _FUNCTIONSVIEW_H_
#include <boost/signal.hpp>
#include <functional>
#include "win32/MDIChild.h"
#include "win32/ListView.h"
#include "win32/Button.h"
#include "layout/VerticalLayout.h"
#include "MIPS.h"
#include "MIPSModule.h"
#include "ELF.h"
class CFunctionsView : public Framework::Win32::CWindow, public boost::signals::trackable
class CFunctionsView :
#ifdef FUNCTIONSVIEW_STANDALONE
public Framework::Win32::CWindow,
#else
public Framework::Win32::CMDIChild,
#endif
public boost::signals::trackable
{
public:
CFunctionsView(HWND, CMIPS*);
~CFunctionsView();
typedef std::list<MIPSMODULE> ModuleList;
typedef std::tr1::function<ModuleList ()> ModuleListProvider;
CFunctionsView(HWND);
virtual ~CFunctionsView();
void SetContext(CMIPS*, const ModuleListProvider&);
void SetELF(CELF*);
void Refresh();
boost::signal<void (uint32)> m_OnFunctionDblClick;
@ -31,6 +46,8 @@ private:
void ResizeListColumns();
void RefreshLayout();
void RefreshList();
void InitializeModuleGrouper();
uint32 GetFunctionGroupId(uint32);
void OnListDblClick();
void OnNewClick();
@ -45,8 +62,13 @@ private:
Framework::Win32::CButton* m_pImport;
Framework::FlatLayoutPtr m_pLayout;
boost::signals::connection m_functionTagsChangeConnection;
CMIPS* m_pCtx;
CELF* m_pELF;
ModuleList m_modules;
ModuleListProvider m_moduleListProvider;
};
#endif

View File

@ -56,8 +56,9 @@ m_memoryView(NULL)
m_registerView = new CRegViewGeneral(m_subSplitter->m_hWnd, Win32::CRect(0, 0, 1, 1), m_virtualMachine, &m_debuggable.GetCpu());
m_registerView->Show(SW_SHOW);
m_functionsView = new CFunctionsView(NULL, &m_debuggable.GetCpu());
m_functionsView = new CFunctionsView(NULL);
m_functionsView->m_OnFunctionDblClick.connect(bind(&CMiniDebugger::OnFunctionDblClick, this, _1));
m_functionsView->SetContext(&m_debuggable.GetCpu(), m_debuggable.GetModules);
m_functionsView->Refresh();
m_subSplitter->SetChild(0, *m_disAsmView);

View File

@ -48,6 +48,11 @@ void CPsfBios::CountTicks(uint32 ticks)
m_bios.CountTicks(ticks);
}
MipsModuleList CPsfBios::GetModuleList()
{
return m_bios.GetModuleList();
}
#ifdef DEBUGGER_INCLUDED
void CPsfBios::LoadDebugTags(Framework::Xml::CNode* root)

View File

@ -19,6 +19,7 @@ namespace PS2
#ifdef DEBUGGER_INCLUDED
void LoadDebugTags(Framework::Xml::CNode*);
void SaveDebugTags(Framework::Xml::CNode*);
MipsModuleList GetModuleList();
#endif
void AppendArchive(const CPsfBase&);

View File

@ -123,22 +123,12 @@ void CPsfVm::LoadDebugTags(const char* packageName)
try
{
string packagePath = MakeTagPackagePath(packageName);
Xml::CNode* document = Xml::CParser::ParseDocument(&CStdStream(packagePath.c_str(), "rb"));
{
Xml::CNode* subNode = document->Select((TAGS_SECTION_TAGS + string("/") + TAGS_SECTION_FUNCTIONS).c_str());
if(subNode)
{
m_cpu.m_Functions.Unserialize(subNode);
}
}
{
Xml::CNode* subNode = document->Select((TAGS_SECTION_TAGS + string("/") + TAGS_SECTION_COMMENTS).c_str());
if(subNode)
{
m_cpu.m_Comments.Unserialize(subNode);
}
}
m_bios->LoadDebugTags(document);
boost::scoped_ptr<Xml::CNode> document(Xml::CParser::ParseDocument(&CStdStream(packagePath.c_str(), "rb")));
Xml::CNode* tagsSection = document->Select(TAGS_SECTION_TAGS);
if(tagsSection == NULL) return;
m_cpu.m_Functions.Unserialize(tagsSection, TAGS_SECTION_FUNCTIONS);
m_cpu.m_Comments.Unserialize(tagsSection, TAGS_SECTION_COMMENTS);
m_bios->LoadDebugTags(document.get());
}
catch(...)
{
@ -149,20 +139,11 @@ void CPsfVm::LoadDebugTags(const char* packageName)
void CPsfVm::SaveDebugTags(const char* packageName)
{
string packagePath = MakeTagPackagePath(packageName);
Xml::CNode* document = new Xml::CNode(TAGS_SECTION_TAGS, true);
{
Xml::CNode* subNode = new Xml::CNode(TAGS_SECTION_FUNCTIONS, true);
m_cpu.m_Functions.Serialize(subNode);
document->InsertNode(subNode);
}
{
Xml::CNode* subNode = new Xml::CNode(TAGS_SECTION_COMMENTS, true);
m_cpu.m_Comments.Serialize(subNode);
document->InsertNode(subNode);
}
m_bios->SaveDebugTags(document);
Xml::CWriter::WriteDocument(&CStdStream(packagePath.c_str(), "wb"), document);
delete document;
boost::scoped_ptr<Xml::CNode> document(new Xml::CNode(TAGS_SECTION_TAGS, true));
m_cpu.m_Functions.Serialize(document.get(), TAGS_SECTION_FUNCTIONS);
m_cpu.m_Comments.Serialize(document.get(), TAGS_SECTION_COMMENTS);
m_bios->SaveDebugTags(document.get());
Xml::CWriter::WriteDocument(&CStdStream(packagePath.c_str(), "wb"), document.get());
}
#endif
@ -265,6 +246,7 @@ CDebuggable CPsfVm::GetDebugInfo()
CDebuggable debug;
debug.Step = bind(&CPsfVm::Step, this);
debug.GetCpu = bind(&CPsfVm::GetCpu, this);
debug.GetModules = bind(&Iop::CBiosBase::GetModuleList, m_bios);
return debug;
}

View File

@ -74,6 +74,7 @@ private:
HW_REG_END = 0x1F9FFFFF
};
MipsModuleList GetIopModules();
unsigned int ExecuteCpu(bool);
void ThreadProc();

View File

@ -122,6 +122,11 @@ void CPsxBios::SaveDebugTags(Framework::Xml::CNode* root)
}
MipsModuleList CPsxBios::GetModuleList()
{
return MipsModuleList();
}
#endif
void CPsxBios::CountTicks(uint32 ticks)

View File

@ -20,6 +20,7 @@ public:
#ifdef DEBUGGER_INCLUDED
void LoadDebugTags(Framework::Xml::CNode*);
void SaveDebugTags(Framework::Xml::CNode*);
MipsModuleList GetModuleList();
#endif
private:

View File

@ -41,7 +41,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer2\Source"
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_MSVC;_PSX;DEBUGGER_INCLUDED"
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_MSVC;_PSX;DEBUGGER_INCLUDED;FUNCTIONSVIEW_STANDALONE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@ -73,6 +73,7 @@
/>
<Tool
Name="VCManifestTool"
AdditionalManifestFiles="manifest.xml"
/>
<Tool
Name="VCXDCMakeTool"
@ -152,6 +153,7 @@
/>
<Tool
Name="VCManifestTool"
AdditionalManifestFiles="manifest.xml"
/>
<Tool
Name="VCXDCMakeTool"
@ -549,6 +551,10 @@
RelativePath="..\..\Source\MIPSInstructionFactory.h"
>
</File>
<File
RelativePath="..\..\Source\MIPSModule.h"
>
</File>
<File
RelativePath="..\..\Source\MIPSReflection.cpp"
>
@ -800,6 +806,14 @@
RelativePath="..\..\Source\iop\Iop_Timrman.h"
>
</File>
<File
RelativePath="..\..\Source\iop\Iop_Vblank.cpp"
>
</File>
<File
RelativePath="..\..\Source\iop\Iop_Vblank.h"
>
</File>
<File
RelativePath="..\..\Source\iop\IopBios.cpp"
>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Purei" type="win32" />
<description>PsfPlayer</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
</assembly>