X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fgui%2Fmainwin.cpp;h=69634f65338ed3f9b6f1ba56901ee0ceace7c4f5;hb=be0b102eec76acf80acce7cd3de8e690e27564d4;hp=e083446b34ffbfeb67c0ed54eafc13a3f6bd1e46;hpb=2c98ddddf1eeb20fe90c3e9759ac77ec96dcbc97;p=virtualjaguar diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index e083446..69634f6 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -8,6 +8,7 @@ // Who When What // --- ---------- ------------------------------------------------------------- // JLH 12/23/2009 Created this file +// JLH 12/20/2010 Added settings, menus & toolbars // // FIXED: @@ -22,100 +23,123 @@ //#define DEBUGFOO // Various tool debugging... //#define DEBUGTP // Toolpalette debugging... -//#include #include "mainwin.h" +//#include //#include #include "glwidget.h" -//#include "editwindow.h" -//#include "charwindow.h" -//#include "ttedit.h" +#include "about.h" +#include "settings.h" -MainWin::MainWin(): running(true) -{ - // 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. +// 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? +// 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. +// 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. -// ((TTEdit *)qApp)->charWnd = new CharWindow(this); +MainWin::MainWin() +{ videoWidget = new GLWidget(this); setCentralWidget(videoWidget); setWindowIcon(QIcon(":/res/vj.xpm")); setWindowTitle("Virtual Jaguar v2.0.0"); - QMenu * menu = menuBar()->addMenu(tr("&File")); - QToolBar * toolbar = addToolBar(tr("x1")); - /*QAction */ action = new QAction(tr("Toggle"), this); - action->setStatusTip(tr("Toggle running state")); - action->setCheckable(true); - toolbar->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(ToggleRunState())); -#if 0 -// createActions(); - newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); - newAct->setShortcuts(QKeySequence::New); - newAct->setStatusTip(tr("Create a new file")); - connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); - - openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); - openAct->setShortcuts(QKeySequence::Open); - openAct->setStatusTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - - aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - -// createMenus(); + aboutWin = new AboutWindow(this); + + videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + // Create actions + + quitAppAct = new QAction(tr("E&xit"), this); + quitAppAct->setShortcuts(QKeySequence::Quit); + quitAppAct->setStatusTip(tr("Quit Virtual Jaguar")); + connect(quitAppAct, SIGNAL(triggered()), this, SLOT(close())); + + powerAct = new QAction(QIcon(":/res/power.png"), tr("&Power"), this); + powerAct->setStatusTip(tr("Toggle running state")); + powerAct->setCheckable(true); + connect(powerAct, 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/generic.png"), tr("NTSC"), tvTypeActs); + ntscAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST")); + ntscAct->setCheckable(true); + connect(ntscAct, SIGNAL(triggered()), this, SLOT(SetNTSC())); + + palAct = new QAction(QIcon(":/res/generic.png"), tr("PAL"), tvTypeActs); + palAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST")); + palAct->setCheckable(true); + connect(palAct, SIGNAL(triggered()), this, SLOT(SetPAL())); + + blurAct = new QAction(QIcon(":/res/generic.png"), 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/generic.png"), tr("&About..."), this); + aboutAct->setStatusTip(tr("Blatant self-promotion")); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin())); + + // Create menus & toolbars + fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(exitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(cutAct); - editMenu->addAction(copyAct); - editMenu->addAction(pasteAct); - - menuBar()->addSeparator(); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(aboutAct); - helpMenu->addAction(aboutQtAct); - -// createToolBars(); - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - fileToolBar->addAction(openAct); - fileToolBar->addAction(saveAct); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->addAction(cutAct); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); -#endif + fileMenu->addAction(powerAct); + fileMenu->addAction(quitAppAct); + + fileMenu = menuBar()->addMenu(tr("&Help")); + fileMenu->addAction(aboutAct); + + QToolBar * toolbar = addToolBar(tr("Stuff")); + toolbar->addAction(powerAct); + toolbar->addAction(x1Act); + toolbar->addAction(x2Act); + toolbar->addAction(x3Act); + toolbar->addAction(ntscAct); + toolbar->addAction(palAct); + toolbar->addAction(blurAct); // Create status bar statusBar()->showMessage(tr("Ready")); ReadSettings(); + setUnifiedTitleAndToolBarOnMac(true); -// connect(textEdit->document(), SIGNAL(contentsChanged()), -// this, SLOT(documentWasModified())); + // Set toolbar button based on setting read in (sync the UI)... + 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); -// setCurrentFile(""); - setUnifiedTitleAndToolBarOnMac(true); + // Do this in case original size isn't correct (mostly for the first-run case) + ResizeMainWindow(); // Set up timer based loop for animation... timer = new QTimer(this); @@ -140,9 +164,9 @@ void MainWin::Timer(void) // Random hash & trash // We try to simulate an untuned tank circuit here... :-) - for(int x=0; xrasterWidth; x++) + for(uint32_t x=0; xrasterWidth; x++) { - for(int y=0; yrasterHeight; y++) + for(uint32_t y=0; yrasterHeight; y++) { videoWidget->buffer[(y * videoWidget->textureWidth) + x] = (rand() & 0xFF) << 8 | (rand() & 0xFF) << 16 | (rand() & 0xFF) << 24;// | (rand() & 0xFF);//0x000000FF; // buffer[(y * textureWidth) + x] = x*y; @@ -155,6 +179,68 @@ void MainWin::Timer(void) void MainWin::ToggleRunState(void) { running = !running; + + if (!running) + { + for(uint32_t x=0; xrasterWidth; x++) + for(uint32_t y=0; yrasterHeight; y++) + videoWidget->buffer[(y * videoWidget->textureWidth) + x] = 0x00000000; + + videoWidget->updateGL(); + } +} + +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) +{ + vjs.hardwareTypeNTSC = true; + ResizeMainWindow(); +} + +void MainWin::SetPAL(void) +{ + vjs.hardwareTypeNTSC = false; + ResizeMainWindow(); +} + +void MainWin::ToggleBlur(void) +{ + vjs.glFilter = !vjs.glFilter; +} + +void MainWin::ShowAboutWin(void) +{ + aboutWin->show(); +} + +void MainWin::ResizeMainWindow(void) +{ + videoWidget->setFixedSize(zoomLevel * 320, zoomLevel * (vjs.hardwareTypeNTSC ? 240 : 256)); + show(); + + for(int i=0; i<2; i++) + { + resize(0, 0); + usleep(2000); + QApplication::processEvents(); + } } void MainWin::ReadSettings(void) @@ -164,11 +250,20 @@ void MainWin::ReadSettings(void) QSize size = settings.value("size", QSize(400, 400)).toSize(); resize(size); move(pos); -//videoWidget->updateGL(); -// pos = settings.value("charWndPos", QPoint(0, 0)).toPoint(); -// size = settings.value("charWndSize", QSize(200, 200)).toSize(); -// ((TTEdit *)qApp)->charWnd->resize(size); -// ((TTEdit *)qApp)->charWnd->move(pos); + + zoomLevel = settings.value("zoom", 1).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.DSPEnabled = settings.value("DSPEnabled", false).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", 0).toInt(); + vjs.renderType = settings.value("renderType", 0).toInt(); } void MainWin::WriteSettings(void) @@ -176,7 +271,105 @@ void MainWin::WriteSettings(void) QSettings settings("Underground Software", "Virtual Jaguar"); settings.setValue("pos", pos()); settings.setValue("size", size()); -// settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos()); -// settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size()); + + settings.setValue("zoom", zoomLevel); + + 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("DSPEnabled", vjs.DSPEnabled); + 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); +} + +// Here's how Byuu does it... +// I think I have it working now... :-) +#if 0 +void Utility::resizeMainWindow() +{ + unsigned region = config().video.context->region; + unsigned multiplier = config().video.context->multiplier; + unsigned width = 256 * multiplier; + unsigned height = (region == 0 ? 224 : 239) * multiplier; + + if(config().video.context->correctAspectRatio) + { + if(region == 0) + { + width = (double)width * config().video.ntscAspectRatio + 0.5; //NTSC adjust + } + else + { + width = (double)width * config().video.palAspectRatio + 0.5; //PAL adjust + } + } + + if(config().video.isFullscreen == false) + { + //get effective desktop work area region (ignore Windows taskbar, OS X dock, etc.) + QRect deskRect = QApplication::desktop()->availableGeometry(mainWindow); + + //ensure window size will not be larger than viewable desktop area + constrainSize(height, width, deskRect.height()); //- frameHeight); + constrainSize(width, height, deskRect.width()); //- frameWidth ); + + mainWindow->canvas->setFixedSize(width, height); + mainWindow->show(); + } + else + { + for(unsigned i = 0; i < 2; i++) + { + unsigned iWidth = width, iHeight = height; + + constrainSize(iHeight, iWidth, mainWindow->canvasContainer->size().height()); + constrainSize(iWidth, iHeight, mainWindow->canvasContainer->size().width()); + + //center canvas onscreen; ensure it is not larger than viewable area + mainWindow->canvas->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + mainWindow->canvas->setFixedSize(iWidth, iHeight); + mainWindow->canvas->setMinimumSize(0, 0); + + usleep(2000); + QApplication::processEvents(); + } + } + + //workaround for Qt/Xlib bug: + //if window resize occurs with cursor over it, Qt shows Qt::Size*DiagCursor; + //so force it to show Qt::ArrowCursor, as expected + mainWindow->setCursor(Qt::ArrowCursor); + mainWindow->canvasContainer->setCursor(Qt::ArrowCursor); + mainWindow->canvas->setCursor(Qt::ArrowCursor); + + //workaround for DirectSound(?) bug: + //window resizing sometimes breaks audio sync, this call re-initializes it + updateAvSync(); +} + +void Utility::setScale(unsigned scale) +{ + config().video.context->multiplier = scale; + resizeMainWindow(); + mainWindow->shrink(); + mainWindow->syncUi(); } +void QbWindow::shrink() +{ + if(config().video.isFullscreen == false) + { + for(unsigned i = 0; i < 2; i++) + { + resize(0, 0); + usleep(2000); + QApplication::processEvents(); + } + } +} +#endif