From 69b837f18b52f9bc2c2c4911409352248a70bc66 Mon Sep 17 00:00:00 2001 From: Xele02 Date: Sun, 10 Feb 2013 16:36:06 +0100 Subject: [PATCH] Add debug dialogs (DisAsm, Memory, VFPU). New features : Breakpoint display, thread status, display list status Update translation and start french translation --- Core/Core.cpp | 10 +- Core/Debugger/Breakpoints.cpp | 10 + Core/Debugger/Breakpoints.h | 3 + Core/Debugger/SymbolMap.cpp | 5 + Core/Debugger/SymbolMap.h | 2 +- Core/HLE/sceKernelThread.cpp | 35 ++ Core/HLE/sceKernelThread.h | 13 + Core/Host.h | 7 + Core/MIPS/MIPS.h | 7 + GPU/GPUCommon.cpp | 13 +- GPU/GPUCommon.h | 9 + GPU/GPUInterface.h | 5 + GPU/GeDisasm.cpp | 6 +- Qt/EmuThread.cpp | 66 ++- Qt/EmuThread.h | 8 +- Qt/PPSSPP.pro | 3 +- Qt/QtHost.cpp | 80 ++- Qt/QtHost.h | 8 + Qt/ctrldisasmview.cpp | 437 +++++++++++++++- Qt/ctrldisasmview.h | 36 +- Qt/ctrlmemview.cpp | 250 +++++++++ Qt/ctrlmemview.h | 91 ++++ Qt/ctrlregisterlist.cpp | 354 ++++++++++++- Qt/ctrlregisterlist.h | 33 +- Qt/ctrlvfpuview.cpp | 98 ++++ Qt/ctrlvfpuview.h | 42 ++ Qt/debugger_disasm.cpp | 541 +++++++++++++++++-- Qt/debugger_disasm.h | 64 ++- Qt/debugger_disasm.ui | 767 ++++++++++++++++++--------- Qt/debugger_memory.cpp | 110 ++++ Qt/debugger_memory.h | 49 ++ Qt/debugger_memory.ui | 92 ++++ Qt/debugger_vfpu.cpp | 55 ++ Qt/debugger_vfpu.h | 35 ++ Qt/debugger_vfpu.ui | 87 ++++ Qt/languages/ppsspp_en.ts | 487 ++++++++++++++---- Qt/languages/ppsspp_fr.ts | 941 ++++++++++++++++++++++++++++++++++ Qt/languages/ppsspp_pl.ts | 487 ++++++++++++++---- Qt/mainwindow.cpp | 205 +++++--- Qt/mainwindow.h | 16 + Qt/mainwindow.ui | 31 +- Qt/qtemugl.cpp | 14 +- Qt/qtemugl.h | 3 + Qt/resources.qrc | 2 + Qt/resources/icon1.ico | Bin 0 -> 766 bytes Qt/resources/stop1.ico | Bin 0 -> 766 bytes 46 files changed, 4999 insertions(+), 618 deletions(-) create mode 100644 Qt/ctrlmemview.cpp create mode 100644 Qt/ctrlmemview.h create mode 100644 Qt/ctrlvfpuview.cpp create mode 100644 Qt/ctrlvfpuview.h create mode 100644 Qt/debugger_memory.cpp create mode 100644 Qt/debugger_memory.h create mode 100644 Qt/debugger_memory.ui create mode 100644 Qt/debugger_vfpu.cpp create mode 100644 Qt/debugger_vfpu.h create mode 100644 Qt/debugger_vfpu.ui create mode 100644 Qt/languages/ppsspp_fr.ts create mode 100644 Qt/resources/icon1.ico create mode 100644 Qt/resources/stop1.ico diff --git a/Core/Core.cpp b/Core/Core.cpp index 2d8a75cf91..f66929d071 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -99,7 +99,15 @@ reswitch: // We should never get here on Android. case CORE_STEPPING: //1: wait for step command.. +#if defined(USING_QT_UI) || defined(_DEBUG) + host->SendCoreWait(true); +#endif + m_hStepEvent.wait(m_hStepMutex); + +#if defined(USING_QT_UI) || defined(_DEBUG) + host->SendCoreWait(false); +#endif if (coreState == CORE_POWERDOWN) return; if (coreState != CORE_STEPPING) @@ -112,7 +120,7 @@ reswitch: currentCPU = &mipsr4k; Core_SingleStep(); //4: update disasm dialog -#ifdef _DEBUG +#if defined(USING_QT_UI) || defined(_DEBUG) host->UpdateDisassembly(); host->UpdateMemView(); #endif diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 7110040081..3aed03de74 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -143,3 +143,13 @@ void CBreakPoints::InvalidateJit() if (MIPSComp::jit && coreState == CORE_STEPPING) MIPSComp::jit->ClearCache(); } + +int CBreakPoints::GetNumBreakpoints() +{ + return m_iBreakPoints.size(); +} + +int CBreakPoints::GetBreakpointAddress(int i) +{ + return m_iBreakPoints[i].iAddress; +} diff --git a/Core/Debugger/Breakpoints.h b/Core/Debugger/Breakpoints.h index c931010301..d3ac2298b2 100644 --- a/Core/Debugger/Breakpoints.h +++ b/Core/Debugger/Breakpoints.h @@ -83,6 +83,9 @@ public: static void InvalidateJit(u32 _iAddress); static void InvalidateJit(); + + static int GetNumBreakpoints(); + static int GetBreakpointAddress(int i); }; diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index 44159f7fb2..91dce38025 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -334,6 +334,11 @@ int SymbolMap::GetNumSymbols() { return (int)entries.size(); } +SymbolType SymbolMap::GetSymbolType(int i) +{ + return entries[i].type; +} + char *SymbolMap::GetSymbolName(int i) { return entries[i].name; diff --git a/Core/Debugger/SymbolMap.h b/Core/Debugger/SymbolMap.h index 3766b68c81..daf3cb8bb4 100644 --- a/Core/Debugger/SymbolMap.h +++ b/Core/Debugger/SymbolMap.h @@ -52,6 +52,7 @@ public: void SetSymbolName(int i, const char *newname); u32 GetSymbolSize(int i); u32 GetSymbolAddr(int i); + SymbolType GetSymbolType(int i); int FindSymbol(const char *name); u32 GetAddress(int num); void IncreaseRunCount(int num); @@ -61,7 +62,6 @@ public: void UseFuncSignaturesFile(const char *filename, u32 maxAddress); void CompileFuncSignaturesFile(const char *filename); - private: struct MapEntry { diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index bda308d7a9..ba8f7eb92f 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2722,3 +2722,38 @@ u32 __KernelNotifyCallbackType(RegisteredCallbackType type, SceUID cbId, int not return 0; } +std::vector GetThreadsInfo() +{ + std::vector threadList; + + u32 error; + for (std::vector::iterator iter = threadqueue.begin(); iter != threadqueue.end(); iter++) + { + Thread *t = kernelObjects.Get(*iter, error); + if (!t) + continue; + + DebugThreadInfo info; + info.id = *iter; + strncpy(info.name,t->GetName(),KERNELOBJECT_MAX_NAME_LENGTH); + info.name[KERNELOBJECT_MAX_NAME_LENGTH+1] = 0; + info.status = t->nt.status; + info.entrypoint = t->nt.entrypoint; + info.curPC = t->context.pc; + info.isCurrent = (*iter == currentThread); + threadList.push_back(info); + } + + return threadList; +} + +void __KernelChangeThreadState(SceUID threadId, ThreadStatus newStatus) +{ + u32 error; + Thread *t = kernelObjects.Get(threadId, error); + if (!t) + return; + + __KernelChangeThreadState(t, newStatus); +} + diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 1000f9597a..1415f2bf00 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -257,3 +257,16 @@ void __KernelChangeThreadState(Thread *thread, ThreadStatus newStatus); typedef void (*ThreadCallback)(SceUID threadID); void __KernelListenThreadEnd(ThreadCallback callback); + +struct DebugThreadInfo +{ + SceUID id; + char name[KERNELOBJECT_MAX_NAME_LENGTH+1]; + u32 status; + int curPC; + int entrypoint; + bool isCurrent; +}; + +std::vector GetThreadsInfo(); +void __KernelChangeThreadState(SceUID threadId, ThreadStatus newStatus); diff --git a/Core/Host.h b/Core/Host.h index d426289d14..f20277ac20 100644 --- a/Core/Host.h +++ b/Core/Host.h @@ -61,6 +61,13 @@ public: virtual bool AttemptLoadSymbolMap() {return false;} virtual void SetWindowTitle(const char *message) {} + virtual void SendCoreWait(bool) {} + + virtual bool GpuStep() { return false; } + virtual void SendGPUWait() {} + virtual void SetGPUStep(bool value) {} + virtual void NextGPUStep() {} + // Used for headless. virtual void SendDebugOutput(const std::string &output) {} virtual void SendDebugScreenshot(const u8 *pixbuf, u32 w, u32 h) {} diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index a2849d28a4..ad0d51cfa6 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -80,6 +80,10 @@ enum // George Marsaglia-style random number generator. class GMRng { public: + GMRng() { + m_w = 0x23E866ED; + m_z = 0x80FD5AF2; + } void Init(int seed) { m_w = seed ^ (seed << 16); if (!m_w) m_w = 1337; @@ -91,6 +95,9 @@ public: m_w = 18000 * (m_w & 65535) + (m_w >> 16); return (m_z << 16) + m_w; } + float F() { + return (float)R32() / (float)(0xFFFFFFFF); + } void DoState(PointerWrap &p); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index d694b89b99..07ef1234c1 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -4,7 +4,9 @@ #include "GPUCommon.h" #include "GPUState.h" #include "ChunkFile.h" - +#if defined(USING_QT_UI) +#include "Core/Host.h" +#endif static int dlIdGenerator = 1; @@ -28,6 +30,9 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) { DisplayList dl; dl.id = dlIdGenerator++; +#if defined(USING_QT_UI) + dl.startpc = listpc & 0xFFFFFFF; +#endif dl.pc = listpc & 0xFFFFFFF; dl.stall = stall & 0xFFFFFFF; dl.status = PSP_GE_LIST_QUEUED; @@ -82,6 +87,12 @@ bool GPUCommon::InterpretList(DisplayList &list) list.status = PSP_GE_LIST_STALL_REACHED; return false; } +#if defined(USING_QT_UI) + if(host->GpuStep()) + { + host->SendGPUWait(); + } +#endif op = Memory::ReadUnchecked_U32(list.pc); //read from memory u32 cmd = op >> 24; u32 diff = op ^ gstate.cmdmem[cmd]; diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index c5b5f16e59..d58ae86ac3 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -53,4 +53,13 @@ public: } return NULL; } + + const std::deque& GetDisplayLists() + { + return dlQueue; + } + DisplayList* GetCurrentDisplayList() + { + return currentList; + } }; diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index c35aa5a88e..a60a0e1a42 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -35,6 +35,9 @@ enum DisplayListStatus struct DisplayList { int id; +#if defined(USING_QT_UI) + u32 startpc; +#endif u32 pc; u32 stall; DisplayListStatus status; @@ -91,4 +94,6 @@ public: // Debugging virtual void DumpNextFrame() = 0; + virtual const std::deque& GetDisplayLists() = 0; + virtual DisplayList* GetCurrentDisplayList() = 0; }; diff --git a/GPU/GeDisasm.cpp b/GPU/GeDisasm.cpp index c75dc1ba93..000b466d4f 100644 --- a/GPU/GeDisasm.cpp +++ b/GPU/GeDisasm.cpp @@ -396,7 +396,11 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) { case GE_CMD_TEXSIZE5: case GE_CMD_TEXSIZE6: case GE_CMD_TEXSIZE7: - sprintf(buffer, "Texture Size %i: %06x", cmd - GE_CMD_TEXSIZE0, data); + { + int w = 1 << (data & 0xf); + int h = 1 << ((data>>8) & 0xf); + sprintf(buffer, "Texture Size %i: %06x, width : %d, height : %d", cmd - GE_CMD_TEXSIZE0, data, w, h); + } break; case GE_CMD_ZBUFPTR: diff --git a/Qt/EmuThread.cpp b/Qt/EmuThread.cpp index 1b88068ed0..69f9d681ca 100644 --- a/Qt/EmuThread.cpp +++ b/Qt/EmuThread.cpp @@ -18,9 +18,10 @@ #include "gfx_es2/gl_state.h" #include "GPU/GPUState.h" #include "android/jni/ui_atlas.h" -#include "native/util/random/rng.h" #include "native/base/timeutil.h" #include "native/base/colorutil.h" +#include "GPU/GPUState.h" +#include "GPU/GPUInterface.h" #include "qtemugl.h" #include "QtHost.h" @@ -114,6 +115,26 @@ void EmuThread_LockDraw(bool value) } } +QString GetCurrentFilename() +{ + return fileToStart; +} + + +EmuThread::EmuThread() + : running(false) + , gameRunning(false) + , needInitGame(false) + , frames_(0) + , gameMutex( new QMutex(QMutex::Recursive)) + , mutexLockNum(0) +{ +} + +EmuThread::~EmuThread() +{ + delete gameMutex; +} void EmuThread::init(InputState *inputState) { @@ -143,13 +164,14 @@ void EmuThread::run() //UpdateGamepad(*input_state); timer.start(); - gameMutex.lock(); + gameMutex->lock(); bool gRun = gameRunning; - gameMutex.unlock(); + gameMutex->unlock(); if(gRun) { - gameMutex.lock(); + + gameMutex->lock(); glWindow->makeCurrent(); if(needInitGame) @@ -227,14 +249,14 @@ void EmuThread::run() qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; - gameMutex.unlock(); + gameMutex->unlock(); if(time < frameTime) { glWindow->doneCurrent(); msleep(frameTime-time); glWindow->makeCurrent(); } - gameMutex.lock(); + gameMutex->lock(); timer.start(); } @@ -265,11 +287,11 @@ void EmuThread::run() #endif glWindow->swapBuffers(); glWindow->doneCurrent(); - gameMutex.unlock(); + gameMutex->unlock(); } else { - gameMutex.lock(); + gameMutex->lock(); glWindow->makeCurrent(); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -311,7 +333,7 @@ void EmuThread::run() glWindow->swapBuffers(); glWindow->doneCurrent(); - gameMutex.unlock(); + gameMutex->unlock(); qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; if(time < frameTime) @@ -358,18 +380,18 @@ void EmuThread::setRunning(bool value) void EmuThread::startGame(QString filename) { - gameMutex.lock(); + gameMutex->lock(); needInitGame = true; gameRunning = true; fileToStart = filename; - gameMutex.unlock(); + gameMutex->unlock(); } void EmuThread::stopGame() { Core_Stop(); - gameMutex.lock(); + gameMutex->lock(); gameRunning = false; PSP_Shutdown(); @@ -380,7 +402,25 @@ void EmuThread::stopGame() g_State.bEmuThreadStarted = false; frames_ = 0; - gameMutex.unlock(); + gameMutex->unlock(); +} + +void EmuThread::LockGL(bool lock) +{ + if(lock) + { + gameMutex->lock(); + if(mutexLockNum == 0) + glWindow->makeCurrent(); + mutexLockNum++; + } + else + { + mutexLockNum--; + if(mutexLockNum == 0) + glWindow->doneCurrent(); + gameMutex->unlock(); + } } diff --git a/Qt/EmuThread.h b/Qt/EmuThread.h index 183c9efad0..5a669f8138 100644 --- a/Qt/EmuThread.h +++ b/Qt/EmuThread.h @@ -8,14 +8,15 @@ class QtEmuGL; class EmuThread : public QThread { public: - EmuThread() : running(false), gameRunning(false), needInitGame(false), frames_(0) {} + EmuThread(); + ~EmuThread(); void init(InputState* inputState); void run(); void FinalShutdown(); void setRunning(bool value); void startGame(QString filename); void stopGame(); - QMutex gameMutex; + void LockGL(bool value); public slots: void Shutdown(); private: @@ -24,6 +25,8 @@ private: bool gameRunning; bool needInitGame; int frames_; + QMutex *gameMutex; + int mutexLockNum; }; @@ -32,3 +35,4 @@ void EmuThread_Stop(); void EmuThread_StartGame(QString filename); void EmuThread_StopGame(); void EmuThread_LockDraw(bool value); +QString GetCurrentFilename(); diff --git a/Qt/PPSSPP.pro b/Qt/PPSSPP.pro index 3446744f32..a233854431 100755 --- a/Qt/PPSSPP.pro +++ b/Qt/PPSSPP.pro @@ -22,7 +22,8 @@ desktop_ui { } TRANSLATIONS = languages/ppsspp_en.ts \ - languages/ppsspp_pl.ts + languages/ppsspp_pl.ts \ + languages/ppsspp_fr.ts # Main SOURCES += ../native/base/QtMain.cpp diff --git a/Qt/QtHost.cpp b/Qt/QtHost.cpp index 54468d2046..78cc696698 100644 --- a/Qt/QtHost.cpp +++ b/Qt/QtHost.cpp @@ -12,6 +12,7 @@ #include "android/jni/EmuScreen.h" #include "android/jni/UIShader.h" #include "android/jni/ui_atlas.h" +#include "EmuThread.h" std::string boot_filename = ""; Texture *uiTexture; @@ -20,20 +21,22 @@ ScreenManager *screenManager; std::string config_filename; std::string game_title; +event m_hGPUStepEvent; +recursive_mutex m_hGPUStepMutex; + QtHost::QtHost(MainWindow *mainWindow_) : mainWindow(mainWindow_) + , m_GPUStep(false) { QObject::connect(this,SIGNAL(BootDoneSignal()),mainWindow,SLOT(Boot())); } void QtHost::InitGL() { - } void QtHost::ShutdownGL() { - //GL_Shutdown(); } void QtHost::SetWindowTitle(const char *message) @@ -45,30 +48,28 @@ void QtHost::SetWindowTitle(const char *message) void QtHost::UpdateUI() { - //mainWindow->Update(); + mainWindow->Update(); mainWindow->UpdateMenus(); } void QtHost::UpdateMemView() { - /*for (int i=0; iUpdate();*/ + if(mainWindow->GetDialogMemory()) + mainWindow->GetDialogMemory()->Update(); } void QtHost::UpdateDisassembly() { - /*for (int i=0; iUpdate();*/ - /*if(dialogDisasm) - dialogDisasm->Update();*/ + if(mainWindow->GetDialogDisasm()) + { + mainWindow->GetDialogDisasm()->GotoPC(); + mainWindow->GetDialogDisasm()->Update(); + } } void QtHost::SetDebugMode(bool mode) { - /*for (int i=0; iGetDialogDisasm()) mainWindow->GetDialogDisasm()->SetDebugMode(mode); } @@ -76,14 +77,9 @@ void QtHost::SetDebugMode(bool mode) void QtHost::BeginFrame() { - /*for (auto iter = this->input.begin(); iter != this->input.end(); iter++) - if ((*iter)->UpdateState() == 0) - break; // *iter is std::shared_ptr, **iter is InputDevice - GL_BeginFrame();*/ } void QtHost::EndFrame() { - //GL_EndFrame(); } void QtHost::InitSound(PMixer *mixer) @@ -102,18 +98,26 @@ void QtHost::BootDone() emit BootDoneSignal(); } + +static QString SymbolMapFilename(QString currentFilename) +{ + std::string result = currentFilename.toStdString(); + size_t dot = result.rfind('.'); + if (dot == result.npos) + return (result + ".map").c_str(); + + result.replace(dot, result.npos, ".map"); + return result.c_str(); +} + bool QtHost::AttemptLoadSymbolMap() { - QFileInfo currentFile(fileToStart); - QString ret = currentFile.baseName() + ".map"; - return symbolMap.LoadSymbolMap(ret.toAscii().constData()); + return symbolMap.LoadSymbolMap(SymbolMapFilename(GetCurrentFilename()).toStdString().c_str()); } void QtHost::PrepareShutdown() { - QFileInfo currentFile(fileToStart); - QString ret = currentFile.baseName() + ".map"; - symbolMap.SaveSymbolMap(ret.toAscii().constData()); + symbolMap.SaveSymbolMap(SymbolMapFilename(GetCurrentFilename()).toStdString().c_str()); } void QtHost::AddSymbol(std::string name, u32 addr, u32 size, int type=0) @@ -130,6 +134,36 @@ bool QtHost::IsDebuggingEnabled() #endif } +void QtHost::SendCoreWait(bool isWaiting) +{ + mainWindow->CoreEmitWait(isWaiting); +} + +bool QtHost::GpuStep() +{ + return m_GPUStep; +} + +void QtHost::SendGPUWait() +{ + EmuThread_LockDraw(false); + + mainWindow->GetDialogDisasm()->UpdateDisplayList(); + m_hGPUStepEvent.wait(m_hGPUStepMutex); + + EmuThread_LockDraw(true); +} + +void QtHost::SetGPUStep(bool value) +{ + m_GPUStep = value; +} + +void QtHost::NextGPUStep() +{ + m_hGPUStepEvent.notify_one(); +} + void NativeMix(short *audio, int num_samples) { if (g_mixer) diff --git a/Qt/QtHost.h b/Qt/QtHost.h index 27a4f943ae..b98ec8954e 100644 --- a/Qt/QtHost.h +++ b/Qt/QtHost.h @@ -12,6 +12,7 @@ #include "gfx/texture.h" #include "input/input_state.h" #include "math/math_util.h" +#include "base/mutex.h" #include "math/lin/matrix4x4.h" #include @@ -48,10 +49,17 @@ public: bool AttemptLoadSymbolMap(); void SetWindowTitle(const char *message); + void SendCoreWait(bool); + bool GpuStep(); + void SendGPUWait(); + void SetGPUStep(bool value); + void NextGPUStep(); + signals: void BootDoneSignal(); private: MainWindow* mainWindow; + bool m_GPUStep; }; #endif // QTAPP_H diff --git a/Qt/ctrldisasmview.cpp b/Qt/ctrldisasmview.cpp index 089d759794..bc5e0a3664 100644 --- a/Qt/ctrldisasmview.cpp +++ b/Qt/ctrldisasmview.cpp @@ -1,18 +1,451 @@ #include "ctrldisasmview.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debugger_disasm.h" +#include "Core/Debugger/SymbolMap.h" + +namespace +{ + u32 halfAndHalf(u32 a, u32 b) + { + return ((a>>1)&0x7f7f7f7f) + ((b>>1)&0x7f7f7f7f); + } +} CtrlDisAsmView::CtrlDisAsmView(QWidget *parent) : - QTableWidget(parent) + QWidget(parent) { + curAddress=0; + rowHeight=14; + align=2; + selecting=false; + showHex=false; +} + +void CtrlDisAsmView::keyPressEvent(QKeyEvent *e) +{ + int page=(rect().bottom()/rowHeight)/2-1; + + if(e->key() == Qt::Key_Down) + { + curAddress += align; + e->accept(); + } + else if(e->key() == Qt::Key_Up) + { + curAddress -= align; + e->accept(); + } + else if(e->key() == Qt::Key_PageDown) + { + curAddress += page*align; + e->accept(); + } + else if(e->key() == Qt::Key_PageUp) + { + curAddress -= page*align; + e->accept(); + } + update(); +} + +void CtrlDisAsmView::mousePressEvent(QMouseEvent *e) +{ + int x = e->pos().x(); + int y = e->pos().y(); + if (x>16) + { + oldSelection=selection; + selection=yToAddress(y); + bool oldselecting=selecting; + selecting=true; + if (!oldselecting || (selection!=oldSelection)) + redraw(); + e->accept(); + } + else + { + EmuThread_LockDraw(true); + debugger->toggleBreakpoint(yToAddress(y)); + EmuThread_LockDraw(false); + parentWindow->Update(); + redraw(); + e->accept(); + } +} + +void CtrlDisAsmView::wheelEvent(QWheelEvent* e) +{ + int numDegrees = e->delta() / 8; + int numSteps = numDegrees / 15; + if (e->orientation() == Qt::Horizontal) { + } else { + curAddress -= numSteps*align; + e->accept(); + update(); + } } void CtrlDisAsmView::redraw() { + update(); } void CtrlDisAsmView::contextMenu(const QPoint &pos) { + QMenu menu(this); + + QAction *copyAddress = new QAction(tr("Copy &address"), this); + connect(copyAddress, SIGNAL(triggered()), this, SLOT(CopyAddress())); + menu.addAction(copyAddress); + + QAction *copyInstrHex = new QAction(tr("Copy instruction (&hex)"), this); + connect(copyInstrHex, SIGNAL(triggered()), this, SLOT(CopyInstrHex())); + menu.addAction(copyInstrHex); + + QAction *copyInstrDisAsm = new QAction(tr("Copy instruction (&disasm)"), this); + connect(copyInstrDisAsm, SIGNAL(triggered()), this, SLOT(CopyInstrDisAsm())); + menu.addAction(copyInstrDisAsm); + + menu.addSeparator(); + + QAction *runToHere = new QAction(tr("&Run to here"), this); + connect(runToHere, SIGNAL(triggered()), this, SLOT(RunToHere())); + menu.addAction(runToHere); + + QAction *setNextStatement = new QAction(tr("&Set Next Statement"), this); + connect(setNextStatement, SIGNAL(triggered()), this, SLOT(SetNextStatement())); + menu.addAction(setNextStatement); + + QAction *toggleBreakpoint = new QAction(tr("&Toggle breakpoint"), this); + connect(toggleBreakpoint, SIGNAL(triggered()), this, SLOT(ToggleBreakpoint())); + menu.addAction(toggleBreakpoint); + + QAction *followBranch = new QAction(tr("&Follow branch"), this); + connect(followBranch, SIGNAL(triggered()), this, SLOT(FollowBranch())); + menu.addAction(followBranch); + + menu.addSeparator(); + + //QAction *showDynarecResults = new QAction(tr("&Show Dynarec Results"), this); + //connect(showDynarecResults, SIGNAL(triggered()), this, SLOT(ShowDynarecResults())); + //menu.addAction(showDynarecResults); + + QAction *goToMemoryView = new QAction(tr("Go to in &Memory View"), this); + connect(goToMemoryView, SIGNAL(triggered()), this, SLOT(GoToMemoryView())); + menu.addAction(goToMemoryView); + + menu.addSeparator(); + + //QAction *killFunction = new QAction(tr("&Kill function"), this); + //connect(killFunction, SIGNAL(triggered()), this, SLOT(KillFunction())); + //menu.addAction(killFunction); + + QAction *renameFunction = new QAction(tr("&Rename function..."), this); + connect(renameFunction, SIGNAL(triggered()), this, SLOT(RenameFunction())); + menu.addAction(renameFunction); + + + menu.exec( mapToGlobal(pos)); } -void CtrlDisAsmView::click(int row, int col) +void CtrlDisAsmView::GoToMemoryView() { + parentWindow->ShowMemory(selection); +} + +void CtrlDisAsmView::CopyAddress() +{ + char temp[16]; + sprintf(temp,"%08x",selection); + QApplication::clipboard()->setText(QString(temp)); +} + +void CtrlDisAsmView::CopyInstrDisAsm() +{ + EmuThread_LockDraw(true); + QApplication::clipboard()->setText(debugger->disasm(selection,align)); + EmuThread_LockDraw(false); +} + +void CtrlDisAsmView::CopyInstrHex() +{ + char temp[24]; + EmuThread_LockDraw(true); + sprintf(temp,"%08x",debugger->readMemory(selection)); + EmuThread_LockDraw(false); + QApplication::clipboard()->setText(temp); +} + +void CtrlDisAsmView::SetNextStatement() +{ + EmuThread_LockDraw(true); + debugger->setPC(selection); + EmuThread_LockDraw(false); + redraw(); +} + +void CtrlDisAsmView::ToggleBreakpoint() +{ + EmuThread_LockDraw(true); + debugger->toggleBreakpoint(selection); + EmuThread_LockDraw(false); + parentWindow->Update(); + redraw(); +} + +void CtrlDisAsmView::FollowBranch() +{ + EmuThread_LockDraw(true); + const char *temp = debugger->disasm(selection,align); + EmuThread_LockDraw(false); + const char *mojs=strstr(temp,"->$"); + if (mojs) + { + u32 dest; + sscanf(mojs+3,"%08x",&dest); + if (dest) + { + marker = selection; + gotoAddr(dest); + } + } +} + +void CtrlDisAsmView::RunToHere() +{ + EmuThread_LockDraw(true); + debugger->setBreakpoint(selection); + debugger->runToBreakpoint(); + EmuThread_LockDraw(false); + redraw(); +} + +void CtrlDisAsmView::RenameFunction() +{ + int sym = symbolMap.GetSymbolNum(selection); + if (sym != -1) + { + char name[256]; + strncpy(name, symbolMap.GetSymbolName(sym),256); + bool ok; + QString newname = QInputDialog::getText(this, tr("New function name"), + tr("New function name :"), QLineEdit::Normal, + name, &ok); + if (ok && !newname.isEmpty()) + { + symbolMap.SetSymbolName(sym,newname.toStdString().c_str()); + redraw(); + parentWindow->NotifyMapLoaded(); + } + } + else + { + QMessageBox::information(this,"Warning","No symbol selected",QMessageBox::Ok); + } +} + +void CtrlDisAsmView::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::white); + painter.drawRect(rect()); + + struct branch + { + int src,dst,srcAddr; + bool conditional; + }; + branch branches[256]; + int numBranches=0; + + int width = rect().width(); + int numRows=(rect().height()/rowHeight)/2+1; + + QColor bgColor = QColor(0xFFFFFFFF); + QPen nullPen= QPen(bgColor); + QPen currentPen=QPen(QColor(0,0,0)); + QPen selPen=QPen(QColor(0xFF808080)); + QPen condPen=QPen(QColor(0xFFFF3020)); + + QBrush lbr; + lbr.setColor(bgColor); + QBrush currentBrush=QBrush(QColor(0xFFFFEfE8)); + QBrush pcBrush=QBrush(QColor(0xFF70FF70)); + + QFont normalFont = QFont("Arial", 10); + QFont boldFont = QFont("Arial", 10); + QFont alignedFont = QFont("Monospace", 10); + boldFont.setBold(true); + painter.setFont(normalFont); + + + QImage breakPoint(":/images/breakpoint"); + int i; + curAddress&=~(align-1); + + align=(debugger->getInstructionSize(0)); + for (i=-numRows; i<=numRows; i++) + { + unsigned int address=curAddress + i*align; + + int rowY1 = rect().bottom()/2 + rowHeight*i - rowHeight/2; + int rowY2 = rect().bottom()/2 + rowHeight*i + rowHeight/2 - 1; + char temp[256]; + sprintf(temp,"%08x",address); + + lbr.setColor(marker==address?QColor(0xFFFFEEE0):QColor(debugger->getColor(address))); + QColor bg = lbr.color(); + painter.setPen(nullPen); + painter.drawRect(0,rowY1,16-1,rowY2-rowY1); + + if (selecting && address == selection) + painter.setPen(selPen); + else + painter.setPen(i==0 ? currentPen : nullPen); + + QBrush mojsBrush=QBrush(lbr.color()); + painter.setBrush(mojsBrush); + + if (address == debugger->getPC()) + { + painter.setBrush(pcBrush); + qDebug() << address; + } + + painter.drawRect(16,rowY1,width-16-1,rowY2-rowY1); + painter.setBrush(currentBrush); + QPen textPen = QPen(QColor(halfAndHalf(bg.rgba(),0))); + painter.setPen(textPen); + painter.setFont(alignedFont); + painter.drawText(17,rowY1-3+rowHeight,QString(temp)); + painter.setFont(normalFont); + textPen.setColor(QColor(0xFF000000)); + painter.setPen(textPen); + if (debugger->isAlive()) + { + const char *dizz = debugger->disasm(address, align); + char dis[512]; + strcpy(dis, dizz); + char *dis2 = strchr(dis,'\t'); + char desc[256]=""; + if (dis2) + { + *dis2=0; + dis2++; + const char *mojs=strstr(dis2,"->$"); + if (mojs) + { + for (int i=0; i<8; i++) + { + bool found=false; + for (int j=0; j<22; j++) + { + if (mojs[i+3]=="0123456789ABCDEFabcdef"[j]) + found=true; + } + if (!found) + { + mojs=0; + break; + } + } + } + if (mojs) + { + int offs; + sscanf(mojs+3,"%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); + branches[numBranches].conditional = (dis[1]!=0); //unconditional 'b' branch + numBranches++; + const char *t = debugger->getDescription(offs); + if (memcmp(t,"z_",2)==0) + t+=2; + if (memcmp(t,"zz_",3)==0) + t+=3; + sprintf(desc,"-->%s", t); + textPen.setColor(QColor(0xFF600060)); + painter.setPen(textPen); + } + else + { + textPen.setColor(QColor(0xFF000000)); + painter.setPen(textPen); + } + painter.drawText(149,rowY1-3+rowHeight,QString(dis2)); + } + textPen.setColor(QColor(0xFF007000)); + painter.setPen(textPen); + painter.setFont(boldFont); + painter.drawText(84,rowY1-3+rowHeight,QString(dis)); + painter.setFont(normalFont); + if (desc[0]==0) + { + const char *t = debugger->getDescription(address); + if (memcmp(t,"z_",2)==0) + t+=2; + if (memcmp(t,"zz_",3)==0) + t+=3; + strcpy(desc,t); + } + if (memcmp(desc,"-->",3) == 0) + { + textPen.setColor(QColor(0xFF0000FF)); + painter.setPen(textPen); + } + else + { + textPen.setColor(halfAndHalf(halfAndHalf(bg.rgba(),0),bg.rgba())); + painter.setPen(textPen); + } + if (strlen(desc)) + painter.drawText(std::max(280,width/3+190),rowY1-3+rowHeight,QString(desc)); + if (debugger->isBreakpoint(address)) + { + painter.drawImage(2,rowY1+2,breakPoint); + } + } + } + for (i=0; i-200) + { + painter.drawLine(curPos, QPoint(x+2,branches[i].src)); + curPos = QPoint(x+2,branches[i].src); + painter.drawLine(curPos, QPoint(x+2,branches[i].dst)); + curPos = QPoint(x+2,branches[i].dst); + painter.drawLine(curPos, QPoint(x-4,branches[i].dst)); + + curPos = QPoint(x,branches[i].dst-4); + painter.drawLine(curPos, QPoint(x-4,branches[i].dst)); + curPos = QPoint(x-4,branches[i].dst); + painter.drawLine(curPos, QPoint(x+1,branches[i].dst+5)); + } + else + { + painter.drawLine(curPos, QPoint(x+4,branches[i].src)); + } + } +} + +int CtrlDisAsmView::yToAddress(int y) +{ + int ydiff=y-rect().bottom()/2-rowHeight/2; + ydiff=(int)(floor((float)ydiff / (float)rowHeight))+1; + return curAddress + ydiff * align; } diff --git a/Qt/ctrldisasmview.h b/Qt/ctrldisasmview.h index 1b5fd89c1f..dd1bce826b 100644 --- a/Qt/ctrldisasmview.h +++ b/Qt/ctrldisasmview.h @@ -1,10 +1,13 @@ #ifndef CTRLDISASMVIEW_H #define CTRLDISASMVIEW_H -#include +#include #include "Core/Debugger/DebugInterface.h" +#include "EmuThread.h" -class CtrlDisAsmView : public QTableWidget +class Debugger_Disasm; + +class CtrlDisAsmView : public QWidget { Q_OBJECT public: @@ -17,11 +20,18 @@ public: align=l; } + void setParentWindow(Debugger_Disasm* win) + { + parentWindow = win; + } + void setDebugger(DebugInterface *deb) { + EmuThread_LockDraw(true); debugger=deb; curAddress=debugger->getPC(); align=debugger->getInstructionSize(0); + EmuThread_LockDraw(false); } DebugInterface *getDebugger() { @@ -34,7 +44,9 @@ public: } void gotoPC() { + EmuThread_LockDraw(true); curAddress=debugger->getPC()&(~(align-1)); + EmuThread_LockDraw(false); redraw(); } unsigned int getSelection() @@ -49,21 +61,38 @@ public: void toggleBreakpoint() { + EmuThread_LockDraw(true); debugger->toggleBreakpoint(curAddress); + EmuThread_LockDraw(false); redraw(); } void contextMenu(const QPoint& pos); - void click(int row, int col); +protected: + void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *); + void wheelEvent(QWheelEvent *e); signals: public slots: + void CopyAddress(); + void CopyInstrDisAsm(); + void SetNextStatement(); + void FollowBranch(); + void CopyInstrHex(); + void RunToHere(); + void ToggleBreakpoint(); + void GoToMemoryView(); + void RenameFunction(); private: + int yToAddress(int y); int curAddress; int align; + int rowHeight; int selection; int marker; int oldSelection; @@ -73,6 +102,7 @@ private: bool showHex; DebugInterface *debugger; + Debugger_Disasm* parentWindow; }; diff --git a/Qt/ctrlmemview.cpp b/Qt/ctrlmemview.cpp new file mode 100644 index 0000000000..ffc768c48f --- /dev/null +++ b/Qt/ctrlmemview.cpp @@ -0,0 +1,250 @@ +#include "ctrlmemview.h" + +#include +#include +#include +#include +#include +#include + +#include "EmuThread.h" +#include "Core/MemMap.h" +#include "Core/Debugger/SymbolMap.h" + +CtrlMemView::CtrlMemView(QWidget *parent) : + QWidget(parent) +{ + + curAddress=0; + rowHeight=14; + align=4; + alignMul=4; + selecting=false; + mode=MV_NORMAL; + debugger = 0; + + setMinimumWidth(500); +} + +void CtrlMemView::redraw() +{ + update(); +} + + +void CtrlMemView::wheelEvent(QWheelEvent* e) +{ + int numDegrees = e->delta() / 8; + int numSteps = numDegrees / 15; + if (e->orientation() == Qt::Horizontal) { + } else { + curAddress -= numSteps*align*alignMul; + e->accept(); + redraw(); + } +} + + +void CtrlMemView::keyPressEvent(QKeyEvent *e) +{ + int page=(rect().bottom()/rowHeight)/2-1; + + if(e->key() == Qt::Key_Up) + { + curAddress-=align*alignMul; + e->accept(); + } + else if(e->key() == Qt::Key_Down) + { + curAddress+=align*alignMul; + e->accept(); + } + else if(e->key() == Qt::Key_PageUp) + { + curAddress-=page*align*alignMul; + e->accept(); + } + else if(e->key() == Qt::Key_PageDown) + { + curAddress+=page*align*alignMul; + e->accept(); + } + redraw(); +} + +void CtrlMemView::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::white); + painter.drawRect(rect()); + + if (!debugger) + return; + + int width = rect().width(); + int numRows=(rect().bottom()/rowHeight)/2+1; + + QPen nullPen=QPen(0xFFFFFF); + QPen currentPen=QPen(0xFF000000); + QPen selPen=QPen(0x808080); + QBrush lbr = QBrush(0xFFFFFF); + QBrush nullBrush=QBrush(0xFFFFFF); + QBrush currentBrush=QBrush(0xFFEfE8); + QBrush pcBrush=QBrush(0x70FF70); + QPen textPen; + + QFont normalFont = QFont("Arial", 10); + QFont alignedFont = QFont("Monospace", 10); + painter.setFont(normalFont); + + int i; + curAddress&=~(align-1); + for (i=-numRows; i<=numRows; i++) + { + unsigned int address=curAddress + i*align*alignMul; + + int rowY1 = rect().bottom()/2 + rowHeight*i - rowHeight/2; + int rowY2 = rect().bottom()/2 + rowHeight*i + rowHeight/2; + + char temp[256]; + sprintf(temp,"%08x",address); + + painter.setBrush(currentBrush); + + if (selecting && address == selection) + painter.setPen(selPen); + else + painter.setPen(i==0 ? currentPen : nullPen); + painter.drawRect(0, rowY1, 16-1, rowY2 - rowY1 - 1); + + painter.drawRect(16, rowY1, width - 16 -1, rowY2 - rowY1 - 1); + painter.setBrush(nullBrush); + textPen.setColor(0x600000); + painter.setPen(textPen); + painter.setFont(alignedFont); + painter.drawText(17,rowY1-2+rowHeight, temp); + textPen.setColor(0xFF000000); + painter.setPen(textPen); + if (debugger->isAlive()) + { + + switch(mode) { + case MV_NORMAL: + { + const char *m = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + if (Memory::IsValidAddress(address)) + { + EmuThread_LockDraw(true); + u32 memory[4] = { + debugger->readMemory(address), + debugger->readMemory(address+4), + debugger->readMemory(address+8), + debugger->readMemory(address+12) + }; + EmuThread_LockDraw(false); + m = (const char*)memory; + sprintf(temp, "%08x %08x %08x %08x ................", + memory[0],memory[1],memory[2],memory[3]); + } + for (int i=0; i<16; i++) + { + int c = (unsigned char)m[i]; + if (c>=32 && c<255) + temp[i+37]=c; + } + } + painter.setFont(alignedFont); + painter.drawText(85,rowY1 - 2 + rowHeight, temp); + break; + + case MV_SYMBOLS: + { + textPen.setColor(0x0000FF); + painter.setPen(textPen); + int fn = symbolMap.GetSymbolNum(address); + if (fn==-1) + { + sprintf(temp, "%s (ns)", Memory::GetAddressName(address)); + } + else + sprintf(temp, "%s (0x%x b)", symbolMap.GetSymbolName(fn),symbolMap.GetSymbolSize(fn)); + painter.drawText(205,rowY1 - 2 + rowHeight, temp); + + textPen.setColor(0xFF0000000); + painter.setPen(textPen); + + if (align==4) + { + u32 value = Memory::ReadUnchecked_U32(address); + sprintf(temp, "%08x [%s]", value, symbolMap.GetSymbolName(symbolMap.GetSymbolNum(value))); + } + else if (align==2) + { + u16 value = Memory::ReadUnchecked_U16(address); + sprintf(temp, "%04x [%s]", value, symbolMap.GetSymbolName(symbolMap.GetSymbolNum(value))); + } + + painter.drawText(85,rowY1 - 2 + rowHeight, temp); + break; + } + } + } + } +} + +void CtrlMemView::mousePressEvent(QMouseEvent *e) +{ + int x = e->pos().x(); + int y = e->pos().y(); + if (x>16) + { + oldSelection=selection; + selection=yToAddress(y); + bool oldselecting=selecting; + selecting=true; + if (!oldselecting || (selection!=oldSelection)) + redraw(); + } +} + +void CtrlMemView::contextMenu(const QPoint &pos) +{ + QMenu menu(this); + + QAction *gotoDisAsm = new QAction(tr("Go to in &disasm"), this); + //connect(gotoDisAsm, SIGNAL(triggered()), this, SLOT(GotoDisAsm())); + menu.addAction(gotoDisAsm); + + menu.addSeparator(); + + QAction *copyValue = new QAction(tr("&Copy value"), this); + connect(copyValue, SIGNAL(triggered()), this, SLOT(CopyValue())); + menu.addAction(copyValue); + + QAction *dump = new QAction(tr("Dump..."), this); + connect(dump, SIGNAL(triggered()), this, SLOT(Dump())); + menu.addAction(dump); + + menu.exec( mapToGlobal(pos)); +} + +void CtrlMemView::CopyValue() +{ + char temp[24]; + sprintf(temp,"%08x",Memory::ReadUnchecked_U32(selection)); + QApplication::clipboard()->setText(temp); +} + +void CtrlMemView::Dump() +{ + QMessageBox::information(this,"Sorry","This feature has not been implemented.",QMessageBox::Ok); +} + +int CtrlMemView::yToAddress(int y) +{ + int ydiff=y-rect().bottom()/2-rowHeight/2; + ydiff=(int)(floor((float)ydiff / (float)rowHeight))+1; + return curAddress + ydiff * align*alignMul; +} + diff --git a/Qt/ctrlmemview.h b/Qt/ctrlmemview.h new file mode 100644 index 0000000000..070b1af7f9 --- /dev/null +++ b/Qt/ctrlmemview.h @@ -0,0 +1,91 @@ +#ifndef CTRLMEMVIEW_H +#define CTRLMEMVIEW_H + +#include "Core/Debugger/DebugInterface.h" +#include + +enum MemViewMode +{ + MV_NORMAL, + MV_SYMBOLS, + MV_MAX +}; + +class CtrlMemView : public QWidget +{ + Q_OBJECT +public: + explicit CtrlMemView(QWidget *parent = 0); + + void setDebugger(DebugInterface *deb) + { + debugger=deb; + if (debugger) + align=debugger->getInstructionSize(0); + } + DebugInterface *getDebugger() + { + return debugger; + } + void redraw(); + + void setMode(MemViewMode m) + { + mode=m; + switch(mode) { + case MV_NORMAL: + alignMul=4; + break; + case MV_SYMBOLS: + alignMul=1; + break; + default: + break; + } + redraw(); + } + + void setAlign(int l) + { + align=l; + } + int yToAddress(int y); + + void gotoAddr(unsigned int addr) + { + curAddress=addr&(~(align-1)); + redraw(); + } + + unsigned int getSelection() + { + return curAddress; + } + void contextMenu(const QPoint &pos); +protected: + void paintEvent(QPaintEvent *); + void keyPressEvent(QKeyEvent *e); + void wheelEvent(QWheelEvent *e); + void mousePressEvent(QMouseEvent *e); +signals: + +public slots: + void CopyValue(); + void Dump(); +private: + int curAddress; + int align; + int alignMul; + int rowHeight; + + int selection; + int oldSelection; + bool selectionChanged; + bool selecting; + bool hasFocus; + + DebugInterface *debugger; + MemViewMode mode; +}; + +#endif // CTRLMEMVIEW_H diff --git a/Qt/ctrlregisterlist.cpp b/Qt/ctrlregisterlist.cpp index 25f157aee8..e3971a01dd 100644 --- a/Qt/ctrlregisterlist.cpp +++ b/Qt/ctrlregisterlist.cpp @@ -1,10 +1,362 @@ #include "ctrlregisterlist.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "EmuThread.h" +#include "debugger_disasm.h" CtrlRegisterList::CtrlRegisterList(QWidget *parent) : - QListWidget(parent) + QWidget(parent) { + rowHeight = 14; + selecting=false; + selection=0; + category=0; + showHex=false; + cpu=0; + lastPC = 0; + lastCat0Values = NULL; + changedCat0Regs = NULL; + curVertOffset = 0; + +} + +CtrlRegisterList::~CtrlRegisterList() +{ + if (lastCat0Values != NULL) + delete [] lastCat0Values; + if (changedCat0Regs != NULL) + delete [] changedCat0Regs; } void CtrlRegisterList::redraw() { + update(); +} + +void CtrlRegisterList::scrollChanged(int action) +{ + QScrollBar *bar = findChild("RegListScroll"); + switch(action) + { + case QScrollBar::SliderSingleStepAdd: + curVertOffset++; + break; + case QScrollBar::SliderSingleStepSub: + curVertOffset--; + break; + case QScrollBar::SliderPageStepAdd: + curVertOffset+= 4; + break; + case QScrollBar::SliderPageStepSub: + curVertOffset-= 4; + break; + case QScrollBar::SliderMove: + curVertOffset = bar->sliderPosition(); + break; + default: + break; + } + redraw(); +} + + +void CtrlRegisterList::keyPressEvent(QKeyEvent *e) +{ + if(e->key() == Qt::Key_Down) + { + selection += 1; + e->accept(); + } + else if(e->key() == Qt::Key_Up) + { + selection -= 1; + e->accept(); + } + else if(e->key() == Qt::Key_PageDown) + { + selection += 4; + e->accept(); + } + else if(e->key() == Qt::Key_PageUp) + { + selection -= 4; + e->accept(); + } + int maxRowsDisplay =rect().bottom()/rowHeight - 1; + curVertOffset = std::min(std::max(curVertOffset, selection-maxRowsDisplay),selection); + update(); +} + +void CtrlRegisterList::mousePressEvent(QMouseEvent *e) +{ + int x = e->pos().x(); + int y = e->pos().y(); + if (x>16) + { + oldSelection=selection; + + if (y>rowHeight) + { + selection=yToIndex(y); + bool oldselecting=selecting; + selecting=true; + if (!oldselecting || (selection!=oldSelection)) + redraw(); + } + else + { + int lastCat = category; + category = (x*cpu->GetNumCategories())/(rect().width()); + if (category<0) category=0; + if (category>=cpu->GetNumCategories()) + category=cpu->GetNumCategories()-1; + if (category!=lastCat) + { + curVertOffset = 0; + redraw(); + } + } + } + else + { + redraw(); + } + e->accept(); +} + +void CtrlRegisterList::wheelEvent(QWheelEvent* e) +{ + int numDegrees = e->delta() / 8; + int numSteps = numDegrees / 15; + if (e->orientation() == Qt::Horizontal) { + } else { + curVertOffset -= numSteps; + e->accept(); + update(); + } +} + + +void CtrlRegisterList::paintEvent(QPaintEvent *) +{ + + int numRowsTotal = cpu->GetNumRegsInCategory(category); + int maxRowsDisplay =rect().bottom()/rowHeight - 1; + + selection = std::min(std::max(selection,0),numRowsTotal); + curVertOffset = std::min(std::max(curVertOffset, 0),numRowsTotal - maxRowsDisplay); + + QScrollBar *bar = findChild("RegListScroll"); + if(bar) + { + bar->setMinimum(0); + bar->setMaximum(numRowsTotal - maxRowsDisplay); + bar->setPageStep(1); + bar->setValue(curVertOffset); + } + + + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::white); + painter.drawRect(rect()); + + if (!cpu) + return; + + QFont normalFont = QFont("Arial", 10); + painter.setFont(normalFont); + + int width = rect().width(); + + QColor bgColor = QColor(0xffffff); + QPen nullPen=QPen(bgColor); + QPen currentPen=QPen(QColor(0xFF000000)); + QPen selPen=QPen(0x808080); + QPen textPen; + + QBrush lbr; + lbr.setColor(bgColor); + QBrush nullBrush=QBrush(bgColor); + QBrush currentBrush=QBrush(0xFFEfE8); + QBrush pcBrush=QBrush(0x70FF70); + + int nc = cpu->GetNumCategories(); + for (int i=0; iGetCategoryName(i); + painter.setPen(currentPen); + painter.drawText(width*i/nc+1,-3+rowHeight,name); + } + + int numRows=rect().bottom()/rowHeight; + + for (int i=curVertOffset; iGetPC()) + { + for (int i = 0, n = cpu->GetNumRegsInCategory(0); i < n; ++i) + { + u32 v = cpu->GetRegValue(0, i); + changedCat0Regs[i] = v != lastCat0Values[i]; + lastCat0Values[i] = v; + } + lastPC = cpu->GetPC(); + } + + painter.setBrush(currentBrush); + if (iGetNumRegsInCategory(category)) + { + char temp[256]; + sprintf(temp,"%s",cpu->GetRegName(category,i)); + textPen.setColor(0x600000); + painter.setPen(textPen); + painter.drawText(17,rowY1-3+rowHeight,temp); + textPen.setColor(0xFF000000); + painter.setPen(textPen); + + cpu->PrintRegValue(category,i,temp); + if (category == 0 && changedCat0Regs[i]) + { + textPen.setColor(0x0000FF); + painter.setPen(textPen); + } + else + { + textPen.setColor(0x004000); + painter.setPen(textPen); + } + painter.drawText(77,rowY1-3+rowHeight,temp); + } + } +} + +int CtrlRegisterList::yToIndex(int y) +{ + int n = (y/rowHeight) - 1 + curVertOffset; + if (n<0) n=0; + return n; +} + +void CtrlRegisterList::contextMenu(const QPoint &pos) +{ + QMenu menu(this); + + QAction *gotoMemory = new QAction(tr("Go to in &memory view"), this); + connect(gotoMemory, SIGNAL(triggered()), this, SLOT(GotoMemory())); + menu.addAction(gotoMemory); + + QAction *gotoDisAsm = new QAction(tr("Go to in &disasm"), this); + connect(gotoDisAsm, SIGNAL(triggered()), this, SLOT(GotoDisAsm())); + menu.addAction(gotoDisAsm); + + menu.addSeparator(); + + QAction *copyValue = new QAction(tr("&Copy value"), this); + connect(copyValue, SIGNAL(triggered()), this, SLOT(CopyValue())); + menu.addAction(copyValue); + + QAction *change = new QAction(tr("C&hange..."), this); + connect(change, SIGNAL(triggered()), this, SLOT(Change())); + menu.addAction(change); + + menu.exec( mapToGlobal(pos)); +} + +void CtrlRegisterList::GotoMemory() +{ + int cat = category; + int reg = selection; + if (selection >= cpu->GetNumRegsInCategory(cat)) + return; + + EmuThread_LockDraw(true); + u32 val = cpu->GetRegValue(cat,reg); + EmuThread_LockDraw(false); + + parentWindow->ShowMemory(val); +} + +void CtrlRegisterList::GotoDisAsm() +{ + int cat = category; + int reg = selection; + if (selection >= cpu->GetNumRegsInCategory(cat)) + return; + + EmuThread_LockDraw(true); + u32 val = cpu->GetRegValue(cat,reg); + EmuThread_LockDraw(false); + + emit GotoDisasm(val); +} + +void CtrlRegisterList::CopyValue() +{ + int cat = category; + int reg = selection; + if (selection >= cpu->GetNumRegsInCategory(cat)) + return; + + EmuThread_LockDraw(true); + u32 val = cpu->GetRegValue(cat,reg); + EmuThread_LockDraw(false); + + char temp[24]; + sprintf(temp,"%08x",val); + + QApplication::clipboard()->setText(temp); +} + +void CtrlRegisterList::Change() +{ + int cat = category; + int reg = selection; + if (selection >= cpu->GetNumRegsInCategory(cat)) + return; + + EmuThread_LockDraw(true); + u32 val = cpu->GetRegValue(cat,reg); + EmuThread_LockDraw(false); + + bool ok; + QString text = QInputDialog::getText(this, tr("Set new value"), + tr("Set new value :"), QLineEdit::Normal, + QString::number(val), &ok); + if (ok && !text.isEmpty()) + { + EmuThread_LockDraw(true); + cpu->SetRegValue(cat,reg,text.toInt()); + EmuThread_LockDraw(false); + redraw(); + } } diff --git a/Qt/ctrlregisterlist.h b/Qt/ctrlregisterlist.h index 1a11462ba9..ca3c498d9a 100644 --- a/Qt/ctrlregisterlist.h +++ b/Qt/ctrlregisterlist.h @@ -1,16 +1,21 @@ #ifndef CTRLREGISTERLIST_H #define CTRLREGISTERLIST_H -#include +#include #include "Core/Debugger/DebugInterface.h" -class CtrlRegisterList : public QListWidget +class Debugger_Disasm; +class CtrlRegisterList : public QWidget { Q_OBJECT public: explicit CtrlRegisterList(QWidget *parent = 0); - void redraw(); + + void setParentWindow(Debugger_Disasm* win) + { + parentWindow = win; + } void setCPU(DebugInterface *deb) { @@ -26,10 +31,27 @@ public: { return cpu; } + ~CtrlRegisterList(); + void contextMenu(const QPoint &pos); +protected: + void paintEvent(QPaintEvent *); + void keyPressEvent(QKeyEvent *e); + void mousePressEvent(QMouseEvent *e); + void wheelEvent(QWheelEvent *e); signals: - + void GotoDisasm(u32); + public slots: + void redraw(); + void scrollChanged(int); + + void GotoDisAsm(); + void CopyValue(); + void Change(); + void GotoMemory(); + private: + int yToIndex(int y); int rowHeight; int selection; @@ -43,10 +65,13 @@ private: bool hasFocus; bool showHex; DebugInterface *cpu; + int curVertOffset; u32 lastPC; u32 *lastCat0Values; bool *changedCat0Regs; + + Debugger_Disasm* parentWindow; }; #endif // CTRLREGISTERLIST_H diff --git a/Qt/ctrlvfpuview.cpp b/Qt/ctrlvfpuview.cpp new file mode 100644 index 0000000000..5ce363dd95 --- /dev/null +++ b/Qt/ctrlvfpuview.cpp @@ -0,0 +1,98 @@ +#include "ctrlvfpuview.h" +#include + +#include "Core/MIPS/MIPS.h" // BAD + +CtrlVfpuView::CtrlVfpuView(QWidget *parent) : + QWidget(parent) +{ + mode = 0; +} + +void CtrlVfpuView::setMode(int newMode) +{ + mode = newMode; + redraw(); +} + +void CtrlVfpuView::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::white); + painter.drawRect(rect()); + + if (!cpu) + return; + + QFont normalFont = QFont("Arial", 10); + painter.setFont(normalFont); + + QPen currentPen=QPen(0xFF000000); + QBrush nullBrush=QBrush(0xFFEfE8); + painter.setPen(currentPen); + painter.setBrush(nullBrush); + + enum + { + rowHeight = 15, + columnWidth = 80, + xStart = columnWidth/2, + yStart = 0 + }; + + for (int matrix = 0; matrix<8; matrix++) + { + int my = (int)(yStart + matrix * rowHeight * 5.5f); + painter.drawRect(0, my, xStart-1, rowHeight-1); + char temp[256]; + sprintf(temp, "M%i00", matrix); + painter.drawText(3, my+rowHeight-3, temp); + painter.drawRect(xStart, my+rowHeight, columnWidth*4-1, 4*rowHeight-1); + + for (int column = 0; column<4; column++) + { + int y = my; + int x = column * columnWidth + xStart; + + painter.drawRect(x, y, columnWidth-1, rowHeight - 1); + char temp[256]; + sprintf(temp, "R%i0%i", matrix, column); + painter.drawText(x+3, y-3+rowHeight, temp); + + painter.drawRect(0, y+rowHeight*(column+1), xStart - 1, rowHeight - 1); + sprintf(temp, "C%i%i0", matrix, column); + painter.drawText(3, y+rowHeight*(column+2)-3, temp); + + y+=rowHeight; + + for (int row = 0; row<4; row++) + { + float val = mipsr4k.v[column*32+row+matrix*4]; + u32 hex = *((u32*)&val); + char temp[256]; + switch (mode) + { + case 0: sprintf(temp,"%f",val); break; +// case 1: sprintf(temp,"??"); break; + case 2: sprintf(temp,"0x%08x",hex); break; + default:sprintf(temp,"%f",val); break; + } + + painter.drawText(x+3, y-3 + rowHeight, temp); + y+=rowHeight; + } + } + } + + setMinimumHeight((int)(yStart + 8 * rowHeight * 5.5f)); + setMinimumWidth(4*columnWidth+xStart); + +} + + +void CtrlVfpuView::redraw() +{ + update(); +} + diff --git a/Qt/ctrlvfpuview.h b/Qt/ctrlvfpuview.h new file mode 100644 index 0000000000..78d4690cf4 --- /dev/null +++ b/Qt/ctrlvfpuview.h @@ -0,0 +1,42 @@ +#ifndef CTRLVFPUVIEW_H +#define CTRLVFPUVIEW_H + +#include +#include "Core/Debugger/DebugInterface.h" + +class Debugger_Vfpu; +class CtrlVfpuView : public QWidget +{ + Q_OBJECT +public: + explicit CtrlVfpuView(QWidget *parent = 0); + + void setParentWindow(Debugger_Vfpu* win) + { + parentWindow = win; + } + + void setCPU(DebugInterface *deb) + { + cpu = deb; + } + DebugInterface *getCPU() + { + return cpu; + } + void setMode(int newMode); + void redraw(); +protected: + + void paintEvent(QPaintEvent *); +signals: + +public slots: +private: + + DebugInterface *cpu; + Debugger_Vfpu* parentWindow; + int mode; +}; + +#endif // CTRLVFPUVIEW_H diff --git a/Qt/debugger_disasm.cpp b/Qt/debugger_disasm.cpp index 9b4d27ccda..bd1a007f07 100644 --- a/Qt/debugger_disasm.cpp +++ b/Qt/debugger_disasm.cpp @@ -1,15 +1,26 @@ #include +#include + +#include + #include "debugger_disasm.h" #include "ui_debugger_disasm.h" #include "Core/CPU.h" #include "Core/Debugger/DebugInterface.h" +#include "Core/Debugger/SymbolMap.h" #include "ctrldisasmview.h" #include "Core/Debugger/Breakpoints.h" #include "Core/HLE/HLE.h" +#include "Core/CoreTiming.h" #include "mainwindow.h" #include "ctrlregisterlist.h" #include "native/base/stringutil.h" #include "Core/Debugger/SymbolMap.h" +#include "GPU/GPUState.h" +#include "GPU/GPUInterface.h" +#include "GPU/GeDisasm.h" +#include "EmuThread.h" +#include "Core/Host.h" Debugger_Disasm::Debugger_Disasm(DebugInterface *_cpu, MainWindow* mainWindow_, QWidget *parent) : QDialog(parent), @@ -19,19 +30,50 @@ Debugger_Disasm::Debugger_Disasm(DebugInterface *_cpu, MainWindow* mainWindow_, { ui->setupUi(this); + vfpudlg = new Debugger_VFPU(_cpu, mainWindow, this); + ui->DisasmView->setWindowTitle(_cpu->GetName()); + QObject::connect(ui->RegListScroll,SIGNAL(actionTriggered(int)), ui->RegList, SLOT(scrollChanged(int))); + QObject::connect(ui->RegList,SIGNAL(GotoDisasm(u32)),this,SLOT(Goto(u32))); + QObject::connect(this, SIGNAL(updateDisplayList_()), this, SLOT(UpdateDisplayListGUI())); + QObject::connect(this, SIGNAL(UpdateBreakpoints_()), this, SLOT(UpdateBreakpointsGUI())); + QObject::connect(this, SIGNAL(UpdateThread_()), this, SLOT(UpdateThreadGUI())); + CtrlDisAsmView *ptr = ui->DisasmView; ptr->setDebugger(cpu); + ptr->setParentWindow(this); ptr->gotoAddr(0x00000000); CtrlRegisterList *rl = ui->RegList; + rl->setParentWindow(this); rl->setCPU(cpu); - //symbolMap.FillSymbolComboBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION) + FillFunctions(); } +void Debugger_Disasm::showEvent(QShowEvent *) +{ + +#ifdef Q_WS_X11 + // Hack to remove the X11 crash with threaded opengl when opening the first dialog + EmuThread_LockDraw(true); + QTimer::singleShot(100, this, SLOT(releaseLock())); +#endif + + if(Core_IsStepping()) + SetDebugMode(true); + else + SetDebugMode(false); +} + +void Debugger_Disasm::releaseLock() +{ + EmuThread_LockDraw(false); +} + + Debugger_Disasm::~Debugger_Disasm() { delete ui; @@ -39,73 +81,68 @@ Debugger_Disasm::~Debugger_Disasm() void Debugger_Disasm::ShowVFPU() { - //vfpudlg->Show(true); + vfpudlg->show(); } -void Debugger_Disasm::FunctionList() +void Debugger_Disasm::Update() { - -} - -void Debugger_Disasm::GotoInt() -{ - + ui->RegList->redraw(); + mainWindow->UpdateMenus(); + UpdateDialog(); } void Debugger_Disasm::Go() { SetDebugMode(false); + EmuThread_LockDraw(true); Core_EnableStepping(false); + EmuThread_LockDraw(false); mainWindow->UpdateMenus(); } void Debugger_Disasm::Step() { - CtrlDisAsmView *ptr = ui->DisasmView; - CtrlRegisterList *reglist = ui->RegList; - + EmuThread_LockDraw(true); Core_DoSingleStep(); - //Sleep(1); - sleep(1); + EmuThread_LockDraw(false); _dbg_update_(); - ptr->gotoPC(); - reglist->redraw(); - //vfpudlg->Update(); } void Debugger_Disasm::StepOver() { - CtrlDisAsmView *ptr = ui->DisasmView; - CtrlRegisterList *reglist = ui->RegList; - SetDebugMode(false); + EmuThread_LockDraw(true); CBreakPoints::AddBreakPoint(cpu->GetPC()+cpu->getInstructionSize(0),true); _dbg_update_(); Core_EnableStepping(false); + EmuThread_LockDraw(false); mainWindow->UpdateMenus(); - //Sleep(1); - sleep(1); - ptr->gotoPC(); - reglist->redraw(); } void Debugger_Disasm::StepHLE() { + EmuThread_LockDraw(true); hleDebugBreak(); SetDebugMode(false); _dbg_update_(); Core_EnableStepping(false); + EmuThread_LockDraw(false); mainWindow->UpdateMenus(); } void Debugger_Disasm::UpdateDialog() { - CtrlDisAsmView *ptr = ui->DisasmView; - CtrlRegisterList *reglist = ui->RegList; + ui->DisasmView->setAlign(cpu->getInstructionSize(0)); + ui->DisasmView->redraw(); + ui->RegList->redraw(); + vfpudlg->Update(); + UpdateBreakpoints(); + UpdateThread(); + UpdateDisplayList(); - ptr->setAlign(cpu->getInstructionSize(0)); - ptr->redraw(); - reglist->redraw(); + char tempTicks[24]; + sprintf(tempTicks, "%lld", CoreTiming::GetTicks()); + ui->debugCount->setText(QString("Ctr : ") + tempTicks); /*ui->callStack->clear(); u32 pc = currentMIPS->pc; @@ -116,12 +153,12 @@ void Debugger_Disasm::UpdateDialog() sprintf(addr_, "0x%08x",pc); ui->callStack->addItem(new QListWidgetItem(addr_)); - u32 addr2 = Memory::ReadUnchecked_U32(ra); + addr = Memory::ReadUnchecked_U32(ra); sprintf(addr_, "0x%08x",ra); ui->callStack->addItem(new QListWidgetItem(addr_)); count++; - while (addr != 0xFFFFFFFF && addr!=0 && count++<20) + while (addr != 0xFFFFFFFF && addr!=0 && Memory::IsValidAddress(addr+4) && count++<20) { u32 fun = Memory::ReadUnchecked_U32(addr+4); sprintf(addr_, "0x%08x",fun); @@ -129,37 +166,30 @@ void Debugger_Disasm::UpdateDialog() addr = Memory::ReadUnchecked_U32(addr); }*/ - /* - for (int i=0; iUpdate(); - */ + + if(mainWindow->GetDialogMemory()) + mainWindow->GetDialogMemory()->Update(); + } void Debugger_Disasm::Stop() { - CtrlDisAsmView *ptr = ui->DisasmView; - CtrlRegisterList *reglist = ui->RegList; - SetDebugMode(true); + EmuThread_LockDraw(true); Core_EnableStepping(true); + EmuThread_LockDraw(false); _dbg_update_(); mainWindow->UpdateMenus(); UpdateDialog(); - //Sleep(1); //let cpu catch up - sleep(1); - ptr->gotoPC(); - reglist->redraw(); - //vfpudlg->Update(); } void Debugger_Disasm::Skip() { CtrlDisAsmView *ptr = ui->DisasmView; + EmuThread_LockDraw(true); cpu->SetPC(cpu->GetPC() + cpu->getInstructionSize(0)); - //Sleep(1); - sleep(1); + EmuThread_LockDraw(false); ptr->gotoPC(); UpdateDialog(); } @@ -185,12 +215,13 @@ void Debugger_Disasm::SetDebugMode(bool _bDebug) { ui->Go->setEnabled(true); ui->StepInto->setEnabled(true); - ui->StepOver->setEnabled(true); + ui->StepOver->setEnabled(false); // Crash, so disable for now ui->NextHLE->setEnabled(true); ui->Stop->setEnabled(false); ui->Skip->setEnabled(true); CtrlDisAsmView *ptr = ui->DisasmView; ptr->gotoPC(); + UpdateDialog(); } else { @@ -200,9 +231,9 @@ void Debugger_Disasm::SetDebugMode(bool _bDebug) ui->NextHLE->setEnabled(false); ui->Stop->setEnabled(true); ui->Skip->setEnabled(false); + CtrlRegisterList *reglist = ui->RegList; + reglist->redraw(); } - CtrlRegisterList *reglist = ui->RegList; - reglist->redraw(); } void Debugger_Disasm::Goto(u32 addr) @@ -272,14 +303,414 @@ void Debugger_Disasm::on_DisasmView_customContextMenuRequested(const QPoint &pos ui->DisasmView->contextMenu(pos); } -void Debugger_Disasm::on_DisasmView_cellClicked(int row, int column) -{ - ui->DisasmView->click(row, column); -} - void Debugger_Disasm::NotifyMapLoaded() { - //symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); + FillFunctions(); CtrlDisAsmView *ptr = ui->DisasmView; ptr->redraw(); } + +void Debugger_Disasm::on_RegList_customContextMenuRequested(const QPoint &pos) +{ + ui->RegList->contextMenu(pos); +} + +void Debugger_Disasm::ShowMemory(u32 addr) +{ + mainWindow->ShowMemory(addr); +} + +void Debugger_Disasm::on_vfpu_clicked() +{ + ShowVFPU(); +} + +void Debugger_Disasm::on_FuncList_itemClicked(QListWidgetItem *item) +{ + u32 addr = item->data(Qt::UserRole).toInt(); + + ui->DisasmView->gotoAddr(addr); +} + +void Debugger_Disasm::FillFunctions() +{ + QListWidgetItem* item = new QListWidgetItem(); + item->setText("(0x02000000)"); + item->setData(Qt::UserRole, 0x02000000); + ui->FuncList->addItem(item); + + for(int i = 0; i < symbolMap.GetNumSymbols(); i++) + { + if(symbolMap.GetSymbolType(i) & ST_FUNCTION) + { + QListWidgetItem* item = new QListWidgetItem(); + item->setText(QString(symbolMap.GetSymbolName(i)) + " ("+ QVariant(symbolMap.GetSymbolSize(i)).toString() +")"); + item->setData(Qt::UserRole, symbolMap.GetAddress(i)); + ui->FuncList->addItem(item); + } + } +} + +void Debugger_Disasm::UpdateBreakpoints() +{ + emit UpdateBreakpoints_(); +} + +void Debugger_Disasm::UpdateBreakpointsGUI() +{ + u32 curBpAddr = 0; + QTreeWidgetItem* curItem = ui->breakpointsList->currentItem(); + if(curItem) + curBpAddr = ui->breakpointsList->currentItem()->data(0,Qt::UserRole).toInt(); + + ui->breakpointsList->clear(); + + EmuThread_LockDraw(true); + for(int i = 0; i < CBreakPoints::GetNumBreakpoints(); i++) + { + u32 addr_ = CBreakPoints::GetBreakpointAddress(i); + if(!CBreakPoints::IsTempBreakPoint(addr_)) + { + QTreeWidgetItem* item = new QTreeWidgetItem(); + char temp[24]; + sprintf(temp,"%08x",addr_); + item->setText(0,temp); + item->setData(0,Qt::UserRole,addr_); + ui->breakpointsList->addTopLevelItem(item); + if(curBpAddr == addr_) + ui->breakpointsList->setCurrentItem(item); + } + } + EmuThread_LockDraw(false); +} + +void Debugger_Disasm::on_breakpointsList_itemClicked(QTreeWidgetItem *item, int column) +{ + ui->DisasmView->gotoAddr(item->data(column,Qt::UserRole).toInt()); +} + +void Debugger_Disasm::on_breakpointsList_customContextMenuRequested(const QPoint &pos) +{ + QTreeWidgetItem* item = ui->breakpointsList->itemAt(pos); + if(item) + { + breakpointAddr = item->data(0,Qt::UserRole).toInt(); + + QMenu menu(this); + + QAction *removeBP = new QAction(tr("Remove breakpoint"), this); + connect(removeBP, SIGNAL(triggered()), this, SLOT(RemoveBreakpoint())); + menu.addAction(removeBP); + + menu.exec( ui->breakpointsList->mapToGlobal(pos)); + } +} + +void Debugger_Disasm::RemoveBreakpoint() +{ + CBreakPoints::RemoveBreakPoint(breakpointAddr); + Update(); +} + +void Debugger_Disasm::on_clearAllBP_clicked() +{ + CBreakPoints::ClearAllBreakPoints(); + Update(); +} + +void Debugger_Disasm::UpdateThread() +{ + emit UpdateThread_(); +} + +void Debugger_Disasm::UpdateThreadGUI() +{ + ui->threadList->clear(); + + EmuThread_LockDraw(true); + std::vector threads = GetThreadsInfo(); + EmuThread_LockDraw(false); + + for(int i = 0; i < threads.size(); i++) + { + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0,QVariant(threads[i].id).toString()); + item->setData(0,Qt::UserRole,threads[i].id); + item->setText(1,threads[i].name); + QString status = ""; + if(threads[i].status & THREADSTATUS_RUNNING) status += "Running "; + if(threads[i].status & THREADSTATUS_WAIT) status += "Wait "; + if(threads[i].status & THREADSTATUS_READY) status += "Ready "; + if(threads[i].status & THREADSTATUS_SUSPEND) status += "Suspend "; + if(threads[i].status & THREADSTATUS_DORMANT) status += "Dormant "; + if(threads[i].status & THREADSTATUS_DEAD) status += "Dead "; + item->setText(2,status); + char temp[24]; + sprintf(temp,"%08x",threads[i].curPC); + item->setText(3,temp); + item->setData(3,Qt::UserRole,threads[i].curPC); + sprintf(temp,"%08x",threads[i].entrypoint); + item->setText(4,temp); + item->setData(4,Qt::UserRole,threads[i].entrypoint); + + if(threads[i].isCurrent) + { + for(int j = 0; j < 5; j++) + item->setTextColor(j,Qt::green); + } + + ui->threadList->addTopLevelItem(item); + } +} + +void Debugger_Disasm::on_threadList_itemClicked(QTreeWidgetItem *item, int column) +{ + ui->DisasmView->gotoAddr(item->data(3,Qt::UserRole).toInt()); +} + +void Debugger_Disasm::on_threadList_customContextMenuRequested(const QPoint &pos) +{ + QTreeWidgetItem* item = ui->threadList->itemAt(pos); + if(item) + { + threadRowSelected = item; + + QMenu menu(this); + + QAction *gotoEntryPoint = new QAction(tr("Go to entry point"), this); + connect(gotoEntryPoint, SIGNAL(triggered()), this, SLOT(GotoThreadEntryPoint())); + menu.addAction(gotoEntryPoint); + + QMenu* changeStatus = menu.addMenu("Change status"); + + QAction *statusRunning = new QAction(tr("Running"), this); + connect(statusRunning, SIGNAL(triggered()), this, SLOT(SetThreadStatusRun())); + changeStatus->addAction(statusRunning); + + QAction *statusWait = new QAction(tr("Wait"), this); + connect(statusWait, SIGNAL(triggered()), this, SLOT(SetThreadStatusWait())); + changeStatus->addAction(statusWait); + + QAction *statusSuspend = new QAction(tr("Suspend"), this); + connect(statusSuspend, SIGNAL(triggered()), this, SLOT(SetThreadStatusSuspend())); + changeStatus->addAction(statusSuspend); + + menu.exec( ui->threadList->mapToGlobal(pos)); + } +} + +void Debugger_Disasm::GotoThreadEntryPoint() +{ + ui->DisasmView->gotoAddr(threadRowSelected->data(4,Qt::UserRole).toInt()); + Update(); +} + +void Debugger_Disasm::SetThreadStatus(ThreadStatus status) +{ + EmuThread_LockDraw(true); + __KernelChangeThreadState(threadRowSelected->data(0,Qt::UserRole).toInt(), status); + EmuThread_LockDraw(false); + + UpdateThread(); +} + +void Debugger_Disasm::SetThreadStatusRun() +{ + SetThreadStatus(THREADSTATUS_RUNNING); +} + +void Debugger_Disasm::SetThreadStatusWait() +{ + SetThreadStatus(THREADSTATUS_WAIT); +} + +void Debugger_Disasm::SetThreadStatusSuspend() +{ + SetThreadStatus(THREADSTATUS_SUSPEND); +} + +void Debugger_Disasm::UpdateDisplayList() +{ + emit updateDisplayList_(); +} + +void Debugger_Disasm::UpdateDisplayListGUI() +{ + u32 curDlId = 0; + QTreeWidgetItem* curItem = ui->displayList->currentItem(); + if(curItem) + curDlId = ui->displayList->currentItem()->data(0,Qt::UserRole).toInt(); + + ui->displayList->clear(); + ui->displayListData->clear(); + + EmuThread_LockDraw(true); + const std::deque& dlQueue = gpu->GetDisplayLists(); + + DisplayList* dl = gpu->GetCurrentDisplayList(); + if(dl) + { + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0,QVariant(dl->id).toString()); + item->setData(0, Qt::UserRole, dl->id); + switch(dl->status) + { + case PSP_GE_LIST_DONE: item->setText(1,"Done"); break; + case PSP_GE_LIST_QUEUED: item->setText(1,"Queued"); break; + case PSP_GE_LIST_DRAWING: item->setText(1,"Drawing"); break; + case PSP_GE_LIST_STALL_REACHED: item->setText(1,"Stall Reached"); break; + case PSP_GE_LIST_END_REACHED: item->setText(1,"End Reached"); break; + case PSP_GE_LIST_CANCEL_DONE: item->setText(1,"Cancel Done"); break; + default: break; + } + char temp[24]; + sprintf(temp,"%08x",dl->startpc); + item->setText(2,temp); + item->setData(2, Qt::UserRole, dl->startpc); + sprintf(temp,"%08x",dl->pc); + item->setText(3,temp); + item->setData(3, Qt::UserRole, dl->pc); + ui->displayList->addTopLevelItem(item); + if(curDlId == dl->id) + { + ui->displayList->setCurrentItem(item); + displayListRowSelected = item; + ShowDLCode(); + } + } + + for(auto it = dlQueue.begin(); it != dlQueue.end(); ++it) + { + if(dl && it->id == dl->id) + continue; + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0,QVariant(it->id).toString()); + item->setData(0, Qt::UserRole, it->id); + switch(it->status) + { + case PSP_GE_LIST_DONE: item->setText(1,"Done"); break; + case PSP_GE_LIST_QUEUED: item->setText(1,"Queued"); break; + case PSP_GE_LIST_DRAWING: item->setText(1,"Drawing"); break; + case PSP_GE_LIST_STALL_REACHED: item->setText(1,"Stall Reached"); break; + case PSP_GE_LIST_END_REACHED: item->setText(1,"End Reached"); break; + case PSP_GE_LIST_CANCEL_DONE: item->setText(1,"Cancel Done"); break; + default: break; + } + char temp[24]; + sprintf(temp,"%08x",it->startpc); + item->setText(2,temp); + item->setData(2, Qt::UserRole, it->startpc); + sprintf(temp,"%08x",it->pc); + item->setText(3,temp); + item->setData(3, Qt::UserRole, it->pc); + ui->displayList->addTopLevelItem(item); + if(curDlId == it->id) + { + ui->displayList->setCurrentItem(item); + displayListRowSelected = item; + ShowDLCode(); + } + } + EmuThread_LockDraw(false); +} + +void Debugger_Disasm::on_displayList_customContextMenuRequested(const QPoint &pos) +{ + QTreeWidgetItem* item = ui->displayList->itemAt(pos); + if(item) + { + displayListRowSelected = item; + + QMenu menu(this); + + QAction *showCode = new QAction(tr("Show code"), this); + connect(showCode, SIGNAL(triggered()), this, SLOT(ShowDLCode())); + menu.addAction(showCode); + + menu.exec( ui->displayList->mapToGlobal(pos)); + } +} + +void Debugger_Disasm::ShowDLCode() +{ + ui->displayListData->clear(); + ui->displayListData->setColumnWidth(0,70); + + u32 startPc = displayListRowSelected->data(2,Qt::UserRole).toInt(); + u32 curPc = displayListRowSelected->data(3,Qt::UserRole).toInt(); + + std::map data; + FillDisplayListCmd(data, startPc,0); + + for(std::map::iterator it = data.begin(); it != data.end(); it++) + { + QTreeWidgetItem* item = new QTreeWidgetItem(); + char temp[24]; + sprintf(temp,"%08x",it->first); + item->setText(0,temp); + item->setText(1,it->second.c_str()); + if(curPc == it->first) + { + for(int j = 0; j < 2; j++) + item->setTextColor(j, Qt::green); + } + ui->displayListData->addTopLevelItem(item); + } +} + +void Debugger_Disasm::FillDisplayListCmd(std::map& data, u32 pc, u32 prev) +{ + u32 curPc = pc; + int debugLimit = 10000; // Anti crash if this code is bugged + while(Memory::IsValidAddress(curPc) && debugLimit > 0) + { + if(data.find(curPc) != data.end()) + return; + + u32 op = Memory::ReadUnchecked_U32(curPc); //read from memory + u32 cmd = op >> 24; + u32 diff = op ^ gstate.cmdmem[cmd]; + char temp[256]; + GeDisassembleOp(curPc, op, prev, temp); + data[curPc] = temp; + prev = op; + if(cmd == GE_CMD_JUMP) + { + u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0x0FFFFFFF; + FillDisplayListCmd(data, target, prev); + return; + } + else if(cmd == GE_CMD_CALL) + { + u32 target = gstate_c.getRelativeAddress(op & 0xFFFFFF); + FillDisplayListCmd(data, target, prev); + } + else if(cmd == GE_CMD_RET) + { + return; + } + else if(cmd == GE_CMD_FINISH) + { + return; + } + else if(cmd == GE_CMD_END) + { + if(prev >> 24 == GE_CMD_FINISH) + return; + } + curPc += 4; + debugLimit--; + } +} + +void Debugger_Disasm::on_nextGPU_clicked() +{ + host->SetGPUStep(true); + host->NextGPUStep(); +} + +void Debugger_Disasm::on_runBtn_clicked() +{ + host->SetGPUStep(false); + host->NextGPUStep(); +} diff --git a/Qt/debugger_disasm.h b/Qt/debugger_disasm.h index f27173a1ce..fb47a1935f 100644 --- a/Qt/debugger_disasm.h +++ b/Qt/debugger_disasm.h @@ -1,8 +1,12 @@ #ifndef DEBUGGER_DISASM_H #define DEBUGGER_DISASM_H +#include "Core/HLE/sceKernelThread.h" #include "Core/Debugger/DebugInterface.h" +#include "debugger_vfpu.h" #include +#include +#include class MainWindow; namespace Ui { @@ -17,11 +21,8 @@ public: explicit Debugger_Disasm(DebugInterface *_cpu, MainWindow* mainWindow_, QWidget *parent = 0); ~Debugger_Disasm(); void SetDebugMode(bool _bDebug); - void Goto(u32 addr); void ShowVFPU(); - void FunctionList(); - void GotoInt(); void Go(); void Step(); void StepOver(); @@ -32,7 +33,32 @@ public: void GotoLR(); void UpdateDialog(); void NotifyMapLoaded(); + void Update(); + void ShowMemory(u32 addr); + void FillFunctions(); + void UpdateBreakpoints(); + void UpdateThread(); + void UpdateDisplayList(); +protected: + void showEvent(QShowEvent *); + void FillDisplayListCmd(std::map& data, u32 pc, u32 prev); + +signals: + void updateDisplayList_(); + void UpdateBreakpoints_(); + void UpdateThread_(); + +public slots: + void Goto(u32 addr); + void RemoveBreakpoint(); + void GotoThreadEntryPoint(); + void ShowDLCode(); + private slots: + void UpdateDisplayListGUI(); + void UpdateBreakpointsGUI(); + void UpdateThreadGUI(); + void on_GotoPc_clicked(); void on_Go_clicked(); @@ -55,12 +81,42 @@ private slots: void on_DisasmView_customContextMenuRequested(const QPoint &pos); - void on_DisasmView_cellClicked(int row, int column); + void releaseLock(); + void on_RegList_customContextMenuRequested(const QPoint &pos); + + void on_vfpu_clicked(); + + void on_FuncList_itemClicked(QListWidgetItem *item); + + void on_breakpointsList_itemClicked(QTreeWidgetItem *item, int column); + + void on_breakpointsList_customContextMenuRequested(const QPoint &pos); + + void on_clearAllBP_clicked(); + + void on_threadList_itemClicked(QTreeWidgetItem *item, int column); + + void on_threadList_customContextMenuRequested(const QPoint &pos); + + void SetThreadStatusRun(); + void SetThreadStatusWait(); + void SetThreadStatusSuspend(); + void on_displayList_customContextMenuRequested(const QPoint &pos); + + void on_nextGPU_clicked(); + + void on_runBtn_clicked(); private: + void SetThreadStatus(ThreadStatus status); + Ui::Debugger_Disasm *ui; DebugInterface* cpu; MainWindow* mainWindow; + Debugger_VFPU* vfpudlg; + u32 breakpointAddr; + QTreeWidgetItem* threadRowSelected; + QTreeWidgetItem* displayListRowSelected; }; #endif // DEBUGGER_DISASM_H diff --git a/Qt/debugger_disasm.ui b/Qt/debugger_disasm.ui index 2471443cde..a120320aa6 100644 --- a/Qt/debugger_disasm.ui +++ b/Qt/debugger_disasm.ui @@ -7,7 +7,7 @@ 0 0 837 - 423 + 492 @@ -16,272 +16,553 @@ Dialog - + - - - - - Ctr: - - - - - - - - 0 - 0 - - - - &Go to - - - - 0 - - - 4 - - - 4 - - - 0 - - - 0 - - - - - - - - QLayout::SetDefaultConstraint + + + Qt::Horizontal + + + + + + + Ctr: + + + + + + + + 0 + 0 + + + + &Go to + + + + 0 + + + 4 + + + 4 + + + 0 + + + 0 - - - - 0 - 0 - - - - &PC - - + - - - - 0 - 0 - + + + QLayout::SetDefaultConstraint - - &LR - - - - - - - - 0 - 0 - - - + + + + + 0 + 0 + + + + &PC + + + + + + + + 0 + 0 + + + + &LR + + + + + + + + 0 + 0 + + + + + - - - - - - - - 0 - - - - - 0 - 0 - - - - Tab 1 - - + + + + - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Show VFPU + + - - - - Tab 2 - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - &Go - - - - - - 0 - 0 - - - - Stop - - - - - - - - 0 - 0 - - - - Step &Into - - - - - - - - 0 - 0 - - - - Step &Over - - - - - - - - 0 - 0 - - - - S&kip - - - - - - - - 0 - 0 - - - - Next &HLE + + + 0 + + + + 0 + 0 + + + + Regs + + + + + + + 0 + 0 + + + + Qt::ClickFocus + + + Qt::CustomContextMenu + + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 229 + 20 + + + + + + + + Qt::Vertical + + + + + + + + + + + Funcs + + + + + + + - - - - - Qt::CustomContextMenu - - - Qt::ScrollBarAlwaysOff - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - Qt::NoPen - - - 5 - - - 5 - - - false - - - false - - - - - - - - - - - - - - - - - + + + + + + + + + + 0 + 0 + + + + &Go + + + + + + + + 0 + 0 + + + + Stop + + + + + + + + 0 + 0 + + + + Step &Into + + + + + + + false + + + + 0 + 0 + + + + Step &Over + + + + + + + + 0 + 0 + + + + S&kip + + + + + + + + 0 + 0 + + + + Next &HLE + + + + + + + + + + 0 + 0 + + + + Qt::ClickFocus + + + Qt::CustomContextMenu + + + + + + + 2 + + + + Breakpoints + + + + + + Qt::CustomContextMenu + + + false + + + false + + + 30 + + + + Address + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Clear All + + + + + + + + + + Callstack + + + + + + + + + + Display Lists + + + + + + Qt::Horizontal + + + + Qt::CustomContextMenu + + + false + + + false + + + false + + + 30 + + + + Id + + + + + Status + + + + + Start Address + + + + + Current Address + + + + + + + + + false + + + false + + + false + + + 2 + + + false + + + + 1 + + + + + 2 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Run + + + + + + + Step + + + + + + + + + + + + + + Threads + + + + + + Qt::CustomContextMenu + + + false + + + false + + + false + + + 50 + + + + Id + + + + + Name + + + + + Status + + + + + Current PC + + + + + Entry point + + + + + + + + + + + - CtrlRegisterList - QListWidget -
ctrlregisterlist.h
+ CtrlDisAsmView + QWidget +
ctrldisasmview.h
+ 1
- CtrlDisAsmView - QTableWidget -
ctrldisasmview.h
+ CtrlRegisterList + QWidget +
ctrlregisterlist.h
+ 1
diff --git a/Qt/debugger_memory.cpp b/Qt/debugger_memory.cpp new file mode 100644 index 0000000000..6689222006 --- /dev/null +++ b/Qt/debugger_memory.cpp @@ -0,0 +1,110 @@ +#include "debugger_memory.h" +#include "ui_debugger_memory.h" +#include "EmuThread.h" +#include "Core/Debugger/SymbolMap.h" +#include + +Debugger_Memory::Debugger_Memory(DebugInterface *_cpu, MainWindow* mainWindow_, QWidget *parent) : + QDialog(parent), + ui(new Ui::Debugger_Memory), + cpu(_cpu), + mainWindow(mainWindow_) +{ + ui->setupUi(this); + + setWindowTitle(QString("Memory Viewer - ")+cpu->GetName()); + + ui->memView->setDebugger(_cpu); +} + +Debugger_Memory::~Debugger_Memory() +{ + delete ui; +} + + +void Debugger_Memory::showEvent(QShowEvent *) +{ + +#ifdef Q_WS_X11 + // Hack to remove the X11 crash with threaded opengl when opening the first dialog + EmuThread_LockDraw(true); + QTimer::singleShot(100, this, SLOT(releaseLock())); +#endif +} + +void Debugger_Memory::releaseLock() +{ + EmuThread_LockDraw(false); +} + +void Debugger_Memory::Update() +{ + ui->memView->redraw(); +} + +void Debugger_Memory::Goto(u32 addr) +{ + show(); + ui->memView->gotoAddr(addr & ~3); +} + +void Debugger_Memory::on_editAddress_textChanged(const QString &arg1) +{ + u32 addr; + sscanf(arg1.toStdString().c_str(),"%08x",&addr); + ui->memView->gotoAddr(addr & ~3); +} + +void Debugger_Memory::on_normalBtn_clicked() +{ + ui->memView->setMode(MV_NORMAL); +} + +void Debugger_Memory::on_symbolsBtn_clicked() +{ + ui->memView->setMode(MV_SYMBOLS); +} + +void Debugger_Memory::on_memView_customContextMenuRequested(const QPoint &pos) +{ + ui->memView->contextMenu(pos); +} + +void Debugger_Memory::NotifyMapLoaded() +{ + QListWidgetItem* item = new QListWidgetItem(); + item->setText("(0x80000000)"); + item->setData(Qt::UserRole, 0x80000000); + ui->symbols->addItem(item); + + for(int i = 0; i < symbolMap.GetNumSymbols(); i++) + { + if(symbolMap.GetSymbolType(i) & ST_DATA) + { + QListWidgetItem* item = new QListWidgetItem(); + item->setText(QString(symbolMap.GetSymbolName(i)) + " ("+ QVariant(symbolMap.GetSymbolSize(i)).toString() +")"); + item->setData(Qt::UserRole, symbolMap.GetAddress(i)); + ui->symbols->addItem(item); + } + } + + ui->regions->clear(); + /* + for (int i = 0; i < cpu->getMemMap()->numRegions; i++) + { + int n = ComboBox_AddString(lb,cpu->getMemMap()->regions[i].name); + ComboBox_SetItemData(lb,n,cpu->getMemMap()->regions[i].start); + } + */ +} + +void Debugger_Memory::on_regions_currentIndexChanged(int index) +{ + ui->memView->gotoAddr(ui->regions->itemData(index,Qt::UserRole).toInt()); +} + +void Debugger_Memory::on_symbols_itemClicked(QListWidgetItem *item) +{ + ui->memView->gotoAddr(item->data(Qt::UserRole).toInt()); +} diff --git a/Qt/debugger_memory.h b/Qt/debugger_memory.h new file mode 100644 index 0000000000..852b24fc37 --- /dev/null +++ b/Qt/debugger_memory.h @@ -0,0 +1,49 @@ +#ifndef DEBUGGER_MEMORY_H +#define DEBUGGER_MEMORY_H + +#include "Core/Debugger/DebugInterface.h" +#include +#include + +class MainWindow; +namespace Ui { +class Debugger_Memory; +} + +class Debugger_Memory : public QDialog +{ + Q_OBJECT + +public: + explicit Debugger_Memory(DebugInterface *_cpu, MainWindow* mainWindow_, QWidget *parent = 0); + ~Debugger_Memory(); + + void Update(); + void Goto(u32 addr); + + void NotifyMapLoaded(); +public slots: + void releaseLock(); +protected: + void showEvent(QShowEvent *); +private slots: + void on_editAddress_textChanged(const QString &arg1); + + void on_normalBtn_clicked(); + + void on_symbolsBtn_clicked(); + + void on_memView_customContextMenuRequested(const QPoint &pos); + + void on_regions_currentIndexChanged(int index); + + void on_symbols_itemClicked(QListWidgetItem *item); + +private: + Ui::Debugger_Memory *ui; + DebugInterface* cpu; + MainWindow* mainWindow; + +}; + +#endif // DEBUGGER_MEMORY_H diff --git a/Qt/debugger_memory.ui b/Qt/debugger_memory.ui new file mode 100644 index 0000000000..abb94dcf32 --- /dev/null +++ b/Qt/debugger_memory.ui @@ -0,0 +1,92 @@ + + + Debugger_Memory + + + + 0 + 0 + 611 + 384 + + + + Dialog + + + + + + + + Goto: + + + + + + + + + + + + + Mode + + + + + + Normal + + + + + + + Symbols + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + Qt::CustomContextMenu + + + + + + + + + + CtrlMemView + QWidget +
ctrlmemview.h
+ 1 +
+
+ + +
diff --git a/Qt/debugger_vfpu.cpp b/Qt/debugger_vfpu.cpp new file mode 100644 index 0000000000..5c30f3e12f --- /dev/null +++ b/Qt/debugger_vfpu.cpp @@ -0,0 +1,55 @@ +#include "debugger_vfpu.h" +#include "ui_debugger_vfpu.h" +#include "EmuThread.h" +#include "mainwindow.h" +#include + +Debugger_VFPU::Debugger_VFPU(DebugInterface *_cpu, MainWindow* mainWindow_, QWidget *parent) : + QDialog(parent), + ui(new Ui::Debugger_VFPU), + cpu(_cpu), + mainWindow(mainWindow_) +{ + ui->setupUi(this); + + setWindowTitle(QString("VFPU - ")+cpu->GetName()); + + ui->vfpu->setCPU(_cpu); +} + +Debugger_VFPU::~Debugger_VFPU() +{ + delete ui; +} + + +void Debugger_VFPU::showEvent(QShowEvent *) +{ + +#ifdef Q_WS_X11 + // Hack to remove the X11 crash with threaded opengl when opening the first dialog + EmuThread_LockDraw(true); + QTimer::singleShot(100, this, SLOT(releaseLock())); +#endif +} + +void Debugger_VFPU::releaseLock() +{ + EmuThread_LockDraw(false); +} + +void Debugger_VFPU::Update() +{ + ui->vfpu->redraw(); +} + +void Debugger_VFPU::Goto(u32 addr) +{ + show(); + mainWindow->GetDialogMemory()->Goto(addr & ~3); +} + +void Debugger_VFPU::on_comboBox_currentIndexChanged(int index) +{ + ui->vfpu->setMode(index); +} diff --git a/Qt/debugger_vfpu.h b/Qt/debugger_vfpu.h new file mode 100644 index 0000000000..c002c9a19d --- /dev/null +++ b/Qt/debugger_vfpu.h @@ -0,0 +1,35 @@ +#ifndef DEBUGGER_VFPU_H +#define DEBUGGER_VFPU_H + +#include "Core/Debugger/DebugInterface.h" +#include + +class MainWindow; +namespace Ui { +class Debugger_VFPU; +} + +class Debugger_VFPU : public QDialog +{ + Q_OBJECT + +public: + explicit Debugger_VFPU(DebugInterface *_cpu, MainWindow *mainWindow_, QWidget *parent = 0); + ~Debugger_VFPU(); + + void Update(); + void Goto(u32 addr); +protected: + void showEvent(QShowEvent *); +public slots: + void releaseLock(); +private slots: + void on_comboBox_currentIndexChanged(int index); + +private: + Ui::Debugger_VFPU *ui; + DebugInterface* cpu; + MainWindow* mainWindow; +}; + +#endif // DEBUGGER_VFPU_H diff --git a/Qt/debugger_vfpu.ui b/Qt/debugger_vfpu.ui new file mode 100644 index 0000000000..c1f2743e4c --- /dev/null +++ b/Qt/debugger_vfpu.ui @@ -0,0 +1,87 @@ + + + Debugger_VFPU + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + + + Float + + + + + HalfFloat + + + + + Hex + + + + + Bytes + + + + + Shorts + + + + + Ints + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::StrongFocus + + + + + + + + CtrlVfpuView + QWidget +
ctrlvfpuview.h
+ 1 +
+
+ + +
diff --git a/Qt/languages/ppsspp_en.ts b/Qt/languages/ppsspp_en.ts index 9343a24500..0819260cdc 100644 --- a/Qt/languages/ppsspp_en.ts +++ b/Qt/languages/ppsspp_en.ts @@ -9,6 +9,115 @@ + + CtrlDisAsmView + + + Copy &address + + + + + Copy instruction (&hex) + + + + + Copy instruction (&disasm) + + + + + &Run to here + + + + + &Set Next Statement + + + + + &Toggle breakpoint + + + + + &Follow branch + + + + + Go to in &Memory View + + + + + &Rename function... + + + + + New function name + + + + + New function name : + + + + + CtrlMemView + + + Go to in &disasm + + + + + &Copy value + + + + + Dump... + + + + + CtrlRegisterList + + + Go to in &memory view + + + + + Go to in &disasm + + + + + &Copy value + + + + + C&hange... + + + + + Set new value + + + + + Set new value : + + + Debugger_Disasm @@ -17,65 +126,243 @@ - + Ctr: - + &Go to - + &PC - + &LR - - - Tab 1 - - - Tab 2 + Show VFPU - + + Regs + + + + + Funcs + + + + &Go - + Stop - + Step &Into - + Step &Over - + S&kip - + Next &HLE + + + Breakpoints + + + + + Address + + + + + Clear All + + + + + Callstack + + + + + Display Lists + + + + + + Id + + + + + + Status + + + + + Start Address + + + + + Current Address + + + + + Run + + + + + Step + + + + + Threads + + + + + Name + + + + + Current PC + + + + + Entry point + + + + + Remove breakpoint + + + + + Go to entry point + + + + + Running + + + + + Wait + + + + + Suspend + + + + + Show code + + + + + Debugger_Memory + + + Dialog + + + + + Goto: + + + + + Mode + + + + + Normal + + + + + Symbols + + + + + Debugger_VFPU + + + Dialog + + + + + Float + + + + + HalfFloat + + + + + Hex + + + + + Bytes + + + + + Shorts + + + + + Ints + + GamePadDialog @@ -205,340 +492,360 @@ - + Debu&g - + &Options - + &Log Levels - + G3D - + HLE - + Default - + Zoom - + Language - + &Help - + &Open... - + &Close - + - - + Quickload state - + F4 - + Quicksave state - + F2 - + &Load State File... - + &Save State File... - + E&xit - + &Run - + F7 - + &Pause - + F8 - + R&eset - + &Interpreter - + &Slightly Faster Interpreter - + &Dynarec - + Load &Map File... - + &Save Map File... - + &Reset Symbol Table - + &Disassembly - + Ctrl+D - + &Log Console - + Ctrl+L - + Memory &View... - + Ctrl+M - + Keyboard &Controls - + &Toggle Full Screen - + F12 - + &Buffered Rendering - + F5 - + &Hardware Transform - + F6 - + &Linear Filtering - + &Wireframe (experimental) - + &Display Raw Framebuffer - + &Show Debug Statistics - + Screen &1x - + Ctrl+1 - + Screen &2x - + Ctrl+2 - + Screen &3x - + Ctrl+3 - + Screen &4x - + Ctrl+4 - + &Fast Memory (dynarec, unstable) - + &Ignore illegal reads/writes - + &Go to http://www.ppsspp.org/ - + &About PPSSPP... - + &Use VBO - - - + + + Debug - - - + + + Warning - - - + + + Error - - - + + + Info - + GamePad Controls - + + &Run on load + + + + + D&ump next frame to log + + + + + &Vertex Cache + + + + + Memory View Texture... + + + + No translations diff --git a/Qt/languages/ppsspp_fr.ts b/Qt/languages/ppsspp_fr.ts new file mode 100644 index 0000000000..0a06406e6a --- /dev/null +++ b/Qt/languages/ppsspp_fr.ts @@ -0,0 +1,941 @@ + + + + + Controls + + + Controls + + + + + CtrlDisAsmView + + + Copy &address + + + + + Copy instruction (&hex) + + + + + Copy instruction (&disasm) + + + + + &Run to here + + + + + &Set Next Statement + + + + + &Toggle breakpoint + + + + + &Follow branch + + + + + Go to in &Memory View + + + + + &Rename function... + + + + + New function name + + + + + New function name : + + + + + CtrlMemView + + + Go to in &disasm + + + + + &Copy value + + + + + Dump... + + + + + CtrlRegisterList + + + Go to in &memory view + + + + + Go to in &disasm + + + + + &Copy value + + + + + C&hange... + + + + + Set new value + + + + + Set new value : + + + + + Debugger_Disasm + + + Dialog + + + + + Ctr: + + + + + &Go to + + + + + &PC + + + + + &LR + + + + + Show VFPU + + + + + Regs + + + + + Funcs + + + + + &Go + + + + + Stop + + + + + Step &Into + + + + + Step &Over + + + + + S&kip + + + + + Next &HLE + + + + + Breakpoints + + + + + Address + + + + + Clear All + + + + + Callstack + + + + + Display Lists + + + + + + Id + + + + + + Status + + + + + Start Address + + + + + Current Address + + + + + Run + + + + + Step + + + + + Threads + + + + + Name + + + + + Current PC + + + + + Entry point + + + + + Remove breakpoint + + + + + Go to entry point + + + + + Running + + + + + Wait + + + + + Suspend + + + + + Show code + + + + + Debugger_Memory + + + Dialog + + + + + Goto: + + + + + Mode + + + + + Normal + + + + + Symbols + + + + + Debugger_VFPU + + + Dialog + + + + + Float + + + + + HalfFloat + + + + + Hex + + + + + Bytes + + + + + Shorts + + + + + Ints + + + + + GamePadDialog + + + Gamepad Configuration + + + + + GamePad List + + + + + Refresh + + + + + Select + + + + + Gamepad Values : + + + + + TextLabel + + + + + Assign Gamepad input + + + + + to PSP button/axis + + + + + Assign + + + + + Press buttons on your gamePad to verify mapping : + + + + + + <b>No gamepad</b> + + + + + <b>Unknown gamepad</b> + + + + + Buttons + + + + + + Button %1 + + + + + Axes + + + + + %1 Neg + + + + + Axes %1 Neg + + + + + %1 Pos + + + + + Axes %1 Pos + + + + + Hats + + + + + <b>Current gamepad: %1</b> + + + + + MainWindow + + + PPSSPP + PPSSPP + + + + &File + &Fichier + + + + &Emulation + &Emulation + + + + Debu&g + Debu&g + + + + &Options + &Options + + + + &Log Levels + Niveaux de &logs + + + + G3D + + + + + HLE + + + + + Default + Défaut + + + + Zoom + + + + + Language + Langue + + + + &Help + &Aide + + + + &Open... + &Ouvrir... + + + + &Close + &Fermer + + + + - + + + + + Quickload state + + + + + F4 + + + + + Quicksave state + + + + + F2 + + + + + &Load State File... + + + + + &Save State File... + + + + + E&xit + &Quitter + + + + &Run + + + + + F7 + + + + + &Pause + + + + + F8 + + + + + R&eset + + + + + &Interpreter + + + + + &Slightly Faster Interpreter + + + + + &Dynarec + + + + + Load &Map File... + + + + + &Save Map File... + + + + + &Reset Symbol Table + + + + + &Disassembly + + + + + Ctrl+D + + + + + &Log Console + + + + + Ctrl+L + + + + + Memory &View... + + + + + Ctrl+M + + + + + Keyboard &Controls + + + + + &Toggle Full Screen + + + + + F12 + + + + + &Buffered Rendering + + + + + F5 + + + + + &Hardware Transform + + + + + F6 + + + + + &Linear Filtering + + + + + &Wireframe (experimental) + + + + + &Display Raw Framebuffer + + + + + &Show Debug Statistics + + + + + Screen &1x + + + + + Ctrl+1 + + + + + Screen &2x + + + + + Ctrl+2 + + + + + Screen &3x + + + + + Ctrl+3 + + + + + Screen &4x + + + + + Ctrl+4 + + + + + &Fast Memory (dynarec, unstable) + + + + + &Ignore illegal reads/writes + + + + + &Go to http://www.ppsspp.org/ + + + + + &About PPSSPP... + + + + + &Use VBO + + + + + + + Debug + + + + + + + Warning + + + + + + + Error + + + + + + + Info + + + + + GamePad Controls + + + + + &Run on load + + + + + D&ump next frame to log + + + + + &Vertex Cache + + + + + Memory View Texture... + + + + + No translations + + + + + gamepadMapping + + + Cross + + + + + Circle + + + + + Square + + + + + Triangle + + + + + Left Trigger + + + + + Right Trigger + + + + + Start + + + + + Select + + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + Home + + + + + Stick left + + + + + Stick right + + + + + Stick up + + + + + Stick bottom + + + + diff --git a/Qt/languages/ppsspp_pl.ts b/Qt/languages/ppsspp_pl.ts index c2d398d637..d5e7b6fb34 100644 --- a/Qt/languages/ppsspp_pl.ts +++ b/Qt/languages/ppsspp_pl.ts @@ -9,6 +9,115 @@ + + CtrlDisAsmView + + + Copy &address + + + + + Copy instruction (&hex) + + + + + Copy instruction (&disasm) + + + + + &Run to here + + + + + &Set Next Statement + + + + + &Toggle breakpoint + + + + + &Follow branch + + + + + Go to in &Memory View + + + + + &Rename function... + + + + + New function name + + + + + New function name : + + + + + CtrlMemView + + + Go to in &disasm + + + + + &Copy value + + + + + Dump... + + + + + CtrlRegisterList + + + Go to in &memory view + + + + + Go to in &disasm + + + + + &Copy value + + + + + C&hange... + + + + + Set new value + + + + + Set new value : + + + Debugger_Disasm @@ -17,65 +126,243 @@ - + Ctr: - + &Go to - + &PC - + &LR - - - Tab 1 - - - Tab 2 + Show VFPU - + + Regs + + + + + Funcs + + + + &Go - + Stop - + Step &Into - + Step &Over - + S&kip - + Next &HLE + + + Breakpoints + + + + + Address + + + + + Clear All + + + + + Callstack + + + + + Display Lists + + + + + + Id + + + + + + Status + + + + + Start Address + + + + + Current Address + + + + + Run + + + + + Step + + + + + Threads + + + + + Name + + + + + Current PC + + + + + Entry point + + + + + Remove breakpoint + + + + + Go to entry point + + + + + Running + + + + + Wait + + + + + Suspend + + + + + Show code + + + + + Debugger_Memory + + + Dialog + + + + + Goto: + + + + + Mode + + + + + Normal + + + + + Symbols + + + + + Debugger_VFPU + + + Dialog + + + + + Float + + + + + HalfFloat + + + + + Hex + + + + + Bytes + + + + + Shorts + + + + + Ints + + GamePadDialog @@ -205,340 +492,360 @@ &Emulacja - + Debu&g &Debugger - + &Options &Opcje - + &Log Levels P&oziomy logowania - + G3D G3D - + HLE HLE - + Default Domyślne - + Zoom Zoom - + Language Język - + &Help Pomo&c - + &Open... &Otwórz... - + &Close &Zamknij - + - - + Quickload state Wczytaj stan - + F4 F4 - + Quicksave state Zapisz stan - + F2 F2 - + &Load State File... &Wczytaj plik stanu... - + &Save State File... &Zapisz plik stanu... - + E&xit Wyj&dź - + &Run &Uruchom - + F7 F7 - + &Pause &Pauza - + F8 F8 - + R&eset &Reset - + &Interpreter &Interpreter - + &Slightly Faster Interpreter &Szybszy interpreter - + &Dynarec R&ekompilacja (Dynarec) - + Load &Map File... &Wczytaj plik mapy... - + &Save Map File... &Zapisz plik mapy... - + &Reset Symbol Table Zresetuj &tablicę symboli - + &Disassembly &Dekompiluj - + Ctrl+D Ctrl+D - + &Log Console &Konsola logowania - + Ctrl+L Ctrl+L - + Memory &View... Widok &pamięci... - + Ctrl+M Ctrl+M - + Keyboard &Controls Ustawienia &klawiatury - + &Toggle Full Screen &Pełny ekran - + F12 F12 - + &Buffered Rendering &Buffered rendering - + F5 F5 - + &Hardware Transform &Hardware Transform - + F6 F6 - + &Linear Filtering &Linear Filtering - + &Wireframe (experimental) - + &Display Raw Framebuffer - + &Show Debug Statistics Pokaż &statystyki emulacji - + Screen &1x &1x - + Ctrl+1 Ctrl+1 - + Screen &2x &2x - + Ctrl+2 Ctrl+2 - + Screen &3x &3x - + Ctrl+3 Ctrl+3 - + Screen &4x &4x - + Ctrl+4 Ctrl+4 - + &Fast Memory (dynarec, unstable) &Fast memory (wymagany Dynarec, niestabilne) - + &Ignore illegal reads/writes &Ignoruj nieprawidłowe odczyty/zapisy - + &Go to http://www.ppsspp.org/ &Idź do http://www.ppsspp.org - + &About PPSSPP... &O PPSSPP... - + &Use VBO Użyj &VBO - - - + + + Debug Debug - - - + + + Warning Ostrzeżenia - - - + + + Error Błędy - - - + + + Info Info - + GamePad Controls &Ustawienia pada - + + &Run on load + + + + + D&ump next frame to log + + + + + &Vertex Cache + + + + + Memory View Texture... + + + + No translations diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 125043c00b..734a0ee449 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -9,6 +9,7 @@ #include #include "Core/MIPS/MIPSDebugInterface.h" +#include "Core/Debugger/SymbolMap.h" #include "Core/SaveState.h" #include "Core/System.h" #include "Core/Config.h" @@ -26,7 +27,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), nextState(CORE_POWERDOWN), - dialogDisasm(0) + dialogDisasm(0), + memoryWindow(0) { ui->setupUi(this); qApp->installEventFilter(this); @@ -36,19 +38,18 @@ MainWindow::MainWindow(QWidget *parent) : gamePadDlg = new GamePadDialog(&input_state, this); #endif + SetPlaying(0); + host = new QtHost(this); w = ui->widget; w->init(&input_state); w->resize(pixel_xres, pixel_yres); w->setMinimumSize(pixel_xres, pixel_yres); w->setMaximumSize(pixel_xres, pixel_yres); + QObject::connect( w, SIGNAL(doubleClick()), this, SLOT(on_action_OptionsFullScreen_triggered()) ); - /* - DialogManager::AddDlg(memoryWindow[0] = new CMemoryDlg(_hInstance, hwndMain, currentDebugMIPS)); - DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS)); - */ - // Update(); createLanguageMenu(); + UpdateMenus(); int zoom = g_Config.iWindowZoom; @@ -173,15 +174,16 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co void MainWindow::SetPlaying(QString text) { - // TODO - /*if (text == 0) - SetWindowText(hwndMain,programname); + if (text == 0) + { + QString title = "PPSSPP " + QString(PPSSPP_VERSION_STR); + setWindowTitle(title); + } else { - char temp[256]; - sprintf(temp, "%s - %s", text, programname); - SetWindowText(hwndMain,temp); - }*/ + QString title = "PPSSPP " + QString(PPSSPP_VERSION_STR) + "-" + text; + setWindowTitle(title); + } } void MainWindow::SetNextState(CoreState state) @@ -205,20 +207,28 @@ void MainWindow::Boot() dialogDisasm = new Debugger_Disasm(currentDebugMIPS, this, this); if(g_Config.bShowDebuggerOnLoad) dialogDisasm->show(); - /* - // TODO - memoryWindow[0] = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); - DialogManager::AddDlg(memoryWindow[0]); - if (disasmWindow[0]) - disasmWindow[0]->NotifyMapLoaded(); - if (memoryWindow[0]) - memoryWindow[0]->NotifyMapLoaded();*/ + + if(g_Config.bFullScreen != isFullScreen()) + on_action_OptionsFullScreen_triggered(); + + memoryWindow = new Debugger_Memory(currentDebugMIPS, this, this); + + if (dialogDisasm) + dialogDisasm->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); if (nextState == CORE_RUNNING) on_action_EmulationRun_triggered(); UpdateMenus(); } +void MainWindow::CoreEmitWait(bool isWaiting) +{ + // Unlock mutex while core is waiting; + EmuThread_LockDraw(!isWaiting); +} + void MainWindow::UpdateMenus() { ui->action_OptionsDisplayRawFramebuffer->setChecked(g_Config.bDisplayFramebuffer); @@ -227,10 +237,14 @@ void MainWindow::UpdateMenus() ui->action_CPUFastInterpreter->setChecked(g_Config.iCpuCore == CPU_FASTINTERPRETER); ui->action_CPUDynarec->setChecked(g_Config.iCpuCore == CPU_JIT); ui->action_OptionsBufferedRendering->setChecked(g_Config.bBufferedRendering); + ui->action_OptionsShowDebugStatistics->setChecked(g_Config.bShowDebugStats); ui->action_OptionsWireframe->setChecked(g_Config.bDrawWireframe); ui->action_OptionsHardwareTransform->setChecked(g_Config.bHardwareTransform); ui->action_OptionsFastMemory->setChecked(g_Config.bFastMemory); ui->action_OptionsLinearFiltering->setChecked(g_Config.bLinearFiltering); + ui->action_EmulationRunLoad->setChecked(g_Config.bAutoRun); + ui->action_OptionsUseVBO->setChecked(g_Config.bUseVBO); + ui->action_OptionsVertexCache->setChecked(g_Config.bVertexCache); bool enable = !Core_IsStepping() ? false : true; ui->action_EmulationRun->setEnabled(g_State.bEmuThreadStarted ? enable : false); @@ -275,6 +289,8 @@ void MainWindow::SetZoom(float zoom) { pixel_xres = 480 * zoom; pixel_yres = 272 * zoom; + dp_xres = pixel_xres; + dp_yres = pixel_yres; w->resize(pixel_xres, pixel_yres); w->setMinimumSize(pixel_xres, pixel_yres); @@ -299,7 +315,6 @@ void MainWindow::on_action_EmulationRun_triggered() { if (g_State.bEmuThreadStarted) { - /*for (int i=0; iStop(); @@ -310,34 +325,29 @@ void MainWindow::on_action_EmulationRun_triggered() void MainWindow::on_action_EmulationStop_triggered() { - /*for (int i=0; iStop(); } - usleep(100); // TODO : UGLY wait for event instead + // This will wait for ppsspp to pause + EmuThread_LockDraw(true); + EmuThread_LockDraw(false); - /*for (int i=0; iGetDlgHandle(), WM_CLOSE, 0, 0); - for (int i=0; iGetDlgHandle(), WM_CLOSE, 0, 0);*/ + if(dialogDisasm && dialogDisasm->isVisible()) + dialogDisasm->close(); + if(memoryWindow && memoryWindow->isVisible()) + memoryWindow->close(); EmuThread_StopGame(); SetPlaying(0); - //Update(); + Update(); UpdateMenus(); } void MainWindow::on_action_EmulationPause_triggered() { - /*for (int i=0; iStop(); - } } void SaveStateActionFinished(bool result, void *userdata) @@ -356,7 +366,6 @@ void SaveStateActionFinished(bool result, void *userdata) if (g_State.bEmuThreadStarted && mainWindow->GetNextState() == CORE_RUNNING) { - /*for (int i=0; iGetDialogDisasm()) mainWindow->GetDialogDisasm()->Go(); } @@ -367,7 +376,6 @@ void MainWindow::on_action_FileLoadStateFile_triggered() if (g_State.bEmuThreadStarted) { nextState = Core_IsStepping() ? CORE_STEPPING : CORE_RUNNING; - /*for (int i=0; iStop(); @@ -393,7 +401,6 @@ void MainWindow::on_action_FileSaveStateFile_triggered() if (g_State.bEmuThreadStarted) { nextState = Core_IsStepping() ? CORE_STEPPING : CORE_RUNNING; - /*for (int i=0; iStop(); @@ -418,7 +425,6 @@ void MainWindow::on_action_FileQuickloadState_triggered() if (g_State.bEmuThreadStarted) { nextState = Core_IsStepping() ? CORE_STEPPING : CORE_RUNNING; - /*for (int i=0; iStop(); @@ -432,7 +438,6 @@ void MainWindow::on_action_FileQuickSaveState_triggered() if (g_State.bEmuThreadStarted) { nextState = Core_IsStepping() ? CORE_STEPPING : CORE_RUNNING; - /*for (int i=0; iStop(); @@ -510,37 +515,47 @@ void MainWindow::on_action_CPUFastInterpreter_triggered() void MainWindow::on_action_DebugLoadMapFile_triggered() { - // TODO - /*if (W32Util::BrowseForFileName(true, hWnd, "Load .MAP",0,"Maps\0*.map\0All files\0*.*\0\0","map",fn)) + QFileDialog dialog(0,"Load .MAP"); + dialog.setFileMode(QFileDialog::ExistingFile); + QStringList filters; + filters << "Maps (*.map)" << "|All files (*.*)"; + dialog.setNameFilters(filters); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + QStringList fileNames; + if (dialog.exec()) { - symbolMap.LoadSymbolMap(fn.c_str()); -// HLE_PatchFunctions(); - for (int i=0; iNotifyMapLoaded(); - for (int i=0; iNotifyMapLoaded(); - }*/ + fileNames = dialog.selectedFiles(); + symbolMap.LoadSymbolMap(fileNames[0].toStdString().c_str()); + if (dialogDisasm) + dialogDisasm->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); + } } void MainWindow::on_action_DebugSaveMapFile_triggered() { - // TODO - /*if (W32Util::BrowseForFileName(false, hWnd, "Save .MAP",0,"Maps\0*.map\0All files\0*.*\0\0","map",fn)) - symbolMap.SaveSymbolMap(fn.c_str());*/ + QFileDialog dialog(0,"Save .MAP"); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setAcceptMode(QFileDialog::AcceptSave); + QStringList filters; + filters << "Save .MAP (*.map)" << "|All files (*.*)"; + dialog.setNameFilters(filters); + QStringList fileNames; + if (dialog.exec()) + { + fileNames = dialog.selectedFiles(); + symbolMap.SaveSymbolMap(fileNames[0].toStdString().c_str()); + } } void MainWindow::on_action_DebugResetSymbolTable_triggered() { - // TODO - /*symbolMap.ResetSymbolMap(); - for (int i=0; iNotifyMapLoaded(); - for (int i=0; iNotifyMapLoaded();*/ + symbolMap.ResetSymbolMap(); + if (dialogDisasm) + dialogDisasm->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); } void MainWindow::on_action_DebugDisassembly_triggered() @@ -551,9 +566,8 @@ void MainWindow::on_action_DebugDisassembly_triggered() void MainWindow::on_action_DebugMemoryView_triggered() { - // TODO - /*if (memoryWindow[0]) - memoryWindow[0]->Show(true);*/ + if (memoryWindow) + memoryWindow->show(); } void MainWindow::on_action_DebugLog_triggered() @@ -570,12 +584,14 @@ void MainWindow::on_action_OptionsIgnoreIllegalReadsWrites_triggered() void MainWindow::on_action_OptionsFullScreen_triggered() { if(isFullScreen()) { + g_Config.bFullScreen = false; showNormal(); ui->menubar->setVisible(true); ui->statusbar->setVisible(true); SetZoom(g_Config.iWindowZoom); } else { + g_Config.bFullScreen = true; ui->menubar->setVisible(false); ui->statusbar->setVisible(false); @@ -597,6 +613,8 @@ void MainWindow::on_action_OptionsFullScreen_triggered() PSP_CoreParameter().outputHeight = height; pixel_xres = width; pixel_yres = height; + dp_xres = pixel_xres; + dp_yres = pixel_yres; if (gpu) gpu->Resized(); } @@ -638,10 +656,7 @@ void MainWindow::on_action_HelpOpenWebsite_triggered() void MainWindow::on_action_HelpAbout_triggered() { - // TODO - /*DialogManager::EnableAll(FALSE); - DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); - DialogManager::EnableAll(TRUE);*/ + // TODO display about } void MainWindow::closeEvent(QCloseEvent *event) @@ -879,3 +894,55 @@ void MainWindow::changeEvent(QEvent *event) } } } + +void MainWindow::ShowMemory(u32 addr) +{ + if(memoryWindow) + memoryWindow->Goto(addr); +} + +void MainWindow::Update() +{ + +} + +void MainWindow::on_action_EmulationReset_triggered() +{ + if(dialogDisasm) + dialogDisasm->Stop(); + + EmuThread_LockDraw(true); + EmuThread_LockDraw(false); + + if(dialogDisasm) + dialogDisasm->close(); + if(memoryWindow) + memoryWindow->close(); + + EmuThread_StopGame(); + + EmuThread_StartGame(GetCurrentFilename()); +} + +void MainWindow::on_action_DebugDumpFrame_triggered() +{ + gpu->DumpNextFrame(); +} + +void MainWindow::on_action_EmulationRunLoad_triggered() +{ + g_Config.bAutoRun = !g_Config.bAutoRun; + UpdateMenus(); +} + +void MainWindow::on_action_OptionsVertexCache_triggered() +{ + g_Config.bVertexCache = !g_Config.bVertexCache; + UpdateMenus(); +} + +void MainWindow::on_action_OptionsUseVBO_triggered() +{ + g_Config.bUseVBO = !g_Config.bUseVBO; + UpdateMenus(); +} diff --git a/Qt/mainwindow.h b/Qt/mainwindow.h index dbb27e3323..d6de1f44e6 100644 --- a/Qt/mainwindow.h +++ b/Qt/mainwindow.h @@ -7,6 +7,7 @@ #include "Core/Core.h" #include "input/input_state.h" #include "debugger_disasm.h" +#include "debugger_memory.h" #include "controls.h" #include "gamepaddialog.h" @@ -31,13 +32,17 @@ public: void SetPlaying(QString text); Debugger_Disasm* GetDialogDisasm() { return dialogDisasm; } + Debugger_Memory* GetDialogMemory() { return memoryWindow; } CoreState GetNextState() { return nextState; } void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *e); + void ShowMemory(u32 addr); + void Update(); public slots: void Boot(); + void CoreEmitWait(bool); private slots: void on_action_FileLoad_triggered(); @@ -138,6 +143,16 @@ private slots: void on_language_changed(QAction *action); + void on_action_EmulationReset_triggered(); + + void on_action_DebugDumpFrame_triggered(); + + void on_action_EmulationRunLoad_triggered(); + + void on_action_OptionsVertexCache_triggered(); + + void on_action_OptionsUseVBO_triggered(); + private: void loadLanguage(const QString &language); void createLanguageMenu(); @@ -156,6 +171,7 @@ private: InputState input_state; Debugger_Disasm *dialogDisasm; + Debugger_Memory *memoryWindow; Controls* controls; GamePadDialog* gamePadDlg; }; diff --git a/Qt/mainwindow.ui b/Qt/mainwindow.ui index acf08f6a94..67e1d79d4e 100644 --- a/Qt/mainwindow.ui +++ b/Qt/mainwindow.ui @@ -70,6 +70,8 @@ + + @@ -82,6 +84,8 @@ + + @@ -148,6 +152,7 @@ + @@ -293,9 +298,6 @@
- - false - &Disassembly @@ -315,9 +317,6 @@ - - false - Memory &View... @@ -568,6 +567,26 @@ GamePad Controls + + + &Run on load + + + + + D&ump next frame to log + + + + + &Vertex Cache + + + + + Memory View Texture... + + diff --git a/Qt/qtemugl.cpp b/Qt/qtemugl.cpp index f9b72ec725..50c9ced278 100644 --- a/Qt/qtemugl.cpp +++ b/Qt/qtemugl.cpp @@ -50,14 +50,7 @@ void QtEmuGL::stop_game() void QtEmuGL::LockDraw(bool value) { - if(value) - { - thread.gameMutex.lock(); - } - else - { - thread.gameMutex.unlock(); - } + thread.LockGL(value); } void QtEmuGL::resizeEvent(QResizeEvent *evt) @@ -75,3 +68,8 @@ void QtEmuGL::closeEvent(QCloseEvent *evt) //TODO stopRendering(); QGLWidget::closeEvent(evt); } + +void QtEmuGL::mouseDoubleClickEvent(QMouseEvent *) +{ + emit doubleClick(); +} diff --git a/Qt/qtemugl.h b/Qt/qtemugl.h index 23b33a430d..f55b9c3f0f 100644 --- a/Qt/qtemugl.h +++ b/Qt/qtemugl.h @@ -19,6 +19,8 @@ public: void start_game(QString filename); void stop_game(); void LockDraw(bool value); +signals: + void doubleClick(); protected: void initializeGL(); @@ -26,6 +28,7 @@ protected: void resizeEvent(QResizeEvent *evt); void paintEvent(QPaintEvent *); void closeEvent(QCloseEvent *evt); + void mouseDoubleClickEvent(QMouseEvent *); signals: public slots: diff --git a/Qt/resources.qrc b/Qt/resources.qrc index 4bcd4f9d3d..444064348b 100644 --- a/Qt/resources.qrc +++ b/Qt/resources.qrc @@ -14,5 +14,7 @@ resources/psp_adown.png resources/psp_aleft.png resources/psp_aup.png + resources/stop1.ico + resources/icon1.ico diff --git a/Qt/resources/icon1.ico b/Qt/resources/icon1.ico new file mode 100644 index 0000000000000000000000000000000000000000..33d3fd8fb1183b829d808b402bd9b0ebf062eafc GIT binary patch literal 766 zcmeH_F%kkH3`K*p1$I=nQhE!$nUq`F<~AH7%MX25p0G^=rEb{k;_K8}vr-2X@Ds6PK%5h2_jA>*?N|Ju`d458Dl# A$^ZZW literal 0 HcmV?d00001 diff --git a/Qt/resources/stop1.ico b/Qt/resources/stop1.ico new file mode 100644 index 0000000000000000000000000000000000000000..b974cdb5e2302cfd7306dc272a4b2e70442ff49e GIT binary patch literal 766 zcmZQzU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdxnc0ZU_qXWf$j`H#bWP$eb@(N1$=;kq?*#}Gm UGzEu&rZ)mHII$toATf{}0O;?X1^@s6 literal 0 HcmV?d00001