-//
-// mainwin.cpp - Qt-based GUI for Virtual Jaguar: Main Application Window
-// by James Hammons
-// (C) 2009 Underground Software
-//
-// JLH = James Hammons <jlhamm@acm.org>
-// JPM = Jean-Paul Mari <djipi.mari@gmail.com>
-//
-// Who When What
-// --- ---------- ------------------------------------------------------------
-// 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 01/11/2017 Added stack browser
-// JPM 01/02/2017 Added GPU disassembly
-// JPM 02/02/2017 Added DSP disassembly
-// JPM 07/12/2017 Added all Watch browser window
-// JPM 08/01/2017 Added heap allocator browser window
-// JPM 08/07/2017 Added memories window browser
-// JPM 08/10/2017 Added a restart feature
-// JPM 08/31/2017 Added breakpoints winndow
-// 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
-//
-
-// FIXED:
-//
-// - Add dbl click/enter to select in cart list, ESC to dimiss [DONE]
-// - Autoscan/autoload all available BIOS from 'software' folder [DONE]
-// - Add 1 key jumping in cartridge list (press 'R', jumps to carts starting
-// with 'R', etc) [DONE]
-// - Controller configuration [DONE]
-//
-// STILL TO BE DONE:
-//
-// - Fix bug in switching between PAL & NTSC in fullscreen mode.
-// - Remove SDL dependencies (sound, mainly) from Jaguar core lib
-// - Fix inconsistency with trailing slashes in paths (eeproms needs one,
-// software doesn't)
-//
-// SFDX CODE: S1E9T8H5M23YS
-
-// Uncomment this for debugging...
-//#define DEBUG
-//#define DEBUGFOO // Various tool debugging... but not used
-//#define DEBUGTP // Toolpalette debugging... but not used
-
-#include "mainwin.h"
-
-#include "SDL.h"
-#include "app.h"
-#include "about.h"
-#include "configdialog.h"
-#include "controllertab.h"
-#include "keybindingstab.h"
-#include "filepicker.h"
-#include "gamepad.h"
-#include "generaltab.h"
-#include "glwidget.h"
-#include "help.h"
-#include "profile.h"
-#include "settings.h"
-#include "version.h"
-#include "emustatus.h"
-#include "debug/cpubrowser.h"
-#include "debug/m68kdasmbrowser.h"
-#include "debug/memorybrowser.h"
-#include "debug/stackbrowser.h"
-#include "debug/opbrowser.h"
-#include "debug/riscdasmbrowser.h"
-
-#include "debugger/allwatchbrowser.h"
-#include "debugger/heapallocatorbrowser.h"
-
-#include "dac.h"
-#include "jaguar.h"
-#include "log.h"
-#include "file.h"
-#include "jagbios.h"
-#include "jagbios2.h"
-#include "jagcdbios.h"
-#include "jagstub2bios.h"
-#include "joystick.h"
-#include "m68000/m68kinterface.h"
-
-#include "debugger/VideoWin.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/exceptionvectortablebrowser.h"
-
-// According to SebRmv, this header isn't seen on Arch Linux either... :-/
-//#ifdef __GCCWIN32__
-// Apparently on win32, usleep() is not pulled in by the usual suspects.
-#ifndef _MSC_VER
-#include <unistd.h>
-#else
-#include "_MSC_VER/unistd.h"
-#endif // !_MSC_VER
-//#endif
-
-// The way BSNES controls things is by setting a timer with a zero
-// timeout, sleeping if not emulating anything. Seems there has to be a
-// better way.
-
-// It has a novel approach to plugging-in/using different video/audio/input
-// methods, can we do something similar or should we just use the built-in
-// QOpenGL?
-
-// We're going to try to use the built-in OpenGL support and see how it goes.
-// We'll make the VJ core modular so that it doesn't matter what GUI is in
-// use, we can drop it in anywhere and use it as-is.
-
-MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
- showUntunedTankCircuit(true), cartridgeLoaded(false), CDActive(false),
- pauseForFileSelector(false), loadAndGo(autoRun), scannedSoftwareFolder(false), plzDontKillMyComputer(false)
-{
- ReadSettings();
-
- debugbar = NULL;
-
- for(int i=0; i<8; i++)
- keyHeld[i] = false;
-
- // FPS management
- for(int i=0; i<RING_BUFFER_SIZE; i++)
- ringBuffer[i] = 0;
-
- ringBufferPointer = RING_BUFFER_SIZE - 1;
-
- // main window
- //if (vjs.softTypeDebugger)
- //{
- // mainWindowCentrale = new QMdiArea;
- // setCentralWidget(mainWindowCentrale);
- //}
-
- // video output
- videoWidget = new GLWidget(this);
- videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
- // set central output window
- if (!vjs.softTypeDebugger)
- {
- setCentralWidget(videoWidget);
- }
- else
- {
- mainWindowCentrale = new QMdiArea(this);
- setCentralWidget(mainWindowCentrale);
- }
-
- setWindowIcon(QIcon(":/res/vj-icon.png"));
-
- QString title = QString(tr("Virtual Jaguar " VJ_RELEASE_VERSION " Rx"));
-
- if (vjs.hardwareTypeAlpine)
- title += QString(tr(" - Alpine Mode"));
-
- if (vjs.softTypeDebugger)
- title += QString(tr(" - Debugger Mode"));
-
- setWindowTitle(title);
-
- aboutWin = new AboutWindow(this);
- helpWin = new HelpWindow(this);
- filePickWin = new FilePickerWindow(this);
- memBrowseWin = new MemoryBrowserWindow(this);
- stackBrowseWin = new StackBrowserWindow(this);
- emuStatusWin = new EmuStatusWindow(this);
- cpuBrowseWin = new CPUBrowserWindow(this);
- opBrowseWin = new OPBrowserWindow(this);
- m68kDasmBrowseWin = new M68KDasmBrowserWindow(this);
- riscDasmBrowseWin = new RISCDasmBrowserWindow(this);
- if (vjs.softTypeDebugger)
- {
- VideoOutputWin = new VideoOutputWindow(this);
- //VideoOutputWin->setCentralWidget()
- //DasmWin = new DasmWindow();
- DasmWin = new DasmWindow(this);
- allWatchBrowseWin = new AllWatchBrowserWindow(this);
- heapallocatorBrowseWin = new HeapAllocatorBrowserWindow(this);
- brkWin = new BrkWindow(this);
- exceptionvectortableBrowseWin = new ExceptionVectorTableBrowserWindow(this);
-
- mem1BrowseWin = (Memory1BrowserWindow **)calloc(vjs.nbrmemory1browserwindow, sizeof(Memory1BrowserWindow));
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to do the memory desalocation for mem1BrowseWin !!!")
-#else
- #warning "!!! Need to do the memory desalocation for mem1BrowseWin !!!"
-#endif // _MSC_VER
- for (size_t i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- mem1BrowseWin[i] = new Memory1BrowserWindow(this);
- }
-
- dasmtabWidget = new QTabWidget(this);
- 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"));
- 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
- }
-
-// videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
- setUnifiedTitleAndToolBarOnMac(true);
-
- // Create actions
-
- quitAppAct = new QAction(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()));
-
- 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()));
-
- QIcon pauseIcon;
- pauseIcon.addFile(":/res/pause-off", QSize(), QIcon::Normal, QIcon::Off);
- pauseIcon.addFile(":/res/pause-on", QSize(), QIcon::Normal, QIcon::On);
- pauseAct = new QAction(pauseIcon, tr("Pause"), this);
- 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);
-
- 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()));
-
- 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.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()));
-
- aboutAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&About..."), this);
- aboutAct->setStatusTip(tr("Blatant self-promotion"));
- connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin()));
-
- 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()));
-
- if (!vjs.softTypeDebugger)
- {
- filePickAct = new QAction(QIcon(":/res/software.png"), tr("&Insert Cartridge..."), this);
- filePickAct->setStatusTip(tr("Insert a cartridge into Virtual Jaguar"));
- }
- else
- {
- 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()));
-
- 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()));
-
- emustatusAct = new QAction(QIcon(""), 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()));
-
- 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()));
-
- 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()));
-
- if (vjs.softTypeDebugger)
- {
- restartAct = new QAction(QIcon(":/res/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(Restart()));
-
- traceStepOverAct = new QAction(QIcon(":/res/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(TraceStepOver()));
-
- traceStepIntoAct = new QAction(QIcon(":/res/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(TraceStepInto()));
-
- 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)
- {
- 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()));
-
- allWatchBrowseAct = new QAction(QIcon(":/res/Watch.png"), tr("All Watch"), this);
- allWatchBrowseAct->setStatusTip(tr("Shows all Watch browser window"));
- connect(allWatchBrowseAct, SIGNAL(triggered()), this, SLOT(ShowAllWatchBrowserWin()));
-
- heapallocatorBrowseAct = new QAction(QIcon(""), tr("Heap allocator"), this);
- heapallocatorBrowseAct->setStatusTip(tr("Shows the heap allocator browser window"));
- connect(heapallocatorBrowseAct, SIGNAL(triggered()), this, SLOT(ShowHeapAllocatorBrowserWin()));
-
- mem1BrowseAct = (QAction **)calloc(vjs.nbrmemory1browserwindow, sizeof(QAction));
- QSignalMapper *signalMapper = new QSignalMapper(this);
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to do the memory desalocation for mem1BrowseAct !!!")
-#else
-#warning "!!! Need to do the memory desalocation for mem1BrowseAct !!!"
-#endif // _MSC_VER
- for (int i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- char MB[100];
- sprintf(MB, "Memory %i", (unsigned int)(i+1));
- mem1BrowseAct[i] = new QAction(QIcon(":/res/tool-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
- 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()));
-
- 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()));
-
- 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()));
-
- 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()));
-
- 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()));
-
- 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()));
-
- // Create menus
-
- fileMenu = menuBar()->addMenu(tr("&Jaguar"));
- fileMenu->addAction(powerAct);
- if (!vjs.softTypeDebugger)
- {
- fileMenu->addAction(pauseAct);
- // fileMenu->addAction(frameAdvanceAct);
- }
- fileMenu->addAction(filePickAct);
- fileMenu->addAction(useCDAct);
- fileMenu->addAction(configAct);
- fileMenu->addAction(emustatusAct);
- fileMenu->addSeparator();
- fileMenu->addAction(quitAppAct);
-
- if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)
- {
- debugMenu = menuBar()->addMenu(tr("&Debug"));
- if (vjs.softTypeDebugger)
- {
- debugWindowsMenu = debugMenu->addMenu(tr("&Windows"));
- debugWindowExceptionMenu = debugWindowsMenu->addMenu(tr("&Exception"));
- debugWindowExceptionMenu->addAction(exceptionVectorTableBrowseAct);
- debugWindowsMenu->addSeparator();
-#if 0
- debugWindowOutputMenu = debugWindowsMenu->addMenu(tr("&Output"));
- debugWindowOutputMenu->addAction(VideoOutputAct);
- debugWindowsMenu->addSeparator();
-#endif
- debugWindowsWatchMenu = debugWindowsMenu->addMenu(tr("&Watch"));
- debugWindowsWatchMenu->addAction(allWatchBrowseAct);
- debugWindowsMenu->addSeparator();
- debugWindowsMemoryMenu = debugWindowsMenu->addMenu(tr("&Memory"));
- debugWindowsMemoryMenu->addAction(heapallocatorBrowseAct);
- debugWindowsMemoryMenu->addSeparator();
- for (int i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- debugWindowsMemoryMenu->addAction(mem1BrowseAct[i]);
- }
- debugWindowsMenu->addSeparator();
- debugWindowsBrowsesMenu = debugWindowsMenu->addMenu(tr("&Browsers"));
- debugWindowsBrowsesMenu->addAction(memBrowseAct);
- debugWindowsBrowsesMenu->addAction(stackBrowseAct);
- debugWindowsBrowsesMenu->addAction(cpuBrowseAct);
- debugWindowsBrowsesMenu->addAction(opBrowseAct);
- debugWindowsBrowsesMenu->addAction(m68kDasmBrowseAct);
- debugWindowsBrowsesMenu->addAction(riscDasmBrowseAct);
- debugMenu->addSeparator();
- debugMenu->addAction(pauseAct);
- debugMenu->addAction(frameAdvanceAct);
- debugMenu->addAction(restartAct);
- debugMenu->addSeparator();
- debugMenu->addAction(traceStepIntoAct);
- debugMenu->addAction(traceStepOverAct);
-#if 0
- debugMenu->addSeparator();
- debugNewBreakpointMenu = debugMenu->addMenu(tr("&New Breakpoint"));
- debugNewBreakpointMenu->addAction(newBreakpointFunctionAct);
-#endif
- //debugMenu->addSeparator();
- //debugMenu->addAction(DasmAct);
- }
- else
- {
- debugMenu->addAction(memBrowseAct);
- debugMenu->addAction(stackBrowseAct);
- debugMenu->addAction(cpuBrowseAct);
- debugMenu->addAction(opBrowseAct);
- debugMenu->addAction(m68kDasmBrowseAct);
- debugMenu->addAction(riscDasmBrowseAct);
- }
- }
-
- helpMenu = menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(helpAct);
- helpMenu->addAction(aboutAct);
-
- // Create toolbars
-
- toolbar = addToolBar(tr("Stuff"));
- toolbar->addAction(powerAct);
- if (!vjs.softTypeDebugger)
- {
- toolbar->addAction(pauseAct);
- toolbar->addAction(frameAdvanceAct);
- }
- toolbar->addAction(filePickAct);
- toolbar->addAction(useCDAct);
- toolbar->addSeparator();
- if (!vjs.softTypeDebugger)
- {
- toolbar->addAction(x1Act);
- toolbar->addAction(x2Act);
- toolbar->addAction(x3Act);
- toolbar->addSeparator();
- toolbar->addAction(ntscAct);
- toolbar->addAction(palAct);
- toolbar->addSeparator();
- toolbar->addAction(blurAct);
- toolbar->addAction(fullScreenAct);
- }
- else
- {
- debuggerbar = addToolBar(tr("&Debugger"));
- debuggerbar->addAction(pauseAct);
- debuggerbar->addAction(frameAdvanceAct);
- debuggerbar->addAction(restartAct);
- debuggerbar->addSeparator();
- debuggerbar->addAction(traceStepIntoAct);
- debuggerbar->addAction(traceStepOverAct);
- }
-
- if (vjs.hardwareTypeAlpine)
- {
- debugbar = addToolBar(tr("&Debug"));
- debugbar->addAction(memBrowseAct);
- debugbar->addAction(stackBrowseAct);
- debugbar->addAction(cpuBrowseAct);
- debugbar->addAction(opBrowseAct);
- debugbar->addAction(m68kDasmBrowseAct);
- debugbar->addAction(riscDasmBrowseAct);
- }
-
- // Add actions to the main window, as hiding widgets with them
- // disables them :-P
- addAction(fullScreenAct);
- addAction(quitAppAct);
- addAction(configAct);
- addAction(emustatusAct);
- addAction(pauseAct);
- addAction(filePickAct);
- addAction(frameAdvanceAct);
-
- // Create status bar
- statusBar()->showMessage(tr("Ready"));
- ReadUISettings();
- // Do this in case original size isn't correct (mostly for the first-run case)
- ResizeMainWindow();
-
- // Create our test pattern bitmaps
- QImage tempImg(":/res/test-pattern.jpg");
- QImage tempImgScaled = tempImg.scaled(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT_PAL, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
-
- for(uint32_t y=0; y<VIRTUAL_SCREEN_HEIGHT_PAL; y++)
- {
- const QRgb * scanline = (QRgb *)tempImgScaled.constScanLine(y);
-
- for(uint32_t x=0; x<VIRTUAL_SCREEN_WIDTH; x++)
- {
- uint32_t pixel = (qRed(scanline[x]) << 24) | (qGreen(scanline[x]) << 16) | (qBlue(scanline[x]) << 8) | 0xFF;
- testPattern[(y * VIRTUAL_SCREEN_WIDTH) + x] = pixel;
- }
- }
-
- QImage tempImg2(":/res/test-pattern-pal");
- QImage tempImgScaled2 = tempImg2.scaled(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT_PAL, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
-
- for(uint32_t y=0; y<VIRTUAL_SCREEN_HEIGHT_PAL; y++)
- {
- const QRgb * scanline = (QRgb *)tempImgScaled2.constScanLine(y);
-
- for(uint32_t x=0; x<VIRTUAL_SCREEN_WIDTH; x++)
- {
- uint32_t pixel = (qRed(scanline[x]) << 24) | (qGreen(scanline[x]) << 16) | (qBlue(scanline[x]) << 8) | 0xFF;
- testPattern2[(y * VIRTUAL_SCREEN_WIDTH) + x] = pixel;
- }
- }
-
- // Set up timer based loop for animation...
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(Timer()));
-
- // This isn't very accurate for NTSC: This is early by 40 msec per frame.
- // This is because it's discarding the 0.6666... on the end of the fraction.
- // Alas, 6 doesn't divide cleanly into 10. :-P
-//Should we defer this until SyncUI? Probably.
-//No, it doesn't work, because it uses setInterval() instead of start()...
-// timer->start(vjs.hardwareTypeNTSC ? 16 : 20);
-
- // We set this initially, to make VJ behave somewhat as it would if no
- // cart were inserted and the BIOS was set as active...
- jaguarCartInserted = true;
- WriteLog("Virtual Jaguar %s Rx (Last full build was on %s %s)\n", VJ_RELEASE_VERSION, __DATE__, __TIME__);
- WriteLog("VJ: Initializing jaguar subsystem...\n");
- JaguarInit();
-// memcpy(jagMemSpace + 0xE00000, jaguarBootROM, 0x20000); // Use the stock BIOS
- memcpy(jagMemSpace + 0xE00000, (vjs.biosType == BT_K_SERIES ? jaguarBootROM : jaguarBootROM2), 0x20000); // Use the stock BIOS
-
- // Prevent the file scanner from running if filename passed
- // in on the command line...
- if (autoRun)
- return;
-
- // Load up the default ROM if in Alpine mode:
- if (vjs.hardwareTypeAlpine)
- {
- bool romLoaded = JaguarLoadFile(vjs.alpineROMPath);
-
- // If regular load failed, try just a straight file load
- // (Dev only! I don't want people to start getting lazy with their releases again! :-P)
- if (!romLoaded)
- romLoaded = AlpineLoadFile(vjs.alpineROMPath);
-
- if (romLoaded)
- WriteLog("Alpine Mode: Successfully loaded file \"%s\".\n", vjs.alpineROMPath);
- else
- WriteLog("Alpine Mode: Unable to load file \"%s\"!\n", vjs.alpineROMPath);
-
- // Attempt to load/run the ABS file...
- LoadSoftware(vjs.absROMPath);
- memcpy(jagMemSpace + 0xE00000, jaguarDevBootROM2, 0x20000); // Use the stub BIOS
- // Prevent the scanner from running...
- return;
- }
-
- // Load up the default ROM if in Debugger mode:
- if (vjs.softTypeDebugger)
- {
- bool romLoaded = JaguarLoadFile(vjs.debuggerROMPath);
-
- // If regular load failed, try just a straight file load
- // (Dev only! I don't want people to start getting lazy with their releases again! :-P)
- if (!romLoaded)
- romLoaded = DebuggerLoadFile(vjs.debuggerROMPath);
-
- if (romLoaded)
- WriteLog("Debugger Mode: Successfully loaded file \"%s\".\n", vjs.debuggerROMPath);
- else
- WriteLog("Debugger Mode: Unable to load file \"%s\"!\n", vjs.debuggerROMPath);
-
- // Attempt to load/run the ABS file...
- LoadSoftware(vjs.absROMPath);
- memcpy(jagMemSpace + 0xE00000, jaguarDevBootROM2, 0x20000); // Use the stub BIOS
- // Prevent the scanner from running...
- return;
- }
-
- // Run the scanner if nothing passed in and *not* Alpine mode...
- // NB: Really need to look into caching the info scanned in here...
- filePickWin->ScanSoftwareFolder(allowUnknownSoftware);
- scannedSoftwareFolder = true;
-}
-
-
-void MainWin::LoadFile(QString file)
-{
- LoadSoftware(file);
-}
-
-
-void MainWin::SyncUI(void)
-{
- // Set toolbar buttons/menus based on settings read in (sync the UI)...
- // (Really, this is to sync command line options passed in)
- blurAct->setChecked(vjs.glFilter);
- x1Act->setChecked(zoomLevel == 1);
- x2Act->setChecked(zoomLevel == 2);
- x3Act->setChecked(zoomLevel == 3);
-// running = powerAct->isChecked();
- ntscAct->setChecked(vjs.hardwareTypeNTSC);
- palAct->setChecked(!vjs.hardwareTypeNTSC);
- powerAct->setIcon(vjs.hardwareTypeNTSC ? powerRed : powerGreen);
-
- fullScreenAct->setChecked(vjs.fullscreen);
- fullScreen = vjs.fullscreen;
- SetFullScreen(fullScreen);
-
- // Reset the timer to be what was set in the command line (if any):
-// timer->setInterval(vjs.hardwareTypeNTSC ? 16 : 20);
- timer->start(vjs.hardwareTypeNTSC ? 16 : 20);
-}
-
-
-void MainWin::closeEvent(QCloseEvent * event)
-{
- JaguarDone();
-// This should only be done by the config dialog
-// WriteSettings();
- WriteUISettings();
- event->accept(); // ignore() if can't close for some reason
-}
-
-
-void MainWin::keyPressEvent(QKeyEvent * e)
-{
-#ifndef VJ_REMOVE_DEV_CODE
- // From jaguar.cpp
- //extern bool startM68KTracing; // moved to jaguar.h
- // From joystick.cpp
- extern int blit_start_log;
- // From blitter.cpp
- extern bool startConciseBlitLogging;
-#endif
-
- // We ignore the Alt key for now, since it causes problems with the GUI
- if (e->key() == Qt::Key_Alt)
- {
- e->accept();
- return;
- }
-// Bar this shite from release versions kthxbai
-#ifndef VJ_REMOVE_DEV_CODE
- else if (e->key() == Qt::Key_F11)
- {
- startM68KTracing = true;
- e->accept();
- return;
- }
- else if (e->key() == Qt::Key_F12)
- {
- blit_start_log = true;
- e->accept();
- return;
- }
- else if (e->key() == Qt::Key_F10)
- {
- startConciseBlitLogging = true;
- e->accept();
- return;
- }
-#endif
- else if (e->key() == Qt::Key_F8)
- {
- // ggn: For extra NYAN pleasure...
- // ggn: There you go James :P
- // Shamus: Thanks for the patch! :-D
- WriteLog(" o + + +\n");
- WriteLog("+ o o + o\n");
- WriteLog("-_-_-_-_-_-_-_,------, o \n");
- WriteLog("_-_-_-_-_-_-_-| /\\_/\\ \n");
- WriteLog("-_-_-_-_-_-_-~|__( ^ .^) + + \n");
- WriteLog("_-_-_-_-_-_-_-\"\" \"\" \n");
- WriteLog("+ o o + o\n");
- WriteLog(" + +\n");
- e->accept();
- return;
- }
-
-/*
-This is done now by a QAction...
- if (e->key() == Qt::Key_F9)
- {
- ToggleFullScreen();
- return;
- }
-*/
- HandleKeys(e, true);
-}
-
-
-void MainWin::keyReleaseEvent(QKeyEvent * e)
-{
- // We ignore the Alt key for now, since it causes problems with the GUI
- if (e->key() == Qt::Key_Alt)
- {
- e->accept();
- return;
- }
-
- HandleKeys(e, false);
-}
-
-
-void MainWin::HandleKeys(QKeyEvent * e, bool state)
-{
- enum { P1LEFT = 0, P1RIGHT, P1UP, P1DOWN, P2LEFT, P2RIGHT, P2UP, P2DOWN };
- // We kill bad key combos here, before they can get to the emulator...
- // This also kills the illegal instruction problem that cropped up in
- // Rayman!
-
- // First, settle key states...
- if (e->key() == (int)vjs.p1KeyBindings[BUTTON_L])
- keyHeld[P1LEFT] = state;
- else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_R])
- keyHeld[P1RIGHT] = state;
- else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_U])
- keyHeld[P1UP] = state;
- else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_D])
- keyHeld[P1DOWN] = state;
- else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_L])
- keyHeld[P2LEFT] = state;
- else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_R])
- keyHeld[P2RIGHT] = state;
- else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_U])
- keyHeld[P2UP] = state;
- else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_D])
- keyHeld[P2DOWN] = state;
-
- // Next, check for conflicts and kill 'em if there are any...
- if (keyHeld[P1LEFT] && keyHeld[P1RIGHT])
- keyHeld[P1LEFT] = keyHeld[P1RIGHT] = false;
-
- if (keyHeld[P1UP] && keyHeld[P1DOWN])
- keyHeld[P1UP] = keyHeld[P1DOWN] = false;
-
- if (keyHeld[P2LEFT] && keyHeld[P2RIGHT])
- keyHeld[P2LEFT] = keyHeld[P2RIGHT] = false;
-
- if (keyHeld[P2UP] && keyHeld[P2DOWN])
- keyHeld[P2UP] = keyHeld[P2DOWN] = false;
-
- // No bad combos exist now, let's stuff the emulator key buffers...!
- for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)
- {
- if (e->key() == (int)vjs.p1KeyBindings[i])
- joypad0Buttons[i] = (state ? 0x01 : 0x00);
-
- if (e->key() == (int)vjs.p2KeyBindings[i])
- joypad1Buttons[i] = (state ? 0x01 : 0x00);
- }
-}
-
-
-//
-// N.B.: The profile system AutoConnect functionality sets the gamepad IDs here.
-//
-void MainWin::HandleGamepads(void)
-{
- Gamepad::Update();
-
- for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)
- {
- if (vjs.p1KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))
- joypad0Buttons[i] = (Gamepad::GetState(gamepadIDSlot1, vjs.p1KeyBindings[i]) ? 0x01 : 0x00);
-
- if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))
- joypad1Buttons[i] = (Gamepad::GetState(gamepadIDSlot2, vjs.p2KeyBindings[i]) ? 0x01 : 0x00);
- }
-}
-
-
-void MainWin::Open(void)
-{
-}
-
-
-void MainWin::Configure(void)
-{
- // Call the configuration dialog and update settings
- ConfigDialog dlg(this);
- //ick.
- dlg.generalTab->useUnknownSoftware->setChecked(allowUnknownSoftware);
- dlg.controllerTab1->profileNum = lastEditedProfile;
- dlg.controllerTab1->SetupLastUsedProfile();
-// maybe instead of this, we tell the controller tab to work on a copy that gets
-// written if the user hits 'OK'.
- SaveProfiles(); // Just in case user cancels
-
- if (dlg.exec() == false)
- {
- RestoreProfiles();
- return;
- }
-
- QString before = vjs.ROMPath;
- QString alpineBefore = vjs.alpineROMPath;
- QString absBefore = vjs.absROMPath;
-// bool audioBefore = vjs.audioEnabled;
- bool audioBefore = vjs.DSPEnabled;
- dlg.UpdateVJSettings();
- QString after = vjs.ROMPath;
- QString alpineAfter = vjs.alpineROMPath;
- QString absAfter = vjs.absROMPath;
-// bool audioAfter = vjs.audioEnabled;
- bool audioAfter = vjs.DSPEnabled;
-
- bool allowOld = allowUnknownSoftware;
- //ick.
- allowUnknownSoftware = dlg.generalTab->useUnknownSoftware->isChecked();
- lastEditedProfile = dlg.controllerTab1->profileNum;
- AutoConnectProfiles();
-
- // We rescan the "software" folder if the user either changed the path or
- // checked/unchecked the "Allow unknown files" option in the config dialog.
- if ((before != after) || (allowOld != allowUnknownSoftware))
- filePickWin->ScanSoftwareFolder(allowUnknownSoftware);
-
- // If the "Alpine" ROM is changed, then let's load it...
- if (alpineBefore != alpineAfter)
- {
- if (!JaguarLoadFile(vjs.alpineROMPath) && !AlpineLoadFile(vjs.alpineROMPath))
- {
- // Oh crap, we couldn't get the file! Alert the media!
- QMessageBox msg;
- msg.setText(QString(tr("Could not load file \"%1\"!")).arg(vjs.alpineROMPath));
- msg.setIcon(QMessageBox::Warning);
- msg.exec();
- }
- }
-
- // If the "ABS" ROM is changed, then let's load it...
- if (absBefore != absAfter)
- {
- if (!JaguarLoadFile(vjs.absROMPath))
- {
- // Oh crap, we couldn't get the file! Alert the media!
- QMessageBox msg;
- msg.setText(QString(tr("Could not load file \"%1\"!")).arg(vjs.absROMPath));
- msg.setIcon(QMessageBox::Warning);
- msg.exec();
- }
- }
-
- // If the "Enable DSP" checkbox changed, then we have to re-init the DAC,
- // since it's running in the host audio IRQ...
- if (audioBefore != audioAfter)
- {
- DACDone();
- DACInit();
- }
-
- // Just in case we crash before a clean exit...
- WriteSettings();
-
- RefreshDebuggerWindows();
-}
-
-
-//
-// Here's the main emulator loop
-//
-void MainWin::Timer(void)
-{
-#if 0
-static uint32_t ntscTickCount;
- if (vjs.hardwareTypeNTSC)
- {
- ntscTickCount++;
- ntscTickCount %= 3;
- timer->start(16 + (ntscTickCount == 0 ? 1 : 0));
- }
-#endif
-
- if (!running)
- return;
-
- if (showUntunedTankCircuit)
- {
- // Some machines can't handle this, so we give them the option to disable it. :-)
- if (!plzDontKillMyComputer)
- {
-// if (!vjs.softTypeDebugger)
- {
- // Random hash & trash
- // We try to simulate an untuned tank circuit here... :-)
- for (uint32_t x = 0; x < videoWidget->rasterWidth; x++)
- {
- for (uint32_t y = 0; y < videoWidget->rasterHeight; y++)
- {
- videoWidget->buffer[(y * videoWidget->textureWidth) + x]
- = (rand() & 0xFF) << 8 | (rand() & 0xFF) << 16 | (rand() & 0xFF) << 24;
- }
- }
- }
- }
- }
- else
- {
- // Otherwise, run the Jaguar simulation
- HandleGamepads();
- JaguarExecuteNew();
- if (!vjs.softTypeDebugger)
- videoWidget->HandleMouseHiding();
-
-static uint32_t refresh = 0;
- // Do autorefresh on debug windows
- // Have to be careful, too much causes the emulator to slow way down!
- if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)
- {
- if (refresh == vjs.refresh)
- {
- RefreshAlpineWindows();
- //memBrowseWin->RefreshContents();
- //cpuBrowseWin->RefreshContents();
- refresh = 0;
- }
- else
- refresh++;
- }
- }
-
- //if (!vjs.softTypeDebugger)
- videoWidget->updateGL();
-
- // FPS handling
- // Approach: We use a ring buffer to store times (in ms) over a given
- // amount of frames, then sum them to figure out the FPS.
- uint32_t timestamp = SDL_GetTicks();
- // This assumes the ring buffer size is a power of 2
-// ringBufferPointer = (ringBufferPointer + 1) & (RING_BUFFER_SIZE - 1);
- // Doing it this way is better. Ring buffer size can be arbitrary then.
- ringBufferPointer = (ringBufferPointer + 1) % RING_BUFFER_SIZE;
- ringBuffer[ringBufferPointer] = timestamp - oldTimestamp;
- uint32_t elapsedTime = 0;
-
- for(uint32_t i=0; i<RING_BUFFER_SIZE; i++)
- elapsedTime += ringBuffer[i];
-
- // elapsedTime must be non-zero
- if (elapsedTime == 0)
- elapsedTime = 1;
-
- // This is in frames per 10 seconds, so we can have 1 decimal
- uint32_t framesPerSecond = (uint32_t)(((float)RING_BUFFER_SIZE / (float)elapsedTime) * 10000.0);
- uint32_t fpsIntegerPart = framesPerSecond / 10;
- uint32_t fpsDecimalPart = framesPerSecond % 10;
- // If this is updated too frequently to be useful, we can throttle it down
- // so that it only updates every 10th frame or so
- statusBar()->showMessage(QString("%1.%2 FPS").arg(fpsIntegerPart).arg(fpsDecimalPart));
- oldTimestamp = timestamp;
-
- if (M68KDebugHaltStatus())
- ToggleRunState();
-}
-
-
-void MainWin::TogglePowerState(void)
-{
- powerButtonOn = !powerButtonOn;
- running = true;
-
- // With the power off, we simulate white noise on the screen. :-)
- if (!powerButtonOn)
- {
- // Restore the mouse pointer, if hidden:
- 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. :-)
- 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++)
- {
- 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));
- }
- }
- }
- }
- else
- {
- useCDAct->setDisabled(true);
- palAct->setDisabled(true);
- ntscAct->setDisabled(true);
- pauseAct->setChecked(false);
- pauseAct->setDisabled(false);
- showUntunedTankCircuit = false;
-
- // Otherwise, we prepare for running regular software...
- if (CDActive)
- {
-// Should check for cartridgeLoaded here as well...!
-// We can clear it when toggling CDActive on, so that when we power cycle it
-// does the expected thing. Otherwise, if we use the file picker to insert a
-// cart, we expect to run the cart! Maybe have a RemoveCart function that only
-// works if the CD unit is active?
- setWindowTitle(QString("Virtual Jaguar " VJ_RELEASE_VERSION
- " Rx - Now playing: Jaguar CD"));
- }
-
- WriteLog("GUI: Resetting Jaguar...\n");
- JaguarReset();
- DACPauseAudioThread(false);
- }
-}
-
-
-void MainWin::ToggleRunState(void)
-{
- startM68KTracing = running;
- running = !running;
-
- if (!running)
- {
- frameAdvanceAct->setDisabled(false);
- pauseAct->setChecked(true);
- pauseAct->setDisabled(false);
- if (vjs.softTypeDebugger)
- {
- traceStepIntoAct->setDisabled(false);
- traceStepOverAct->setDisabled(false);
- restartAct->setDisabled(false);
- m68kDasmWin->Use68KPCAddress();
- GPUDasmWin->UseGPUPCAddress();
- DSPDasmWin->UseDSPPCAddress();
- }
-
- //if (!vjs.softTypeDebugger)
- {
- // Restore the mouse pointer, if hidden:
- videoWidget->CheckAndRestoreMouseCursor();
- // frameAdvanceAct->setDisabled(false);
-
- for (uint32_t i = 0; i < (uint32_t)(videoWidget->textureWidth * 256); i++)
- {
- uint32_t pixel = videoWidget->buffer[i];
- uint8_t r = (pixel >> 24) & 0xFF, g = (pixel >> 16) & 0xFF, b = (pixel >> 8) & 0xFF;
- pixel = ((r + g + b) / 3) & 0x00FF;
- videoWidget->buffer[i] = 0x000000FF | (pixel << 16) | (pixel << 8);
- }
-
- videoWidget->updateGL();
-
- cpuBrowseWin->HoldBPM();
- cpuBrowseWin->HandleBPMContinue();
- RefreshDebuggerWindows();
- }
- }
- else
- {
- frameAdvanceAct->setDisabled(true);
- pauseAct->setChecked(false);
- pauseAct->setDisabled(false);
- if (vjs.softTypeDebugger)
- {
- traceStepIntoAct->setDisabled(true);
- traceStepOverAct->setDisabled(true);
- restartAct->setDisabled(true);
- }
-
- cpuBrowseWin->UnholdBPM();
- }
-
- // Pause/unpause any running/non-running threads...
- DACPauseAudioThread(!running);
-}
-
-
-void MainWin::SetZoom100(void)
-{
- zoomLevel = 1;
- ResizeMainWindow();
-}
-
-
-void MainWin::SetZoom200(void)
-{
- zoomLevel = 2;
- ResizeMainWindow();
-}
-
-
-void MainWin::SetZoom300(void)
-{
- zoomLevel = 3;
- ResizeMainWindow();
-}
-
-
-void MainWin::SetNTSC(void)
-{
- powerAct->setIcon(powerRed);
- timer->setInterval(16);
- vjs.hardwareTypeNTSC = true;
- ResizeMainWindow();
- WriteSettings();
-}
-
-
-void MainWin::SetPAL(void)
-{
- powerAct->setIcon(powerGreen);
- timer->setInterval(20);
- vjs.hardwareTypeNTSC = false;
- ResizeMainWindow();
- WriteSettings();
-}
-
-
-void MainWin::ToggleBlur(void)
-{
- vjs.glFilter = !vjs.glFilter;
- WriteSettings();
-}
-
-
-void MainWin::ShowAboutWin(void)
-{
- aboutWin->show();
-}
-
-
-void MainWin::ShowHelpWin(void)
-{
- helpWin->show();
-}
-
-
-void MainWin::InsertCart(void)
-{
- // Check to see if we did autorun, 'cause we didn't load anything in that
- // case
- if (!scannedSoftwareFolder)
- {
- filePickWin->ScanSoftwareFolder(allowUnknownSoftware);
- scannedSoftwareFolder = true;
- }
-
- // If the emulator is running, we pause it here and unpause it later
- // if we dismiss the file selector without choosing anything
- if (running && powerButtonOn)
- {
- ToggleRunState();
- pauseForFileSelector = true;
- }
-
- filePickWin->show();
-}
-
-
-void MainWin::Unpause(void)
-{
- // Here we unpause the emulator if it was paused when we went into the file selector
- if (pauseForFileSelector)
- {
- pauseForFileSelector = false;
-
- // Some nutter might have unpaused while in the file selector, so check for that
- if (!running)
- ToggleRunState();
- }
-}
-
-
-void MainWin::LoadSoftware(QString file)
-{
- running = false; // Prevent bad things(TM) from happening...
- pauseForFileSelector = false; // Reset the file selector pause flag
-
- uint8_t * biosPointer = jaguarBootROM;
-
- if (vjs.hardwareTypeAlpine)
- biosPointer = jaguarDevBootROM2;
-
- if (vjs.softTypeDebugger)
- biosPointer = jaguarDevBootROM2;
-
- memcpy(jagMemSpace + 0xE00000, biosPointer, 0x20000);
-
- powerAct->setDisabled(false);
- powerAct->setChecked(true);
- powerButtonOn = false;
- TogglePowerState();
-
- // 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...
-
- // This is icky because we've already done it
-// it gets worse :-P
- if (!vjs.useJaguarBIOS)
- SET32(jaguarMainRAM, 4, jaguarRunAddress);
-
- m68k_pulse_reset();
-
-// set the M68K in halt mode in case of a debug mode is used, so control is at user side
- if (vjs.softTypeDebugger)
- {
- m68kDasmWin->SetAddress(jaguarRunAddress);
- //pauseAct->setDisabled(false);
- //pauseAct->setChecked(true);
- ToggleRunState();
- //RefreshWindows();
- }
- else
- {
- if (vjs.hardwareTypeAlpine && !jaguarRunAddress)
- {
- ToggleRunState();
- }
- }
-
- if ((!vjs.hardwareTypeAlpine || !vjs.softTypeDebugger) && !loadAndGo && jaguarRunAddress)
- {
- QString newTitle = QString("Virtual Jaguar " VJ_RELEASE_VERSION " Rx - Now playing: %1")
- .arg(filePickWin->GetSelectedPrettyName());
- setWindowTitle(newTitle);
- }
-}
-
-
-void MainWin::ToggleCDUsage(void)
-{
- CDActive = !CDActive;
-
- // Set up the Jaguar CD for execution, otherwise, clear memory
- if (CDActive)
- memcpy(jagMemSpace + 0x800000, jaguarCDBootROM, 0x40000);
- else
- memset(jagMemSpace + 0x800000, 0xFF, 0x40000);
-}
-
-
-//
-void MainWin::NewBreakpointFunction(void)
-{
- brkWin->show();
- brkWin->RefreshContents();
-}
-
-
-// Step Into trace
-void MainWin::TraceStepInto(void)
-{
- JaguarStepInto();
- videoWidget->updateGL();
- RefreshDebuggerWindows();
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to verify the Step Into function !!!")
-#else
- #warning "!!! Need to verify the Step Into function !!!"
-#endif // _MSC_VER
-}
-
-
-// Restart
-void MainWin::Restart(void)
-{
- m68k_set_reg(M68K_REG_PC, jaguarRunAddress);
- //m68kDasmWin->SetAddress(jaguarRunAddress);
- RefreshDebuggerWindows();
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to verify the Restart function !!!")
-#else
- #warning "!!! Need to verify the Restart function !!!"
-#endif // _MSC_VER
-}
-
-
-// Step Over trace
-void MainWin::TraceStepOver(void)
-{
- JaguarStepOver(0);
- videoWidget->updateGL();
- RefreshDebuggerWindows();
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to verify the Step Over function !!!")
-#else
- #warning "!!! Need to verify the Step Over function !!!"
-#endif // _MSC_VER
-}
-
-
-// Advance / Execute for one frame
-void MainWin::FrameAdvance(void)
-{
-//printf("Frame Advance...\n");
- ToggleRunState();
- // Execute 1 frame, then exit (only useful in Pause mode)
- JaguarExecuteNew();
- //if (!vjs.softTypeDebugger)
- videoWidget->updateGL();
- ToggleRunState();
- // Need to execute 1 frames' worth of DSP thread as well :-/
-
- //m68kDasmWin->Use68KPCAddress();
- //RefreshWindows();
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to execute the DSP thread for 1 frame too !!!")
-#else
-#warning "!!! Need to execute the DSP thread for 1 frame too !!!"
-#endif // _MSC_VER
-}
-
-
-void MainWin::SetFullScreen(bool state/*= true*/)
-{
- if (!vjs.softTypeDebugger)
- {
- if (state)
- {
- mainWinPosition = pos();
- menuBar()->hide();
- statusBar()->hide();
- toolbar->hide();
-
- if (debugbar)
- debugbar->hide();
-
- // This is needed because the fullscreen may happen on a different
- // screen than screen 0:
- int screenNum = QApplication::desktop()->screenNumber(videoWidget);
- QRect r = QApplication::desktop()->screenGeometry(screenNum);
- double targetWidth = (double)VIRTUAL_SCREEN_WIDTH,
- targetHeight = (double)(vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
- double aspectRatio = targetWidth / targetHeight;
- // NOTE: Really should check here to see which dimension constrains the
- // other. Right now, we assume that height is the constraint.
- int newWidth = (int)(aspectRatio * (double)r.height());
- videoWidget->offset = (r.width() - newWidth) / 2;
- videoWidget->fullscreen = true;
- videoWidget->outputWidth = newWidth;
- videoWidget->setFixedSize(r.width(), r.height());
- showFullScreen();
- }
- else
- {
- // Seems Qt is fussy about this: showNormal() has to go first, or it
- // will keep the window stuck in a psuedo-fullscreen mode with no way
- // to get out of it (except closing the app).
- showNormal();
-
- // Reset the video widget to windowed mode
- videoWidget->offset = 0;
- videoWidget->fullscreen = false;
- menuBar()->show();
- statusBar()->show();
- toolbar->show();
-
- if (debugbar)
- debugbar->show();
-
- ResizeMainWindow();
- move(mainWinPosition);
- }
- }
-}
-
-
-void MainWin::ToggleFullScreen(void)
-{
- fullScreen = !fullScreen;
- SetFullScreen(fullScreen);
-}
-
-
-void MainWin::ShowExceptionVectorTableBrowserWin(void)
-{
- exceptionvectortableBrowseWin->show();
- exceptionvectortableBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowAllWatchBrowserWin(void)
-{
- allWatchBrowseWin->show();
- allWatchBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowHeapAllocatorBrowserWin(void)
-{
- heapallocatorBrowseWin->show();
- heapallocatorBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowMemoryBrowserWin(void)
-{
- memBrowseWin->show();
- memBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowMemory1BrowserWin(int NumWin)
-{
-// for (int i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- mem1BrowseWin[NumWin]->show();
- mem1BrowseWin[NumWin]->RefreshContents(NumWin);
- }
-}
-
-
-void MainWin::ShowEmuStatusWin(void)
-{
- emuStatusWin->show();
- emuStatusWin->RefreshContents();
-}
-
-
-void MainWin::ShowStackBrowserWin(void)
-{
- stackBrowseWin->show();
- stackBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowCPUBrowserWin(void)
-{
- cpuBrowseWin->show();
- cpuBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowOPBrowserWin(void)
-{
- opBrowseWin->show();
- opBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowM68KDasmBrowserWin(void)
-{
- m68kDasmBrowseWin->show();
- m68kDasmBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowRISCDasmBrowserWin(void)
-{
- riscDasmBrowseWin->show();
- riscDasmBrowseWin->RefreshContents();
-}
-
-
-void MainWin::ShowDasmWin(void)
-{
- DasmWin->show();
-// DasmWin->RefreshContents();
-}
-
-
-void MainWin::ShowVideoOutputWin(void)
-{
- //VideoOutputWindowCentrale = mainWindowCentrale->addSubWindow(videoWidget);
- //VideoOutputWindowCentrale->setWindowTitle(QString(tr("Video output")));
- //VideoOutputWindowCentrale->show();
- //memBrowseWin->show();
- VideoOutputWin->show();
- //VideoOutputWin->RefreshContents(videoWidget);
-}
-
-
-void MainWin::ResizeMainWindow(void)
-{
- if (!vjs.softTypeDebugger)
- {
- 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)
- {
- 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));
- }
- }
-
- adjustSize();
- }
-}
-
-
-// Read settings
-void MainWin::ReadSettings(void)
-{
- size_t i;
-
- QSettings settings("Underground Software", "Virtual Jaguar");
-
- zoomLevel = settings.value("zoom", 2).toInt();
- allowUnknownSoftware = settings.value("showUnknownSoftware", false).toBool();
- lastEditedProfile = settings.value("lastEditedProfile", 0).toInt();
-
- vjs.useJoystick = settings.value("useJoystick", false).toBool();
- vjs.joyport = settings.value("joyport", 0).toInt();
- vjs.hardwareTypeNTSC = settings.value("hardwareTypeNTSC", true).toBool();
- vjs.frameSkip = settings.value("frameSkip", 0).toInt();
- vjs.useJaguarBIOS = settings.value("useJaguarBIOS", false).toBool();
- vjs.GPUEnabled = settings.value("GPUEnabled", true).toBool();
- vjs.DSPEnabled = settings.value("DSPEnabled", true).toBool();
- vjs.audioEnabled = settings.value("audioEnabled", true).toBool();
- vjs.usePipelinedDSP = settings.value("usePipelinedDSP", false).toBool();
- vjs.fullscreen = settings.value("fullscreen", false).toBool();
- vjs.useOpenGL = settings.value("useOpenGL", true).toBool();
- vjs.glFilter = settings.value("glFilterType", 1).toInt();
- vjs.renderType = settings.value("renderType", 0).toInt();
- vjs.biosType = settings.value("biosType", BT_M_SERIES).toInt();
- 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());
-
- // Read settings from the Debugger mode
- settings.beginGroup("debugger");
- strcpy(vjs.debuggerROMPath, settings.value("DefaultROM", "").toString().toUtf8().data());
- vjs.nbrdisasmlines = settings.value("NbrDisasmLines", 32).toUInt();
- vjs.disasmopcodes = settings.value("DisasmOpcodes", true).toBool();
- vjs.displayHWlabels = settings.value("DisplayHWLabels", true).toBool();
- vjs.displayFullSourceFilename = settings.value("displayFullSourceFilename", true).toBool();
- vjs.nbrmemory1browserwindow = settings.value("NbrMemory1BrowserWindow", MaxMemory1BrowserWindow).toUInt();
- settings.endGroup();
-
- // Read settings from the Alpine mode
- settings.beginGroup("alpine");
- strcpy(vjs.alpineROMPath, settings.value("DefaultROM", "").toString().toUtf8().data());
- strcpy(vjs.absROMPath, settings.value("DefaultABS", "").toString().toUtf8().data());
- vjs.refresh = settings.value("refresh", 60).toUInt();
- vjs.allowWritesToROM = settings.value("writeROM", false).toBool();
- settings.endGroup();
-
- // Read settings from the Keybindings
- settings.beginGroup("keybindings");
- for (i = 0; i < KB_END; i++)
- {
- strcpy(vjs.KBContent[i].KBSettingValue, settings.value(KeyBindingsTable[i].KBNameSetting, KeyBindingsTable[i].KBDefaultValue).toString().toUtf8().data());
- }
- settings.endGroup();
-
- // 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"));
-
-#if 0
- // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *
- vjs.p1KeyBindings[BUTTON_U] = settings.value("p1k_up", Qt::Key_S).toInt();
- vjs.p1KeyBindings[BUTTON_D] = settings.value("p1k_down", Qt::Key_X).toInt();
- vjs.p1KeyBindings[BUTTON_L] = settings.value("p1k_left", Qt::Key_A).toInt();
- vjs.p1KeyBindings[BUTTON_R] = settings.value("p1k_right", Qt::Key_D).toInt();
- vjs.p1KeyBindings[BUTTON_C] = settings.value("p1k_c", Qt::Key_J).toInt();
- vjs.p1KeyBindings[BUTTON_B] = settings.value("p1k_b", Qt::Key_K).toInt();
- vjs.p1KeyBindings[BUTTON_A] = settings.value("p1k_a", Qt::Key_L).toInt();
- vjs.p1KeyBindings[BUTTON_OPTION] = settings.value("p1k_option", Qt::Key_O).toInt();
- vjs.p1KeyBindings[BUTTON_PAUSE] = settings.value("p1k_pause", Qt::Key_P).toInt();
- vjs.p1KeyBindings[BUTTON_0] = settings.value("p1k_0", Qt::Key_0).toInt();
- vjs.p1KeyBindings[BUTTON_1] = settings.value("p1k_1", Qt::Key_1).toInt();
- vjs.p1KeyBindings[BUTTON_2] = settings.value("p1k_2", Qt::Key_2).toInt();
- vjs.p1KeyBindings[BUTTON_3] = settings.value("p1k_3", Qt::Key_3).toInt();
- vjs.p1KeyBindings[BUTTON_4] = settings.value("p1k_4", Qt::Key_4).toInt();
- vjs.p1KeyBindings[BUTTON_5] = settings.value("p1k_5", Qt::Key_5).toInt();
- vjs.p1KeyBindings[BUTTON_6] = settings.value("p1k_6", Qt::Key_6).toInt();
- vjs.p1KeyBindings[BUTTON_7] = settings.value("p1k_7", Qt::Key_7).toInt();
- vjs.p1KeyBindings[BUTTON_8] = settings.value("p1k_8", Qt::Key_8).toInt();
- vjs.p1KeyBindings[BUTTON_9] = settings.value("p1k_9", Qt::Key_9).toInt();
- vjs.p1KeyBindings[BUTTON_d] = settings.value("p1k_pound", Qt::Key_Minus).toInt();
- vjs.p1KeyBindings[BUTTON_s] = settings.value("p1k_star", Qt::Key_Equal).toInt();
-
- vjs.p2KeyBindings[BUTTON_U] = settings.value("p2k_up", Qt::Key_Up).toInt();
- vjs.p2KeyBindings[BUTTON_D] = settings.value("p2k_down", Qt::Key_Down).toInt();
- vjs.p2KeyBindings[BUTTON_L] = settings.value("p2k_left", Qt::Key_Left).toInt();
- vjs.p2KeyBindings[BUTTON_R] = settings.value("p2k_right", Qt::Key_Right).toInt();
- vjs.p2KeyBindings[BUTTON_C] = settings.value("p2k_c", Qt::Key_Z).toInt();
- vjs.p2KeyBindings[BUTTON_B] = settings.value("p2k_b", Qt::Key_X).toInt();
- vjs.p2KeyBindings[BUTTON_A] = settings.value("p2k_a", Qt::Key_C).toInt();
- vjs.p2KeyBindings[BUTTON_OPTION] = settings.value("p2k_option", Qt::Key_Apostrophe).toInt();
- vjs.p2KeyBindings[BUTTON_PAUSE] = settings.value("p2k_pause", Qt::Key_Return).toInt();
- vjs.p2KeyBindings[BUTTON_0] = settings.value("p2k_0", Qt::Key_0).toInt();
- vjs.p2KeyBindings[BUTTON_1] = settings.value("p2k_1", Qt::Key_1).toInt();
- vjs.p2KeyBindings[BUTTON_2] = settings.value("p2k_2", Qt::Key_2).toInt();
- vjs.p2KeyBindings[BUTTON_3] = settings.value("p2k_3", Qt::Key_3).toInt();
- vjs.p2KeyBindings[BUTTON_4] = settings.value("p2k_4", Qt::Key_4).toInt();
- vjs.p2KeyBindings[BUTTON_5] = settings.value("p2k_5", Qt::Key_5).toInt();
- vjs.p2KeyBindings[BUTTON_6] = settings.value("p2k_6", Qt::Key_6).toInt();
- vjs.p2KeyBindings[BUTTON_7] = settings.value("p2k_7", Qt::Key_7).toInt();
- vjs.p2KeyBindings[BUTTON_8] = settings.value("p2k_8", Qt::Key_8).toInt();
- vjs.p2KeyBindings[BUTTON_9] = settings.value("p2k_9", Qt::Key_9).toInt();
- vjs.p2KeyBindings[BUTTON_d] = settings.value("p2k_pound", Qt::Key_Slash).toInt();
- vjs.p2KeyBindings[BUTTON_s] = settings.value("p2k_star", Qt::Key_Asterisk).toInt();
-#endif
-
- ReadProfiles(&settings);
-}
-
-
-// Read UI settings
-// Default values will be used in case of no settings can be found
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to check the window geometry to see if the positions are legal !!!")
-#else
-#warning "!!! Need to check the window geometry to see if the positions are legal !!!"
-#endif // _MSC_VER
-// i.e., someone could drag it to another screen, close it, then disconnect that screen
-void MainWin::ReadUISettings(void)
-{
- QPoint pos;
- char mem1Name[100];
- size_t i;
- QSize size;
-
- // Point on the emulator settings
- QSettings settings("Underground Software", "Virtual Jaguar");
- settings.beginGroup("ui");
-
- // Emulator main window UI information
- mainWinPosition = settings.value("pos", QPoint(200, 200)).toPoint();
- size = settings.value("size", QSize(400, 400)).toSize();
- resize(size);
- move(mainWinPosition);
- pos = settings.value("cartLoadPos", QPoint(200, 200)).toPoint();
- filePickWin->move(pos);
-
- // Alpine debug UI information (also needed by the Debugger)
- if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)
- {
- // CPU registers UI information
- pos = settings.value("cpuBrowseWinPos", QPoint(200, 200)).toPoint();
- cpuBrowseWin->move(pos);
- settings.value("cpuBrowseWinIsVisible", false).toBool() ? ShowCPUBrowserWin() : void();
-
- // Memory browser UI information
- pos = settings.value("memBrowseWinPos", QPoint(200, 200)).toPoint();
- memBrowseWin->move(pos);
- settings.value("memBrowseWinIsVisible", false).toBool() ? ShowMemoryBrowserWin() : void();
-
- // Stack browser UI information
- pos = settings.value("stackBrowseWinPos", QPoint(200, 200)).toPoint();
- stackBrowseWin->move(pos);
- settings.value("stackBrowseWinIsVisible", false).toBool() ? ShowStackBrowserWin() : void();
- size = settings.value("stackBrowseWinSize", QSize(400, 400)).toSize();
- stackBrowseWin->resize(size);
-
- // Emulator status UI information
- pos = settings.value("emuStatusWinPos", QPoint(200, 200)).toPoint();
- emuStatusWin->move(pos);
- settings.value("emuStatusWinIsVisible", false).toBool() ? ShowEmuStatusWin() : void();
-
- // OP (Object Processor) UI information
- pos = settings.value("opBrowseWinPos", QPoint(200, 200)).toPoint();
- opBrowseWin->move(pos);
- settings.value("opBrowseWinIsVisible", false).toBool() ? ShowOPBrowserWin() : void();
- size = settings.value("opBrowseWinSize", QSize(400, 400)).toSize();
- opBrowseWin->resize(size);
-
- // RISC disassembly UI information
- pos = settings.value("riscDasmBrowseWinPos", QPoint(200, 200)).toPoint();
- riscDasmBrowseWin->move(pos);
- settings.value("riscDasmBrowseWinIsVisible", false).toBool() ? ShowRISCDasmBrowserWin() : void();
-
- // M68k disassembly UI information
- pos = settings.value("m68kDasmBrowseWinPos", QPoint(200, 200)).toPoint();
- m68kDasmBrowseWin->move(pos);
- //settings.value("m68kDasmBrowseWinIsVisible", false).toBool() ? ShowM68KDasmBrowserWin() : void();
-#ifdef _MSC_VER
-#pragma message("Warning: !!! Need to check the M68k disassembly window position crashing !!!")
-#else
- #warning "!!! Need to check the M68k disassembly window position crashing !!!"
-#endif // _MSC_VER
- }
-
- // Debugger UI information
- if (vjs.softTypeDebugger)
- {
-#if 0
- pos = settings.value("m68kDasmWinPos", QPoint(200, 200)).toPoint();
- m68kDasmWin->move(pos);
- //settings.value("m68kDasmWinIsVisible", false).toBool() ? m68kDasmWin->show() : m68kDasmWin->hide();
- pos = settings.value("GPUDasmWinPos", QPoint(200, 200)).toPoint();
- GPUDasmWin->move(pos);
- pos = settings.value("DSPDasmWinPos", QPoint(200, 200)).toPoint();
- DSPDasmWin->move(pos);
-#endif
- // All watch browser UI information
- pos = settings.value("allWatchBrowseWinPos", QPoint(200, 200)).toPoint();
- allWatchBrowseWin->move(pos);
- settings.value("allWatchBrowseWinIsVisible", false).toBool() ? ShowAllWatchBrowserWin() : void();
- size = settings.value("allWatchBrowseWinSize", QSize(400, 400)).toSize();
- allWatchBrowseWin->resize(size);
-
- // Heap memory allocation browser UI information
- pos = settings.value("heapallocatorBrowseWinPos", QPoint(200, 200)).toPoint();
- heapallocatorBrowseWin->move(pos);
- settings.value("heapallocatorBrowseWinIsVisible", false).toBool() ? ShowHeapAllocatorBrowserWin() : void();
- size = settings.value("heapallocatorBrowseWinSize", QSize(400, 400)).toSize();
- heapallocatorBrowseWin->resize(size);
-
- // Exception Vector Table UI Information
- pos = settings.value("exceptionVectorTableBrowseWinPos", QPoint(200, 200)).toPoint();
- exceptionvectortableBrowseWin->move(pos);
- settings.value("exceptionVectorTableBrowseWinIsVisible", false).toBool() ? ShowExceptionVectorTableBrowserWin() : void();
- size = settings.value("exceptionVectorTableBrowseWinSize", QSize(400, 400)).toSize();
- exceptionvectortableBrowseWin->resize(size);
-
- // Memories browser UI information
- for (i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- sprintf(mem1Name, "mem1BrowseWinPos[%i]", (unsigned int)i);
- pos = settings.value(mem1Name, QPoint(200, 200)).toPoint();
- mem1BrowseWin[i]->move(pos);
- sprintf(mem1Name, "mem1BrowseWinIsVisible[%i]", (unsigned int)i);
- settings.value(mem1Name, false).toBool() ? ShowMemory1BrowserWin((int)i) : void();
- sprintf(mem1Name, "mem1BrowseWinSize[%i]", (unsigned int)i);
- size = settings.value(mem1Name, QSize(400, 400)).toSize();
- mem1BrowseWin[i]->resize(size);
- }
- }
-
- settings.endGroup();
-}
-
-
-// Save the settings
-void MainWin::WriteSettings(void)
-{
- size_t i;
-
- // Point on the emulator settings
- QSettings settings("Underground Software", "Virtual Jaguar");
- //settings.setValue("pos", pos());
- //settings.setValue("size", size());
- //settings.setValue("cartLoadPos", filePickWin->pos());
-
- settings.setValue("zoom", zoomLevel);
- settings.setValue("showUnknownSoftware", allowUnknownSoftware);
- settings.setValue("lastEditedProfile", lastEditedProfile);
-
- settings.setValue("useJoystick", vjs.useJoystick);
- settings.setValue("joyport", vjs.joyport);
- settings.setValue("hardwareTypeNTSC", vjs.hardwareTypeNTSC);
- settings.setValue("frameSkip", vjs.frameSkip);
- settings.setValue("useJaguarBIOS", vjs.useJaguarBIOS);
- settings.setValue("GPUEnabled", vjs.GPUEnabled);
- settings.setValue("DSPEnabled", vjs.DSPEnabled);
- settings.setValue("audioEnabled", vjs.audioEnabled);
- settings.setValue("usePipelinedDSP", vjs.usePipelinedDSP);
- settings.setValue("fullscreen", vjs.fullscreen);
- settings.setValue("useOpenGL", vjs.useOpenGL);
- settings.setValue("glFilterType", vjs.glFilter);
- settings.setValue("renderType", vjs.renderType);
- settings.setValue("biosType", vjs.biosType);
- settings.setValue("useFastBlitter", vjs.useFastBlitter);
- settings.setValue("JagBootROM", vjs.jagBootPath);
- settings.setValue("CDBootROM", vjs.CDBootPath);
- settings.setValue("EEPROMs", vjs.EEPROMPath);
- settings.setValue("ROMs", vjs.ROMPath);
-
- // Write settings from the Alpine mode
- settings.beginGroup("alpine");
- settings.setValue("refresh", vjs.refresh);
- settings.setValue("DefaultROM", vjs.alpineROMPath);
- settings.setValue("DefaultABS", vjs.absROMPath);
- settings.setValue("writeROM", vjs.allowWritesToROM);
- settings.endGroup();
-
- // Write settings from the Debugger mode
- settings.beginGroup("debugger");
- settings.setValue("DisplayHWLabels", vjs.displayHWlabels);
- settings.setValue("NbrDisasmLines", vjs.nbrdisasmlines);
- settings.setValue("DisasmOpcodes", vjs.disasmopcodes);
- settings.setValue("displayFullSourceFilename", vjs.displayFullSourceFilename);
- settings.setValue("NbrMemory1BrowserWindow", (unsigned int)vjs.nbrmemory1browserwindow);
- settings.setValue("DefaultROM", vjs.debuggerROMPath);
- settings.endGroup();
-
- // Write settings from the Keybindings
- settings.beginGroup("keybindings");
- for (i = 0; i < KB_END; i++)
- {
- settings.setValue(KeyBindingsTable[i].KBNameSetting, vjs.KBContent[i].KBSettingValue);
- }
- settings.endGroup();
-
-#if 0
- settings.setValue("p1k_up", vjs.p1KeyBindings[BUTTON_U]);
- settings.setValue("p1k_down", vjs.p1KeyBindings[BUTTON_D]);
- settings.setValue("p1k_left", vjs.p1KeyBindings[BUTTON_L]);
- settings.setValue("p1k_right", vjs.p1KeyBindings[BUTTON_R]);
- settings.setValue("p1k_c", vjs.p1KeyBindings[BUTTON_C]);
- settings.setValue("p1k_b", vjs.p1KeyBindings[BUTTON_B]);
- settings.setValue("p1k_a", vjs.p1KeyBindings[BUTTON_A]);
- settings.setValue("p1k_option", vjs.p1KeyBindings[BUTTON_OPTION]);
- settings.setValue("p1k_pause", vjs.p1KeyBindings[BUTTON_PAUSE]);
- settings.setValue("p1k_0", vjs.p1KeyBindings[BUTTON_0]);
- settings.setValue("p1k_1", vjs.p1KeyBindings[BUTTON_1]);
- settings.setValue("p1k_2", vjs.p1KeyBindings[BUTTON_2]);
- settings.setValue("p1k_3", vjs.p1KeyBindings[BUTTON_3]);
- settings.setValue("p1k_4", vjs.p1KeyBindings[BUTTON_4]);
- settings.setValue("p1k_5", vjs.p1KeyBindings[BUTTON_5]);
- settings.setValue("p1k_6", vjs.p1KeyBindings[BUTTON_6]);
- settings.setValue("p1k_7", vjs.p1KeyBindings[BUTTON_7]);
- settings.setValue("p1k_8", vjs.p1KeyBindings[BUTTON_8]);
- settings.setValue("p1k_9", vjs.p1KeyBindings[BUTTON_9]);
- settings.setValue("p1k_pound", vjs.p1KeyBindings[BUTTON_d]);
- settings.setValue("p1k_star", vjs.p1KeyBindings[BUTTON_s]);
-
- settings.setValue("p2k_up", vjs.p2KeyBindings[BUTTON_U]);
- settings.setValue("p2k_down", vjs.p2KeyBindings[BUTTON_D]);
- settings.setValue("p2k_left", vjs.p2KeyBindings[BUTTON_L]);
- settings.setValue("p2k_right", vjs.p2KeyBindings[BUTTON_R]);
- settings.setValue("p2k_c", vjs.p2KeyBindings[BUTTON_C]);
- settings.setValue("p2k_b", vjs.p2KeyBindings[BUTTON_B]);
- settings.setValue("p2k_a", vjs.p2KeyBindings[BUTTON_A]);
- settings.setValue("p2k_option", vjs.p2KeyBindings[BUTTON_OPTION]);
- settings.setValue("p2k_pause", vjs.p2KeyBindings[BUTTON_PAUSE]);
- settings.setValue("p2k_0", vjs.p2KeyBindings[BUTTON_0]);
- settings.setValue("p2k_1", vjs.p2KeyBindings[BUTTON_1]);
- settings.setValue("p2k_2", vjs.p2KeyBindings[BUTTON_2]);
- settings.setValue("p2k_3", vjs.p2KeyBindings[BUTTON_3]);
- settings.setValue("p2k_4", vjs.p2KeyBindings[BUTTON_4]);
- settings.setValue("p2k_5", vjs.p2KeyBindings[BUTTON_5]);
- settings.setValue("p2k_6", vjs.p2KeyBindings[BUTTON_6]);
- settings.setValue("p2k_7", vjs.p2KeyBindings[BUTTON_7]);
- settings.setValue("p2k_8", vjs.p2KeyBindings[BUTTON_8]);
- settings.setValue("p2k_9", vjs.p2KeyBindings[BUTTON_9]);
- settings.setValue("p2k_pound", vjs.p2KeyBindings[BUTTON_d]);
- settings.setValue("p2k_star", vjs.p2KeyBindings[BUTTON_s]);
-#endif
-
- WriteProfiles(&settings);
-}
-
-
-// Save the UI settings
-void MainWin::WriteUISettings(void)
-{
- char mem1Name[100];
- size_t i;
-
- // Point on the emulator settings
- QSettings settings("Underground Software", "Virtual Jaguar");
- settings.beginGroup("ui");
-
- // Emulator UI information
- settings.setValue("pos", pos());
- settings.setValue("size", size());
- settings.setValue("cartLoadPos", filePickWin->pos());
- settings.setValue("zoom", zoomLevel);
-
- // Alpine debug UI information (also needed by the Debugger)
- if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)
- {
- settings.setValue("cpuBrowseWinPos", cpuBrowseWin->pos());
- settings.setValue("cpuBrowseWinIsVisible", cpuBrowseWin->isVisible());
- settings.setValue("memBrowseWinPos", memBrowseWin->pos());
- settings.setValue("memBrowseWinIsVisible", memBrowseWin->isVisible());
- settings.setValue("stackBrowseWinPos", stackBrowseWin->pos());
- settings.setValue("stackBrowseWinIsVisible", stackBrowseWin->isVisible());
- settings.setValue("stackBrowseWinSize", stackBrowseWin->size());
- settings.setValue("emuStatusWinPos", emuStatusWin->pos());
- settings.setValue("emuStatusWinIsVisible", emuStatusWin->isVisible());
- settings.setValue("opBrowseWinPos", opBrowseWin->pos());
- settings.setValue("opBrowseWinIsVisible", opBrowseWin->isVisible());
- settings.setValue("opBrowseWinSize", opBrowseWin->size());
- settings.setValue("riscDasmBrowseWinPos", riscDasmBrowseWin->pos());
- settings.setValue("riscDasmBrowseWinIsVisible", riscDasmBrowseWin->isVisible());
- settings.setValue("m68kDasmBrowseWinPos", m68kDasmBrowseWin->pos());
- settings.setValue("m68kDasmBrowseWinIsVisible", m68kDasmBrowseWin->isVisible());
- }
-
- // Debugger UI information
- if (vjs.softTypeDebugger)
- {
-#if 0
- settings.setValue("m68kDasmWinPos", m68kDasmWin->pos());
- //settings.setValue("m68kDasmWinIsVisible", m68kDasmWin->isVisible());
- settings.setValue("GPUDasmWinPos", GPUDasmWin->pos());
- settings.setValue("DSPDasmWinPos", DSPDasmWin->pos());
-#endif
- settings.setValue("allWatchBrowseWinPos", allWatchBrowseWin->pos());
- settings.setValue("allWatchBrowseWinIsVisible", allWatchBrowseWin->isVisible());
- settings.setValue("allWatchBrowseWinSize", allWatchBrowseWin->size());
- settings.setValue("heapallocatorBrowseWinPos", heapallocatorBrowseWin->pos());
- settings.setValue("heapallocatorBrowseWinIsVisible", heapallocatorBrowseWin->isVisible());
- settings.setValue("heapallocatorBrowseWinSize", heapallocatorBrowseWin->size());
- settings.setValue("exceptionVectorTableBrowseWinPos", exceptionvectortableBrowseWin->pos());
- settings.setValue("exceptionVectorTableBrowseWinIsVisible", exceptionvectortableBrowseWin->isVisible());
- settings.setValue("exceptionVectorTableBrowseWinSize", exceptionvectortableBrowseWin->size());
- for (i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- sprintf(mem1Name, "mem1BrowseWinPos[%i]", (unsigned int)i);
- settings.setValue(mem1Name, mem1BrowseWin[i]->pos());
- sprintf(mem1Name, "mem1BrowseWinIsVisible[%i]", (unsigned int)i);
- settings.setValue(mem1Name, mem1BrowseWin[i]->isVisible());
- sprintf(mem1Name, "mem1BrowseWinSize[%i]", (unsigned int)i);
- settings.setValue(mem1Name, mem1BrowseWin[i]->size());
- }
- }
-
- settings.endGroup();
-}
-
-
-// Refresh alpine debug windows
-void MainWin::RefreshAlpineWindows(void)
-{
- cpuBrowseWin->RefreshContents();
- memBrowseWin->RefreshContents();
- stackBrowseWin->RefreshContents();
- emuStatusWin->RefreshContents();
- opBrowseWin->RefreshContents();
- riscDasmBrowseWin->RefreshContents();
- m68kDasmBrowseWin->RefreshContents();
-}
-
-
-// Refresh soft debugger & alpine debug windows
-void MainWin::RefreshDebuggerWindows(void)
-{
- size_t i;
-
- if (vjs.softTypeDebugger)
- {
- m68kDasmWin->RefreshContents();
- GPUDasmWin->RefreshContents();
- DSPDasmWin->RefreshContents();
- allWatchBrowseWin->RefreshContents();
- heapallocatorBrowseWin->RefreshContents();
- for (i = 0; i < vjs.nbrmemory1browserwindow; i++)
- {
- mem1BrowseWin[i]->RefreshContents(i);
- }
-
- RefreshAlpineWindows();
- }
-}
+//\r
+// mainwin.cpp - Qt-based GUI for Virtual Jaguar: Main Application Window\r
+// by James Hammons\r
+// (C) 2009 Underground Software\r
+//\r
+// JLH = James Hammons <jlhamm@acm.org>\r
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
+// RG = Richard Goedeken\r
+\r
+//\r
+// Who When What\r
+// --- ---------- ------------------------------------------------------------\r
+// JLH 12/23/2009 Created this file\r
+// JLH 12/20/2010 Added settings, menus & toolbars\r
+// JLH 07/05/2011 Added CD BIOS functionality to GUI\r
+// JPM June/2016 Visual Studio support & Soft debugger integration\r
+// JPM 01/11/2017 Added stack browser\r
+// JPM Feb./2017 Added GPU/DSP disassembly\r
+// JPM 07/12/2017 Added all Watch window\r
+// JPM Aug./2017 Added heap allocator and memories window, a restart feature, and a [Not Supported] breakpoints window\r
+// 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\r
+// JPM 11/04/2017 Added the local window\r
+// JPM 08/31/2018 Added the call stack window\r
+// JPM Sept./2018 Added the new Models and BIOS handler, a screenshot feature and source code files browsing\r
+// JPM Oct./2018 Added search paths in the settings, breakpoints feature, cartridge view menu\r
+// JPM 11/18/2018 Fix crash with non-debugger mode\r
+// JPM April/2019 Added ELF sections check, added a save memory dump\r
+// JPM Aug./2019 Update texts descriptions, set cartridge view menu for debugger mode only, added a HW registers browser and source level tracing\r
+// JPM Marc./2020 Added the step over for source level tracing\r
+// RG Jan./2021 Linux build fixes\r
+// JPM Apr./2021 Handle number of M68K cycles used in tracing mode\r
+//\r
+\r
+// FIXED:\r
+//\r
+// - Add dbl click/enter to select in cart list, ESC to dimiss [DONE]\r
+// - Autoscan/autoload all available BIOS from 'software' folder [DONE]\r
+// - Add 1 key jumping in cartridge list (press 'R', jumps to carts starting\r
+// with 'R', etc) [DONE]\r
+// - Controller configuration [DONE]\r
+//\r
+// STILL TO BE DONE:\r
+//\r
+// - The source file listing do not need to be refresh more than one time\r
+// - Fix bug in switching between PAL & NTSC in fullscreen mode.\r
+// - Remove SDL dependencies (sound, mainly) from Jaguar core lib\r
+// - Fix inconsistency with trailing slashes in paths (eeproms needs one, software doesn't)\r
+//\r
+// SFDX CODE: S1E9T8H5M23YS\r
+\r
+// Uncomment this for debugging...\r
+//#define DEBUG\r
+//#define DEBUGFOO // Various tool debugging... but not used\r
+//#define DEBUGTP // Toolpalette debugging... but not used\r
+\r
+#include "mainwin.h"\r
+\r
+#include "SDL.h"\r
+#include "app.h"\r
+#include "about.h"\r
+#include "configdialog.h"\r
+#include "controllertab.h"\r
+#include "keybindingstab.h"\r
+#include "filepicker.h"\r
+#include "gamepad.h"\r
+#include "generaltab.h"\r
+#include "glwidget.h"\r
+#include "help.h"\r
+#include "profile.h"\r
+#include "settings.h"\r
+#include "version.h"\r
+#include "emustatus.h"\r
+#include "debug/cpubrowser.h"\r
+#include "debug/m68kdasmbrowser.h"\r
+#include "debug/memorybrowser.h"\r
+#include "debug/stackbrowser.h"\r
+#include "debug/opbrowser.h"\r
+#include "debug/riscdasmbrowser.h"\r
+#include "debug/hwregsbrowser.h"\r
+\r
+#include "dac.h"\r
+#include "jaguar.h"\r
+#include "log.h"\r
+#include "file.h"\r
+#ifndef NEWMODELSBIOSHANDLER\r
+#include "jagbios.h"\r
+#include "jagbios2.h"\r
+#include "jagstub2bios.h"\r
+#else\r
+#include "modelsBIOS.h"\r
+#endif\r
+#include "jagcdbios.h"\r
+#include "joystick.h"\r
+#include "m68000/m68kinterface.h"\r
+\r
+#include "debugger/DBGManager.h"\r
+//#include "debugger/VideoWin.h"\r
+//#include "debugger/DasmWin.h"\r
+#include "debugger/SourcesWin.h"\r
+#include "debugger/m68kDasmWin.h"\r
+#include "debugger/GPUDasmWin.h"\r
+#include "debugger/DSPDasmWin.h"\r
+#include "debugger/memory1browser.h"\r
+#include "debugger/BreakpointsWin.h"\r
+#include "debugger/NewFnctBreakpointWin.h"\r
+#include "debugger/FilesrcListWin.h"\r
+#include "debugger/exceptionvectortablebrowser.h"\r
+#include "debugger/allwatchbrowser.h"\r
+#include "debugger/localbrowser.h"\r
+#include "debugger/heapallocatorbrowser.h"\r
+#include "debugger/callstackbrowser.h"\r
+#include "debugger/CartFilesListWin.h"\r
+#include "debugger/SaveDumpAsWin.h"\r
+\r
+\r
+// According to SebRmv, this header isn't seen on Arch Linux either... :-/\r
+//#ifdef __GCCWIN32__\r
+// Apparently on win32, usleep() is not pulled in by the usual suspects.\r
+#ifndef _MSC_VER\r
+#include <unistd.h>\r
+#else\r
+#include "_MSC_VER/unistd.h"\r
+#endif // !_MSC_VER\r
+//#endif\r
+\r
+// The way BSNES controls things is by setting a timer with a zero\r
+// timeout, sleeping if not emulating anything. Seems there has to be a\r
+// better way.\r
+\r
+// It has a novel approach to plugging-in/using different video/audio/input\r
+// methods, can we do something similar or should we just use the built-in\r
+// QOpenGL?\r
+\r
+// We're going to try to use the built-in OpenGL support and see how it goes.\r
+// We'll make the VJ core modular so that it doesn't matter what GUI is in\r
+// use, we can drop it in anywhere and use it as-is.\r
+\r
+MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),\r
+ showUntunedTankCircuit(true), cartridgeLoaded(false), CDActive(false),\r
+ pauseForFileSelector(false), loadAndGo(autoRun), scannedSoftwareFolder(false), plzDontKillMyComputer(false)\r
+{\r
+ ReadSettings();\r
+\r
+ debugbar = NULL;\r
+\r
+ for(int i=0; i<8; i++)\r
+ keyHeld[i] = false;\r
+\r
+ // FPS management\r
+ for(int i=0; i<RING_BUFFER_SIZE; i++)\r
+ ringBuffer[i] = 0;\r
+\r
+ ringBufferPointer = RING_BUFFER_SIZE - 1;\r
+\r
+ // main window\r
+ //if (vjs.softTypeDebugger)\r
+ //{\r
+ // mainWindowCentrale = new QMdiArea;\r
+ // setCentralWidget(mainWindowCentrale);\r
+ //}\r
+\r
+ WriteLog("Window creation start\n");\r
+\r
+ // video output\r
+ videoWidget = new GLWidget(this);\r
+ videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);\r
+\r
+ // set central output window\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ setCentralWidget(videoWidget);\r
+ }\r
+ else\r
+ {\r
+ mainWindowCentrale = new QMdiArea(this);\r
+ setCentralWidget(mainWindowCentrale);\r
+ }\r
+\r
+ setWindowIcon(QIcon(":/res/vj-icon.png"));\r
+\r
+ QString title = QString(tr("Virtual Jaguar " VJ_RELEASE_VERSION " Rx"));\r
+\r
+ if (vjs.hardwareTypeAlpine)\r
+ title += QString(tr(" - Alpine Mode"));\r
+\r
+ if (vjs.softTypeDebugger)\r
+ title += QString(tr(" - Debugger Mode"));\r
+\r
+ setWindowTitle(title);\r
+\r
+ // Windows common features\r
+ aboutWin = new AboutWindow(this);\r
+ helpWin = new HelpWindow(this);\r
+ filePickWin = new FilePickerWindow(this);\r
+ emuStatusWin = new EmuStatusWindow(this);\r
+ \r
+ // Windows alpine mode features\r
+ memBrowseWin = new MemoryBrowserWindow(this);\r
+ stackBrowseWin = new StackBrowserWindow(this);\r
+ cpuBrowseWin = new CPUBrowserWindow(this);\r
+ opBrowseWin = new OPBrowserWindow(this);\r
+ m68kDasmBrowseWin = new M68KDasmBrowserWindow(this);\r
+ riscDasmBrowseWin = new RISCDasmBrowserWindow(this);\r
+ hwRegsBrowseWin = new HWRegsBrowserWindow(this);\r
+\r
+ // Windows debugger mode features\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ //VideoOutputWin = new VideoOutputWindow(this);\r
+ //VideoOutputWin->setCentralWidget()\r
+ //DasmWin = new DasmWindow();\r
+ //DasmWin = new DasmWindow(this);\r
+ allWatchBrowseWin = new AllWatchBrowserWindow(this);\r
+ LocalBrowseWin = new LocalBrowserWindow(this);\r
+ heapallocatorBrowseWin = new HeapAllocatorBrowserWindow(this);\r
+ BreakpointsWin = new BreakpointsWindow(this);\r
+ NewFunctionBreakpointWin = new NewFnctBreakpointWindow(this);\r
+ SaveDumpAsWin = new SaveDumpAsWindow(this);\r
+ exceptionvectortableBrowseWin = new ExceptionVectorTableBrowserWindow(this);\r
+ CallStackBrowseWin = new CallStackBrowserWindow(this);\r
+ CartFilesListWin = new CartFilesListWindow(this);\r
+\r
+ mem1BrowseWin = (Memory1BrowserWindow **)calloc(vjs.nbrmemory1browserwindow, sizeof(Memory1BrowserWindow));\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to do the memory desalocation for mem1BrowseWin !!!")\r
+#else\r
+ #warning "!!! Need to do the memory desalocation for mem1BrowseWin !!!"\r
+#endif // _MSC_VER\r
+ for (size_t i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ mem1BrowseWin[i] = new Memory1BrowserWindow(this);\r
+ }\r
+\r
+ // Setup dock to display source code filenames tree\r
+ QDockWidget *dockFiles = new QDockWidget(tr("Files"), this);\r
+ dockFiles->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);\r
+ dockFiles->hide();\r
+ addDockWidget(Qt::LeftDockWidgetArea, dockFiles);\r
+ mainWindowCentrale->addAction(dockFiles->toggleViewAction());\r
+ dockFiles->setWidget(FilesrcListWin = new FilesrcListWindow(this));\r
+#if 0\r
+ // Setup dock to display disassembly\r
+ QDockWidget *dockDisasm = new QDockWidget(tr("Disassembly"), this);\r
+ dockDisasm->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);\r
+ addDockWidget(Qt::RightDockWidgetArea, dockDisasm);\r
+ mainWindowCentrale->addAction(dockDisasm->toggleViewAction());\r
+ dockDisasm->setWidget(dasmtabWidget = new QTabWidget(this));\r
+#else\r
+ dasmtabWidget = new QTabWidget(this);\r
+#endif\r
+ // Setup disasm tabs\r
+ dasmtabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);\r
+ dasmtabWidget->addTab(SourcesWin = new SourcesWindow(this), tr("Sources"));\r
+ dasmtabWidget->setCurrentIndex(dasmtabWidget->addTab(m68kDasmWin = new m68KDasmWindow(this), tr("M68000")));\r
+ dasmtabWidget->addTab(GPUDasmWin = new GPUDasmWindow(this), tr("GPU"));\r
+ dasmtabWidget->addTab(DSPDasmWin = new DSPDasmWindow(this), tr("DSP"));\r
+ connect(dasmtabWidget, SIGNAL(currentChanged(const int)), this, SLOT(SelectdasmtabWidget(const int)));\r
+#if 1\r
+ setCentralWidget(dasmtabWidget);\r
+#endif\r
+ }\r
+\r
+// videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);\r
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);\r
+\r
+ setUnifiedTitleAndToolBarOnMac(true);\r
+\r
+ // Quit actions\r
+ quitAppAct = new QAction(QIcon(":/res/exit.png"), tr("E&xit"), this);\r
+ quitAppAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBQUIT].KBSettingValue)));\r
+ quitAppAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ quitAppAct->setStatusTip(tr("Quit Virtual Jaguar"));\r
+ connect(quitAppAct, SIGNAL(triggered()), this, SLOT(close()));\r
+\r
+ // Power action\r
+ powerGreen.addFile(":/res/power-off.png", QSize(), QIcon::Normal, QIcon::Off);\r
+ powerGreen.addFile(":/res/power-on-green.png", QSize(), QIcon::Normal, QIcon::On);\r
+ powerRed.addFile(":/res/power-off.png", QSize(), QIcon::Normal, QIcon::Off);\r
+ powerRed.addFile(":/res/power-on-red.png", QSize(), QIcon::Normal, QIcon::On);\r
+ powerAct = new QAction(powerGreen, tr("&Power"), this);\r
+ powerAct->setStatusTip(tr("Powers Jaguar on/off"));\r
+ powerAct->setCheckable(true);\r
+ powerAct->setChecked(false);\r
+ connect(powerAct, SIGNAL(triggered()), this, SLOT(TogglePowerState()));\r
+\r
+ // Pause action\r
+ QIcon pauseIcon;\r
+ pauseIcon.addFile(":/res/pause-off.png", QSize(), QIcon::Normal, QIcon::Off);\r
+ pauseIcon.addFile(":/res/pause-on.png", QSize(), QIcon::Normal, QIcon::On);\r
+ pauseAct = new QAction(pauseIcon, tr("Pause"), this);\r
+ pauseAct->setStatusTip(tr("Toggles the running state"));\r
+ pauseAct->setCheckable(true);\r
+ pauseAct->setDisabled(true);\r
+ pauseAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBPAUSE].KBSettingValue)));\r
+ pauseAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ connect(pauseAct, SIGNAL(triggered()), this, SLOT(ToggleRunState()));\r
+\r
+ // Screenshot action\r
+ screenshotAct = new QAction(QIcon(":/res/screenshot.png"), tr("&Screenshot"), this);\r
+ screenshotAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBSCREENSHOT].KBSettingValue)));\r
+ screenshotAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ screenshotAct->setCheckable(false);\r
+ screenshotAct->setDisabled(false);\r
+ connect(screenshotAct, SIGNAL(triggered()), this, SLOT(MakeScreenshot()));\r
+\r
+ // Zoom actions\r
+ zoomActs = new QActionGroup(this);\r
+ x1Act = new QAction(QIcon(":/res/zoom100.png"), tr("Zoom 100%"), zoomActs);\r
+ x1Act->setStatusTip(tr("Set window zoom to 100%"));\r
+ x1Act->setCheckable(true);\r
+ connect(x1Act, SIGNAL(triggered()), this, SLOT(SetZoom100()));\r
+ x2Act = new QAction(QIcon(":/res/zoom200.png"), tr("Zoom 200%"), zoomActs);\r
+ x2Act->setStatusTip(tr("Set window zoom to 200%"));\r
+ x2Act->setCheckable(true);\r
+ connect(x2Act, SIGNAL(triggered()), this, SLOT(SetZoom200()));\r
+ x3Act = new QAction(QIcon(":/res/zoom300.png"), tr("Zoom 300%"), zoomActs);\r
+ x3Act->setStatusTip(tr("Set window zoom to 300%"));\r
+ x3Act->setCheckable(true);\r
+ connect(x3Act, SIGNAL(triggered()), this, SLOT(SetZoom300()));\r
+\r
+ // TV type actions\r
+ tvTypeActs = new QActionGroup(this);\r
+ ntscAct = new QAction(QIcon(":/res/ntsc.png"), tr("NTSC"), tvTypeActs);\r
+ ntscAct->setStatusTip(tr("Sets Jaguar to NTSC mode"));\r
+ ntscAct->setCheckable(true);\r
+ connect(ntscAct, SIGNAL(triggered()), this, SLOT(SetNTSC()));\r
+ palAct = new QAction(QIcon(":/res/pal.png"), tr("PAL"), tvTypeActs);\r
+ palAct->setStatusTip(tr("Sets Jaguar to PAL mode"));\r
+ palAct->setCheckable(true);\r
+ connect(palAct, SIGNAL(triggered()), this, SLOT(SetPAL()));\r
+\r
+ // Blur action\r
+ blur.addFile(":/res/blur-off.png", QSize(), QIcon::Normal, QIcon::Off);\r
+ blur.addFile(":/res/blur-on.png", QSize(), QIcon::Normal, QIcon::On);\r
+ blurAct = new QAction(blur, tr("Blur"), this);\r
+ blurAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST"));\r
+ blurAct->setCheckable(true);\r
+ connect(blurAct, SIGNAL(triggered()), this, SLOT(ToggleBlur()));\r
+\r
+ // About action\r
+ aboutAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&About..."), this);\r
+ aboutAct->setStatusTip(tr("Blatant self-promotion"));\r
+ connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin()));\r
+\r
+ // Help action\r
+ helpAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&Contents..."), this);\r
+ helpAct->setStatusTip(tr("Help is available, if you should need it"));\r
+ connect(helpAct, SIGNAL(triggered()), this, SLOT(ShowHelpWin()));\r
+\r
+ // File pickup action\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ filePickAct = new QAction(QIcon(":/res/software.png"), tr("&Insert Cartridge..."), this);\r
+ filePickAct->setStatusTip(tr("Insert a cartridge into Virtual Jaguar"));\r
+ }\r
+ else\r
+ {\r
+ filePickAct = new QAction(QIcon(":/res/software.png"), tr("&Insert executable file..."), this);\r
+ filePickAct->setStatusTip(tr("Insert an executable into Virtual Jaguar"));\r
+ }\r
+ filePickAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBPICKFILE].KBSettingValue)));\r
+ filePickAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ connect(filePickAct, SIGNAL(triggered()), this, SLOT(InsertCart()));\r
+\r
+ // Configuration action\r
+ configAct = new QAction(QIcon(":/res/wrench.png"), tr("&Configure"), this);\r
+ configAct->setStatusTip(tr("Configure options for Virtual Jaguar"));\r
+ configAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBCONFIGURE].KBSettingValue)));\r
+ configAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ connect(configAct, SIGNAL(triggered()), this, SLOT(Configure()));\r
+\r
+ // Emulation status action\r
+ emustatusAct = new QAction(QIcon(":/res/status.png"), tr("&Status"), this);\r
+ emustatusAct->setStatusTip(tr("Emulator status"));\r
+ emustatusAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBEMUSTATUS].KBSettingValue)));\r
+ emustatusAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ connect(emustatusAct, SIGNAL(triggered()), this, SLOT(ShowEmuStatusWin()));\r
+\r
+ // Use CD action\r
+ useCDAct = new QAction(QIcon(":/res/compact-disc.png"), tr("&Use CD Unit"), this);\r
+ useCDAct->setStatusTip(tr("Use Jaguar Virtual CD unit"));\r
+ useCDAct->setCheckable(true);\r
+ connect(useCDAct, SIGNAL(triggered()), this, SLOT(ToggleCDUsage()));\r
+\r
+ // Frame advance action\r
+ frameAdvanceAct = new QAction(QIcon(":/res/frame-advance.png"), tr("&Frame Advance"), this);\r
+ frameAdvanceAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFRAMEADVANCE].KBSettingValue)));\r
+ frameAdvanceAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ frameAdvanceAct->setDisabled(true);\r
+ connect(frameAdvanceAct, SIGNAL(triggered()), this, SLOT(FrameAdvance()));\r
+\r
+ // Fullscreen action\r
+ fullScreenAct = new QAction(QIcon(":/res/fullscreen.png"), tr("F&ull Screen"), this);\r
+ fullScreenAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFULLSCREEN].KBSettingValue)));\r
+ fullScreenAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ fullScreenAct->setCheckable(true);\r
+ connect(fullScreenAct, SIGNAL(triggered()), this, SLOT(ToggleFullScreen()));\r
+\r
+ // Actions dedicated to debugger mode\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ // Restart\r
+ restartAct = new QAction(QIcon(":/res/debug-restart.png"), tr("&Restart"), this);\r
+ restartAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBRESTART].KBSettingValue)));\r
+ restartAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ restartAct->setCheckable(false);\r
+ restartAct->setDisabled(true);\r
+ connect(restartAct, SIGNAL(triggered()), this, SLOT(DebuggerRestart()));\r
+\r
+ // Step over trace\r
+ traceStepOverAct = new QAction(QIcon(":/res/debug-stepover.png"), tr("&Step Over"), this);\r
+ traceStepOverAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBSTEPOVER].KBSettingValue)));\r
+ traceStepOverAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ traceStepOverAct->setCheckable(false);\r
+ traceStepOverAct->setDisabled(true);\r
+ connect(traceStepOverAct, SIGNAL(triggered()), this, SLOT(DebuggerTraceStepOver()));\r
+\r
+ // Trace into tracing\r
+ traceStepIntoAct = new QAction(QIcon(":/res/debug-stepinto.png"), tr("&Step Into"), this);\r
+ traceStepIntoAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBSTEPINTO].KBSettingValue)));\r
+ traceStepIntoAct->setShortcutContext(Qt::ApplicationShortcut);\r
+ traceStepIntoAct->setCheckable(false);\r
+ traceStepIntoAct->setDisabled(true);\r
+ connect(traceStepIntoAct, SIGNAL(triggered()), this, SLOT(DebuggerTraceStepInto()));\r
+\r
+ // Function breakpoint\r
+ newFunctionBreakpointAct = new QAction(QIcon(""), tr("&Function Breakpoint"), this);\r
+ newFunctionBreakpointAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBFUNCTIONBREAKPOINT].KBSettingValue)));\r
+ connect(newFunctionBreakpointAct, SIGNAL(triggered()), this, SLOT(ShowNewFunctionBreakpointWin()));\r
+ BreakpointsAct = new QAction(QIcon(":/res/debug-breakpoints.png"), tr("&Breakpoints"), this);\r
+ BreakpointsAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBBREAKPOINTS].KBSettingValue)));\r
+ connect(BreakpointsAct, SIGNAL(triggered()), this, SLOT(ShowBreakpointsWin()));\r
+ deleteAllBreakpointsAct = new QAction(QIcon(":/res/debug-deleteallbreakpoints.png"), tr("&Delete All Breakpoints"), this);\r
+ deleteAllBreakpointsAct->setShortcut(QKeySequence(tr(vjs.KBContent[KBDELETEALLBREAKPOINTS].KBSettingValue)));\r
+ connect(deleteAllBreakpointsAct, SIGNAL(triggered()), this, SLOT(DeleteAllBreakpoints()));\r
+ disableAllBreakpointsAct = new QAction(QIcon(":/res/debug-disableallbreakpoints.png"), tr("&Disable All Breakpoints"), this);\r
+ connect(disableAllBreakpointsAct, SIGNAL(triggered()), this, SLOT(DisableAllBreakpoints()));\r
+\r
+ // Save dump\r
+ saveDumpAsAct = new QAction(tr("&Save Dump As..."), this);\r
+ saveDumpAsAct->setCheckable(false);\r
+ saveDumpAsAct->setDisabled(false);\r
+ connect(saveDumpAsAct, SIGNAL(triggered()), this, SLOT(ShowSaveDumpAsWin()));\r
+\r
+ //VideoOutputAct = new QAction(tr("Output Video"), this);\r
+ //VideoOutputAct->setStatusTip(tr("Shows the output video window"));\r
+ //connect(VideoOutputAct, SIGNAL(triggered()), this, SLOT(ShowVideoOutputWin()));\r
+\r
+ //DasmAct = new QAction(tr("Disassembly"), this);\r
+ //DasmAct->setStatusTip(tr("Shows the disassembly window"));\r
+ //connect(DasmAct, SIGNAL(triggered()), this, SLOT(ShowDasmWin()));\r
+\r
+ // Exception vector table window\r
+ exceptionVectorTableBrowseAct = new QAction(QIcon(""), tr("Exception Vector Table"), this);\r
+ exceptionVectorTableBrowseAct->setStatusTip(tr("Shows all Exception Vector Table browser window"));\r
+ connect(exceptionVectorTableBrowseAct, SIGNAL(triggered()), this, SLOT(ShowExceptionVectorTableBrowserWin()));\r
+\r
+ // All watch variables window\r
+ allWatchBrowseAct = new QAction(QIcon(":/res/debug-watch.png"), tr("All Watch"), this);\r
+ allWatchBrowseAct->setStatusTip(tr("Shows all Watch browser window"));\r
+ connect(allWatchBrowseAct, SIGNAL(triggered()), this, SLOT(ShowAllWatchBrowserWin()));\r
+\r
+ // Local variables window\r
+ LocalBrowseAct = new QAction(QIcon(":/res/debug-local.png"), tr("Locals"), this);\r
+ LocalBrowseAct->setStatusTip(tr("Shows Locals browser window"));\r
+ connect(LocalBrowseAct, SIGNAL(triggered()), this, SLOT(ShowLocalBrowserWin()));\r
+\r
+ // Heap (memory) allocation window\r
+ heapallocatorBrowseAct = new QAction(QIcon(""), tr("Heap allocator"), this);\r
+ heapallocatorBrowseAct->setStatusTip(tr("Shows the heap allocator browser window"));\r
+ connect(heapallocatorBrowseAct, SIGNAL(triggered()), this, SLOT(ShowHeapAllocatorBrowserWin()));\r
+\r
+ // Call stack window\r
+ CallStackBrowseAct = new QAction(QIcon(":/res/debug-callstack.png"), tr("Call Stack"), this);\r
+ CallStackBrowseAct->setStatusTip(tr("Shows Call Stack browser window"));\r
+ connect(CallStackBrowseAct, SIGNAL(triggered()), this, SLOT(ShowCallStackBrowserWin()));\r
+\r
+ // Cart files list\r
+ CartFilesListAct = new QAction(QIcon(""), tr("Directory and files"), this);\r
+ CartFilesListAct->setStatusTip(tr("List of the files in the cartridge's directory structure"));\r
+ connect(CartFilesListAct, SIGNAL(triggered()), this, SLOT(ShowCartFilesListWin()));\r
+\r
+ // Memory windows\r
+ mem1BrowseAct = (QAction **)calloc(vjs.nbrmemory1browserwindow, sizeof(QAction));\r
+ QSignalMapper *signalMapper = new QSignalMapper(this);\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to do the memory desalocation for mem1BrowseAct !!!")\r
+#else\r
+#warning "!!! Need to do the memory desalocation for mem1BrowseAct !!!"\r
+#endif // _MSC_VER\r
+ for (int i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ char MB[100];\r
+ sprintf(MB, "Memory %i", (unsigned int)(i+1));\r
+ mem1BrowseAct[i] = new QAction(QIcon(":/res/debug-memory.png"), tr(MB), this);\r
+ mem1BrowseAct[i]->setStatusTip(tr("Shows a Jaguar memory browser window"));\r
+ connect(mem1BrowseAct[i], SIGNAL(triggered()), signalMapper, SLOT(map()));\r
+ signalMapper->setMapping(mem1BrowseAct[i], (int)i);\r
+ connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(ShowMemory1BrowserWin(int)));\r
+ }\r
+ }\r
+\r
+ // Memory browser window action\r
+ memBrowseAct = new QAction(QIcon(":/res/tool-memory.png"), tr("Memory Browser"), this);\r
+ memBrowseAct->setStatusTip(tr("Shows the Jaguar memory browser window"));\r
+ connect(memBrowseAct, SIGNAL(triggered()), this, SLOT(ShowMemoryBrowserWin()));\r
+\r
+ // Stack browser window action\r
+ stackBrowseAct = new QAction(QIcon(":/res/tool-stack.png"), tr("Stack Browser"), this);\r
+ stackBrowseAct->setStatusTip(tr("Shows the Jaguar stack browser window"));\r
+ connect(stackBrowseAct, SIGNAL(triggered()), this, SLOT(ShowStackBrowserWin()));\r
+\r
+ // CPUs (M68000, GPU & DSP browser window action\r
+ cpuBrowseAct = new QAction(QIcon(":/res/tool-cpu.png"), tr("CPU Browser"), this);\r
+ cpuBrowseAct->setStatusTip(tr("Shows the Jaguar CPU browser window"));\r
+ connect(cpuBrowseAct, SIGNAL(triggered()), this, SLOT(ShowCPUBrowserWin()));\r
+\r
+ // OP browser window action\r
+ opBrowseAct = new QAction(QIcon(":/res/tool-op.png"), tr("OP Browser"), this);\r
+ opBrowseAct->setStatusTip(tr("Shows the Jaguar OP browser window"));\r
+ connect(opBrowseAct, SIGNAL(triggered()), this, SLOT(ShowOPBrowserWin()));\r
+\r
+ // M68000 disassembly browser window\r
+ m68kDasmBrowseAct = new QAction(QIcon(":/res/tool-68k-dis.png"), tr("68K Listing Browser"), this);\r
+ m68kDasmBrowseAct->setStatusTip(tr("Shows the 68K disassembly browser window"));\r
+ connect(m68kDasmBrowseAct, SIGNAL(triggered()), this, SLOT(ShowM68KDasmBrowserWin()));\r
+\r
+ // HW registers browser window\r
+ hwRegsBrowseAct = new QAction(QIcon(":/res/tool-hw-regs.png"), tr("HW Registers Browser"), this);\r
+ hwRegsBrowseAct->setStatusTip(tr("Shows the HW registers browser window"));\r
+ connect(hwRegsBrowseAct, SIGNAL(triggered()), this, SLOT(ShowHWRegsBrowserWin()));\r
+\r
+ // Risc (DSP / GPU) disassembly browser window\r
+ riscDasmBrowseAct = new QAction(QIcon(":/res/tool-risc-dis.png"), tr("RISC Listing Browser"), this);\r
+ riscDasmBrowseAct->setStatusTip(tr("Shows the RISC disassembly browser window"));\r
+ connect(riscDasmBrowseAct, SIGNAL(triggered()), this, SLOT(ShowRISCDasmBrowserWin()));\r
+\r
+ // Misc. connections...\r
+ connect(filePickWin, SIGNAL(RequestLoad(QString)), this, SLOT(LoadSoftware(QString)));\r
+ connect(filePickWin, SIGNAL(FilePickerHiding()), this, SLOT(Unpause()));\r
+\r
+ // Create menus\r
+\r
+ fileMenu = menuBar()->addMenu(tr("&Jaguar"));\r
+ fileMenu->addAction(powerAct);\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ fileMenu->addAction(pauseAct);\r
+ // fileMenu->addAction(frameAdvanceAct);\r
+ }\r
+ fileMenu->addAction(filePickAct);\r
+ fileMenu->addAction(useCDAct);\r
+ fileMenu->addAction(configAct);\r
+ fileMenu->addAction(emustatusAct);\r
+ fileMenu->addSeparator();\r
+ fileMenu->addAction(quitAppAct);\r
+\r
+ // Alpine and debugger menus\r
+ if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)\r
+ {\r
+ // Create debug menu\r
+ debugMenu = menuBar()->addMenu(tr("&Debug"));\r
+\r
+ // Create debugger menu\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ // Create view menu\r
+ viewMenu = menuBar()->addMenu(tr("&View"));\r
+\r
+ // Cart menu\r
+ viewCartMenu = viewMenu->addMenu(tr("&Cartridge"));\r
+ viewCartMenu->addAction(CartFilesListAct);\r
+#if 0\r
+ viewCartMenu->addSeparator();\r
+ viewCartMenu->addAction(CartStreamsAct);\r
+#endif\r
+\r
+ // Windows menu\r
+ debugWindowsMenu = debugMenu->addMenu(tr("&Windows"));\r
+ debugWindowsMenu->addAction(BreakpointsAct);\r
+ debugWindowExceptionMenu = debugWindowsMenu->addMenu(tr("&Exception"));\r
+ debugWindowExceptionMenu->addAction(exceptionVectorTableBrowseAct);\r
+ debugWindowsMenu->addSeparator();\r
+#if 0\r
+ debugWindowOutputMenu = debugWindowsMenu->addMenu(tr("&Output"));\r
+ debugWindowOutputMenu->addAction(VideoOutputAct);\r
+ debugWindowsMenu->addSeparator();\r
+#endif\r
+ debugWindowsWatchMenu = debugWindowsMenu->addMenu(tr("&Watch"));\r
+ debugWindowsWatchMenu->addAction(allWatchBrowseAct);\r
+ debugWindowsMenu->addAction(LocalBrowseAct);\r
+ debugWindowsMenu->addSeparator();\r
+ debugWindowsMenu->addAction(CallStackBrowseAct);\r
+ debugWindowsMenu->addSeparator();\r
+ debugWindowsMemoryMenu = debugWindowsMenu->addMenu(tr("&Memory"));\r
+ debugWindowsMemoryMenu->addAction(heapallocatorBrowseAct);\r
+ debugWindowsMemoryMenu->addSeparator();\r
+ for (int i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ debugWindowsMemoryMenu->addAction(mem1BrowseAct[i]);\r
+ }\r
+ debugWindowsMenu->addSeparator();\r
+ debugWindowsBrowsesMenu = debugWindowsMenu->addMenu(tr("&Browsers"));\r
+ debugWindowsBrowsesMenu->addAction(memBrowseAct);\r
+ debugWindowsBrowsesMenu->addAction(stackBrowseAct);\r
+ debugWindowsBrowsesMenu->addAction(cpuBrowseAct);\r
+ debugWindowsBrowsesMenu->addAction(opBrowseAct);\r
+ debugWindowsBrowsesMenu->addAction(m68kDasmBrowseAct);\r
+ debugWindowsBrowsesMenu->addAction(riscDasmBrowseAct);\r
+ debugWindowsBrowsesMenu->addAction(hwRegsBrowseAct);\r
+ debugMenu->addSeparator();\r
+ debugMenu->addAction(pauseAct);\r
+ debugMenu->addAction(frameAdvanceAct);\r
+ debugMenu->addAction(restartAct);\r
+ debugMenu->addSeparator();\r
+ debugMenu->addAction(traceStepIntoAct);\r
+ debugMenu->addAction(traceStepOverAct);\r
+ debugMenu->addSeparator();\r
+ debugNewBreakpointMenu = debugMenu->addMenu(tr("&New Breakpoint"));\r
+ debugNewBreakpointMenu->addAction(newFunctionBreakpointAct);\r
+ debugMenu->addAction(deleteAllBreakpointsAct);\r
+ debugMenu->addAction(disableAllBreakpointsAct);\r
+ debugMenu->addSeparator();\r
+ debugMenu->addAction(saveDumpAsAct);\r
+#if 0\r
+ debugMenu->addSeparator();\r
+ debugMenu->addAction(DasmAct);\r
+#endif\r
+ }\r
+ else\r
+ {\r
+ // Create alpine menu\r
+ debugMenu->addAction(memBrowseAct);\r
+ debugMenu->addAction(stackBrowseAct);\r
+ debugMenu->addAction(cpuBrowseAct);\r
+ debugMenu->addAction(opBrowseAct);\r
+ debugMenu->addAction(m68kDasmBrowseAct);\r
+ debugMenu->addAction(riscDasmBrowseAct);\r
+ debugMenu->addAction(hwRegsBrowseAct);\r
+ }\r
+ }\r
+\r
+ // Help menus\r
+ helpMenu = menuBar()->addMenu(tr("&Help"));\r
+ helpMenu->addAction(helpAct);\r
+ helpMenu->addAction(aboutAct);\r
+\r
+ // Create toolbars\r
+\r
+ toolbar = addToolBar(tr("System"));\r
+ toolbar->addAction(powerAct);\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ toolbar->addAction(pauseAct);\r
+ toolbar->addAction(frameAdvanceAct);\r
+ }\r
+ toolbar->addAction(filePickAct);\r
+ toolbar->addAction(useCDAct);\r
+ toolbar->addSeparator();\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ toolbar->addAction(screenshotAct);\r
+ toolbar->addSeparator();\r
+ toolbar->addAction(x1Act);\r
+ toolbar->addAction(x2Act);\r
+ toolbar->addAction(x3Act);\r
+ toolbar->addSeparator();\r
+ toolbar->addAction(ntscAct);\r
+ toolbar->addAction(palAct);\r
+ toolbar->addSeparator();\r
+ toolbar->addAction(blurAct);\r
+ toolbar->addAction(fullScreenAct);\r
+ }\r
+ else\r
+ {\r
+ debuggerbar = addToolBar(tr("&Debugger"));\r
+ debuggerbar->addAction(pauseAct);\r
+ debuggerbar->addAction(frameAdvanceAct);\r
+ debuggerbar->addAction(restartAct);\r
+ debuggerbar->addSeparator();\r
+ debuggerbar->addAction(traceStepIntoAct);\r
+ debuggerbar->addAction(traceStepOverAct);\r
+ debuggerbar->addSeparator();\r
+ debuggerbar->addAction(BreakpointsAct);\r
+ }\r
+\r
+ if (vjs.hardwareTypeAlpine)\r
+ {\r
+ debugbar = addToolBar(tr("&Debug"));\r
+ debugbar->addAction(memBrowseAct);\r
+ debugbar->addAction(stackBrowseAct);\r
+ debugbar->addAction(cpuBrowseAct);\r
+ debugbar->addAction(opBrowseAct);\r
+ debugbar->addAction(m68kDasmBrowseAct);\r
+ debugbar->addAction(riscDasmBrowseAct);\r
+ debugbar->addAction(hwRegsBrowseAct);\r
+ }\r
+\r
+ // Add actions to the main window, as hiding widgets with them\r
+ // disables them :-P\r
+ addAction(fullScreenAct);\r
+ addAction(quitAppAct);\r
+ addAction(configAct);\r
+ addAction(emustatusAct);\r
+ addAction(pauseAct);\r
+ addAction(filePickAct);\r
+ addAction(frameAdvanceAct);\r
+\r
+ // Create status bar\r
+ statusBar()->showMessage(tr("Ready"));\r
+ ReadUISettings();\r
+ // Do this in case original size isn't correct (mostly for the first-run case)\r
+ ResizeMainWindow();\r
+\r
+ WriteLog("Window creation done\n");\r
+\r
+ // Create our test pattern NTSC bitmap\r
+ WriteLog("Test pattern 1 bitmap\n");\r
+\r
+ QImage tempImg(":/res/test-pattern.jpg");\r
+ QImage tempImgScaled = tempImg.scaled(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT_PAL, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);\r
+\r
+ for(uint32_t y=0; y<VIRTUAL_SCREEN_HEIGHT_PAL; y++)\r
+ {\r
+ const QRgb * scanline = (QRgb *)tempImgScaled.constScanLine(y);\r
+\r
+ for(uint32_t x=0; x<VIRTUAL_SCREEN_WIDTH; x++)\r
+ {\r
+ uint32_t pixel = (qRed(scanline[x]) << 24) | (qGreen(scanline[x]) << 16) | (qBlue(scanline[x]) << 8) | 0xFF;\r
+ testPattern[(y * VIRTUAL_SCREEN_WIDTH) + x] = pixel;\r
+ }\r
+ }\r
+\r
+ // Create our test pattern PAL bitmap\r
+ WriteLog("Test pattern 2 bitmap\n");\r
+\r
+ QImage tempImg2(":/res/test-pattern-pal.jpg");\r
+ QImage tempImgScaled2 = tempImg2.scaled(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT_PAL, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);\r
+\r
+ for(uint32_t y=0; y<VIRTUAL_SCREEN_HEIGHT_PAL; y++)\r
+ {\r
+ const QRgb * scanline = (QRgb *)tempImgScaled2.constScanLine(y);\r
+\r
+ for(uint32_t x=0; x<VIRTUAL_SCREEN_WIDTH; x++)\r
+ {\r
+ uint32_t pixel = (qRed(scanline[x]) << 24) | (qGreen(scanline[x]) << 16) | (qBlue(scanline[x]) << 8) | 0xFF;\r
+ testPattern2[(y * VIRTUAL_SCREEN_WIDTH) + x] = pixel;\r
+ }\r
+ }\r
+\r
+ // Set up timer based loop for animation...\r
+ timer = new QTimer(this);\r
+ connect(timer, SIGNAL(timeout()), this, SLOT(Timer()));\r
+\r
+ // This isn't very accurate for NTSC: This is early by 40 msec per frame.\r
+ // This is because it's discarding the 0.6666... on the end of the fraction.\r
+ // Alas, 6 doesn't divide cleanly into 10. :-P\r
+//Should we defer this until SyncUI? Probably.\r
+//No, it doesn't work, because it uses setInterval() instead of start()...\r
+// timer->start(vjs.hardwareTypeNTSC ? 16 : 20);\r
+\r
+ // We set this initially, to make VJ behave somewhat as it would if no\r
+ // cart were inserted and the BIOS was set as active...\r
+ jaguarCartInserted = true;\r
+ WriteLog("Virtual Jaguar %s Rx (Last full build was on %s %s)\n", VJ_RELEASE_VERSION, __DATE__, __TIME__);\r
+ WriteLog("VJ: Initializing jaguar subsystem...\n");\r
+ JaguarInit();\r
+\r
+#ifndef NEWMODELSBIOSHANDLER\r
+ // memcpy(jagMemSpace + 0xE00000, jaguarBootROM, 0x20000); // Use the stock BIOS\r
+ memcpy(jagMemSpace + 0xE00000, (vjs.biosType == BT_K_SERIES ? jaguarBootROM : jaguarBootROM2), 0x20000); // Use the stock BIOS\r
+#else\r
+ SelectBIOS(vjs.biosType);\r
+#endif\r
+\r
+ // Prevent the file scanner from running if filename passed\r
+ // in on the command line...\r
+ if (autoRun)\r
+ return;\r
+\r
+ // Load up the default ROM if in Alpine mode:\r
+ if (vjs.hardwareTypeAlpine)\r
+ {\r
+ bool romLoaded = JaguarLoadFile(vjs.alpineROMPath);\r
+\r
+ // If regular load failed, try just a straight file load\r
+ // (Dev only! I don't want people to start getting lazy with their releases again! :-P)\r
+ if (!romLoaded)\r
+ romLoaded = AlpineLoadFile(vjs.alpineROMPath);\r
+\r
+ if (romLoaded)\r
+ WriteLog("Alpine Mode: Successfully loaded file \"%s\".\n", vjs.alpineROMPath);\r
+ else\r
+ WriteLog("Alpine Mode: Unable to load file \"%s\"!\n", vjs.alpineROMPath);\r
+\r
+ // Attempt to load/run the ABS file...\r
+ LoadSoftware(vjs.absROMPath);\r
+#ifndef NEWMODELSBIOSHANDLER\r
+ memcpy(jagMemSpace + 0xE00000, jaguarDevBootROM2, 0x20000); // Use the stub BIOS\r
+#else\r
+ SelectBIOS(vjs.biosType);\r
+#endif\r
+ // Prevent the scanner from running...\r
+ return;\r
+ }\r
+\r
+ // Load up the default ROM if in Debugger mode:\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ bool romLoaded = JaguarLoadFile(vjs.debuggerROMPath);\r
+\r
+ // If regular load failed, try just a straight file load\r
+ // (Dev only! I don't want people to start getting lazy with their releases again! :-P)\r
+ if (!romLoaded)\r
+ romLoaded = DebuggerLoadFile(vjs.debuggerROMPath);\r
+\r
+ if (romLoaded)\r
+ WriteLog("Debugger Mode: Successfully loaded file \"%s\".\n", vjs.debuggerROMPath);\r
+ else\r
+ WriteLog("Debugger Mode: Unable to load file \"%s\"!\n", vjs.debuggerROMPath);\r
+\r
+ // Attempt to load/run the ABS file...\r
+ LoadSoftware(vjs.absROMPath);\r
+#ifndef NEWMODELSBIOSHANDLER\r
+ memcpy(jagMemSpace + 0xE00000, jaguarDevBootROM2, 0x20000); // Use the stub BIOS\r
+ // Prevent the scanner from running...\r
+#else\r
+ SelectBIOS(vjs.biosType);\r
+#endif\r
+ return;\r
+ }\r
+\r
+ // Run the scanner if nothing passed in and *not* Alpine mode...\r
+ // NB: Really need to look into caching the info scanned in here...\r
+ filePickWin->ScanSoftwareFolder(allowUnknownSoftware);\r
+ scannedSoftwareFolder = true;\r
+}\r
+\r
+\r
+void MainWin::LoadFile(QString file)\r
+{\r
+ LoadSoftware(file);\r
+}\r
+\r
+\r
+void MainWin::SyncUI(void)\r
+{\r
+ // Set toolbar buttons/menus based on settings read in (sync the UI)...\r
+ // (Really, this is to sync command line options passed in)\r
+ blurAct->setChecked(vjs.glFilter);\r
+ x1Act->setChecked(zoomLevel == 1);\r
+ x2Act->setChecked(zoomLevel == 2);\r
+ x3Act->setChecked(zoomLevel == 3);\r
+// running = powerAct->isChecked();\r
+ ntscAct->setChecked(vjs.hardwareTypeNTSC);\r
+ palAct->setChecked(!vjs.hardwareTypeNTSC);\r
+ powerAct->setIcon(vjs.hardwareTypeNTSC ? powerRed : powerGreen);\r
+\r
+ fullScreenAct->setChecked(vjs.fullscreen);\r
+ fullScreen = vjs.fullscreen;\r
+ SetFullScreen(fullScreen);\r
+\r
+ // Reset the timer to be what was set in the command line (if any):\r
+// timer->setInterval(vjs.hardwareTypeNTSC ? 16 : 20);\r
+ timer->start(vjs.hardwareTypeNTSC ? 16 : 20);\r
+}\r
+\r
+\r
+// \r
+void MainWin::SelectdasmtabWidget(const int Index)\r
+{\r
+ // check sources tab\r
+ if (Index == 0)\r
+ {\r
+ SourcesWin->RefreshContents();\r
+ }\r
+}\r
+\r
+\r
+void MainWin::closeEvent(QCloseEvent * event)\r
+{\r
+ JaguarDone();\r
+// This should only be done by the config dialog\r
+// WriteSettings();\r
+ WriteUISettings();\r
+ event->accept(); // ignore() if can't close for some reason\r
+}\r
+\r
+\r
+void MainWin::keyPressEvent(QKeyEvent * e)\r
+{\r
+#ifndef VJ_REMOVE_DEV_CODE\r
+ // From jaguar.cpp\r
+ //extern bool startM68KTracing; // moved to jaguar.h\r
+ // From joystick.cpp\r
+ extern int blit_start_log;\r
+ // From blitter.cpp\r
+ extern bool startConciseBlitLogging;\r
+#endif\r
+\r
+ // We ignore the Alt key for now, since it causes problems with the GUI\r
+ if (e->key() == Qt::Key_Alt)\r
+ {\r
+ e->accept();\r
+ return;\r
+ }\r
+// Bar this shite from release versions kthxbai\r
+#ifndef VJ_REMOVE_DEV_CODE\r
+ else if (e->key() == Qt::Key_F11)\r
+ {\r
+ startM68KTracing = true;\r
+ e->accept();\r
+ return;\r
+ }\r
+ else if (e->key() == Qt::Key_F12)\r
+ {\r
+ blit_start_log = true;\r
+ e->accept();\r
+ return;\r
+ }\r
+ else if (e->key() == Qt::Key_F10)\r
+ {\r
+ startConciseBlitLogging = true;\r
+ e->accept();\r
+ return;\r
+ }\r
+#endif\r
+ else if (e->key() == Qt::Key_F8)\r
+ {\r
+ // ggn: For extra NYAN pleasure...\r
+ // ggn: There you go James :P\r
+ // Shamus: Thanks for the patch! :-D\r
+ WriteLog(" o + + +\n");\r
+ WriteLog("+ o o + o\n");\r
+ WriteLog("-_-_-_-_-_-_-_,------, o \n");\r
+ WriteLog("_-_-_-_-_-_-_-| /\\_/\\ \n");\r
+ WriteLog("-_-_-_-_-_-_-~|__( ^ .^) + + \n");\r
+ WriteLog("_-_-_-_-_-_-_-\"\" \"\" \n");\r
+ WriteLog("+ o o + o\n");\r
+ WriteLog(" + +\n");\r
+ e->accept();\r
+ return;\r
+ }\r
+\r
+/*\r
+This is done now by a QAction...\r
+ if (e->key() == Qt::Key_F9)\r
+ {\r
+ ToggleFullScreen();\r
+ return;\r
+ }\r
+*/\r
+ HandleKeys(e, true);\r
+}\r
+\r
+\r
+void MainWin::keyReleaseEvent(QKeyEvent * e)\r
+{\r
+ // We ignore the Alt key for now, since it causes problems with the GUI\r
+ if (e->key() == Qt::Key_Alt)\r
+ {\r
+ e->accept();\r
+ return;\r
+ }\r
+\r
+ HandleKeys(e, false);\r
+}\r
+\r
+\r
+void MainWin::HandleKeys(QKeyEvent * e, bool state)\r
+{\r
+ enum { P1LEFT = 0, P1RIGHT, P1UP, P1DOWN, P2LEFT, P2RIGHT, P2UP, P2DOWN };\r
+ // We kill bad key combos here, before they can get to the emulator...\r
+ // This also kills the illegal instruction problem that cropped up in\r
+ // Rayman!\r
+\r
+ // First, settle key states...\r
+ if (e->key() == (int)vjs.p1KeyBindings[BUTTON_L])\r
+ keyHeld[P1LEFT] = state;\r
+ else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_R])\r
+ keyHeld[P1RIGHT] = state;\r
+ else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_U])\r
+ keyHeld[P1UP] = state;\r
+ else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_D])\r
+ keyHeld[P1DOWN] = state;\r
+ else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_L])\r
+ keyHeld[P2LEFT] = state;\r
+ else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_R])\r
+ keyHeld[P2RIGHT] = state;\r
+ else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_U])\r
+ keyHeld[P2UP] = state;\r
+ else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_D])\r
+ keyHeld[P2DOWN] = state;\r
+\r
+ // Next, check for conflicts and kill 'em if there are any...\r
+ if (keyHeld[P1LEFT] && keyHeld[P1RIGHT])\r
+ keyHeld[P1LEFT] = keyHeld[P1RIGHT] = false;\r
+\r
+ if (keyHeld[P1UP] && keyHeld[P1DOWN])\r
+ keyHeld[P1UP] = keyHeld[P1DOWN] = false;\r
+\r
+ if (keyHeld[P2LEFT] && keyHeld[P2RIGHT])\r
+ keyHeld[P2LEFT] = keyHeld[P2RIGHT] = false;\r
+\r
+ if (keyHeld[P2UP] && keyHeld[P2DOWN])\r
+ keyHeld[P2UP] = keyHeld[P2DOWN] = false;\r
+\r
+ // No bad combos exist now, let's stuff the emulator key buffers...!\r
+ for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)\r
+ {\r
+ if (e->key() == (int)vjs.p1KeyBindings[i])\r
+ joypad0Buttons[i] = (state ? 0x01 : 0x00);\r
+\r
+ if (e->key() == (int)vjs.p2KeyBindings[i])\r
+ joypad1Buttons[i] = (state ? 0x01 : 0x00);\r
+ }\r
+}\r
+\r
+\r
+//\r
+// N.B.: The profile system AutoConnect functionality sets the gamepad IDs here.\r
+//\r
+void MainWin::HandleGamepads(void)\r
+{\r
+ Gamepad::Update();\r
+\r
+ for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)\r
+ {\r
+ if (vjs.p1KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))\r
+ joypad0Buttons[i] = (Gamepad::GetState(gamepadIDSlot1, vjs.p1KeyBindings[i]) ? 0x01 : 0x00);\r
+\r
+ if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))\r
+ joypad1Buttons[i] = (Gamepad::GetState(gamepadIDSlot2, vjs.p2KeyBindings[i]) ? 0x01 : 0x00);\r
+ }\r
+}\r
+\r
+\r
+void MainWin::Open(void)\r
+{\r
+}\r
+\r
+\r
+void MainWin::Configure(void)\r
+{\r
+ // Call the configuration dialog and update settings\r
+ ConfigDialog dlg(this);\r
+ //ick.\r
+ dlg.generalTab->useUnknownSoftware->setChecked(allowUnknownSoftware);\r
+ dlg.controllerTab1->profileNum = lastEditedProfile;\r
+ dlg.controllerTab1->SetupLastUsedProfile();\r
+// maybe instead of this, we tell the controller tab to work on a copy that gets\r
+// written if the user hits 'OK'.\r
+ SaveProfiles(); // Just in case user cancels\r
+\r
+ if (dlg.exec() == false)\r
+ {\r
+ RestoreProfiles();\r
+ return;\r
+ }\r
+\r
+ QString before = vjs.ROMPath;\r
+ QString alpineBefore = vjs.alpineROMPath;\r
+ QString absBefore = vjs.absROMPath;\r
+// bool audioBefore = vjs.audioEnabled;\r
+ bool audioBefore = vjs.DSPEnabled;\r
+ dlg.UpdateVJSettings();\r
+ QString after = vjs.ROMPath;\r
+ QString alpineAfter = vjs.alpineROMPath;\r
+ QString absAfter = vjs.absROMPath;\r
+// bool audioAfter = vjs.audioEnabled;\r
+ bool audioAfter = vjs.DSPEnabled;\r
+\r
+ bool allowOld = allowUnknownSoftware;\r
+ //ick.\r
+ allowUnknownSoftware = dlg.generalTab->useUnknownSoftware->isChecked();\r
+ lastEditedProfile = dlg.controllerTab1->profileNum;\r
+ AutoConnectProfiles();\r
+\r
+ // We rescan the "software" folder if the user either changed the path or\r
+ // checked/unchecked the "Allow unknown files" option in the config dialog.\r
+ if ((before != after) || (allowOld != allowUnknownSoftware))\r
+ filePickWin->ScanSoftwareFolder(allowUnknownSoftware);\r
+\r
+ // If the "Alpine" ROM is changed, then let's load it...\r
+ if (alpineBefore != alpineAfter)\r
+ {\r
+ if (!JaguarLoadFile(vjs.alpineROMPath) && !AlpineLoadFile(vjs.alpineROMPath))\r
+ {\r
+ // Oh crap, we couldn't get the file! Alert the media!\r
+ QMessageBox msg;\r
+ msg.setText(QString(tr("Could not load file \"%1\"!")).arg(vjs.alpineROMPath));\r
+ msg.setIcon(QMessageBox::Warning);\r
+ msg.exec();\r
+ }\r
+ }\r
+\r
+ // If the "ABS" ROM is changed, then let's load it...\r
+ if (absBefore != absAfter)\r
+ {\r
+ if (!JaguarLoadFile(vjs.absROMPath))\r
+ {\r
+ // Oh crap, we couldn't get the file! Alert the media!\r
+ QMessageBox msg;\r
+ msg.setText(QString(tr("Could not load file \"%1\"!")).arg(vjs.absROMPath));\r
+ msg.setIcon(QMessageBox::Warning);\r
+ msg.exec();\r
+ }\r
+ }\r
+\r
+ // If the "Enable DSP" checkbox changed, then we have to re-init the DAC,\r
+ // since it's running in the host audio IRQ...\r
+ if (audioBefore != audioAfter)\r
+ {\r
+ DACDone();\r
+ DACInit();\r
+ }\r
+\r
+ // Just in case we crash before a clean exit...\r
+ WriteSettings();\r
+\r
+ RefreshWindows();\r
+}\r
+\r
+\r
+//\r
+// Here's the main emulator loop\r
+//\r
+void MainWin::Timer(void)\r
+{\r
+#if 0\r
+static uint32_t ntscTickCount;\r
+ if (vjs.hardwareTypeNTSC)\r
+ {\r
+ ntscTickCount++;\r
+ ntscTickCount %= 3;\r
+ timer->start(16 + (ntscTickCount == 0 ? 1 : 0));\r
+ }\r
+#endif\r
+\r
+ if (!running)\r
+ return;\r
+\r
+ if (showUntunedTankCircuit)\r
+ {\r
+ // Some machines can't handle this, so we give them the option to disable it. :-)\r
+ if (!plzDontKillMyComputer)\r
+ {\r
+// if (!vjs.softTypeDebugger)\r
+ {\r
+ // Random hash & trash\r
+ // We try to simulate an untuned tank circuit here... :-)\r
+ for (uint32_t x = 0; x < videoWidget->rasterWidth; x++)\r
+ {\r
+ for (uint32_t y = 0; y < videoWidget->rasterHeight; y++)\r
+ {\r
+ videoWidget->buffer[(y * videoWidget->textureWidth) + x] = (rand() & 0xFF) << 8 | (rand() & 0xFF) << 16 | (rand() & 0xFF) << 24;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // Otherwise, run the Jaguar simulation\r
+ HandleGamepads();\r
+ JaguarExecuteNew();\r
+ //if (!vjs.softTypeDebugger)\r
+ videoWidget->HandleMouseHiding();\r
+\r
+static uint32_t refresh = 0;\r
+ // Do autorefresh on debug windows\r
+ // Have to be careful, too much causes the emulator to slow way down!\r
+ if (refresh == vjs.refresh)\r
+ {\r
+ if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)\r
+ {\r
+ AlpineRefreshWindows();\r
+ //memBrowseWin->RefreshContents();\r
+ //cpuBrowseWin->RefreshContents();\r
+ }\r
+ CommonRefreshWindows();\r
+ refresh = 0;\r
+ }\r
+ else\r
+ {\r
+ refresh++;\r
+ }\r
+ }\r
+\r
+ //if (!vjs.softTypeDebugger)\r
+ videoWidget->updateGL();\r
+\r
+ // FPS handling\r
+ // Approach: We use a ring buffer to store times (in ms) over a given\r
+ // amount of frames, then sum them to figure out the FPS.\r
+ uint32_t timestamp = SDL_GetTicks();\r
+ // This assumes the ring buffer size is a power of 2\r
+// ringBufferPointer = (ringBufferPointer + 1) & (RING_BUFFER_SIZE - 1);\r
+ // Doing it this way is better. Ring buffer size can be arbitrary then.\r
+ ringBufferPointer = (ringBufferPointer + 1) % RING_BUFFER_SIZE;\r
+ ringBuffer[ringBufferPointer] = timestamp - oldTimestamp;\r
+ uint32_t elapsedTime = 0;\r
+\r
+ for(uint32_t i=0; i<RING_BUFFER_SIZE; i++)\r
+ elapsedTime += ringBuffer[i];\r
+\r
+ // elapsedTime must be non-zero\r
+ if (elapsedTime == 0)\r
+ elapsedTime = 1;\r
+\r
+ // This is in frames per 10 seconds, so we can have 1 decimal\r
+ uint32_t framesPerSecond = (uint32_t)(((float)RING_BUFFER_SIZE / (float)elapsedTime) * 10000.0);\r
+ uint32_t fpsIntegerPart = framesPerSecond / 10;\r
+ uint32_t fpsDecimalPart = framesPerSecond % 10;\r
+ // If this is updated too frequently to be useful, we can throttle it down\r
+ // so that it only updates every 10th frame or so\r
+ statusBar()->showMessage(QString("%1.%2 FPS").arg(fpsIntegerPart).arg(fpsDecimalPart));\r
+ oldTimestamp = timestamp;\r
+\r
+ if (M68KDebugHaltStatus())\r
+ ToggleRunState();\r
+}\r
+\r
+\r
+// Toggle the power state, it can be either on or off\r
+void MainWin::TogglePowerState(void)\r
+{\r
+ powerButtonOn = !powerButtonOn;\r
+ running = true;\r
+\r
+ // With the power off, we simulate white noise on the screen. :-)\r
+ if (!powerButtonOn)\r
+ {\r
+ // Restore the mouse pointer, if hidden:\r
+ //if (!vjs.softTypeDebugger)\r
+ {\r
+ videoWidget->CheckAndRestoreMouseCursor();\r
+ }\r
+\r
+ useCDAct->setDisabled(false);\r
+ palAct->setDisabled(false);\r
+ ntscAct->setDisabled(false);\r
+ pauseAct->setChecked(false);\r
+ pauseAct->setDisabled(true);\r
+ showUntunedTankCircuit = true;\r
+\r
+ DACPauseAudioThread();\r
+ // 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. :-)\r
+ TOMReset();\r
+\r
+ if (plzDontKillMyComputer)\r
+ {\r
+ // We have to do it line by line, because the texture pitch is not the same as the picture buffer's pitch.\r
+ for (uint32_t y = 0; y < videoWidget->rasterHeight; y++)\r
+ {\r
+ if (vjs.hardwareTypeNTSC)\r
+ {\r
+ memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t));\r
+ }\r
+ else\r
+ {\r
+ memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern2 + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ useCDAct->setDisabled(true);\r
+ palAct->setDisabled(true);\r
+ ntscAct->setDisabled(true);\r
+ pauseAct->setChecked(false);\r
+ pauseAct->setDisabled(false);\r
+ showUntunedTankCircuit = false;\r
+\r
+ // Otherwise, we prepare for running regular software...\r
+ if (CDActive)\r
+ {\r
+// Should check for cartridgeLoaded here as well...!\r
+// We can clear it when toggling CDActive on, so that when we power cycle it\r
+// does the expected thing. Otherwise, if we use the file picker to insert a\r
+// cart, we expect to run the cart! Maybe have a RemoveCart function that only\r
+// works if the CD unit is active?\r
+ setWindowTitle(QString("Virtual Jaguar " VJ_RELEASE_VERSION " Rx - Now playing: Jaguar CD"));\r
+ }\r
+\r
+ WriteLog("GUI: Resetting Jaguar...\n");\r
+ JaguarReset();\r
+ DebuggerReset();\r
+ CommonReset();\r
+ DebuggerResetWindows();\r
+ CommonResetWindows();\r
+ DACPauseAudioThread(false);\r
+ }\r
+}\r
+\r
+\r
+// Toggle the emulator state, it can be either on or off\r
+void MainWin::ToggleRunState(void)\r
+{\r
+ startM68KTracing = running;\r
+ running = !running;\r
+\r
+ // Pause mode\r
+ if (!running)\r
+ {\r
+ // Set action buttons for the pause mode\r
+ frameAdvanceAct->setDisabled(false);\r
+ pauseAct->setChecked(true);\r
+ pauseAct->setDisabled(false);\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ traceStepIntoAct->setDisabled(false);\r
+ traceStepOverAct->setDisabled(false);\r
+ restartAct->setDisabled(false);\r
+ m68kDasmWin->Use68KPCAddress();\r
+ GPUDasmWin->UseGPUPCAddress();\r
+ DSPDasmWin->UseDSPPCAddress();\r
+ }\r
+\r
+ //if (!vjs.softTypeDebugger)\r
+ {\r
+ // Restore the mouse pointer, if hidden:\r
+ videoWidget->CheckAndRestoreMouseCursor();\r
+\r
+ for (uint32_t i = 0; i < (uint32_t)(videoWidget->textureWidth * 256); i++)\r
+ {\r
+ uint32_t pixel = videoWidget->buffer[i];\r
+ uint8_t r = (pixel >> 24) & 0xFF, g = (pixel >> 16) & 0xFF, b = (pixel >> 8) & 0xFF;\r
+ pixel = ((r + g + b) / 3) & 0x00FF;\r
+ videoWidget->buffer[i] = 0x000000FF | (pixel << 16) | (pixel << 8);\r
+ }\r
+\r
+ videoWidget->updateGL();\r
+\r
+ cpuBrowseWin->HoldBPM();\r
+ cpuBrowseWin->HandleBPMContinue();\r
+ RefreshWindows();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ frameAdvanceAct->setDisabled(true);\r
+ pauseAct->setChecked(false);\r
+ pauseAct->setDisabled(false);\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ traceStepIntoAct->setDisabled(true);\r
+ traceStepOverAct->setDisabled(true);\r
+ restartAct->setDisabled(true);\r
+ BreakpointsWin->RefreshContents();\r
+ }\r
+\r
+ cpuBrowseWin->UnholdBPM();\r
+ }\r
+\r
+ emuStatusWin->ResetM68KCycles();\r
+ // Pause/unpause any running/non-running threads...\r
+ DACPauseAudioThread(!running);\r
+}\r
+\r
+\r
+void MainWin::SetZoom100(void)\r
+{\r
+ zoomLevel = 1;\r
+ ResizeMainWindow();\r
+}\r
+\r
+\r
+void MainWin::SetZoom200(void)\r
+{\r
+ zoomLevel = 2;\r
+ ResizeMainWindow();\r
+}\r
+\r
+\r
+void MainWin::SetZoom300(void)\r
+{\r
+ zoomLevel = 3;\r
+ ResizeMainWindow();\r
+}\r
+\r
+\r
+void MainWin::SetNTSC(void)\r
+{\r
+ powerAct->setIcon(powerRed);\r
+ timer->setInterval(16);\r
+ vjs.hardwareTypeNTSC = true;\r
+ ResizeMainWindow();\r
+ WriteSettings();\r
+}\r
+\r
+\r
+void MainWin::SetPAL(void)\r
+{\r
+ powerAct->setIcon(powerGreen);\r
+ timer->setInterval(20);\r
+ vjs.hardwareTypeNTSC = false;\r
+ ResizeMainWindow();\r
+ WriteSettings();\r
+}\r
+\r
+\r
+void MainWin::ToggleBlur(void)\r
+{\r
+ vjs.glFilter = !vjs.glFilter;\r
+ WriteSettings();\r
+}\r
+\r
+\r
+void MainWin::ShowAboutWin(void)\r
+{\r
+ aboutWin->show();\r
+}\r
+\r
+\r
+void MainWin::ShowHelpWin(void)\r
+{\r
+ helpWin->show();\r
+}\r
+\r
+\r
+void MainWin::InsertCart(void)\r
+{\r
+ // Check to see if we did autorun, 'cause we didn't load anything in that\r
+ // case\r
+ if (!scannedSoftwareFolder)\r
+ {\r
+ filePickWin->ScanSoftwareFolder(allowUnknownSoftware);\r
+ scannedSoftwareFolder = true;\r
+ }\r
+\r
+ // If the emulator is running, we pause it here and unpause it later\r
+ // if we dismiss the file selector without choosing anything\r
+ if (running && powerButtonOn)\r
+ {\r
+ ToggleRunState();\r
+ pauseForFileSelector = true;\r
+ }\r
+\r
+ filePickWin->show();\r
+}\r
+\r
+\r
+void MainWin::Unpause(void)\r
+{\r
+ // Here we unpause the emulator if it was paused when we went into the file selector\r
+ if (pauseForFileSelector)\r
+ {\r
+ pauseForFileSelector = false;\r
+\r
+ // Some nutter might have unpaused while in the file selector, so check for that\r
+ if (!running)\r
+ ToggleRunState();\r
+ }\r
+}\r
+\r
+\r
+// Jaguar initialisation and load software file\r
+void MainWin::LoadSoftware(QString file)\r
+{\r
+ running = false; // Prevent bad things(TM) from happening...\r
+ pauseForFileSelector = false; // Reset the file selector pause flag\r
+\r
+ // Setup BIOS in his own dedicated Jaguar memory\r
+#ifndef NEWMODELSBIOSHANDLER\r
+ uint8_t * biosPointer = jaguarBootROM;\r
+\r
+ if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)\r
+ {\r
+ biosPointer = jaguarDevBootROM2;\r
+ }\r
+\r
+ memcpy(jagMemSpace + 0xE00000, biosPointer, 0x20000);\r
+#else\r
+ SelectBIOS(vjs.biosType);\r
+#endif\r
+\r
+ // Turn 'on' the power to initialize the Jaguar\r
+ powerAct->setDisabled(false);\r
+ powerAct->setChecked(true);\r
+ powerButtonOn = false;\r
+ TogglePowerState();\r
+\r
+ // We have to load our software *after* the Jaguar RESET\r
+ cartridgeLoaded = JaguarLoadFile(file.toUtf8().data());\r
+ SET32(jaguarMainRAM, 0, vjs.DRAM_size); // Set stack in the M68000's Reset SP\r
+\r
+ // This is icky because we've already done it\r
+// it gets worse :-P\r
+ if (!vjs.useJaguarBIOS)\r
+ {\r
+ SET32(jaguarMainRAM, 4, jaguarRunAddress);\r
+ }\r
+\r
+ m68k_pulse_reset();\r
+\r
+// set the M68K in halt mode in case of a debug mode is used, so control is at user side\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ m68k_set_reg(M68K_REG_A6, 0);\r
+ m68kDasmWin->SetAddress(jaguarRunAddress);\r
+ SourcesWin->Init();\r
+ //pauseAct->setDisabled(false);\r
+ //pauseAct->setChecked(true);\r
+ ToggleRunState();\r
+ //RefreshWindows();\r
+ }\r
+ else\r
+ {\r
+ // Prevent the launch in case of software without a start address and without BIOS presence\r
+ if (!vjs.useJaguarBIOS && !jaguarRunAddress)\r
+ {\r
+ ToggleRunState();\r
+ }\r
+ }\r
+\r
+ // Display the Atari Jaguar software which is running\r
+ if ((!vjs.hardwareTypeAlpine || !vjs.softTypeDebugger) && !loadAndGo && jaguarRunAddress)\r
+ {\r
+ QString newTitle = QString("Virtual Jaguar " VJ_RELEASE_VERSION " Rx - Now playing: %1").arg(filePickWin->GetSelectedPrettyName());\r
+ setWindowTitle(newTitle);\r
+ }\r
+}\r
+\r
+\r
+void MainWin::ToggleCDUsage(void)\r
+{\r
+ CDActive = !CDActive;\r
+\r
+ // Set up the Jaguar CD for execution, otherwise, clear memory\r
+ if (CDActive)\r
+ memcpy(jagMemSpace + 0x800000, jaguarCDBootROM, 0x40000);\r
+ else\r
+ memset(jagMemSpace + 0x800000, 0xFF, 0x40000);\r
+}\r
+\r
+\r
+// Open, or display, the breakpoints list window\r
+void MainWin::ShowBreakpointsWin(void)\r
+{\r
+ BreakpointsWin->show();\r
+ BreakpointsWin->RefreshContents();\r
+}\r
+\r
+\r
+// Delete all breakpoints\r
+void MainWin::DeleteAllBreakpoints(void)\r
+{\r
+ cpuBrowseWin->ResetBPM();\r
+ m68k_brk_reset();\r
+ ShowBreakpointsWin();\r
+}\r
+\r
+\r
+// Disable all breakpoints\r
+void MainWin::DisableAllBreakpoints(void)\r
+{\r
+ cpuBrowseWin->DisableBPM();\r
+ m68k_brk_disable();\r
+ ShowBreakpointsWin();\r
+}\r
+\r
+\r
+// Open, or display, the new breakpoint function window\r
+void MainWin::ShowNewFunctionBreakpointWin(void)\r
+{\r
+ NewFunctionBreakpointWin->SetFnctBreakpointWin(BreakpointsWin);\r
+ NewFunctionBreakpointWin->show();\r
+ ShowBreakpointsWin();\r
+}\r
+\r
+\r
+// Display list of files found in cartridge\r
+void MainWin::ShowCartFilesListWin(void)\r
+{\r
+ CartFilesListWin->show();\r
+ CartFilesListWin->RefreshContents();\r
+}\r
+\r
+\r
+// Display the save dump pickup file\r
+void MainWin::ShowSaveDumpAsWin(void)\r
+{\r
+ SaveDumpAsWin->show();\r
+}\r
+\r
+\r
+// Step Into trace\r
+void MainWin::DebuggerTraceStepInto(void)\r
+{\r
+ if (SourcesWin->isVisible() && SourcesWin->GetTraceStatus())\r
+ {\r
+ while (!SourcesWin->CheckChangeLine())\r
+ {\r
+ emuStatusWin->UpdateM68KCycles(JaguarStepInto());\r
+ }\r
+ }\r
+ else\r
+ {\r
+ emuStatusWin->UpdateM68KCycles(JaguarStepInto());\r
+ }\r
+\r
+ videoWidget->updateGL();\r
+ RefreshWindows();\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to verify the Step Into function !!!")\r
+#else\r
+ #warning "!!! Need to verify the Step Into function !!!"\r
+#endif // _MSC_VER\r
+}\r
+\r
+\r
+// Restart the Jaguar executable\r
+void MainWin::DebuggerRestart(void)\r
+{\r
+#if 1\r
+ m68k_pulse_reset();\r
+#else\r
+ m68k_set_reg(M68K_REG_PC, jaguarRunAddress);\r
+ m68k_set_reg(M68K_REG_SP, vjs.DRAM_size);\r
+#endif\r
+ dasmtabWidget->setCurrentIndex(1); // set focus on the disasm M68K tab\r
+ m68k_set_reg(M68K_REG_A6, 0);\r
+ m68k_brk_hitcounts_reset();\r
+ emuStatusWin->ResetM68KCycles();\r
+ bpmHitCounts = 0;\r
+ DebuggerResetWindows();\r
+ CommonResetWindows();\r
+ SourcesWin->Init();\r
+ RefreshWindows();\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to verify the Restart function !!!")\r
+#else\r
+ #warning "!!! Need to verify the Restart function !!!"\r
+#endif // _MSC_VER\r
+}\r
+\r
+\r
+// Step Over trace\r
+void MainWin::DebuggerTraceStepOver(void)\r
+{\r
+ if (SourcesWin->isVisible() && SourcesWin->GetTraceStatus())\r
+ {\r
+ while (!SourcesWin->CheckChangeLine())\r
+ {\r
+ emuStatusWin->UpdateM68KCycles(JaguarStepOver(0));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ emuStatusWin->UpdateM68KCycles(JaguarStepOver(0));\r
+ }\r
+\r
+ videoWidget->updateGL();\r
+ RefreshWindows();\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to verify the Step Over function !!!")\r
+#else\r
+ #warning "!!! Need to verify the Step Over function !!!"\r
+#endif // _MSC_VER\r
+}\r
+\r
+\r
+// Advance / Execute for one frame\r
+void MainWin::FrameAdvance(void)\r
+{\r
+//printf("Frame Advance...\n");\r
+ ToggleRunState();\r
+ // Execute 1 frame, then exit (only useful in Pause mode)\r
+ JaguarExecuteNew();\r
+ //if (!vjs.softTypeDebugger)\r
+ videoWidget->updateGL();\r
+ ToggleRunState();\r
+ // Need to execute 1 frames' worth of DSP thread as well :-/\r
+\r
+ //m68kDasmWin->Use68KPCAddress();\r
+ //RefreshWindows();\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to execute the DSP thread for 1 frame too !!!")\r
+#else\r
+#warning "!!! Need to execute the DSP thread for 1 frame too !!!"\r
+#endif // _MSC_VER\r
+}\r
+\r
+\r
+void MainWin::SetFullScreen(bool state/*= true*/)\r
+{\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ if (state)\r
+ {\r
+ mainWinPosition = pos();\r
+ menuBar()->hide();\r
+ statusBar()->hide();\r
+ toolbar->hide();\r
+\r
+ if (debugbar)\r
+ debugbar->hide();\r
+\r
+ // This is needed because the fullscreen may happen on a different\r
+ // screen than screen 0:\r
+ int screenNum = QApplication::desktop()->screenNumber(videoWidget);\r
+ QRect r = QApplication::desktop()->screenGeometry(screenNum);\r
+ double targetWidth = (double)VIRTUAL_SCREEN_WIDTH,\r
+ targetHeight = (double)(vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);\r
+ double aspectRatio = targetWidth / targetHeight;\r
+ // NOTE: Really should check here to see which dimension constrains the\r
+ // other. Right now, we assume that height is the constraint.\r
+ int newWidth = (int)(aspectRatio * (double)r.height());\r
+ videoWidget->offset = (r.width() - newWidth) / 2;\r
+ videoWidget->fullscreen = true;\r
+ videoWidget->outputWidth = newWidth;\r
+ videoWidget->setFixedSize(r.width(), r.height());\r
+ showFullScreen();\r
+ }\r
+ else\r
+ {\r
+ // Seems Qt is fussy about this: showNormal() has to go first, or it\r
+ // will keep the window stuck in a psuedo-fullscreen mode with no way\r
+ // to get out of it (except closing the app).\r
+ showNormal();\r
+\r
+ // Reset the video widget to windowed mode\r
+ videoWidget->offset = 0;\r
+ videoWidget->fullscreen = false;\r
+ menuBar()->show();\r
+ statusBar()->show();\r
+ toolbar->show();\r
+\r
+ if (debugbar)\r
+ debugbar->show();\r
+\r
+ ResizeMainWindow();\r
+ move(mainWinPosition);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+void MainWin::ToggleFullScreen(void)\r
+{\r
+ fullScreen = !fullScreen;\r
+ SetFullScreen(fullScreen);\r
+}\r
+\r
+\r
+// \r
+void MainWin::ShowExceptionVectorTableBrowserWin(void)\r
+{\r
+ exceptionvectortableBrowseWin->show();\r
+ exceptionvectortableBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+// \r
+void MainWin::ShowLocalBrowserWin(void)\r
+{\r
+ LocalBrowseWin->show();\r
+ LocalBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+// \r
+void MainWin::ShowCallStackBrowserWin(void)\r
+{\r
+ CallStackBrowseWin->show();\r
+ CallStackBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowAllWatchBrowserWin(void)\r
+{\r
+ allWatchBrowseWin->show();\r
+ allWatchBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowHeapAllocatorBrowserWin(void)\r
+{\r
+ heapallocatorBrowseWin->show();\r
+ heapallocatorBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowMemoryBrowserWin(void)\r
+{\r
+ memBrowseWin->show();\r
+ memBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowMemory1BrowserWin(int NumWin)\r
+{\r
+// for (int i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ mem1BrowseWin[NumWin]->show();\r
+ mem1BrowseWin[NumWin]->RefreshContents(NumWin);\r
+ }\r
+}\r
+\r
+\r
+void MainWin::ShowEmuStatusWin(void)\r
+{\r
+ emuStatusWin->show();\r
+ emuStatusWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowStackBrowserWin(void)\r
+{\r
+ stackBrowseWin->show();\r
+ stackBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowCPUBrowserWin(void)\r
+{\r
+ cpuBrowseWin->show();\r
+ cpuBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+// Show the OP browser window\r
+void MainWin::ShowOPBrowserWin(void)\r
+{\r
+ opBrowseWin->show();\r
+ opBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+// Show the HW registers browser window\r
+void MainWin::ShowHWRegsBrowserWin(void)\r
+{\r
+ hwRegsBrowseWin->show();\r
+ hwRegsBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+// Show the M68K browser window\r
+void MainWin::ShowM68KDasmBrowserWin(void)\r
+{\r
+ m68kDasmBrowseWin->show();\r
+ m68kDasmBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+void MainWin::ShowRISCDasmBrowserWin(void)\r
+{\r
+ riscDasmBrowseWin->show();\r
+ riscDasmBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+//\r
+#if 0\r
+void MainWin::ShowDasmWin(void)\r
+{\r
+// DasmWin->show();\r
+// DasmWin->RefreshContents();\r
+}\r
+#endif\r
+\r
+\r
+// \r
+#if 0\r
+void MainWin::ShowVideoOutputWin(void)\r
+{\r
+ //VideoOutputWindowCentrale = mainWindowCentrale->addSubWindow(videoWidget);\r
+ //VideoOutputWindowCentrale->setWindowTitle(QString(tr("Video output")));\r
+ //VideoOutputWindowCentrale->show();\r
+ //memBrowseWin->show();\r
+ //VideoOutputWin->show();\r
+ //VideoOutputWin->RefreshContents(videoWidget);\r
+}\r
+#endif\r
+\r
+\r
+// Resize video window based on zoom factor\r
+// It doesn't apply in debugger mode as we use this window to display disassembly\r
+void MainWin::ResizeMainWindow(void)\r
+{\r
+ if (!vjs.softTypeDebugger)\r
+ {\r
+ videoWidget->setFixedSize(zoomLevel * VIRTUAL_SCREEN_WIDTH, zoomLevel * (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL));\r
+\r
+ // Show the test pattern if user requested plzDontKillMyComputer mode\r
+ if (!powerButtonOn && plzDontKillMyComputer)\r
+ {\r
+ for (uint32_t y = 0; y < videoWidget->rasterHeight; y++)\r
+ {\r
+ if (vjs.hardwareTypeNTSC)\r
+ {\r
+ memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t));\r
+ }\r
+ else\r
+ {\r
+ memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern2 + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t));\r
+ }\r
+ }\r
+ }\r
+\r
+ adjustSize();\r
+ }\r
+}\r
+\r
+\r
+// Read settings\r
+void MainWin::ReadSettings(void)\r
+{\r
+ size_t i;\r
+\r
+ QSettings settings("Underground Software", "Virtual Jaguar");\r
+\r
+ //zoomLevel = settings.value("zoom", 2).toInt();\r
+ allowUnknownSoftware = settings.value("showUnknownSoftware", false).toBool();\r
+ lastEditedProfile = settings.value("lastEditedProfile", 0).toInt();\r
+\r
+ vjs.useJoystick = settings.value("useJoystick", false).toBool();\r
+ vjs.joyport = settings.value("joyport", 0).toInt();\r
+ vjs.hardwareTypeNTSC = settings.value("hardwareTypeNTSC", true).toBool();\r
+ vjs.frameSkip = settings.value("frameSkip", 0).toInt();\r
+ vjs.useJaguarBIOS = settings.value("useJaguarBIOS", false).toBool();\r
+ vjs.useRetailBIOS = settings.value("useRetailBIOS", false).toBool();\r
+ vjs.useDevBIOS = settings.value("useDevBIOS", false).toBool();\r
+ vjs.GPUEnabled = settings.value("GPUEnabled", true).toBool();\r
+ vjs.DSPEnabled = settings.value("DSPEnabled", true).toBool();\r
+ vjs.audioEnabled = settings.value("audioEnabled", true).toBool();\r
+ vjs.usePipelinedDSP = settings.value("usePipelinedDSP", false).toBool();\r
+ vjs.fullscreen = settings.value("fullscreen", false).toBool();\r
+ vjs.useOpenGL = settings.value("useOpenGL", true).toBool();\r
+ vjs.glFilter = settings.value("glFilterType", 1).toInt();\r
+ vjs.renderType = settings.value("renderType", 0).toInt();\r
+ vjs.biosType = settings.value("biosType", BT_M_SERIES).toInt();\r
+ vjs.jaguarModel = settings.value("jaguarModel", JAG_M_SERIES).toInt();\r
+ vjs.useFastBlitter = settings.value("useFastBlitter", false).toBool();\r
+ strcpy(vjs.EEPROMPath, settings.value("EEPROMs", QStandardPaths::writableLocation(QStandardPaths::DataLocation).append("/eeproms/")).toString().toUtf8().data());\r
+ strcpy(vjs.ROMPath, settings.value("ROMs", QStandardPaths::writableLocation(QStandardPaths::DataLocation).append("/software/")).toString().toUtf8().data());\r
+ strcpy(vjs.screenshotPath, settings.value("Screenshots", QStandardPaths::writableLocation(QStandardPaths::DataLocation).append("/screenshots/")).toString().toUtf8().data());\r
+\r
+ // Read settings from the Debugger mode\r
+ settings.beginGroup("debugger");\r
+ strcpy(vjs.debuggerROMPath, settings.value("DefaultROM", "").toString().toUtf8().data());\r
+ strcpy(vjs.sourcefilesearchPaths, settings.value("SourceFileSearchPaths", "").toString().toUtf8().data());\r
+ vjs.nbrdisasmlines = settings.value("NbrDisasmLines", 32).toUInt();\r
+ vjs.disasmopcodes = settings.value("DisasmOpcodes", true).toBool();\r
+ vjs.displayHWlabels = settings.value("DisplayHWLabels", true).toBool();\r
+ vjs.displayFullSourceFilename = settings.value("displayFullSourceFilename", true).toBool();\r
+ vjs.ELFSectionsCheck = settings.value("ELFSectionsCheck", false).toBool();\r
+ vjs.nbrmemory1browserwindow = settings.value("NbrMemory1BrowserWindow", MaxMemory1BrowserWindow).toUInt();\r
+ settings.endGroup();\r
+\r
+ // Read settings from the Alpine mode\r
+ settings.beginGroup("alpine");\r
+ strcpy(vjs.alpineROMPath, settings.value("DefaultROM", "").toString().toUtf8().data());\r
+ strcpy(vjs.absROMPath, settings.value("DefaultABS", "").toString().toUtf8().data());\r
+ vjs.refresh = settings.value("refresh", 60).toUInt();\r
+ vjs.allowWritesToROM = settings.value("writeROM", false).toBool();\r
+ vjs.allowM68KExceptionCatch = settings.value("M68KExceptionCatch", false).toBool();\r
+ settings.endGroup();\r
+\r
+ // Read settings from the Keybindings\r
+ settings.beginGroup("keybindings");\r
+ for (i = 0; i < KB_END; i++)\r
+ {\r
+ strcpy(vjs.KBContent[i].KBSettingValue, settings.value(KeyBindingsTable[i].KBNameSetting, KeyBindingsTable[i].KBDefaultValue).toString().toUtf8().data());\r
+ }\r
+ settings.endGroup();\r
+\r
+ // Write important settings to the log file\r
+ WriteLog("MainWin: Paths\n");\r
+ WriteLog(" EEPROMPath = \"%s\"\n", vjs.EEPROMPath);\r
+ WriteLog(" ROMPath = \"%s\"\n", vjs.ROMPath);\r
+ WriteLog(" AlpineROMPath = \"%s\"\n", vjs.alpineROMPath);\r
+ WriteLog(" DebuggerROMPath = \"%s\"\n", vjs.debuggerROMPath);\r
+ WriteLog(" absROMPath = \"%s\"\n", vjs.absROMPath);\r
+ WriteLog(" ScreenshotsPath = \"%s\"\n", vjs.screenshotPath);\r
+ WriteLog("SourceFileSearchPaths = \"%s\"\n", vjs.sourcefilesearchPaths);\r
+ WriteLog("MainWin: Misc.\n");\r
+ WriteLog(" Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off"));\r
+\r
+#if 0\r
+ // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *\r
+ vjs.p1KeyBindings[BUTTON_U] = settings.value("p1k_up", Qt::Key_S).toInt();\r
+ vjs.p1KeyBindings[BUTTON_D] = settings.value("p1k_down", Qt::Key_X).toInt();\r
+ vjs.p1KeyBindings[BUTTON_L] = settings.value("p1k_left", Qt::Key_A).toInt();\r
+ vjs.p1KeyBindings[BUTTON_R] = settings.value("p1k_right", Qt::Key_D).toInt();\r
+ vjs.p1KeyBindings[BUTTON_C] = settings.value("p1k_c", Qt::Key_J).toInt();\r
+ vjs.p1KeyBindings[BUTTON_B] = settings.value("p1k_b", Qt::Key_K).toInt();\r
+ vjs.p1KeyBindings[BUTTON_A] = settings.value("p1k_a", Qt::Key_L).toInt();\r
+ vjs.p1KeyBindings[BUTTON_OPTION] = settings.value("p1k_option", Qt::Key_O).toInt();\r
+ vjs.p1KeyBindings[BUTTON_PAUSE] = settings.value("p1k_pause", Qt::Key_P).toInt();\r
+ vjs.p1KeyBindings[BUTTON_0] = settings.value("p1k_0", Qt::Key_0).toInt();\r
+ vjs.p1KeyBindings[BUTTON_1] = settings.value("p1k_1", Qt::Key_1).toInt();\r
+ vjs.p1KeyBindings[BUTTON_2] = settings.value("p1k_2", Qt::Key_2).toInt();\r
+ vjs.p1KeyBindings[BUTTON_3] = settings.value("p1k_3", Qt::Key_3).toInt();\r
+ vjs.p1KeyBindings[BUTTON_4] = settings.value("p1k_4", Qt::Key_4).toInt();\r
+ vjs.p1KeyBindings[BUTTON_5] = settings.value("p1k_5", Qt::Key_5).toInt();\r
+ vjs.p1KeyBindings[BUTTON_6] = settings.value("p1k_6", Qt::Key_6).toInt();\r
+ vjs.p1KeyBindings[BUTTON_7] = settings.value("p1k_7", Qt::Key_7).toInt();\r
+ vjs.p1KeyBindings[BUTTON_8] = settings.value("p1k_8", Qt::Key_8).toInt();\r
+ vjs.p1KeyBindings[BUTTON_9] = settings.value("p1k_9", Qt::Key_9).toInt();\r
+ vjs.p1KeyBindings[BUTTON_d] = settings.value("p1k_pound", Qt::Key_Minus).toInt();\r
+ vjs.p1KeyBindings[BUTTON_s] = settings.value("p1k_star", Qt::Key_Equal).toInt();\r
+\r
+ vjs.p2KeyBindings[BUTTON_U] = settings.value("p2k_up", Qt::Key_Up).toInt();\r
+ vjs.p2KeyBindings[BUTTON_D] = settings.value("p2k_down", Qt::Key_Down).toInt();\r
+ vjs.p2KeyBindings[BUTTON_L] = settings.value("p2k_left", Qt::Key_Left).toInt();\r
+ vjs.p2KeyBindings[BUTTON_R] = settings.value("p2k_right", Qt::Key_Right).toInt();\r
+ vjs.p2KeyBindings[BUTTON_C] = settings.value("p2k_c", Qt::Key_Z).toInt();\r
+ vjs.p2KeyBindings[BUTTON_B] = settings.value("p2k_b", Qt::Key_X).toInt();\r
+ vjs.p2KeyBindings[BUTTON_A] = settings.value("p2k_a", Qt::Key_C).toInt();\r
+ vjs.p2KeyBindings[BUTTON_OPTION] = settings.value("p2k_option", Qt::Key_Apostrophe).toInt();\r
+ vjs.p2KeyBindings[BUTTON_PAUSE] = settings.value("p2k_pause", Qt::Key_Return).toInt();\r
+ vjs.p2KeyBindings[BUTTON_0] = settings.value("p2k_0", Qt::Key_0).toInt();\r
+ vjs.p2KeyBindings[BUTTON_1] = settings.value("p2k_1", Qt::Key_1).toInt();\r
+ vjs.p2KeyBindings[BUTTON_2] = settings.value("p2k_2", Qt::Key_2).toInt();\r
+ vjs.p2KeyBindings[BUTTON_3] = settings.value("p2k_3", Qt::Key_3).toInt();\r
+ vjs.p2KeyBindings[BUTTON_4] = settings.value("p2k_4", Qt::Key_4).toInt();\r
+ vjs.p2KeyBindings[BUTTON_5] = settings.value("p2k_5", Qt::Key_5).toInt();\r
+ vjs.p2KeyBindings[BUTTON_6] = settings.value("p2k_6", Qt::Key_6).toInt();\r
+ vjs.p2KeyBindings[BUTTON_7] = settings.value("p2k_7", Qt::Key_7).toInt();\r
+ vjs.p2KeyBindings[BUTTON_8] = settings.value("p2k_8", Qt::Key_8).toInt();\r
+ vjs.p2KeyBindings[BUTTON_9] = settings.value("p2k_9", Qt::Key_9).toInt();\r
+ vjs.p2KeyBindings[BUTTON_d] = settings.value("p2k_pound", Qt::Key_Slash).toInt();\r
+ vjs.p2KeyBindings[BUTTON_s] = settings.value("p2k_star", Qt::Key_Asterisk).toInt();\r
+#endif\r
+\r
+ WriteLog("Read setting = Done\n");\r
+\r
+ ReadProfiles(&settings);\r
+ DBGManager_SourceFileSearchPathsSet(vjs.sourcefilesearchPaths);\r
+}\r
+\r
+\r
+// Read UI settings\r
+// Default values will be used in case of no settings can be found\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to check the window geometry to see if the positions are legal !!!")\r
+#else\r
+#warning "!!! Need to check the window geometry to see if the positions are legal !!!"\r
+#endif // _MSC_VER\r
+// i.e., someone could drag it to another screen, close it, then disconnect that screen\r
+void MainWin::ReadUISettings(void)\r
+{\r
+ QPoint pos;\r
+ char mem1Name[100];\r
+ size_t i;\r
+ QSize size;\r
+\r
+ // Point on the emulator settings\r
+ QSettings settings("Underground Software", "Virtual Jaguar");\r
+ settings.beginGroup("ui");\r
+\r
+ // Emulator main window UI information\r
+ mainWinPosition = settings.value("pos", QPoint(200, 200)).toPoint();\r
+ size = settings.value("size", QSize(400, 400)).toSize();\r
+ resize(size);\r
+ move(mainWinPosition);\r
+ pos = settings.value("cartLoadPos", QPoint(200, 200)).toPoint();\r
+ filePickWin->move(pos);\r
+\r
+ // Video output information\r
+ zoomLevel = settings.value("zoom", 2).toInt();\r
+\r
+// Emulator status UI information\r
+ pos = settings.value("emuStatusWinPos", QPoint(200, 200)).toPoint();\r
+ emuStatusWin->move(pos);\r
+ settings.value("emuStatusWinIsVisible", false).toBool() ? ShowEmuStatusWin() : void();\r
+ \r
+ // Alpine debug UI information (also needed by the Debugger)\r
+ if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)\r
+ {\r
+ // CPU registers UI information\r
+ pos = settings.value("cpuBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ cpuBrowseWin->move(pos);\r
+ settings.value("cpuBrowseWinIsVisible", false).toBool() ? ShowCPUBrowserWin() : void();\r
+\r
+ // Memory browser UI information\r
+ pos = settings.value("memBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ memBrowseWin->move(pos);\r
+ settings.value("memBrowseWinIsVisible", false).toBool() ? ShowMemoryBrowserWin() : void();\r
+\r
+ // Stack browser UI information\r
+ pos = settings.value("stackBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ stackBrowseWin->move(pos);\r
+ settings.value("stackBrowseWinIsVisible", false).toBool() ? ShowStackBrowserWin() : void();\r
+ size = settings.value("stackBrowseWinSize", QSize(400, 400)).toSize();\r
+ stackBrowseWin->resize(size);\r
+\r
+ // OP (Object Processor) UI information\r
+ pos = settings.value("opBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ opBrowseWin->move(pos);\r
+ settings.value("opBrowseWinIsVisible", false).toBool() ? ShowOPBrowserWin() : void();\r
+ size = settings.value("opBrowseWinSize", QSize(400, 400)).toSize();\r
+ opBrowseWin->resize(size);\r
+\r
+ // HW registers UI information\r
+ pos = settings.value("hwRegsBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ hwRegsBrowseWin->move(pos);\r
+ settings.value("hwRegsBrowseWinIsVisible", false).toBool() ? ShowHWRegsBrowserWin() : void();\r
+ size = settings.value("hwRegsBrowseWinSize", QSize(400, 400)).toSize();\r
+ hwRegsBrowseWin->resize(size);\r
+\r
+ // RISC disassembly UI information\r
+ pos = settings.value("riscDasmBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ riscDasmBrowseWin->move(pos);\r
+ settings.value("riscDasmBrowseWinIsVisible", false).toBool() ? ShowRISCDasmBrowserWin() : void();\r
+\r
+ // M68k disassembly UI information\r
+ pos = settings.value("m68kDasmBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ m68kDasmBrowseWin->move(pos);\r
+ //settings.value("m68kDasmBrowseWinIsVisible", false).toBool() ? ShowM68KDasmBrowserWin() : void();\r
+#ifdef _MSC_VER\r
+#pragma message("Warning: !!! Need to check the M68k disassembly window position crashing !!!")\r
+#else\r
+ #warning "!!! Need to check the M68k disassembly window position crashing !!!"\r
+#endif // _MSC_VER\r
+ }\r
+\r
+ // Debugger UI information\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+#if 0\r
+ pos = settings.value("m68kDasmWinPos", QPoint(200, 200)).toPoint();\r
+ m68kDasmWin->move(pos);\r
+ //settings.value("m68kDasmWinIsVisible", false).toBool() ? m68kDasmWin->show() : m68kDasmWin->hide();\r
+ pos = settings.value("GPUDasmWinPos", QPoint(200, 200)).toPoint();\r
+ GPUDasmWin->move(pos);\r
+ pos = settings.value("DSPDasmWinPos", QPoint(200, 200)).toPoint();\r
+ DSPDasmWin->move(pos);\r
+#endif\r
+ // All watch browser UI information\r
+ pos = settings.value("allWatchBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ allWatchBrowseWin->move(pos);\r
+ settings.value("allWatchBrowseWinIsVisible", false).toBool() ? ShowAllWatchBrowserWin() : void();\r
+ size = settings.value("allWatchBrowseWinSize", QSize(400, 400)).toSize();\r
+ allWatchBrowseWin->resize(size);\r
+\r
+ // Local browser UI information\r
+ pos = settings.value("LocalBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ LocalBrowseWin->move(pos);\r
+ settings.value("LocalBrowseWinIsVisible", false).toBool() ? ShowLocalBrowserWin() : void();\r
+ size = settings.value("LocalBrowseWinSize", QSize(400, 400)).toSize();\r
+ LocalBrowseWin->resize(size);\r
+\r
+ // Heap memory allocation browser UI information\r
+ pos = settings.value("heapallocatorBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ heapallocatorBrowseWin->move(pos);\r
+ settings.value("heapallocatorBrowseWinIsVisible", false).toBool() ? ShowHeapAllocatorBrowserWin() : void();\r
+ size = settings.value("heapallocatorBrowseWinSize", QSize(400, 400)).toSize();\r
+ heapallocatorBrowseWin->resize(size);\r
+\r
+ // Exception Vector Table UI Information\r
+ pos = settings.value("exceptionVectorTableBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ exceptionvectortableBrowseWin->move(pos);\r
+ settings.value("exceptionVectorTableBrowseWinIsVisible", false).toBool() ? ShowExceptionVectorTableBrowserWin() : void();\r
+ size = settings.value("exceptionVectorTableBrowseWinSize", QSize(400, 400)).toSize();\r
+ exceptionvectortableBrowseWin->resize(size);\r
+\r
+ // Call Stack browser UI information\r
+ pos = settings.value("CallStackBrowseWinPos", QPoint(200, 200)).toPoint();\r
+ CallStackBrowseWin->move(pos);\r
+ settings.value("CallStackBrowseWinIsVisible", false).toBool() ? ShowCallStackBrowserWin() : void();\r
+ size = settings.value("CallStackBrowseWinSize", QSize(400, 400)).toSize();\r
+ CallStackBrowseWin->resize(size);\r
+\r
+ // cartridge directory and files UI information\r
+ pos = settings.value("CartFilesListWinPos", QPoint(200, 200)).toPoint();\r
+ CartFilesListWin->move(pos);\r
+ settings.value("CartFilesListWinIsVisible", false).toBool() ? ShowCartFilesListWin() : void();\r
+ size = settings.value("CartFilesListWinSize", QSize(400, 400)).toSize();\r
+ CartFilesListWin->resize(size);\r
+\r
+ // Save dump UI information\r
+ pos = settings.value("SaveDumpAsWinPos", QPoint(200, 200)).toPoint();\r
+ SaveDumpAsWin->move(pos);\r
+ settings.value("SaveDumpAsWinIsVisible", false).toBool() ? ShowSaveDumpAsWin() : void();\r
+ size = settings.value("SaveDumpAsWinSize", QSize(400, 400)).toSize();\r
+ SaveDumpAsWin->resize(size);\r
+\r
+ // Breakpoints UI information\r
+ pos = settings.value("BreakpointsWinPos", QPoint(200, 200)).toPoint();\r
+ BreakpointsWin->move(pos);\r
+ settings.value("BreakpointsWinIsVisible", false).toBool() ? ShowBreakpointsWin() : void();\r
+ size = settings.value("BreakpointsWinSize", QSize(400, 400)).toSize();\r
+ BreakpointsWin->resize(size);\r
+ // New function breakpoint UI information\r
+ pos = settings.value("NewFunctionBreakpointWinPos", QPoint(200, 200)).toPoint();\r
+ NewFunctionBreakpointWin->move(pos);\r
+ settings.value("NewFunctionBreakpointWinIsVisible", false).toBool() ? ShowNewFunctionBreakpointWin() : void();\r
+ size = settings.value("NewFunctionBreakpointWinSize", QSize(400, 400)).toSize();\r
+ NewFunctionBreakpointWin->resize(size);\r
+\r
+ // Memories browser UI information\r
+ for (i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ sprintf(mem1Name, "mem1BrowseWinPos[%i]", (unsigned int)i);\r
+ pos = settings.value(mem1Name, QPoint(200, 200)).toPoint();\r
+ mem1BrowseWin[i]->move(pos);\r
+ sprintf(mem1Name, "mem1BrowseWinIsVisible[%i]", (unsigned int)i);\r
+ settings.value(mem1Name, false).toBool() ? ShowMemory1BrowserWin((int)i) : void();\r
+ sprintf(mem1Name, "mem1BrowseWinSize[%i]", (unsigned int)i);\r
+ size = settings.value(mem1Name, QSize(400, 400)).toSize();\r
+ mem1BrowseWin[i]->resize(size);\r
+ }\r
+ }\r
+\r
+ settings.endGroup();\r
+\r
+ WriteLog("Read UI setting = Done\n");\r
+}\r
+\r
+\r
+// Save the settings\r
+void MainWin::WriteSettings(void)\r
+{\r
+ size_t i;\r
+\r
+ // Point on the emulator settings\r
+ QSettings settings("Underground Software", "Virtual Jaguar");\r
+ //settings.setValue("pos", pos());\r
+ //settings.setValue("size", size());\r
+ //settings.setValue("cartLoadPos", filePickWin->pos());\r
+\r
+ //settings.setValue("zoom", zoomLevel);\r
+ settings.setValue("showUnknownSoftware", allowUnknownSoftware);\r
+ settings.setValue("lastEditedProfile", lastEditedProfile);\r
+\r
+ settings.setValue("useJoystick", vjs.useJoystick);\r
+ settings.setValue("joyport", vjs.joyport);\r
+ settings.setValue("hardwareTypeNTSC", vjs.hardwareTypeNTSC);\r
+ settings.setValue("frameSkip", vjs.frameSkip);\r
+ settings.setValue("useJaguarBIOS", vjs.useJaguarBIOS);\r
+ settings.setValue("useRetailBIOS", vjs.useRetailBIOS);\r
+ settings.setValue("useDevBIOS", vjs.useDevBIOS);\r
+ settings.setValue("GPUEnabled", vjs.GPUEnabled);\r
+ settings.setValue("DSPEnabled", vjs.DSPEnabled);\r
+ settings.setValue("audioEnabled", vjs.audioEnabled);\r
+ settings.setValue("usePipelinedDSP", vjs.usePipelinedDSP);\r
+ settings.setValue("fullscreen", vjs.fullscreen);\r
+ settings.setValue("useOpenGL", vjs.useOpenGL);\r
+ settings.setValue("glFilterType", vjs.glFilter);\r
+ settings.setValue("renderType", vjs.renderType);\r
+ settings.setValue("jaguarModel", vjs.jaguarModel);\r
+ settings.setValue("biosType", vjs.biosType);\r
+ settings.setValue("useFastBlitter", vjs.useFastBlitter);\r
+ //settings.setValue("JagBootROM", vjs.jagBootPath);\r
+ //settings.setValue("CDBootROM", vjs.CDBootPath);\r
+ settings.setValue("EEPROMs", vjs.EEPROMPath);\r
+ settings.setValue("ROMs", vjs.ROMPath);\r
+ settings.setValue("Screenshots", vjs.screenshotPath);\r
+\r
+ // Write settings from the Alpine mode\r
+ settings.beginGroup("alpine");\r
+ settings.setValue("refresh", vjs.refresh);\r
+ settings.setValue("DefaultROM", vjs.alpineROMPath);\r
+ settings.setValue("DefaultABS", vjs.absROMPath);\r
+ settings.setValue("writeROM", vjs.allowWritesToROM);\r
+ settings.setValue("M68KExceptionCatch", vjs.allowM68KExceptionCatch);\r
+ settings.endGroup();\r
+\r
+ // Write settings from the Debugger mode\r
+ settings.beginGroup("debugger");\r
+ settings.setValue("DisplayHWLabels", vjs.displayHWlabels);\r
+ settings.setValue("NbrDisasmLines", (qulonglong) vjs.nbrdisasmlines);\r
+ settings.setValue("DisasmOpcodes", vjs.disasmopcodes);\r
+ settings.setValue("displayFullSourceFilename", vjs.displayFullSourceFilename);\r
+ settings.setValue("ELFSectionsCheck", vjs.ELFSectionsCheck);\r
+ settings.setValue("NbrMemory1BrowserWindow", (unsigned int)vjs.nbrmemory1browserwindow);\r
+ settings.setValue("DefaultROM", vjs.debuggerROMPath);\r
+ settings.setValue("SourceFileSearchPaths", vjs.sourcefilesearchPaths);\r
+ settings.endGroup();\r
+\r
+ // Write settings from the Keybindings\r
+ settings.beginGroup("keybindings");\r
+ for (i = 0; i < KB_END; i++)\r
+ {\r
+ settings.setValue(KeyBindingsTable[i].KBNameSetting, vjs.KBContent[i].KBSettingValue);\r
+ }\r
+ settings.endGroup();\r
+\r
+#if 0\r
+ settings.setValue("p1k_up", vjs.p1KeyBindings[BUTTON_U]);\r
+ settings.setValue("p1k_down", vjs.p1KeyBindings[BUTTON_D]);\r
+ settings.setValue("p1k_left", vjs.p1KeyBindings[BUTTON_L]);\r
+ settings.setValue("p1k_right", vjs.p1KeyBindings[BUTTON_R]);\r
+ settings.setValue("p1k_c", vjs.p1KeyBindings[BUTTON_C]);\r
+ settings.setValue("p1k_b", vjs.p1KeyBindings[BUTTON_B]);\r
+ settings.setValue("p1k_a", vjs.p1KeyBindings[BUTTON_A]);\r
+ settings.setValue("p1k_option", vjs.p1KeyBindings[BUTTON_OPTION]);\r
+ settings.setValue("p1k_pause", vjs.p1KeyBindings[BUTTON_PAUSE]);\r
+ settings.setValue("p1k_0", vjs.p1KeyBindings[BUTTON_0]);\r
+ settings.setValue("p1k_1", vjs.p1KeyBindings[BUTTON_1]);\r
+ settings.setValue("p1k_2", vjs.p1KeyBindings[BUTTON_2]);\r
+ settings.setValue("p1k_3", vjs.p1KeyBindings[BUTTON_3]);\r
+ settings.setValue("p1k_4", vjs.p1KeyBindings[BUTTON_4]);\r
+ settings.setValue("p1k_5", vjs.p1KeyBindings[BUTTON_5]);\r
+ settings.setValue("p1k_6", vjs.p1KeyBindings[BUTTON_6]);\r
+ settings.setValue("p1k_7", vjs.p1KeyBindings[BUTTON_7]);\r
+ settings.setValue("p1k_8", vjs.p1KeyBindings[BUTTON_8]);\r
+ settings.setValue("p1k_9", vjs.p1KeyBindings[BUTTON_9]);\r
+ settings.setValue("p1k_pound", vjs.p1KeyBindings[BUTTON_d]);\r
+ settings.setValue("p1k_star", vjs.p1KeyBindings[BUTTON_s]);\r
+\r
+ settings.setValue("p2k_up", vjs.p2KeyBindings[BUTTON_U]);\r
+ settings.setValue("p2k_down", vjs.p2KeyBindings[BUTTON_D]);\r
+ settings.setValue("p2k_left", vjs.p2KeyBindings[BUTTON_L]);\r
+ settings.setValue("p2k_right", vjs.p2KeyBindings[BUTTON_R]);\r
+ settings.setValue("p2k_c", vjs.p2KeyBindings[BUTTON_C]);\r
+ settings.setValue("p2k_b", vjs.p2KeyBindings[BUTTON_B]);\r
+ settings.setValue("p2k_a", vjs.p2KeyBindings[BUTTON_A]);\r
+ settings.setValue("p2k_option", vjs.p2KeyBindings[BUTTON_OPTION]);\r
+ settings.setValue("p2k_pause", vjs.p2KeyBindings[BUTTON_PAUSE]);\r
+ settings.setValue("p2k_0", vjs.p2KeyBindings[BUTTON_0]);\r
+ settings.setValue("p2k_1", vjs.p2KeyBindings[BUTTON_1]);\r
+ settings.setValue("p2k_2", vjs.p2KeyBindings[BUTTON_2]);\r
+ settings.setValue("p2k_3", vjs.p2KeyBindings[BUTTON_3]);\r
+ settings.setValue("p2k_4", vjs.p2KeyBindings[BUTTON_4]);\r
+ settings.setValue("p2k_5", vjs.p2KeyBindings[BUTTON_5]);\r
+ settings.setValue("p2k_6", vjs.p2KeyBindings[BUTTON_6]);\r
+ settings.setValue("p2k_7", vjs.p2KeyBindings[BUTTON_7]);\r
+ settings.setValue("p2k_8", vjs.p2KeyBindings[BUTTON_8]);\r
+ settings.setValue("p2k_9", vjs.p2KeyBindings[BUTTON_9]);\r
+ settings.setValue("p2k_pound", vjs.p2KeyBindings[BUTTON_d]);\r
+ settings.setValue("p2k_star", vjs.p2KeyBindings[BUTTON_s]);\r
+#endif\r
+\r
+ WriteProfiles(&settings);\r
+ DBGManager_SourceFileSearchPathsSet(vjs.sourcefilesearchPaths);\r
+}\r
+\r
+\r
+// Save the UI settings\r
+void MainWin::WriteUISettings(void)\r
+{\r
+ char mem1Name[100];\r
+ size_t i;\r
+\r
+ // Point on the emulator settings\r
+ QSettings settings("Underground Software", "Virtual Jaguar");\r
+ settings.beginGroup("ui");\r
+ \r
+ // Emulator UI information\r
+ settings.setValue("pos", pos());\r
+ settings.setValue("size", size());\r
+ settings.setValue("cartLoadPos", filePickWin->pos());\r
+\r
+ // Video output information\r
+ settings.setValue("zoom", zoomLevel);\r
+\r
+ // Common UI information\r
+ settings.setValue("emuStatusWinPos", emuStatusWin->pos());\r
+ settings.setValue("emuStatusWinIsVisible", emuStatusWin->isVisible());\r
+ \r
+ // Alpine debug UI information (also needed by the Debugger)\r
+ if (vjs.hardwareTypeAlpine || vjs.softTypeDebugger)\r
+ {\r
+ settings.setValue("cpuBrowseWinPos", cpuBrowseWin->pos());\r
+ settings.setValue("cpuBrowseWinIsVisible", cpuBrowseWin->isVisible());\r
+ settings.setValue("memBrowseWinPos", memBrowseWin->pos());\r
+ settings.setValue("memBrowseWinIsVisible", memBrowseWin->isVisible());\r
+ settings.setValue("stackBrowseWinPos", stackBrowseWin->pos());\r
+ settings.setValue("stackBrowseWinIsVisible", stackBrowseWin->isVisible());\r
+ settings.setValue("stackBrowseWinSize", stackBrowseWin->size());\r
+ settings.setValue("opBrowseWinPos", opBrowseWin->pos());\r
+ settings.setValue("opBrowseWinIsVisible", opBrowseWin->isVisible());\r
+ settings.setValue("opBrowseWinSize", opBrowseWin->size());\r
+ settings.setValue("hwRegsBrowseWinPos", hwRegsBrowseWin->pos());\r
+ settings.setValue("hwRegsBrowseWinIsVisible", hwRegsBrowseWin->isVisible());\r
+ settings.setValue("hwRegsBrowseWinSize", hwRegsBrowseWin->size());\r
+ settings.setValue("riscDasmBrowseWinPos", riscDasmBrowseWin->pos());\r
+ settings.setValue("riscDasmBrowseWinIsVisible", riscDasmBrowseWin->isVisible());\r
+ settings.setValue("m68kDasmBrowseWinPos", m68kDasmBrowseWin->pos());\r
+ settings.setValue("m68kDasmBrowseWinIsVisible", m68kDasmBrowseWin->isVisible());\r
+ }\r
+\r
+ // Debugger UI information\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+#if 0\r
+ settings.setValue("m68kDasmWinPos", m68kDasmWin->pos());\r
+ //settings.setValue("m68kDasmWinIsVisible", m68kDasmWin->isVisible());\r
+ settings.setValue("GPUDasmWinPos", GPUDasmWin->pos());\r
+ settings.setValue("DSPDasmWinPos", DSPDasmWin->pos());\r
+#endif\r
+ settings.setValue("allWatchBrowseWinPos", allWatchBrowseWin->pos());\r
+ settings.setValue("allWatchBrowseWinIsVisible", allWatchBrowseWin->isVisible());\r
+ settings.setValue("allWatchBrowseWinSize", allWatchBrowseWin->size());\r
+ settings.setValue("LocalBrowseWinPos", LocalBrowseWin->pos());\r
+ settings.setValue("LocalBrowseWinIsVisible", LocalBrowseWin->isVisible());\r
+ settings.setValue("LocalBrowseWinSize", LocalBrowseWin->size());\r
+ settings.setValue("heapallocatorBrowseWinPos", heapallocatorBrowseWin->pos());\r
+ settings.setValue("heapallocatorBrowseWinIsVisible", heapallocatorBrowseWin->isVisible());\r
+ settings.setValue("heapallocatorBrowseWinSize", heapallocatorBrowseWin->size());\r
+ settings.setValue("exceptionVectorTableBrowseWinPos", exceptionvectortableBrowseWin->pos());\r
+ settings.setValue("exceptionVectorTableBrowseWinIsVisible", exceptionvectortableBrowseWin->isVisible());\r
+ settings.setValue("exceptionVectorTableBrowseWinSize", exceptionvectortableBrowseWin->size());\r
+ settings.setValue("CallStackBrowseWinPos", CallStackBrowseWin->pos());\r
+ settings.setValue("CallStackBrowseWinIsVisible", CallStackBrowseWin->isVisible());\r
+ settings.setValue("CallStackBrowseWinSize", CallStackBrowseWin->size());\r
+ settings.setValue("BreakpointsWinPos", BreakpointsWin->pos());\r
+ settings.setValue("BreakpointsWinIsVisible", BreakpointsWin->isVisible());\r
+ settings.setValue("BreakpointsWinSize", BreakpointsWin->size());\r
+ settings.setValue("NewFunctionBreakpointWinPos", NewFunctionBreakpointWin->pos());\r
+ settings.setValue("NewFunctionBreakpointWinIsVisible", NewFunctionBreakpointWin->isVisible());\r
+ settings.setValue("NewFunctionBreakpointWinSize", NewFunctionBreakpointWin->size());\r
+ settings.setValue("CartFilesListWinPos", CartFilesListWin->pos());\r
+ settings.setValue("CartFilesListWinIsVisible", CartFilesListWin->isVisible());\r
+ settings.setValue("CartFilesListWinSize", CartFilesListWin->size());\r
+ settings.setValue("SaveDumpAsWinPos", SaveDumpAsWin->pos());\r
+ settings.setValue("SaveDumpAsWinIsVisible", SaveDumpAsWin->isVisible());\r
+ settings.setValue("SaveDumpAsWinSize", SaveDumpAsWin->size());\r
+\r
+ for (i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ sprintf(mem1Name, "mem1BrowseWinPos[%i]", (unsigned int)i);\r
+ settings.setValue(mem1Name, mem1BrowseWin[i]->pos());\r
+ sprintf(mem1Name, "mem1BrowseWinIsVisible[%i]", (unsigned int)i);\r
+ settings.setValue(mem1Name, mem1BrowseWin[i]->isVisible());\r
+ sprintf(mem1Name, "mem1BrowseWinSize[%i]", (unsigned int)i);\r
+ settings.setValue(mem1Name, mem1BrowseWin[i]->size());\r
+ }\r
+ }\r
+\r
+ settings.endGroup();\r
+}\r
+\r
+\r
+// Refresh alpine debug windows\r
+void MainWin::AlpineRefreshWindows(void)\r
+{\r
+ cpuBrowseWin->RefreshContents();\r
+ memBrowseWin->RefreshContents();\r
+ stackBrowseWin->RefreshContents();\r
+ opBrowseWin->RefreshContents();\r
+ riscDasmBrowseWin->RefreshContents();\r
+ m68kDasmBrowseWin->RefreshContents();\r
+ hwRegsBrowseWin->RefreshContents();\r
+}\r
+\r
+\r
+// \r
+void MainWin::CommonResetWindows(void)\r
+{\r
+}\r
+\r
+\r
+// Reset common\r
+void MainWin::CommonReset(void)\r
+{\r
+}\r
+\r
+\r
+// Reset soft debugger\r
+void MainWin::DebuggerReset(void)\r
+{\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ DeleteAllBreakpoints();\r
+ }\r
+}\r
+\r
+\r
+// Reset soft debugger windows\r
+void MainWin::DebuggerResetWindows(void)\r
+{\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ FilesrcListWin->Reset();\r
+ allWatchBrowseWin->Reset();\r
+ heapallocatorBrowseWin->Reset();\r
+ BreakpointsWin->Reset();\r
+ CartFilesListWin->Reset();\r
+ SourcesWin->Reset();\r
+ //ResetAlpineWindows();\r
+ }\r
+}\r
+\r
+\r
+// Refresh common windows\r
+void MainWin::CommonRefreshWindows(void)\r
+{\r
+ emuStatusWin->RefreshContents();\r
+}\r
+\r
+\r
+// Refresh view windows\r
+void MainWin::ViewRefreshWindows(void)\r
+{\r
+ CartFilesListWin->RefreshContents();\r
+}\r
+\r
+\r
+// \r
+void MainWin::RefreshWindows(void)\r
+{\r
+ DebuggerRefreshWindows();\r
+ CommonRefreshWindows();\r
+}\r
+\r
+\r
+// Refresh soft debugger & alpine debug windows\r
+void MainWin::DebuggerRefreshWindows(void)\r
+{\r
+ if (vjs.softTypeDebugger)\r
+ {\r
+ FilesrcListWin->RefreshContents();\r
+ SourcesWin->RefreshContents();\r
+ m68kDasmWin->RefreshContents();\r
+ GPUDasmWin->RefreshContents();\r
+ DSPDasmWin->RefreshContents();\r
+ allWatchBrowseWin->RefreshContents();\r
+ LocalBrowseWin->RefreshContents();\r
+ CallStackBrowseWin->RefreshContents();\r
+ heapallocatorBrowseWin->RefreshContents();\r
+ BreakpointsWin->RefreshContents();\r
+ for (size_t i = 0; i < vjs.nbrmemory1browserwindow; i++)\r
+ {\r
+ mem1BrowseWin[i]->RefreshContents(i);\r
+ }\r
+\r
+ AlpineRefreshWindows();\r
+ ViewRefreshWindows();\r
+ }\r
+}\r
+\r
+\r
+// Create and save screenshot\r
+void MainWin::MakeScreenshot(void)\r
+{\r
+ char Text[256];\r
+ QImage screenshot;\r
+ time_t now = time(0);\r
+ struct tm tstruct;\r
+\r
+ // Create filename\r
+ tstruct = *localtime(&now);\r
+ 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);\r
+\r
+ // Create screenshot\r
+ screenshot = videoWidget->grabFrameBuffer();\r
+ screenshot.save((char *)Text, "JPG", 100);\r
+}\r
+\r