X-Git-Url: http://git.hcoop.net/clinton/Virtual-Jaguar-Rx.git/blobdiff_plain/ed31b9990544235632b07e7b8946b5df9e695660..acd3342fdfdd4195fdad3d4c4d248b9610f90622:/src/gui/mainwin.cpp diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index bf7db69..a941d48 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -11,24 +11,17 @@ // JLH 12/23/2009 Created this file // JLH 12/20/2010 Added settings, menus & toolbars // JLH 07/05/2011 Added CD BIOS functionality to GUI -// JPM 06/06/2016 Visual Studio support -// JPM 06/19/2016 Soft debugger integration +// JPM June/2016 Visual Studio support & Soft debugger integration // JPM 01/11/2017 Added stack browser -// JPM 01/02/2017 Added GPU disassembly -// JPM 02/02/2017 Added DSP disassembly +// JPM Feb./2017 Added GPU/DSP disassembly // JPM 07/12/2017 Added all Watch window -// JPM 08/01/2017 Added heap allocator window -// JPM 08/07/2017 Added memories window -// JPM 08/10/2017 Added a restart feature -// JPM 08/31/2017 Added breakpoints window [Not Supported] -// JPM 09/01/2017 Save position & visibility windows status in the settings -// JPM 09/02/2017 Save size windows in the settings -// JPM 09/05/2017 Added Exception Vector Table window -// JPM 09/06/2017 Added the 'Rx' word to the emulator window name -// JPM 09/12/2017 Added the keybindings in the settings +// JPM Aug./2017 Added heap allocator and memories window, a restart feature, and a [Not Supported] breakpoints window +// JPM Sept./2017 Save position, size & visibility windows status in the settings; added Exception Vector Table window, the 'Rx' word to the emulator window name, and the keybindings in the settings // JPM 11/04/2017 Added the local window // JPM 08/31/2018 Added the call stack window -// JPM 09/04/2018 Added the new Models and BIOS handler +// JPM Sept./2018 Added the new Models and BIOS handler, a screenshot feature and source code files browsing +// JPM Oct./2018 Added search paths in the settings, breakpoints feature, cartdridge view menu +// JPM 11/18/2018 Fix crash with non-debugger mode // // FIXED: @@ -92,18 +85,22 @@ #include "joystick.h" #include "m68000/m68kinterface.h" +#include "debugger/DBGManager.h" //#include "debugger/VideoWin.h" -#include "debugger/DasmWin.h" +//#include "debugger/DasmWin.h" #include "debugger/m68KDasmWin.h" #include "debugger/GPUDasmWin.h" #include "debugger/DSPDasmWin.h" #include "debugger/memory1browser.h" -#include "debugger/brkWin.h" +#include "debugger/BreakpointsWin.h" +#include "debugger/NewFnctBreakpointWin.h" +#include "debugger/FilesrcListWin.h" #include "debugger/exceptionvectortablebrowser.h" #include "debugger/allwatchbrowser.h" #include "debugger/localbrowser.h" #include "debugger/heapallocatorbrowser.h" #include "debugger/callstackbrowser.h" +#include "debugger/CartFilesListWin.h" // According to SebRmv, this header isn't seen on Arch Linux either... :-/ @@ -196,13 +193,15 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), //VideoOutputWin = new VideoOutputWindow(this); //VideoOutputWin->setCentralWidget() //DasmWin = new DasmWindow(); - DasmWin = new DasmWindow(this); + //DasmWin = new DasmWindow(this); allWatchBrowseWin = new AllWatchBrowserWindow(this); LocalBrowseWin = new LocalBrowserWindow(this); heapallocatorBrowseWin = new HeapAllocatorBrowserWindow(this); - brkWin = new BrkWindow(this); + BreakpointsWin = new BreakpointsWindow(this); + NewFunctionBreakpointWin = new NewFnctBreakpointWindow(this); exceptionvectortableBrowseWin = new ExceptionVectorTableBrowserWindow(this); CallStackBrowseWin = new CallStackBrowserWindow(this); + CartFilesListWin = new CartFilesListWindow(this); mem1BrowseWin = (Memory1BrowserWindow **)calloc(vjs.nbrmemory1browserwindow, sizeof(Memory1BrowserWindow)); #ifdef _MSC_VER @@ -215,21 +214,30 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), mem1BrowseWin[i] = new Memory1BrowserWindow(this); } + // Setup dock to display source code filenames tree + QDockWidget *dockFiles = new QDockWidget(tr("Files"), this); + dockFiles->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + dockFiles->hide(); + addDockWidget(Qt::LeftDockWidgetArea, dockFiles); + mainWindowCentrale->addAction(dockFiles->toggleViewAction()); + dockFiles->setWidget(FilesrcListWin = new FilesrcListWindow(this)); +#if 0 + // Setup dock to display disassembly + QDockWidget *dockDisasm = new QDockWidget(tr("Disassembly"), this); + dockDisasm->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + addDockWidget(Qt::RightDockWidgetArea, dockDisasm); + mainWindowCentrale->addAction(dockDisasm->toggleViewAction()); + dockDisasm->setWidget(dasmtabWidget = new QTabWidget(this)); +#else dasmtabWidget = new QTabWidget(this); +#endif + // Setup disasm tabs dasmtabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); dasmtabWidget->addTab(m68kDasmWin = new m68KDasmWindow(this), tr("M68000")); dasmtabWidget->addTab(GPUDasmWin = new GPUDasmWindow(this), tr("GPU")); dasmtabWidget->addTab(DSPDasmWin = new DSPDasmWindow(this), tr("DSP")); - ////dasmtabWidget->addTab(m68kDasmBrowseWin, tr("M68000")); +#if 1 setCentralWidget(dasmtabWidget); - -#if 0 - QDockWidget *shapesDockWidget = new QDockWidget(tr("Shapes")); - shapesDockWidget->setObjectName("shapesDockWidget"); - shapesDockWidget->setWidget(m68kDasmWin); - //shapesDockWidget->setWidget(treeWidget); - shapesDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - addDockWidget(Qt::LeftDockWidgetArea, shapesDockWidget); #endif } @@ -238,28 +246,25 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), setUnifiedTitleAndToolBarOnMac(true); - // Create actions - + // Quit actions quitAppAct = new QAction(QIcon(":/res/exit.png"), tr("E&xit"), this); -// quitAppAct->setShortcuts(QKeySequence::Quit); -// quitAppAct->setShortcut(QKeySequence(tr("Alt+x"))); - //quitAppAct->setShortcut(QKeySequence(tr("Ctrl+q"))); quitAppAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBQUIT].KBSettingValue))); quitAppAct->setShortcutContext(Qt::ApplicationShortcut); quitAppAct->setStatusTip(tr("Quit Virtual Jaguar")); connect(quitAppAct, SIGNAL(triggered()), this, SLOT(close())); + // Power action powerGreen.addFile(":/res/power-off.png", QSize(), QIcon::Normal, QIcon::Off); powerGreen.addFile(":/res/power-on-green.png", QSize(), QIcon::Normal, QIcon::On); powerRed.addFile(":/res/power-off.png", QSize(), QIcon::Normal, QIcon::Off); powerRed.addFile(":/res/power-on-red.png", QSize(), QIcon::Normal, QIcon::On); - powerAct = new QAction(powerGreen, tr("&Power"), this); powerAct->setStatusTip(tr("Powers Jaguar on/off")); powerAct->setCheckable(true); powerAct->setChecked(false); connect(powerAct, SIGNAL(triggered()), this, SLOT(TogglePowerState())); + // Pause action QIcon pauseIcon; pauseIcon.addFile(":/res/pause-off.png", QSize(), QIcon::Normal, QIcon::Off); pauseIcon.addFile(":/res/pause-on.png", QSize(), QIcon::Normal, QIcon::On); @@ -267,56 +272,63 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), pauseAct->setStatusTip(tr("Toggles the running state")); pauseAct->setCheckable(true); pauseAct->setDisabled(true); - //pauseAct->setShortcut(QKeySequence(tr("Esc"))); pauseAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBPAUSE].KBSettingValue))); pauseAct->setShortcutContext(Qt::ApplicationShortcut); connect(pauseAct, SIGNAL(triggered()), this, SLOT(ToggleRunState())); - zoomActs = new QActionGroup(this); + // Screenshot action + screenshotAct = new QAction(QIcon(":/res/screenshot.png"), tr("&Screenshot"), this); + screenshotAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBSCREENSHOT].KBSettingValue))); + screenshotAct->setShortcutContext(Qt::ApplicationShortcut); + screenshotAct->setCheckable(false); + screenshotAct->setDisabled(false); + connect(screenshotAct, SIGNAL(triggered()), this, SLOT(MakeScreenshot())); + // Zoom actions + zoomActs = new QActionGroup(this); x1Act = new QAction(QIcon(":/res/zoom100.png"), tr("Zoom 100%"), zoomActs); x1Act->setStatusTip(tr("Set window zoom to 100%")); x1Act->setCheckable(true); connect(x1Act, SIGNAL(triggered()), this, SLOT(SetZoom100())); - x2Act = new QAction(QIcon(":/res/zoom200.png"), tr("Zoom 200%"), zoomActs); x2Act->setStatusTip(tr("Set window zoom to 200%")); x2Act->setCheckable(true); connect(x2Act, SIGNAL(triggered()), this, SLOT(SetZoom200())); - x3Act = new QAction(QIcon(":/res/zoom300.png"), tr("Zoom 300%"), zoomActs); x3Act->setStatusTip(tr("Set window zoom to 300%")); x3Act->setCheckable(true); connect(x3Act, SIGNAL(triggered()), this, SLOT(SetZoom300())); + // TV type actions tvTypeActs = new QActionGroup(this); - ntscAct = new QAction(QIcon(":/res/ntsc.png"), tr("NTSC"), tvTypeActs); ntscAct->setStatusTip(tr("Sets Jaguar to NTSC mode")); ntscAct->setCheckable(true); connect(ntscAct, SIGNAL(triggered()), this, SLOT(SetNTSC())); - palAct = new QAction(QIcon(":/res/pal.png"), tr("PAL"), tvTypeActs); palAct->setStatusTip(tr("Sets Jaguar to PAL mode")); palAct->setCheckable(true); connect(palAct, SIGNAL(triggered()), this, SLOT(SetPAL())); + // Blur action blur.addFile(":/res/blur-off.png", QSize(), QIcon::Normal, QIcon::Off); blur.addFile(":/res/blur-on.png", QSize(), QIcon::Normal, QIcon::On); - blurAct = new QAction(blur, tr("Blur"), this); blurAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST")); blurAct->setCheckable(true); connect(blurAct, SIGNAL(triggered()), this, SLOT(ToggleBlur())); + // About action aboutAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&About..."), this); aboutAct->setStatusTip(tr("Blatant self-promotion")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin())); + // Help action helpAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&Contents..."), this); helpAct->setStatusTip(tr("Help is available, if you should need it")); connect(helpAct, SIGNAL(triggered()), this, SLOT(ShowHelpWin())); + // File pickup action if (!vjs.softTypeDebugger) { filePickAct = new QAction(QIcon(":/res/software.png"), tr("&Insert Cartridge..."), this); @@ -327,99 +339,123 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), filePickAct = new QAction(QIcon(":/res/software.png"), tr("&Insert executable file..."), this); filePickAct->setStatusTip(tr("Insert an executable into Virtual Jaguar")); } - //filePickAct->setShortcut(QKeySequence(tr("Ctrl+i"))); filePickAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBPICKFILE].KBSettingValue))); filePickAct->setShortcutContext(Qt::ApplicationShortcut); connect(filePickAct, SIGNAL(triggered()), this, SLOT(InsertCart())); + // Configuration action configAct = new QAction(QIcon(":/res/wrench.png"), tr("&Configure"), this); configAct->setStatusTip(tr("Configure options for Virtual Jaguar")); - //configAct->setShortcut(QKeySequence(tr("Ctrl+c"))); configAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBCONFIGURE].KBSettingValue))); configAct->setShortcutContext(Qt::ApplicationShortcut); connect(configAct, SIGNAL(triggered()), this, SLOT(Configure())); + // Emulation status action emustatusAct = new QAction(QIcon(":/res/status.png"), tr("&Status"), this); emustatusAct->setStatusTip(tr("Emulator status")); - //emustatusAct->setShortcut(QKeySequence(tr("Ctrl+s"))); emustatusAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBEMUSTATUS].KBSettingValue))); emustatusAct->setShortcutContext(Qt::ApplicationShortcut); connect(emustatusAct, SIGNAL(triggered()), this, SLOT(ShowEmuStatusWin())); + // Use CD action useCDAct = new QAction(QIcon(":/res/compact-disc.png"), tr("&Use CD Unit"), this); useCDAct->setStatusTip(tr("Use Jaguar Virtual CD unit")); -// useCDAct->setShortcut(QKeySequence(tr("Ctrl+c"))); useCDAct->setCheckable(true); connect(useCDAct, SIGNAL(triggered()), this, SLOT(ToggleCDUsage())); + // Frame advance action frameAdvanceAct = new QAction(QIcon(":/res/frame-advance.png"), tr("&Frame Advance"), this); - //frameAdvanceAct->setShortcut(QKeySequence(tr("F7"))); frameAdvanceAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFRAMEADVANCE].KBSettingValue))); frameAdvanceAct->setShortcutContext(Qt::ApplicationShortcut); frameAdvanceAct->setDisabled(true); connect(frameAdvanceAct, SIGNAL(triggered()), this, SLOT(FrameAdvance())); + // Fullscreen action + fullScreenAct = new QAction(QIcon(":/res/fullscreen.png"), tr("F&ull Screen"), this); + fullScreenAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFULLSCREEN].KBSettingValue))); + fullScreenAct->setShortcutContext(Qt::ApplicationShortcut); + fullScreenAct->setCheckable(true); + connect(fullScreenAct, SIGNAL(triggered()), this, SLOT(ToggleFullScreen())); + + // Actions dedicated to debugger mode if (vjs.softTypeDebugger) { + // Restart restartAct = new QAction(QIcon(":/res/debug-restart.png"), tr("&Restart"), this); - //restartAct->setShortcut(QKeySequence(tr("Ctrl+Shift+F5"))); restartAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBRESTART].KBSettingValue))); restartAct->setShortcutContext(Qt::ApplicationShortcut); restartAct->setCheckable(false); restartAct->setDisabled(true); connect(restartAct, SIGNAL(triggered()), this, SLOT(DebuggerRestart())); + // Step over trace traceStepOverAct = new QAction(QIcon(":/res/debug-stepover.png"), tr("&Step Over"), this); - //traceStepOverAct->setShortcut(QKeySequence(tr("F10"))); traceStepOverAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBSTEPOVER].KBSettingValue))); traceStepOverAct->setShortcutContext(Qt::ApplicationShortcut); traceStepOverAct->setCheckable(false); traceStepOverAct->setDisabled(true); connect(traceStepOverAct, SIGNAL(triggered()), this, SLOT(DebuggerTraceStepOver())); + // Trace into tracing traceStepIntoAct = new QAction(QIcon(":/res/debug-stepinto.png"), tr("&Step Into"), this); - //traceStepIntoAct->setShortcut(QKeySequence(tr("F11"))); traceStepIntoAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBSTEPINTO].KBSettingValue))); traceStepIntoAct->setShortcutContext(Qt::ApplicationShortcut); traceStepIntoAct->setCheckable(false); traceStepIntoAct->setDisabled(true); connect(traceStepIntoAct, SIGNAL(triggered()), this, SLOT(DebuggerTraceStepInto())); - newBreakpointFunctionAct = new QAction(QIcon(""), tr("&Function Breakpoint"), this); - newBreakpointFunctionAct->setShortcut(QKeySequence(tr("Ctrl+B"))); - connect(newBreakpointFunctionAct, SIGNAL(triggered()), this, SLOT(NewBreakpointFunction())); - } - - fullScreenAct = new QAction(QIcon(":/res/fullscreen.png"), tr("F&ull Screen"), this); - //fullScreenAct->setShortcut(QKeySequence(tr("F9"))); - fullScreenAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFULLSCREEN].KBSettingValue))); - fullScreenAct->setShortcutContext(Qt::ApplicationShortcut); - fullScreenAct->setCheckable(true); - connect(fullScreenAct, SIGNAL(triggered()), this, SLOT(ToggleFullScreen())); - - // Debugger Actions - if (vjs.softTypeDebugger) - { + // Function breakpoint + newFunctionBreakpointAct = new QAction(QIcon(""), tr("&Function Breakpoint"), this); + newFunctionBreakpointAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFUNCTIONBREAKPOINT].KBSettingValue))); + connect(newFunctionBreakpointAct, SIGNAL(triggered()), this, SLOT(ShowNewFunctionBreakpointWin())); + BreakpointsAct = new QAction(QIcon(":/res/debug-breakpoints.png"), tr("&Breakpoints"), this); + BreakpointsAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBBREAKPOINTS].KBSettingValue))); + connect(BreakpointsAct, SIGNAL(triggered()), this, SLOT(ShowBreakpointsWin())); + deleteAllBreakpointsAct = new QAction(QIcon(":/res/debug-deleteallbreakpoints.png"), tr("&Delete All Breakpoints"), this); + deleteAllBreakpointsAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBDELETEALLBREAKPOINTS].KBSettingValue))); + connect(deleteAllBreakpointsAct, SIGNAL(triggered()), this, SLOT(DeleteAllBreakpoints())); + disableAllBreakpointsAct = new QAction(QIcon(":/res/debug-disableallbreakpoints.png"), tr("&Disable All Breakpoints"), this); + connect(disableAllBreakpointsAct, SIGNAL(triggered()), this, SLOT(DisableAllBreakpoints())); + + //VideoOutputAct = new QAction(tr("Output Video"), this); + //VideoOutputAct->setStatusTip(tr("Shows the output video window")); + //connect(VideoOutputAct, SIGNAL(triggered()), this, SLOT(ShowVideoOutputWin())); + + //DasmAct = new QAction(tr("Disassembly"), this); + //DasmAct->setStatusTip(tr("Shows the disassembly window")); + //connect(DasmAct, SIGNAL(triggered()), this, SLOT(ShowDasmWin())); + + // Exception vector table window exceptionVectorTableBrowseAct = new QAction(QIcon(""), tr("Exception Vector Table"), this); exceptionVectorTableBrowseAct->setStatusTip(tr("Shows all Exception Vector Table browser window")); connect(exceptionVectorTableBrowseAct, SIGNAL(triggered()), this, SLOT(ShowExceptionVectorTableBrowserWin())); + // All watch variables window allWatchBrowseAct = new QAction(QIcon(":/res/debug-watch.png"), tr("All Watch"), this); allWatchBrowseAct->setStatusTip(tr("Shows all Watch browser window")); connect(allWatchBrowseAct, SIGNAL(triggered()), this, SLOT(ShowAllWatchBrowserWin())); - LocalBrowseAct = new QAction(QIcon(":/res/debug-local.png"), tr("Local"), this); - LocalBrowseAct->setStatusTip(tr("Shows Local browser window")); + // Local variables window + LocalBrowseAct = new QAction(QIcon(":/res/debug-local.png"), tr("Locals"), this); + LocalBrowseAct->setStatusTip(tr("Shows Locals browser window")); connect(LocalBrowseAct, SIGNAL(triggered()), this, SLOT(ShowLocalBrowserWin())); + // Heap (memory) allocation window heapallocatorBrowseAct = new QAction(QIcon(""), tr("Heap allocator"), this); heapallocatorBrowseAct->setStatusTip(tr("Shows the heap allocator browser window")); connect(heapallocatorBrowseAct, SIGNAL(triggered()), this, SLOT(ShowHeapAllocatorBrowserWin())); + // Call stack window CallStackBrowseAct = new QAction(QIcon(":/res/debug-callstack.png"), tr("Call Stack"), this); CallStackBrowseAct->setStatusTip(tr("Shows Call Stack browser window")); connect(CallStackBrowseAct, SIGNAL(triggered()), this, SLOT(ShowCallStackBrowserWin())); + // Cart files list + CartFilesListAct = new QAction(QIcon(""), tr("Directory and files"), this); + CartFilesListAct->setStatusTip(tr("List of the files in the cartdridge's directory")); + connect(CartFilesListAct, SIGNAL(triggered()), this, SLOT(ShowCartFilesListWin())); + + // Memory windows mem1BrowseAct = (QAction **)calloc(vjs.nbrmemory1browserwindow, sizeof(QAction)); QSignalMapper *signalMapper = new QSignalMapper(this); #ifdef _MSC_VER @@ -433,56 +469,42 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), sprintf(MB, "Memory %i", (unsigned int)(i+1)); mem1BrowseAct[i] = new QAction(QIcon(":/res/debug-memory.png"), tr(MB), this); mem1BrowseAct[i]->setStatusTip(tr("Shows a Jaguar memory browser window")); - //mem1BrowseAct[i]-> - //connect(mem1BrowseAct[0], SIGNAL(triggered()), this, SLOT(ShowMemory1BrowserWin(size_t(0)))); connect(mem1BrowseAct[i], SIGNAL(triggered()), signalMapper, SLOT(map())); signalMapper->setMapping(mem1BrowseAct[i], (int)i); connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(ShowMemory1BrowserWin(int))); } } - // Debugger Browser Actions + // Memory browser window action memBrowseAct = new QAction(QIcon(":/res/tool-memory.png"), tr("Memory Browser"), this); memBrowseAct->setStatusTip(tr("Shows the Jaguar memory browser window")); -// memBrowseAct->setCheckable(true); connect(memBrowseAct, SIGNAL(triggered()), this, SLOT(ShowMemoryBrowserWin())); + // Stack browser window action stackBrowseAct = new QAction(QIcon(":/res/tool-stack.png"), tr("Stack Browser"), this); stackBrowseAct->setStatusTip(tr("Shows the Jaguar stack browser window")); - // memBrowseAct->setCheckable(true); connect(stackBrowseAct, SIGNAL(triggered()), this, SLOT(ShowStackBrowserWin())); + // CPUs (M68000, GPU & DSP browser window action cpuBrowseAct = new QAction(QIcon(":/res/tool-cpu.png"), tr("CPU Browser"), this); cpuBrowseAct->setStatusTip(tr("Shows the Jaguar CPU browser window")); -// memBrowseAct->setCheckable(true); connect(cpuBrowseAct, SIGNAL(triggered()), this, SLOT(ShowCPUBrowserWin())); + // OP browser window action opBrowseAct = new QAction(QIcon(":/res/tool-op.png"), tr("OP Browser"), this); opBrowseAct->setStatusTip(tr("Shows the Jaguar OP browser window")); -// memBrowseAct->setCheckable(true); connect(opBrowseAct, SIGNAL(triggered()), this, SLOT(ShowOPBrowserWin())); + // M68000 disassembly browser window m68kDasmBrowseAct = new QAction(QIcon(":/res/tool-68k-dis.png"), tr("68K Listing Browser"), this); m68kDasmBrowseAct->setStatusTip(tr("Shows the 68K disassembly browser window")); -// memBrowseAct->setCheckable(true); connect(m68kDasmBrowseAct, SIGNAL(triggered()), this, SLOT(ShowM68KDasmBrowserWin())); + // Risc (DSP / GPU) disassembly browser window riscDasmBrowseAct = new QAction(QIcon(":/res/tool-risc-dis.png"), tr("RISC Listing Browser"), this); riscDasmBrowseAct->setStatusTip(tr("Shows the RISC disassembly browser window")); -// memBrowseAct->setCheckable(true); connect(riscDasmBrowseAct, SIGNAL(triggered()), this, SLOT(ShowRISCDasmBrowserWin())); - if (vjs.softTypeDebugger) - { - VideoOutputAct = new QAction(tr("Output Video"), this); - VideoOutputAct->setStatusTip(tr("Shows the output video window")); - connect(VideoOutputAct, SIGNAL(triggered()), this, SLOT(ShowVideoOutputWin())); - - DasmAct = new QAction(tr("Disassembly"), this); - DasmAct->setStatusTip(tr("Shows the disassembly window")); - connect(DasmAct, SIGNAL(triggered()), this, SLOT(ShowDasmWin())); - } - // Misc. connections... connect(filePickWin, SIGNAL(RequestLoad(QString)), this, SLOT(LoadSoftware(QString))); connect(filePickWin, SIGNAL(FilePickerHiding()), this, SLOT(Unpause())); @@ -503,12 +525,27 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), fileMenu->addSeparator(); fileMenu->addAction(quitAppAct); + // Alpine and debugger menus if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger) { + // Create debug & view menu debugMenu = menuBar()->addMenu(tr("&Debug")); + viewMenu = menuBar()->addMenu(tr("&View")); + + // Create debugger menu if (vjs.softTypeDebugger) { + // Cart menu + viewCartMenu = viewMenu->addMenu(tr("&Cartridge")); + viewCartMenu->addAction(CartFilesListAct); +#if 0 + viewCartMenu->addSeparator(); + viewCartMenu->addAction(CartStreamsAct); +#endif + + // Windows menu debugWindowsMenu = debugMenu->addMenu(tr("&Windows")); + debugWindowsMenu->addAction(BreakpointsAct); debugWindowExceptionMenu = debugWindowsMenu->addMenu(tr("&Exception")); debugWindowExceptionMenu->addAction(exceptionVectorTableBrowseAct); debugWindowsMenu->addSeparator(); @@ -545,16 +582,19 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), debugMenu->addSeparator(); debugMenu->addAction(traceStepIntoAct); debugMenu->addAction(traceStepOverAct); -#if 0 debugMenu->addSeparator(); debugNewBreakpointMenu = debugMenu->addMenu(tr("&New Breakpoint")); - debugNewBreakpointMenu->addAction(newBreakpointFunctionAct); + debugNewBreakpointMenu->addAction(newFunctionBreakpointAct); + debugMenu->addAction(deleteAllBreakpointsAct); + debugMenu->addAction(disableAllBreakpointsAct); +#if 0 + debugMenu->addSeparator(); + debugMenu->addAction(DasmAct); #endif - //debugMenu->addSeparator(); - //debugMenu->addAction(DasmAct); } else { + // Create alpine menu debugMenu->addAction(memBrowseAct); debugMenu->addAction(stackBrowseAct); debugMenu->addAction(cpuBrowseAct); @@ -564,13 +604,14 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), } } + // Help menus helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(helpAct); helpMenu->addAction(aboutAct); // Create toolbars - toolbar = addToolBar(tr("Stuff")); + toolbar = addToolBar(tr("System")); toolbar->addAction(powerAct); if (!vjs.softTypeDebugger) { @@ -582,6 +623,8 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), toolbar->addSeparator(); if (!vjs.softTypeDebugger) { + toolbar->addAction(screenshotAct); + toolbar->addSeparator(); toolbar->addAction(x1Act); toolbar->addAction(x2Act); toolbar->addAction(x3Act); @@ -601,6 +644,8 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), debuggerbar->addSeparator(); debuggerbar->addAction(traceStepIntoAct); debuggerbar->addAction(traceStepOverAct); + debuggerbar->addSeparator(); + debuggerbar->addAction(BreakpointsAct); } if (vjs.hardwareTypeAlpine) @@ -1071,7 +1116,7 @@ static uint32_t ntscTickCount; // Otherwise, run the Jaguar simulation HandleGamepads(); JaguarExecuteNew(); - if (!vjs.softTypeDebugger) + //if (!vjs.softTypeDebugger) videoWidget->HandleMouseHiding(); static uint32_t refresh = 0; @@ -1081,7 +1126,7 @@ static uint32_t refresh = 0; { if (refresh == vjs.refresh) { - RefreshAlpineWindows(); + AlpineRefreshWindows(); //memBrowseWin->RefreshContents(); //cpuBrowseWin->RefreshContents(); refresh = 0; @@ -1126,6 +1171,7 @@ static uint32_t refresh = 0; } +// Toggle the power state, it can be either on or off void MainWin::TogglePowerState(void) { powerButtonOn = !powerButtonOn; @@ -1135,31 +1181,34 @@ void MainWin::TogglePowerState(void) if (!powerButtonOn) { // Restore the mouse pointer, if hidden: - if (!vjs.softTypeDebugger) + //if (!vjs.softTypeDebugger) + { videoWidget->CheckAndRestoreMouseCursor(); + } + useCDAct->setDisabled(false); palAct->setDisabled(false); ntscAct->setDisabled(false); pauseAct->setChecked(false); pauseAct->setDisabled(true); showUntunedTankCircuit = true; + DACPauseAudioThread(); - // This is just in case the ROM we were playing was in a narrow or wide - // field mode, so the untuned tank sim doesn't look wrong. :-) + // This is just in case the ROM we were playing was in a narrow or wide field mode, so the untuned tank sim doesn't look wrong. :-) TOMReset(); if (plzDontKillMyComputer) { - //if (!vjs.softTypeDebugger) + // We have to do it line by line, because the texture pitch is not the same as the picture buffer's pitch. + for (uint32_t y = 0; y < videoWidget->rasterHeight; y++) { - // We have to do it line by line, because the texture pitch is not - // the same as the picture buffer's pitch. - for (uint32_t y = 0; y < videoWidget->rasterHeight; y++) + if (vjs.hardwareTypeNTSC) { - if (vjs.hardwareTypeNTSC) - memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t)); - else - memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern2 + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t)); + memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t)); + } + else + { + memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern2 + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t)); } } } @@ -1186,19 +1235,23 @@ void MainWin::TogglePowerState(void) WriteLog("GUI: Resetting Jaguar...\n"); JaguarReset(); + DebuggerReset(); DebuggerResetWindows(); DACPauseAudioThread(false); } } +// Toggle the emulator state, it can be either on or off void MainWin::ToggleRunState(void) { startM68KTracing = running; running = !running; + // Pause mode if (!running) { + // Set action buttons for the pause mode frameAdvanceAct->setDisabled(false); pauseAct->setChecked(true); pauseAct->setDisabled(false); @@ -1216,7 +1269,6 @@ void MainWin::ToggleRunState(void) { // Restore the mouse pointer, if hidden: videoWidget->CheckAndRestoreMouseCursor(); - // frameAdvanceAct->setDisabled(false); for (uint32_t i = 0; i < (uint32_t)(videoWidget->textureWidth * 256); i++) { @@ -1243,6 +1295,7 @@ void MainWin::ToggleRunState(void) traceStepIntoAct->setDisabled(true); traceStepOverAct->setDisabled(true); restartAct->setDisabled(true); + BreakpointsWin->RefreshContents(); } cpuBrowseWin->UnholdBPM(); @@ -1355,6 +1408,7 @@ void MainWin::LoadSoftware(QString file) running = false; // Prevent bad things(TM) from happening... pauseForFileSelector = false; // Reset the file selector pause flag + // Setup BIOS in his own dedicated Jaguar memory #ifndef NEWMODELSBIOSHANDLER uint8_t * biosPointer = jaguarBootROM; @@ -1368,6 +1422,7 @@ void MainWin::LoadSoftware(QString file) SelectBIOS(vjs.biosType); #endif + // Turn 'on' the power to initialize the Jaguar powerAct->setDisabled(false); powerAct->setChecked(true); powerButtonOn = false; @@ -1375,7 +1430,7 @@ void MainWin::LoadSoftware(QString file) // We have to load our software *after* the Jaguar RESET cartridgeLoaded = JaguarLoadFile(file.toUtf8().data()); - SET32(jaguarMainRAM, 0, vjs.DRAM_size); // Set top of stack... + SET32(jaguarMainRAM, 0, vjs.DRAM_size); // Set stack in the M68000's Reset SP // This is icky because we've already done it // it gets worse :-P @@ -1398,8 +1453,8 @@ void MainWin::LoadSoftware(QString file) } else { - // Prevent the Alpine mode to crash in case of software without a start address - if (vjs.hardwareTypeAlpine && !jaguarRunAddress) + // Prevent the launch in case of software without a start address and without BIOS presence + if (!vjs.useJaguarBIOS && !jaguarRunAddress) { ToggleRunState(); } @@ -1425,11 +1480,45 @@ void MainWin::ToggleCDUsage(void) } -// -void MainWin::NewBreakpointFunction(void) +// Open, or display, the breakpoints list window +void MainWin::ShowBreakpointsWin(void) +{ + BreakpointsWin->show(); + BreakpointsWin->RefreshContents(); +} + + +// Delete all breakpoints +void MainWin::DeleteAllBreakpoints(void) +{ + cpuBrowseWin->ResetBPM(); + m68k_brk_reset(); + ShowBreakpointsWin(); +} + + +// Disable all breakpoints +void MainWin::DisableAllBreakpoints(void) +{ + cpuBrowseWin->DisableBPM(); + m68k_brk_disable(); + ShowBreakpointsWin(); +} + + +// Open, or display, the new breakpoint function window +void MainWin::ShowNewFunctionBreakpointWin(void) +{ + NewFunctionBreakpointWin->show(); + ShowBreakpointsWin(); +} + + +// +void MainWin::ShowCartFilesListWin(void) { - brkWin->show(); - brkWin->RefreshContents(); + CartFilesListWin->show(); + CartFilesListWin->RefreshContents(); } @@ -1447,7 +1536,7 @@ void MainWin::DebuggerTraceStepInto(void) } -// Restart +// Restart the Jaguar executable void MainWin::DebuggerRestart(void) { #if 1 @@ -1457,7 +1546,8 @@ void MainWin::DebuggerRestart(void) m68k_set_reg(M68K_REG_SP, vjs.DRAM_size); #endif m68k_set_reg(M68K_REG_A6, 0); - + m68k_brk_hitcounts_reset(); + bpmHitCounts = 0; DebuggerResetWindows(); DebuggerRefreshWindows(); #ifdef _MSC_VER @@ -1662,13 +1752,18 @@ void MainWin::ShowRISCDasmBrowserWin(void) } +// +#if 0 void MainWin::ShowDasmWin(void) { - DasmWin->show(); +// DasmWin->show(); // DasmWin->RefreshContents(); } +#endif +// +#if 0 void MainWin::ShowVideoOutputWin(void) { //VideoOutputWindowCentrale = mainWindowCentrale->addSubWindow(videoWidget); @@ -1678,14 +1773,16 @@ void MainWin::ShowVideoOutputWin(void) //VideoOutputWin->show(); //VideoOutputWin->RefreshContents(videoWidget); } +#endif +// Resize video window based on zoom factor +// It doesn't apply in debugger mode as we use this window to display disassembly void MainWin::ResizeMainWindow(void) { if (!vjs.softTypeDebugger) { - videoWidget->setFixedSize(zoomLevel * VIRTUAL_SCREEN_WIDTH, - zoomLevel * (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL)); + videoWidget->setFixedSize(zoomLevel * VIRTUAL_SCREEN_WIDTH, zoomLevel * (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL)); // Show the test pattern if user requested plzDontKillMyComputer mode if (!powerButtonOn && plzDontKillMyComputer) @@ -1693,9 +1790,13 @@ void MainWin::ResizeMainWindow(void) for (uint32_t y = 0; y < videoWidget->rasterHeight; y++) { if (vjs.hardwareTypeNTSC) + { memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t)); + } else + { memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern2 + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t)); + } } } @@ -1735,10 +1836,12 @@ void MainWin::ReadSettings(void) vjs.useFastBlitter = settings.value("useFastBlitter", false).toBool(); strcpy(vjs.EEPROMPath, settings.value("EEPROMs", QStandardPaths::writableLocation(QStandardPaths::DataLocation).append("/eeproms/")).toString().toUtf8().data()); strcpy(vjs.ROMPath, settings.value("ROMs", QStandardPaths::writableLocation(QStandardPaths::DataLocation).append("/software/")).toString().toUtf8().data()); + strcpy(vjs.screenshotPath, settings.value("Screenshots", QStandardPaths::writableLocation(QStandardPaths::DataLocation).append("/screenshots/")).toString().toUtf8().data()); // Read settings from the Debugger mode settings.beginGroup("debugger"); strcpy(vjs.debuggerROMPath, settings.value("DefaultROM", "").toString().toUtf8().data()); + strcpy(vjs.sourcefilesearchPaths, settings.value("SourceFileSearchPaths", "").toString().toUtf8().data()); vjs.nbrdisasmlines = settings.value("NbrDisasmLines", 32).toUInt(); vjs.disasmopcodes = settings.value("DisasmOpcodes", true).toBool(); vjs.displayHWlabels = settings.value("DisplayHWLabels", true).toBool(); @@ -1764,12 +1867,15 @@ void MainWin::ReadSettings(void) // Write important settings to the log file WriteLog("MainWin: Paths\n"); - WriteLog(" EEPROMPath = \"%s\"\n", vjs.EEPROMPath); - WriteLog(" ROMPath = \"%s\"\n", vjs.ROMPath); - WriteLog(" AlpineROMPath = \"%s\"\n", vjs.alpineROMPath); - WriteLog("DebuggerROMPath = \"%s\"\n", vjs.debuggerROMPath); - WriteLog(" absROMPath = \"%s\"\n", vjs.absROMPath); - WriteLog(" Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off")); + WriteLog(" EEPROMPath = \"%s\"\n", vjs.EEPROMPath); + WriteLog(" ROMPath = \"%s\"\n", vjs.ROMPath); + WriteLog(" AlpineROMPath = \"%s\"\n", vjs.alpineROMPath); + WriteLog(" DebuggerROMPath = \"%s\"\n", vjs.debuggerROMPath); + WriteLog(" absROMPath = \"%s\"\n", vjs.absROMPath); + WriteLog(" ScreenshotsPath = \"%s\"\n", vjs.screenshotPath); + WriteLog("SourceFileSearchPaths = \"%s\"\n", vjs.sourcefilesearchPaths); + WriteLog("MainWin: Misc.\n"); + WriteLog(" Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off")); #if 0 // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, * @@ -1821,6 +1927,7 @@ void MainWin::ReadSettings(void) WriteLog("Read setting = Done\n"); ReadProfiles(&settings); + DBGManager_SourceFileSearchPathsSet(vjs.sourcefilesearchPaths); } @@ -1949,6 +2056,26 @@ void MainWin::ReadUISettings(void) size = settings.value("CallStackBrowseWinSize", QSize(400, 400)).toSize(); CallStackBrowseWin->resize(size); + // Cartdridge directory and files + pos = settings.value("CartFilesListWinPos", QPoint(200, 200)).toPoint(); + CartFilesListWin->move(pos); + settings.value("CartFilesListWinIsVisible", false).toBool() ? ShowCartFilesListWin() : void(); + size = settings.value("CartFilesListWinSize", QSize(400, 400)).toSize(); + CartFilesListWin->resize(size); + + // Breakpoints UI information + pos = settings.value("BreakpointsWinPos", QPoint(200, 200)).toPoint(); + BreakpointsWin->move(pos); + settings.value("BreakpointsWinIsVisible", false).toBool() ? ShowBreakpointsWin() : void(); + size = settings.value("BreakpointsWinSize", QSize(400, 400)).toSize(); + BreakpointsWin->resize(size); + // New function breakpoint UI information + pos = settings.value("NewFunctionBreakpointWinPos", QPoint(200, 200)).toPoint(); + NewFunctionBreakpointWin->move(pos); + settings.value("NewFunctionBreakpointWinIsVisible", false).toBool() ? ShowNewFunctionBreakpointWin() : void(); + size = settings.value("NewFunctionBreakpointWinSize", QSize(400, 400)).toSize(); + NewFunctionBreakpointWin->resize(size); + // Memories browser UI information for (i = 0; i < vjs.nbrmemory1browserwindow; i++) { @@ -2002,10 +2129,11 @@ void MainWin::WriteSettings(void) settings.setValue("jaguarModel", vjs.jaguarModel); settings.setValue("biosType", vjs.biosType); settings.setValue("useFastBlitter", vjs.useFastBlitter); - settings.setValue("JagBootROM", vjs.jagBootPath); - settings.setValue("CDBootROM", vjs.CDBootPath); + //settings.setValue("JagBootROM", vjs.jagBootPath); + //settings.setValue("CDBootROM", vjs.CDBootPath); settings.setValue("EEPROMs", vjs.EEPROMPath); settings.setValue("ROMs", vjs.ROMPath); + settings.setValue("Screenshots", vjs.screenshotPath); // Write settings from the Alpine mode settings.beginGroup("alpine"); @@ -2023,6 +2151,7 @@ void MainWin::WriteSettings(void) settings.setValue("displayFullSourceFilename", vjs.displayFullSourceFilename); settings.setValue("NbrMemory1BrowserWindow", (unsigned int)vjs.nbrmemory1browserwindow); settings.setValue("DefaultROM", vjs.debuggerROMPath); + settings.setValue("SourceFileSearchPaths", vjs.sourcefilesearchPaths); settings.endGroup(); // Write settings from the Keybindings @@ -2080,6 +2209,7 @@ void MainWin::WriteSettings(void) #endif WriteProfiles(&settings); + DBGManager_SourceFileSearchPathsSet(vjs.sourcefilesearchPaths); } @@ -2146,6 +2276,16 @@ void MainWin::WriteUISettings(void) settings.setValue("CallStackBrowseWinPos", CallStackBrowseWin->pos()); settings.setValue("CallStackBrowseWinIsVisible", CallStackBrowseWin->isVisible()); settings.setValue("CallStackBrowseWinSize", CallStackBrowseWin->size()); + settings.setValue("BreakpointsWinPos", BreakpointsWin->pos()); + settings.setValue("BreakpointsWinIsVisible", BreakpointsWin->isVisible()); + settings.setValue("BreakpointsWinSize", BreakpointsWin->size()); + settings.setValue("NewFunctionBreakpointWinPos", NewFunctionBreakpointWin->pos()); + settings.setValue("NewFunctionBreakpointWinIsVisible", NewFunctionBreakpointWin->isVisible()); + settings.setValue("NewFunctionBreakpointWinSize", NewFunctionBreakpointWin->size()); + settings.setValue("CartFilesListWinPos", CartFilesListWin->pos()); + settings.setValue("CartFilesListWinIsVisible", CartFilesListWin->isVisible()); + settings.setValue("CartFilesListWinSize", CartFilesListWin->size()); + for (i = 0; i < vjs.nbrmemory1browserwindow; i++) { sprintf(mem1Name, "mem1BrowseWinPos[%i]", (unsigned int)i); @@ -2162,7 +2302,7 @@ void MainWin::WriteUISettings(void) // Refresh alpine debug windows -void MainWin::RefreshAlpineWindows(void) +void MainWin::AlpineRefreshWindows(void) { cpuBrowseWin->RefreshContents(); memBrowseWin->RefreshContents(); @@ -2174,26 +2314,44 @@ void MainWin::RefreshAlpineWindows(void) } +// Reset soft debugger +void MainWin::DebuggerReset(void) +{ + if (vjs.softTypeDebugger) + { + DeleteAllBreakpoints(); + } +} + + // Reset soft debugger windows void MainWin::DebuggerResetWindows(void) { if (vjs.softTypeDebugger) { + FilesrcListWin->Reset(); allWatchBrowseWin->Reset(); heapallocatorBrowseWin->Reset(); - + BreakpointsWin->Reset(); + CartFilesListWin->Reset(); //ResetAlpineWindows(); } } +// Refresh view windows +void MainWin::ViewRefreshWindows(void) +{ + CartFilesListWin->RefreshContents(); +} + + // Refresh soft debugger & alpine debug windows void MainWin::DebuggerRefreshWindows(void) { - size_t i; - if (vjs.softTypeDebugger) { + FilesrcListWin->RefreshContents(); m68kDasmWin->RefreshContents(); GPUDasmWin->RefreshContents(); DSPDasmWin->RefreshContents(); @@ -2201,11 +2359,32 @@ void MainWin::DebuggerRefreshWindows(void) LocalBrowseWin->RefreshContents(); CallStackBrowseWin->RefreshContents(); heapallocatorBrowseWin->RefreshContents(); - for (i = 0; i < vjs.nbrmemory1browserwindow; i++) + BreakpointsWin->RefreshContents(); + for (size_t i = 0; i < vjs.nbrmemory1browserwindow; i++) { mem1BrowseWin[i]->RefreshContents(i); } - RefreshAlpineWindows(); + AlpineRefreshWindows(); + ViewRefreshWindows(); } } + + +// Create and save screenshot +void MainWin::MakeScreenshot(void) +{ + char Text[256]; + QImage screenshot; + time_t now = time(0); + struct tm tstruct; + + // Create filename + tstruct = *localtime(&now); + sprintf(Text, "%svj_%i%i%i_%i%i%i.jpg", vjs.screenshotPath, tstruct.tm_year, tstruct.tm_mon, tstruct.tm_mday, tstruct.tm_hour, tstruct.tm_min, tstruct.tm_sec); + + // Create screenshot + screenshot = videoWidget->grabFrameBuffer(); + screenshot.save((char *)Text, "JPG", 100); +} +