5075 lines
130 KiB
C++
5075 lines
130 KiB
C++
/* FCE Ultra - NES/Famicom Emulator
|
|
*
|
|
* Copyright notice for this file:
|
|
* Copyright (C) 2020 mjbudd77
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
// ConsoleWindow.cpp
|
|
//
|
|
#if defined(__linux__) || defined(__unix__)
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/types.h>
|
|
#include <sys/syscall.h>
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <cstdlib>
|
|
|
|
#include <QPixmap>
|
|
#include <QWindow>
|
|
#include <QScreen>
|
|
#include <QSettings>
|
|
#include <QHeaderView>
|
|
#include <QFileInfo>
|
|
#include <QFileDialog>
|
|
#include <QMessageBox>
|
|
#include <QInputDialog>
|
|
#include <QDesktopServices>
|
|
#include <QStyleFactory>
|
|
#include <QApplication>
|
|
#include <QActionGroup>
|
|
#include <QShortcut>
|
|
#include <QUrl>
|
|
|
|
#include "../../fceu.h"
|
|
#include "../../fds.h"
|
|
#include "../../file.h"
|
|
#include "../../input.h"
|
|
#include "../../movie.h"
|
|
#include "../../wave.h"
|
|
#include "../../state.h"
|
|
#include "../../profiler.h"
|
|
#include "../../version.h"
|
|
#include "common/os_utils.h"
|
|
#include "utils/timeStamp.h"
|
|
|
|
#ifdef _S9XLUA_H
|
|
#include "../../fceulua.h"
|
|
#endif
|
|
|
|
#include "Qt/main.h"
|
|
#include "Qt/dface.h"
|
|
#include "Qt/input.h"
|
|
#include "Qt/throttle.h"
|
|
#include "Qt/ColorMenu.h"
|
|
#include "Qt/ConsoleWindow.h"
|
|
#include "Qt/InputConf.h"
|
|
#include "Qt/GamePadConf.h"
|
|
#include "Qt/FamilyKeyboard.h"
|
|
#include "Qt/HotKeyConf.h"
|
|
#include "Qt/PaletteConf.h"
|
|
#include "Qt/PaletteEditor.h"
|
|
#include "Qt/HelpPages.h"
|
|
#include "Qt/GuiConf.h"
|
|
#include "Qt/AviRecord.h"
|
|
#include "Qt/AviRiffViewer.h"
|
|
#include "Qt/MoviePlay.h"
|
|
#include "Qt/MovieRecord.h"
|
|
#include "Qt/MovieOptions.h"
|
|
#include "Qt/StateRecorderConf.h"
|
|
#include "Qt/TimingConf.h"
|
|
#include "Qt/FrameTimingStats.h"
|
|
#include "Qt/LuaControl.h"
|
|
#include "Qt/QtScriptManager.h"
|
|
#include "Qt/CheatsConf.h"
|
|
#include "Qt/GameGenie.h"
|
|
#include "Qt/HexEditor.h"
|
|
#include "Qt/TraceLogger.h"
|
|
#include "Qt/CodeDataLogger.h"
|
|
#include "Qt/ConsoleDebugger.h"
|
|
#include "Qt/ConsoleUtilities.h"
|
|
#include "Qt/ConsoleSoundConf.h"
|
|
#include "Qt/ConsoleVideoConf.h"
|
|
#include "Qt/MsgLogViewer.h"
|
|
#include "Qt/AboutWindow.h"
|
|
#include "Qt/fceuWrapper.h"
|
|
#include "Qt/ppuViewer.h"
|
|
#include "Qt/NameTableViewer.h"
|
|
#include "Qt/iNesHeaderEditor.h"
|
|
#include "Qt/RamWatch.h"
|
|
#include "Qt/RamSearch.h"
|
|
#include "Qt/keyscan.h"
|
|
#include "Qt/nes_shm.h"
|
|
#include "Qt/NetPlay.h"
|
|
#include "Qt/TasEditor/TasEditorWindow.h"
|
|
|
|
#ifdef __APPLE__
|
|
void qt_set_sequence_auto_mnemonic(bool enable);
|
|
#endif
|
|
|
|
consoleWin_t::consoleWin_t(QWidget *parent)
|
|
: QMainWindow( parent )
|
|
{
|
|
int opt, xWinPos = -1, yWinPos = -1, xWinSize = 256, yWinSize = 240;
|
|
int videoDriver = 0;
|
|
int setFullScreen = false;
|
|
|
|
//QString libpath = QLibraryInfo::location(QLibraryInfo::PluginsPath);
|
|
//printf("LibPath: '%s'\n", libpath.toLocal8Bit().constData() );
|
|
|
|
#ifdef __APPLE__
|
|
qt_set_sequence_auto_mnemonic(true);
|
|
#endif
|
|
|
|
printf("Running on Platform: %s\n", QGuiApplication::platformName().toLocal8Bit().constData() );
|
|
|
|
QThread *thread = QThread::currentThread();
|
|
|
|
if (thread)
|
|
{
|
|
thread->setObjectName( QString("MainThread") );
|
|
}
|
|
|
|
QApplication::setStyle( new fceuStyle() );
|
|
|
|
initHotKeys();
|
|
|
|
firstResize = true;
|
|
closeRequested = false;
|
|
errorMsgValid = false;
|
|
viewport_GL = NULL;
|
|
viewport_SDL = NULL;
|
|
viewport_QWidget = NULL;
|
|
viewport_Interface = NULL;
|
|
|
|
contextMenuEnable = false;
|
|
soundUseGlobalFocus = false;
|
|
mainMenuEmuPauseSet = false;
|
|
mainMenuEmuWasPaused = false;
|
|
mainMenuPauseWhenActv = false;
|
|
autoHideMenuFullscreen = false;
|
|
redrawVideoRequest = false;
|
|
|
|
createMainMenu();
|
|
|
|
g_config->getOption( "SDL.PauseOnMainMenuAccess", &mainMenuPauseWhenActv );
|
|
g_config->getOption( "SDL.AutoHideMenuFullsreen", &autoHideMenuFullscreen );
|
|
g_config->getOption( "SDL.ContextMenuEnable", &contextMenuEnable );
|
|
g_config->getOption( "SDL.Sound.UseGlobalFocus", &soundUseGlobalFocus );
|
|
g_config->getOption ("SDL.VideoDriver", &videoDriver);
|
|
|
|
loadVideoDriver( videoDriver );
|
|
|
|
setWindowTitle( tr(FCEU_NAME_AND_VERSION) );
|
|
setWindowIcon(QIcon(":fceux1.png"));
|
|
setAcceptDrops(true);
|
|
|
|
gameTimer = new QTimer( this );
|
|
emulatorThread = new emulatorThread_t(this);
|
|
|
|
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);
|
|
connect(emulatorThread, SIGNAL(frameFinished(void)), this, SLOT(emuFrameFinish(void)) );
|
|
connect(emulatorThread, SIGNAL(loadRomRequest(QString)), this, SLOT(loadRomRequestCB(QString)) );
|
|
|
|
connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updatePeriodic );
|
|
|
|
gameTimer->setTimerType( Qt::PreciseTimer );
|
|
gameTimer->start( 8 ); // 120hz
|
|
|
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
|
QtScriptManager::create(nullptr);
|
|
#endif
|
|
|
|
emulatorThread->start();
|
|
|
|
g_config->getOption( "SDL.SetSchedParam", &opt );
|
|
|
|
if ( opt )
|
|
{
|
|
#ifndef WIN32
|
|
int policy, prio, nice;
|
|
|
|
g_config->getOption( "SDL.GuiSchedPolicy", &policy );
|
|
g_config->getOption( "SDL.GuiSchedPrioRt", &prio );
|
|
g_config->getOption( "SDL.GuiSchedNice" , &nice );
|
|
|
|
setNicePriority( nice );
|
|
|
|
setSchedParam( policy, prio );
|
|
#endif
|
|
}
|
|
|
|
|
|
SDL_DisplayMode mode;
|
|
int sdl_err = SDL_GetCurrentDisplayMode(0,&mode);
|
|
g_config->getOption( "SDL.Fullscreen", &setFullScreen );
|
|
if( (sdl_err == 0) && setFullScreen )
|
|
{
|
|
xWinPos = 0;
|
|
yWinPos = 0;
|
|
xWinSize = mode.w;
|
|
yWinSize = mode.h;
|
|
}
|
|
else
|
|
{
|
|
g_config->getOption( "SDL.WinPosX" , &xWinPos );
|
|
g_config->getOption( "SDL.WinPosY" , &yWinPos );
|
|
g_config->getOption( "SDL.WinSizeX", &xWinSize );
|
|
g_config->getOption( "SDL.WinSizeY", &yWinSize );
|
|
}
|
|
|
|
if ( (xWinSize >= 256) && (yWinSize >= 224) )
|
|
{
|
|
this->resize( xWinSize, yWinSize );
|
|
|
|
if ( (xWinPos >= 0) && (yWinPos >= 0) )
|
|
{
|
|
this->move( xWinPos, yWinPos );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QSize reqSize = calcRequiredSize();
|
|
|
|
// Since the height of menu is unknown until Qt has shows the window
|
|
// Set the minimum viewport sizes to exactly what we need so that
|
|
// the window is resized appropriately. On the first resize event,
|
|
// we will set the minimum viewport size back to 1x values that the
|
|
// window can be shrunk by dragging lower corner.
|
|
if ( viewport_Interface != NULL )
|
|
{
|
|
viewport_Interface->setMinimumSize( reqSize );
|
|
}
|
|
//this->resize( reqSize );
|
|
}
|
|
|
|
g_config->getOption( "SDL.Fullscreen", &setFullScreen );
|
|
g_config->setOption( "SDL.Fullscreen", 0 ); // Reset full screen config parameter to false so it is never saved this way
|
|
|
|
if ( setFullScreen )
|
|
{
|
|
if ( autoHideMenuFullscreen )
|
|
{
|
|
menubar->setVisible(false);
|
|
}
|
|
this->showFullScreen();
|
|
}
|
|
|
|
refreshRate = 0.0;
|
|
updateCounter = 0;
|
|
recentRomMenuReset = false;
|
|
helpWin = 0;
|
|
|
|
// Viewport Cursor Type and Visibility
|
|
loadCursor();
|
|
|
|
// Create AVI Recording Disk Thread
|
|
aviDiskThread = new AviRecordDiskThread_t(this);
|
|
|
|
scrHandlerConnected = false;
|
|
}
|
|
|
|
consoleWin_t::~consoleWin_t(void)
|
|
{
|
|
QSize w;
|
|
QClipboard *clipboard;
|
|
|
|
// Save window size and image scaling parameters at app exit.
|
|
w = size();
|
|
|
|
// Only Save window size if not fullscreen and not maximized
|
|
if ( !isFullScreen() && !isMaximized() )
|
|
{
|
|
// Scaling is only saved when applying video settings
|
|
g_config->setOption( "SDL.WinPosX" , pos().x() );
|
|
g_config->setOption( "SDL.WinPosY" , pos().y() );
|
|
g_config->setOption( "SDL.WinSizeX", w.width() );
|
|
g_config->setOption( "SDL.WinSizeY", w.height() );
|
|
}
|
|
else
|
|
{
|
|
QRect rect = normalGeometry();
|
|
|
|
if ( rect.isValid() )
|
|
{
|
|
g_config->setOption( "SDL.WinPosX" , rect.x() );
|
|
g_config->setOption( "SDL.WinPosY" , rect.y() );
|
|
g_config->setOption( "SDL.WinSizeX", rect.width() );
|
|
g_config->setOption( "SDL.WinSizeY", rect.height() );
|
|
}
|
|
}
|
|
g_config->save();
|
|
|
|
// Signal Emulator Thread to Stop
|
|
nes_shm->runEmulator = 0;
|
|
|
|
gameTimer->stop();
|
|
|
|
closeGamePadConfWindow();
|
|
|
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
|
QtScriptManager::destroy();
|
|
#endif
|
|
// The closeApp function call stops all threads.
|
|
// Calling quit on threads should not happen here.
|
|
//printf("Thread Finished: %i \n", emulatorThread->isFinished() );
|
|
//emulatorThread->quit();
|
|
//emulatorThread->wait( 1000 );
|
|
|
|
//aviDiskThread->requestInterruption();
|
|
//aviDiskThread->quit();
|
|
//aviDiskThread->wait( 10000 );
|
|
|
|
//FCEU_WRAPPER_LOCK();
|
|
//fceuWrapperClose();
|
|
//FCEU_WRAPPER_UNLOCK();
|
|
|
|
unloadVideoDriver();
|
|
|
|
// LoadGame() checks for an IP and if it finds one begins a network session
|
|
// clear the NetworkIP field so this doesn't happen unintentionally
|
|
//g_config->setOption ("SDL.NetworkIP", "");
|
|
//g_config->save ();
|
|
|
|
// Clear Clipboard Contents on Program Exit
|
|
clipboard = QGuiApplication::clipboard();
|
|
|
|
if ( clipboard->ownsClipboard() )
|
|
{
|
|
clipboard->clear( QClipboard::Clipboard );
|
|
}
|
|
if ( clipboard->ownsSelection() )
|
|
{
|
|
clipboard->clear( QClipboard::Selection );
|
|
}
|
|
|
|
clearRomList();
|
|
|
|
if ( this == consoleWindow )
|
|
{
|
|
consoleWindow = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
int consoleWin_t::videoInit(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (viewport_Interface)
|
|
{
|
|
ret = viewport_Interface->init();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void consoleWin_t::videoReset(void)
|
|
{
|
|
if (viewport_Interface)
|
|
{
|
|
viewport_Interface->reset();
|
|
}
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::initScreenHandler(void)
|
|
{
|
|
if ( !scrHandlerConnected )
|
|
{
|
|
QWidget *w;
|
|
|
|
w = this->window();
|
|
|
|
// This needs to be scheduled after window creation.
|
|
if ( w != NULL)
|
|
{
|
|
QWindow *hdl = w->windowHandle();
|
|
|
|
if (hdl != NULL)
|
|
{
|
|
//printf("Connecting to screenChanged Signal\n");
|
|
connect( hdl, SIGNAL(screenChanged(QScreen*)), this, SLOT(winScreenChanged(QScreen*)) );
|
|
scrHandlerConnected = true;
|
|
|
|
winScreenChanged( hdl->screen() );
|
|
|
|
connect( hdl, SIGNAL(activeChanged(void)), this, SLOT(winActiveChanged(void)) );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void consoleWin_t::winScreenChanged(QScreen *scr)
|
|
{
|
|
if ( scr == NULL )
|
|
{
|
|
return;
|
|
}
|
|
refreshRate = scr->refreshRate();
|
|
printf("Screen Refresh Rate: %f\n", scr->refreshRate() );
|
|
|
|
//printf("Screen Changed: %p\n", scr );
|
|
if ( viewport_GL != NULL )
|
|
{
|
|
viewport_GL->screenChanged( scr );
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::winActiveChanged(void)
|
|
{
|
|
QWidget *w;
|
|
bool muteWindow = false;
|
|
|
|
w = this->window();
|
|
|
|
//printf("Active Changed\n");
|
|
|
|
if ( w != NULL)
|
|
{
|
|
QWindow *hdl = w->windowHandle();
|
|
|
|
if (hdl != NULL)
|
|
{
|
|
if ( !soundUseGlobalFocus )
|
|
{
|
|
if ( hdl->isActive() )
|
|
{
|
|
muteWindow = false;
|
|
}
|
|
else
|
|
{
|
|
muteWindow = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
FCEUD_MuteSoundWindow(muteWindow);
|
|
}
|
|
|
|
QSize consoleWin_t::calcRequiredSize(void)
|
|
{
|
|
QSize out( GL_NES_WIDTH, GL_NES_HEIGHT );
|
|
|
|
QSize w, v;
|
|
double xscale = 1.0, yscale = 1.0, aspectRatio = 1.0;
|
|
int texture_width = GL_NES_WIDTH;
|
|
int texture_height = GL_NES_HEIGHT;
|
|
int l=0, r=texture_width;
|
|
int t=0, b=texture_height;
|
|
int dw=0, dh=0, rw, rh;
|
|
bool forceAspect = true;
|
|
|
|
CalcVideoDimensions();
|
|
|
|
texture_width = nes_shm->video.ncol;
|
|
texture_height = nes_shm->video.nrow;
|
|
|
|
l=0, r=texture_width;
|
|
t=0, b=texture_height;
|
|
|
|
w = size();
|
|
|
|
if ( viewport_Interface )
|
|
{
|
|
v = viewport_Interface->size();
|
|
forceAspect = viewport_Interface->getForceAspectOpt();
|
|
aspectRatio = viewport_Interface->getAspectRatio();
|
|
xscale = viewport_Interface->getScaleX();
|
|
yscale = viewport_Interface->getScaleY();
|
|
}
|
|
|
|
dw = 0;
|
|
dh = 0;
|
|
|
|
if ( forceAspect )
|
|
{
|
|
yscale = xscale * (double)nes_shm->video.xyRatio;
|
|
}
|
|
rw=(int)((r-l)*xscale);
|
|
rh=(int)((b-t)*yscale);
|
|
|
|
//printf("view %i x %i \n", rw, rh );
|
|
|
|
if ( forceAspect )
|
|
{
|
|
double rr;
|
|
|
|
rr = (double)rh / (double)rw;
|
|
|
|
if ( rr > aspectRatio )
|
|
{
|
|
rw = (int)( (((double)rh) / aspectRatio) + 0.50);
|
|
}
|
|
else
|
|
{
|
|
rh = (int)( (((double)rw) * aspectRatio) + 0.50);
|
|
}
|
|
}
|
|
|
|
out.setWidth( rw + dw );
|
|
out.setHeight( rh + dh );
|
|
|
|
//printf("Win %i x %i \n", rw + dw, rh + dh );
|
|
|
|
return out;
|
|
}
|
|
|
|
void consoleWin_t::setViewportAspect(void)
|
|
{
|
|
int aspectSel;
|
|
double x,y;
|
|
|
|
g_config->getOption ("SDL.AspectSelect", &aspectSel);
|
|
|
|
switch ( aspectSel )
|
|
{
|
|
default:
|
|
case 0:
|
|
x = 1.0; y = 1.0;
|
|
break;
|
|
case 1:
|
|
x = 8.0; y = 7.0;
|
|
break;
|
|
case 2:
|
|
x = 11.0; y = 8.0;
|
|
break;
|
|
case 3:
|
|
x = 4.0; y = 3.0;
|
|
break;
|
|
case 4:
|
|
x = 16.0; y = 9.0;
|
|
break;
|
|
case 5:
|
|
{
|
|
x = 1.0; y = 1.0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (viewport_Interface)
|
|
{
|
|
viewport_Interface->setAspectXY( x, y );
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::setMenuAccessPauseEnable( bool enable )
|
|
{
|
|
mainMenuPauseWhenActv = enable;
|
|
}
|
|
|
|
void consoleWin_t::setContextMenuEnable( bool enable )
|
|
{
|
|
contextMenuEnable = enable;
|
|
}
|
|
|
|
void consoleWin_t::setSoundUseGlobalFocus( bool enable )
|
|
{
|
|
soundUseGlobalFocus = enable;
|
|
|
|
winActiveChanged();
|
|
}
|
|
|
|
void consoleWin_t::loadCursor(void)
|
|
{
|
|
int cursorVis;
|
|
|
|
// Viewport Cursor Type and Visibility
|
|
g_config->getOption("SDL.CursorVis", &cursorVis );
|
|
|
|
if ( cursorVis )
|
|
{
|
|
int cursorType;
|
|
|
|
g_config->getOption("SDL.CursorType", &cursorType );
|
|
|
|
switch ( cursorType )
|
|
{
|
|
case 4:
|
|
{
|
|
QPixmap reticle(":/icons/reticle.png");
|
|
|
|
setViewerCursor( QCursor(reticle.scaled(64,64)) );
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
QPixmap reticle(":/icons/reticle.png");
|
|
|
|
setViewerCursor( QCursor(reticle.scaled(32,32)) );
|
|
}
|
|
break;
|
|
case 2:
|
|
setViewerCursor( Qt::BlankCursor );
|
|
break;
|
|
case 1:
|
|
setViewerCursor( Qt::CrossCursor );
|
|
break;
|
|
default:
|
|
case 0:
|
|
setViewerCursor( Qt::ArrowCursor );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setViewerCursor( Qt::BlankCursor );
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::setViewerCursor( QCursor s )
|
|
{
|
|
if (viewport_Interface)
|
|
{
|
|
viewport_Interface->setCursor(s);
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::setViewerCursor( Qt::CursorShape s )
|
|
{
|
|
if (viewport_Interface)
|
|
{
|
|
viewport_Interface->setCursor(s);
|
|
}
|
|
}
|
|
|
|
Qt::CursorShape consoleWin_t::getViewerCursor(void)
|
|
{
|
|
Qt::CursorShape s = Qt::ArrowCursor;
|
|
|
|
if (viewport_Interface)
|
|
{
|
|
s = viewport_Interface->cursor().shape();
|
|
}
|
|
return s;
|
|
}
|
|
|
|
void consoleWin_t::resizeEvent(QResizeEvent *event)
|
|
{
|
|
if ( firstResize )
|
|
{
|
|
// We are assuming that window has been exposed and all sizing of menu is finished
|
|
// Restore minimum sizes to 1x values after first resize event so that
|
|
// window is still able to be shrunk by dragging lower corners.
|
|
if (viewport_Interface)
|
|
{
|
|
viewport_Interface->setMinimumSize( QSize( 256, 224 ) );
|
|
}
|
|
|
|
firstResize = false;
|
|
}
|
|
//printf("%i x %i \n", event->size().width(), event->size().height() );
|
|
}
|
|
|
|
void consoleWin_t::setCyclePeriodms( int ms )
|
|
{
|
|
// If timer is already running, it will be restarted.
|
|
gameTimer->start( ms );
|
|
|
|
//printf("Period Set to: %i ms \n", ms );
|
|
}
|
|
|
|
void consoleWin_t::showErrorMsgWindow()
|
|
{
|
|
QMessageBox msgBox(this);
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
msgBox.resize( this->size() );
|
|
msgBox.setIcon( QMessageBox::Critical );
|
|
msgBox.setText( tr(errorMsg.c_str()) );
|
|
errorMsg.clear();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
//msgBox.show();
|
|
msgBox.exec();
|
|
}
|
|
|
|
void consoleWin_t::QueueErrorMsgWindow( const char *msg )
|
|
{
|
|
errorMsg.append( msg );
|
|
errorMsg.append("\n");
|
|
errorMsgValid = true;
|
|
}
|
|
|
|
void consoleWin_t::closeEvent(QCloseEvent *event)
|
|
{
|
|
//printf("Main Window Close Event\n");
|
|
closeGamePadConfWindow();
|
|
|
|
event->accept();
|
|
|
|
closeApp();
|
|
}
|
|
|
|
void consoleWin_t::requestClose(void)
|
|
{
|
|
closeRequested = true;
|
|
}
|
|
|
|
void consoleWin_t::keyPressEvent(QKeyEvent *event)
|
|
{
|
|
//printf("Key Press: 0x%x \n", event->key() );
|
|
pushKeyEvent( event, 1 );
|
|
|
|
event->accept();
|
|
}
|
|
|
|
void consoleWin_t::keyReleaseEvent(QKeyEvent *event)
|
|
{
|
|
//printf("Key Release: 0x%x \n", event->key() );
|
|
pushKeyEvent( event, 0 );
|
|
|
|
event->accept();
|
|
}
|
|
|
|
void consoleWin_t::dragEnterEvent(QDragEnterEvent *event)
|
|
{
|
|
if (event->mimeData()->hasUrls() )
|
|
{
|
|
event->acceptProposedAction();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::dropEvent(QDropEvent *event)
|
|
{
|
|
if (event->mimeData()->hasUrls() )
|
|
{
|
|
QList<QUrl> urls = event->mimeData()->urls();
|
|
|
|
QString filename = urls[0].toString( QUrl::PreferLocalFile );
|
|
|
|
QFileInfo fi( filename );
|
|
QString suffix = fi.suffix();
|
|
|
|
bool isStateSaveFile = (suffix.size() == 3) &&
|
|
(suffix[0] == 'f') && (suffix[1] == 'c') &&
|
|
( (suffix[2] == 's') || suffix[2].isDigit() );
|
|
|
|
//printf("DragNDrop Suffix: %s\n", suffix.toLocal8Bit().constData() );
|
|
|
|
if (isStateSaveFile)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_LoadState( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
event->accept();
|
|
}
|
|
else if ( suffix.compare("lua", Qt::CaseInsensitive) == 0 )
|
|
{
|
|
int luaLoadSuccess;
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
luaLoadSuccess = FCEU_LoadLuaCode( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
if (luaLoadSuccess)
|
|
{
|
|
g_config->setOption("SDL.LastLoadLua", filename.toLocal8Bit().constData());
|
|
}
|
|
event->accept();
|
|
}
|
|
else
|
|
{
|
|
int romLoadSuccess;
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
romLoadSuccess = LoadGame( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
if (!romLoadSuccess)
|
|
{
|
|
printf("DragNDrop ROM Load Failed for %s\n", filename.toLocal8Bit().constData() );
|
|
}
|
|
event->accept();
|
|
}
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::showEvent(QShowEvent *event)
|
|
{
|
|
//printf("Main Window Show Event\n");
|
|
initScreenHandler();
|
|
}
|
|
|
|
void consoleWin_t::contextMenuEvent(QContextMenuEvent *event)
|
|
{
|
|
QAction *act;
|
|
QMenu menu(this);
|
|
|
|
if ( !contextMenuEnable )
|
|
{
|
|
return;
|
|
}
|
|
|
|
act = new QAction(tr("Open ROM"), &menu);
|
|
connect( act, SIGNAL(triggered(void)), this, SLOT(openROMFile(void)) );
|
|
|
|
menu.addAction( act );
|
|
|
|
act = new QAction(tr("Last ROM Used"), &menu);
|
|
act->setEnabled( romList.size() > 0 );
|
|
connect( act, SIGNAL(triggered(void)), this, SLOT(loadMostRecentROM(void)) );
|
|
|
|
menu.addAction( act );
|
|
|
|
menu.addSeparator();
|
|
|
|
act = new QAction(tr("Online Help"), &menu);
|
|
connect( act, SIGNAL(triggered(void)), this, SLOT(openOnlineDocs(void)) );
|
|
|
|
menu.addAction( act );
|
|
|
|
menu.addSeparator();
|
|
|
|
act = new QAction(tr("Disable Context Menu via Options -> GUI Config"), &menu);
|
|
connect( act, SIGNAL(triggered(void)), this, SLOT(openGuiConfWin(void)) );
|
|
|
|
menu.addAction( act );
|
|
|
|
menu.addSeparator();
|
|
|
|
menu.exec(event->globalPos());
|
|
|
|
event->accept();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::initHotKeys(void)
|
|
{
|
|
for (int i = 0; i < HK_MAX; i++)
|
|
{
|
|
Hotkeys[i].init( this );
|
|
}
|
|
|
|
for (int i = 0; i < HK_MAX; i++)
|
|
{
|
|
QShortcut *shortcut = Hotkeys[i].getShortcut();
|
|
|
|
// Use Lambda Function to set callback
|
|
connect( shortcut, &QShortcut::activatedAmbiguously, [ this, shortcut ] { warnAmbiguousShortcut( shortcut ); } );
|
|
}
|
|
|
|
// Frame Advance uses key state directly, disable shortcut events
|
|
Hotkeys[HK_FRAME_ADVANCE].getShortcut()->setEnabled(false);
|
|
Hotkeys[HK_TURBO ].getShortcut()->setEnabled(false);
|
|
|
|
connect( Hotkeys[ HK_SPEED_QUARTER ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 25); } );
|
|
connect( Hotkeys[ HK_SPEED_HALF ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 50); } );
|
|
connect( Hotkeys[ HK_SPEED_NORMAL ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 100); } );
|
|
connect( Hotkeys[ HK_SPEED_2X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 200); } );
|
|
connect( Hotkeys[ HK_SPEED_4X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 400); } );
|
|
connect( Hotkeys[ HK_SPEED_8X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 800); } );
|
|
connect( Hotkeys[ HK_SPEED_16X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed(1600); } );
|
|
|
|
connect( Hotkeys[ HK_VOLUME_MUTE ].getShortcut(), SIGNAL(activated()), this, SLOT(muteSoundVolume(void)) );
|
|
connect( Hotkeys[ HK_VOLUME_DOWN ].getShortcut(), SIGNAL(activated()), this, SLOT(decrSoundVolume(void)) );
|
|
connect( Hotkeys[ HK_VOLUME_UP ].getShortcut(), SIGNAL(activated()), this, SLOT(incrSoundVolume(void)) );
|
|
|
|
connect( Hotkeys[ HK_LAG_COUNTER_DISPLAY ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleLagCounterDisplay(void)) );
|
|
connect( Hotkeys[ HK_FA_LAG_SKIP ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleFrameAdvLagSkip(void)) );
|
|
connect( Hotkeys[ HK_BIND_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleMovieBindSaveState(void)));
|
|
connect( Hotkeys[ HK_TOGGLE_FRAME_DISPLAY ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleMovieFrameDisplay(void)) );
|
|
connect( Hotkeys[ HK_MOVIE_TOGGLE_RW ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleMovieReadWrite(void)) );
|
|
connect( Hotkeys[ HK_TOGGLE_INPUT_DISPLAY ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleInputDisplay(void)) );
|
|
connect( Hotkeys[ HK_TOGGLE_BG ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleBackground(void)) );
|
|
connect( Hotkeys[ HK_TOGGLE_FG ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleForeground(void)) );
|
|
connect( Hotkeys[ HK_FKB_ENABLE ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleFamKeyBrdEnable(void)) );
|
|
connect( Hotkeys[ HK_TOGGLE_ALL_CHEATS ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleGlobalCheatEnable(void)) );
|
|
|
|
connect( Hotkeys[ HK_SAVE_STATE_0 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState0(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_1 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState1(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_2 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState2(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_3 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState3(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_4 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState4(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_5 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState5(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_6 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState6(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_7 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState7(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_8 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState8(void)) );
|
|
connect( Hotkeys[ HK_SAVE_STATE_9 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState9(void)) );
|
|
|
|
connect( Hotkeys[ HK_LOAD_STATE_0 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState0(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_1 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState1(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_2 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState2(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_3 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState3(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_4 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState4(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_5 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState5(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_6 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState6(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_7 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState7(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_8 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState8(void)) );
|
|
connect( Hotkeys[ HK_LOAD_STATE_9 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState9(void)) );
|
|
|
|
connect( Hotkeys[ HK_LOAD_PREV_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(loadPrevState(void)) );
|
|
connect( Hotkeys[ HK_LOAD_NEXT_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(loadNextState(void)) );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::createMainMenu(void)
|
|
{
|
|
QAction *act;
|
|
QMenu *subMenu;
|
|
QActionGroup *group;
|
|
int useNativeMenuBar;
|
|
int customAutofireOnFrames, customAutofireOffFrames;
|
|
//QShortcut *shortcut;
|
|
|
|
menubar = new consoleMenuBar(this);
|
|
|
|
this->setMenuBar(menubar);
|
|
|
|
// This is needed for menu bar to show up on MacOS
|
|
g_config->getOption( "SDL.UseNativeMenuBar", &useNativeMenuBar );
|
|
|
|
menubar->setNativeMenuBar( useNativeMenuBar ? true : false );
|
|
|
|
// Top Level Menu Iterms
|
|
fileMenu = menubar->addMenu(tr("&File"));
|
|
movieMenu = menubar->addMenu(tr("&Movie"));
|
|
optMenu = menubar->addMenu(tr("&Options"));
|
|
emuMenu = menubar->addMenu(tr("&Emulation"));
|
|
netPlayMenu = menubar->addMenu(tr("&NetPlay"));
|
|
toolsMenu = menubar->addMenu(tr("&Tools"));
|
|
debugMenu = menubar->addMenu(tr("&Debug"));
|
|
helpMenu = menubar->addMenu(tr("&Help"));
|
|
|
|
//-----------------------------------------------------------------------
|
|
// File
|
|
|
|
connect( fileMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( fileMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// File -> Open ROM
|
|
openROM = new QAction(tr("&Open ROM"), this);
|
|
//openROM->setShortcuts(QKeySequence::Open);
|
|
openROM->setStatusTip(tr("Open ROM File"));
|
|
//openROM->setIcon( QIcon(":icons/rom.png") );
|
|
//openROM->setIcon( style->standardIcon( QStyle::SP_FileIcon ) );
|
|
openROM->setIcon( style()->standardIcon( QStyle::SP_FileDialogStart ) );
|
|
connect(openROM, SIGNAL(triggered()), this, SLOT(openROMFile(void)) );
|
|
|
|
Hotkeys[ HK_OPEN_ROM ].setAction( openROM );
|
|
connect( Hotkeys[ HK_OPEN_ROM ].getShortcut(), SIGNAL(activated()), this, SLOT(openROMFile(void)) );
|
|
|
|
fileMenu->addAction(openROM);
|
|
|
|
// File -> Close ROM
|
|
closeROM = new QAction(tr("&Close ROM"), this);
|
|
//closeROM->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
closeROM->setStatusTip(tr("Close Loaded ROM"));
|
|
closeROM->setIcon( style()->standardIcon( QStyle::SP_BrowserStop ) );
|
|
connect(closeROM, SIGNAL(triggered()), this, SLOT(closeROMCB(void)) );
|
|
|
|
Hotkeys[ HK_CLOSE_ROM ].setAction( closeROM );
|
|
connect( Hotkeys[ HK_CLOSE_ROM ].getShortcut(), SIGNAL(activated()), this, SLOT(closeROMCB(void)) );
|
|
|
|
fileMenu->addAction(closeROM);
|
|
|
|
// File -> Recent ROMs
|
|
recentRomMenu = fileMenu->addMenu( tr("&Recent ROMs") );
|
|
|
|
buildRecentRomMenu();
|
|
|
|
fileMenu->addSeparator();
|
|
|
|
// File -> Play NSF
|
|
playNSF = new QAction(tr("Play &NSF"), this);
|
|
//playNSF->setShortcut( QKeySequence(tr("Ctrl+N")));
|
|
playNSF->setStatusTip(tr("Play NSF"));
|
|
connect(playNSF, SIGNAL(triggered()), this, SLOT(loadNSF(void)) );
|
|
|
|
fileMenu->addAction(playNSF);
|
|
|
|
fileMenu->addSeparator();
|
|
|
|
// File -> Load State From
|
|
loadStateAct = new QAction(tr("Load State &From"), this);
|
|
//loadStateAct->setShortcut( QKeySequence(tr("Ctrl+N")));
|
|
loadStateAct->setStatusTip(tr("Load State From"));
|
|
loadStateAct->setIcon( style()->standardIcon( QStyle::SP_FileDialogStart ) );
|
|
connect(loadStateAct, SIGNAL(triggered()), this, SLOT(loadStateFrom(void)) );
|
|
|
|
fileMenu->addAction(loadStateAct);
|
|
|
|
// File -> Save State As
|
|
saveStateAct = new QAction(tr("Save State &As"), this);
|
|
//loadStateAct->setShortcut( QKeySequence(tr("Ctrl+N")));
|
|
saveStateAct->setStatusTip(tr("Save State As"));
|
|
saveStateAct->setIcon( style()->standardIcon( QStyle::SP_DialogSaveButton ) );
|
|
connect(saveStateAct, SIGNAL(triggered()), this, SLOT(saveStateAs(void)) );
|
|
|
|
fileMenu->addAction(saveStateAct);
|
|
|
|
// File -> Quick Load
|
|
quickLoadAct = new QAction(tr("Quick &Load"), this);
|
|
//quickLoadAct->setShortcut( QKeySequence(tr("Shift+I")));
|
|
quickLoadAct->setStatusTip(tr("Quick Load"));
|
|
connect(quickLoadAct, SIGNAL(triggered()), this, SLOT(quickLoad(void)) );
|
|
|
|
fileMenu->addAction(quickLoadAct);
|
|
|
|
Hotkeys[ HK_LOAD_STATE ].setAction( quickLoadAct );
|
|
connect( Hotkeys[ HK_LOAD_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(quickLoad(void)) );
|
|
|
|
// File -> Quick Save
|
|
quickSaveAct = new QAction(tr("Quick &Save"), this);
|
|
//quickSaveAct->setShortcut( QKeySequence(tr("F5")));
|
|
quickSaveAct->setStatusTip(tr("Quick Save"));
|
|
connect(quickSaveAct, SIGNAL(triggered()), this, SLOT(quickSave(void)) );
|
|
|
|
fileMenu->addAction(quickSaveAct);
|
|
|
|
Hotkeys[ HK_SAVE_STATE ].setAction( quickSaveAct );
|
|
connect( Hotkeys[ HK_SAVE_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(quickSave(void)) );
|
|
|
|
// File -> Change State Slot
|
|
subMenu = fileMenu->addMenu(tr("Change &State Slot"));
|
|
group = new QActionGroup(this);
|
|
|
|
group->setExclusive(true);
|
|
|
|
for (int i=0; i<10; i++)
|
|
{
|
|
char stmp[8];
|
|
|
|
sprintf( stmp, "Slot &%i", i );
|
|
|
|
state[i] = new QAction(tr(stmp), this);
|
|
state[i]->setCheckable(true);
|
|
|
|
group->addAction(state[i]);
|
|
subMenu->addAction(state[i]);
|
|
}
|
|
state[0]->setChecked(true);
|
|
|
|
connect(state[0], SIGNAL(triggered()), this, SLOT(changeState0(void)) );
|
|
connect(state[1], SIGNAL(triggered()), this, SLOT(changeState1(void)) );
|
|
connect(state[2], SIGNAL(triggered()), this, SLOT(changeState2(void)) );
|
|
connect(state[3], SIGNAL(triggered()), this, SLOT(changeState3(void)) );
|
|
connect(state[4], SIGNAL(triggered()), this, SLOT(changeState4(void)) );
|
|
connect(state[5], SIGNAL(triggered()), this, SLOT(changeState5(void)) );
|
|
connect(state[6], SIGNAL(triggered()), this, SLOT(changeState6(void)) );
|
|
connect(state[7], SIGNAL(triggered()), this, SLOT(changeState7(void)) );
|
|
connect(state[8], SIGNAL(triggered()), this, SLOT(changeState8(void)) );
|
|
connect(state[9], SIGNAL(triggered()), this, SLOT(changeState9(void)) );
|
|
|
|
fileMenu->addSeparator();
|
|
|
|
Hotkeys[ HK_SELECT_STATE_0 ].setAction( state[0] );
|
|
Hotkeys[ HK_SELECT_STATE_1 ].setAction( state[1] );
|
|
Hotkeys[ HK_SELECT_STATE_2 ].setAction( state[2] );
|
|
Hotkeys[ HK_SELECT_STATE_3 ].setAction( state[3] );
|
|
Hotkeys[ HK_SELECT_STATE_4 ].setAction( state[4] );
|
|
Hotkeys[ HK_SELECT_STATE_5 ].setAction( state[5] );
|
|
Hotkeys[ HK_SELECT_STATE_6 ].setAction( state[6] );
|
|
Hotkeys[ HK_SELECT_STATE_7 ].setAction( state[7] );
|
|
Hotkeys[ HK_SELECT_STATE_8 ].setAction( state[8] );
|
|
Hotkeys[ HK_SELECT_STATE_9 ].setAction( state[9] );
|
|
|
|
connect( Hotkeys[ HK_SELECT_STATE_0 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState0(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_1 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState1(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_2 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState2(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_3 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState3(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_4 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState4(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_5 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState5(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_6 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState6(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_7 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState7(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_8 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState8(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_9 ].getShortcut(), SIGNAL(activated()), this, SLOT(changeState9(void)) );
|
|
|
|
connect( Hotkeys[ HK_SELECT_STATE_PREV ].getShortcut(), SIGNAL(activated()), this, SLOT(decrementState(void)) );
|
|
connect( Hotkeys[ HK_SELECT_STATE_NEXT ].getShortcut(), SIGNAL(activated()), this, SLOT(incrementState(void)) );
|
|
|
|
#ifdef _S9XLUA_H
|
|
// File -> Load Lua
|
|
loadLuaAct = new QAction(tr("Load &Lua Script"), this);
|
|
//loadLuaAct->setShortcut( QKeySequence(tr("F5")));
|
|
loadLuaAct->setStatusTip(tr("Load Lua Script"));
|
|
//loadLuaAct->setIcon( QIcon(":icons/lua-logo.png") );
|
|
connect(loadLuaAct, SIGNAL(triggered()), this, SLOT(loadLua(void)) );
|
|
|
|
fileMenu->addAction(loadLuaAct);
|
|
|
|
fileMenu->addSeparator();
|
|
#else
|
|
loadLuaAct = nullptr;
|
|
#endif
|
|
|
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
|
// File -> Load JavaScript
|
|
loadJsAct = new QAction(tr("Load &JavaScript"), this);
|
|
loadJsAct->setStatusTip(tr("Load JavaScript"));
|
|
connect(loadJsAct, SIGNAL(triggered()), this, SLOT(loadJs(void)) );
|
|
|
|
fileMenu->addAction(loadJsAct);
|
|
|
|
fileMenu->addSeparator();
|
|
#else
|
|
loadJsAct = NULL;
|
|
#endif
|
|
|
|
// File -> Screenshot
|
|
scrShotAct = new QAction(tr("Screens&hot"), this);
|
|
//scrShotAct->setShortcut( QKeySequence(tr("F12")));
|
|
scrShotAct->setStatusTip(tr("Screenshot"));
|
|
scrShotAct->setIcon( QIcon(":icons/camera.png") );
|
|
connect(scrShotAct, SIGNAL(triggered()), this, SLOT(prepareScreenShot(void)));
|
|
|
|
fileMenu->addAction(scrShotAct);
|
|
|
|
Hotkeys[ HK_SCREENSHOT ].setAction( scrShotAct );
|
|
connect( Hotkeys[ HK_SCREENSHOT ].getShortcut(), SIGNAL(activated()), this, SLOT(takeScreenShot(void)) );
|
|
|
|
// File -> Quit
|
|
quitAct = new QAction(tr("&Quit"), this);
|
|
//quitAct->setShortcut( QKeySequence(tr("Ctrl+Q")));
|
|
quitAct->setStatusTip(tr("Quit the Application"));
|
|
//quitAct->setIcon( style()->standardIcon( QStyle::SP_DialogCloseButton ) );
|
|
quitAct->setIcon( QIcon(":icons/application-exit.png") );
|
|
connect(quitAct, SIGNAL(triggered()), this, SLOT(closeApp()));
|
|
|
|
fileMenu->addAction(quitAct);
|
|
|
|
Hotkeys[ HK_QUIT ].setAction( quitAct );
|
|
connect( Hotkeys[ HK_QUIT ].getShortcut(), SIGNAL(activated()), this, SLOT(closeApp(void)) );
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Options
|
|
|
|
connect( optMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( optMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// Options -> Input Config
|
|
inputConfig = new QAction(tr("&Input Config"), this);
|
|
//inputConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
inputConfig->setStatusTip(tr("Input Configure"));
|
|
inputConfig->setIcon( QIcon(":icons/input-gaming.png") );
|
|
connect(inputConfig, SIGNAL(triggered()), this, SLOT(openInputConfWin(void)) );
|
|
|
|
optMenu->addAction(inputConfig);
|
|
|
|
// Options -> GamePad Config
|
|
gamePadConfig = new QAction(tr("&GamePad Config"), this);
|
|
//gamePadConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
gamePadConfig->setStatusTip(tr("GamePad Configure"));
|
|
gamePadConfig->setIcon( QIcon(":icons/input-gaming-symbolic.png") );
|
|
connect(gamePadConfig, SIGNAL(triggered()), this, SLOT(openGamePadConfWin(void)) );
|
|
|
|
optMenu->addAction(gamePadConfig);
|
|
|
|
// Options -> Sound Config
|
|
gameSoundConfig = new QAction(tr("&Sound Config"), this);
|
|
//gameSoundConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
gameSoundConfig->setStatusTip(tr("Sound Configure"));
|
|
gameSoundConfig->setIcon( style()->standardIcon( QStyle::SP_MediaVolume ) );
|
|
connect(gameSoundConfig, SIGNAL(triggered()), this, SLOT(openGameSndConfWin(void)) );
|
|
|
|
optMenu->addAction(gameSoundConfig);
|
|
|
|
// Options -> Video Config
|
|
gameVideoConfig = new QAction(tr("&Video Config"), this);
|
|
//gameVideoConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
gameVideoConfig->setStatusTip(tr("Video Preferences"));
|
|
gameVideoConfig->setIcon( style()->standardIcon( QStyle::SP_ComputerIcon ) );
|
|
connect(gameVideoConfig, SIGNAL(triggered()), this, SLOT(openGameVideoConfWin(void)) );
|
|
|
|
optMenu->addAction(gameVideoConfig);
|
|
|
|
// Options -> HotKey Config
|
|
hotkeyConfig = new QAction(tr("Hot&Key Config"), this);
|
|
//hotkeyConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
hotkeyConfig->setStatusTip(tr("Hotkey Configure"));
|
|
hotkeyConfig->setIcon( QIcon(":icons/input-keyboard.png") );
|
|
connect(hotkeyConfig, SIGNAL(triggered()), this, SLOT(openHotkeyConfWin(void)) );
|
|
|
|
optMenu->addAction(hotkeyConfig);
|
|
|
|
// Options -> Palette Config
|
|
paletteConfig = new QAction(tr("&Palette Config"), this);
|
|
//paletteConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
paletteConfig->setStatusTip(tr("Palette Configure"));
|
|
paletteConfig->setIcon( QIcon(":icons/graphics-palette.png") );
|
|
connect(paletteConfig, SIGNAL(triggered()), this, SLOT(openPaletteConfWin(void)) );
|
|
|
|
optMenu->addAction(paletteConfig);
|
|
|
|
// Options -> GUI Config
|
|
guiConfig = new QAction(tr("G&UI Config"), this);
|
|
//guiConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
guiConfig->setStatusTip(tr("GUI Configure"));
|
|
guiConfig->setIcon( style()->standardIcon( QStyle::SP_TitleBarNormalButton ) );
|
|
connect(guiConfig, SIGNAL(triggered()), this, SLOT(openGuiConfWin(void)) );
|
|
|
|
optMenu->addAction(guiConfig);
|
|
|
|
// Options -> Timing Config
|
|
timingConfig = new QAction(tr("&Timing Config"), this);
|
|
//timingConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
timingConfig->setStatusTip(tr("Timing Configure"));
|
|
timingConfig->setIcon( QIcon(":icons/timer.png") );
|
|
connect(timingConfig, SIGNAL(triggered()), this, SLOT(openTimingConfWin(void)) );
|
|
|
|
optMenu->addAction(timingConfig);
|
|
|
|
// Options -> State Recorder Config
|
|
stateRecordConfig = new QAction(tr("&State Recorder Config"), this);
|
|
//stateRecordConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
stateRecordConfig->setStatusTip(tr("State Recorder Configure"));
|
|
stateRecordConfig->setIcon( QIcon(":icons/media-record.png") );
|
|
connect(stateRecordConfig, SIGNAL(triggered()), this, SLOT(openStateRecorderConfWin(void)) );
|
|
|
|
optMenu->addAction(stateRecordConfig);
|
|
|
|
// Options -> Movie Options
|
|
movieConfig = new QAction(tr("&Movie Options"), this);
|
|
//movieConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
movieConfig->setStatusTip(tr("Movie Options"));
|
|
movieConfig->setIcon( QIcon(":icons/movie.png") );
|
|
connect(movieConfig, SIGNAL(triggered()), this, SLOT(openMovieOptWin(void)) );
|
|
|
|
optMenu->addAction(movieConfig);
|
|
|
|
// Options -> Auto-Resume
|
|
autoResume = new QAction(tr("Auto-&Resume Play"), this);
|
|
//autoResume->setShortcut( QKeySequence(tr("Ctrl+C")));
|
|
autoResume->setCheckable(true);
|
|
autoResume->setStatusTip(tr("Auto-Resume Play"));
|
|
syncActionConfig( autoResume, "SDL.AutoResume" );
|
|
connect(autoResume, SIGNAL(triggered()), this, SLOT(toggleAutoResume(void)) );
|
|
|
|
optMenu->addAction(autoResume);
|
|
|
|
optMenu->addSeparator();
|
|
|
|
// Options -> Window Resize
|
|
subMenu = optMenu->addMenu( tr("Window Resi&ze") );
|
|
|
|
for (int i=0; i<4; i++)
|
|
{
|
|
char stmp[8];
|
|
|
|
sprintf( stmp, "&%ix", i+1 );
|
|
|
|
winSizeAct[i] = new QAction(tr(stmp), this);
|
|
|
|
subMenu->addAction(winSizeAct[i]);
|
|
|
|
connect( winSizeAct[i], &QAction::triggered, [ this, i ]{ consoleWin_t::winResizeIx(i+1); } );
|
|
}
|
|
|
|
// Options -> Full Screen
|
|
fullscreen = new QAction(tr("&Fullscreen"), this);
|
|
//fullscreen->setShortcut( QKeySequence(tr("Alt+Return")));
|
|
fullscreen->setStatusTip(tr("Fullscreen"));
|
|
fullscreen->setIcon( QIcon(":icons/view-fullscreen.png") );
|
|
connect(fullscreen, SIGNAL(triggered()), this, SLOT(toggleFullscreen(void)) );
|
|
|
|
optMenu->addAction(fullscreen);
|
|
|
|
Hotkeys[ HK_FULLSCREEN ].setAction( fullscreen );
|
|
connect( Hotkeys[ HK_FULLSCREEN ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleFullscreen(void)) );
|
|
|
|
// Options -> Hide Menu Screen
|
|
act = new QAction(tr("&Hide Menu"), this);
|
|
//act->setShortcut( QKeySequence(tr("Alt+/")));
|
|
act->setStatusTip(tr("Hide Menu"));
|
|
act->setIcon( style()->standardIcon( QStyle::SP_TitleBarMaxButton ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(toggleMenuVis(void)) );
|
|
|
|
optMenu->addAction(act);
|
|
|
|
Hotkeys[ HK_MAIN_MENU_HIDE ].setAction( act );
|
|
connect( Hotkeys[ HK_MAIN_MENU_HIDE ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleMenuVis(void)) );
|
|
|
|
// Options -> Auto Hide Menu on Fullscreen
|
|
g_config->getOption( "SDL.AutoHideMenuFullsreen", &autoHideMenuFullscreen );
|
|
|
|
act = new QAction(tr("&Auto Hide Menu on Fullscreen"), this);
|
|
//act->setShortcut( QKeySequence(tr("Alt+/")));
|
|
act->setCheckable(true);
|
|
act->setChecked( autoHideMenuFullscreen );
|
|
act->setStatusTip(tr("Auto Hide Menu on Fullscreen"));
|
|
//act->setIcon( style()->standardIcon( QStyle::SP_TitleBarMaxButton ) );
|
|
connect(act, SIGNAL(triggered(bool)), this, SLOT(toggleMenuAutoHide(bool)) );
|
|
|
|
optMenu->addAction(act);
|
|
|
|
optMenu->addSeparator();
|
|
|
|
// Options -> Video BG Color
|
|
fceuLoadConfigColor( "SDL.VideoBgColor", &videoBgColor );
|
|
|
|
bgColorMenuItem = new ColorMenuItem( tr("BG Side Panel Color"), "SDL.VideoBgColor", this );
|
|
bgColorMenuItem->connectColor( &videoBgColor );
|
|
|
|
optMenu->addAction(bgColorMenuItem);
|
|
|
|
connect( bgColorMenuItem, SIGNAL(colorChanged(QColor&)), this, SLOT(videoBgColorChanged(QColor&)) );
|
|
|
|
// Options -> Use BG Palette for Video BG Color
|
|
g_config->getOption( "SDL.UseBgPaletteForVideo", &usePaletteForVideoBg );
|
|
|
|
act = new QAction(tr("Use BG Palette for Video BG Color"), this);
|
|
//act->setShortcut( QKeySequence(tr("Alt+/")));
|
|
act->setCheckable(true);
|
|
act->setChecked( usePaletteForVideoBg );
|
|
act->setStatusTip(tr("Use BG Palette for Video BG Color"));
|
|
//act->setIcon( style()->standardIcon( QStyle::SP_TitleBarMaxButton ) );
|
|
connect(act, SIGNAL(triggered(bool)), this, SLOT(toggleUseBgPaletteForVideo(bool)) );
|
|
|
|
optMenu->addAction(act);
|
|
|
|
bgColorMenuItem->setEnabled( !usePaletteForVideoBg );
|
|
//-----------------------------------------------------------------------
|
|
// Emulation
|
|
|
|
connect( emuMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( emuMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// Emulation -> Power
|
|
powerAct = new QAction(tr("&Power"), this);
|
|
//powerAct->setShortcut( QKeySequence(tr("Ctrl+P")));
|
|
powerAct->setStatusTip(tr("Power On Console"));
|
|
powerAct->setIcon( QIcon(":icons/power.png") );
|
|
connect(powerAct, SIGNAL(triggered()), this, SLOT(powerConsoleCB(void)) );
|
|
|
|
emuMenu->addAction(powerAct);
|
|
|
|
Hotkeys[ HK_POWER ].setAction( powerAct );
|
|
connect( Hotkeys[ HK_POWER ].getShortcut(), SIGNAL(activated()), this, SLOT(powerConsoleCB(void)) );
|
|
|
|
// Emulation -> Reset
|
|
resetAct = new QAction(tr("Hard &Reset"), this);
|
|
//resetAct->setShortcut( QKeySequence(tr("Ctrl+R")));
|
|
resetAct->setStatusTip(tr("Hard Reset of Console"));
|
|
resetAct->setIcon( style()->standardIcon( QStyle::SP_DialogResetButton ) );
|
|
connect(resetAct, SIGNAL(triggered()), this, SLOT(consoleHardReset(void)) );
|
|
|
|
emuMenu->addAction(resetAct);
|
|
|
|
Hotkeys[ HK_HARD_RESET ].setAction( resetAct );
|
|
connect( Hotkeys[ HK_HARD_RESET ].getShortcut(), SIGNAL(activated()), this, SLOT(consoleHardReset(void)) );
|
|
|
|
// Emulation -> Soft Reset
|
|
sresetAct = new QAction(tr("&Soft Reset"), this);
|
|
//sresetAct->setShortcut( QKeySequence(tr("Ctrl+R")));
|
|
sresetAct->setStatusTip(tr("Soft Reset of Console"));
|
|
sresetAct->setIcon( style()->standardIcon( QStyle::SP_BrowserReload ) );
|
|
connect(sresetAct, SIGNAL(triggered()), this, SLOT(consoleSoftReset(void)) );
|
|
|
|
emuMenu->addAction(sresetAct);
|
|
|
|
Hotkeys[ HK_SOFT_RESET ].setAction( sresetAct );
|
|
connect( Hotkeys[ HK_SOFT_RESET ].getShortcut(), SIGNAL(activated()), this, SLOT(consoleSoftReset(void)) );
|
|
|
|
// Emulation -> Pause
|
|
pauseAct = new QAction(tr("&Pause"), this);
|
|
//pauseAct->setShortcut( QKeySequence(tr("Pause")));
|
|
pauseAct->setStatusTip(tr("Pause Console"));
|
|
pauseAct->setIcon( style()->standardIcon( QStyle::SP_MediaPause ) );
|
|
connect(pauseAct, SIGNAL(triggered()), this, SLOT(consolePause(void)) );
|
|
|
|
emuMenu->addAction(pauseAct);
|
|
|
|
Hotkeys[ HK_PAUSE ].setAction( pauseAct );
|
|
connect( Hotkeys[ HK_PAUSE ].getShortcut(), SIGNAL(activated()), this, SLOT(consolePause(void)) );
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> Region
|
|
subMenu = emuMenu->addMenu(tr("&Region"));
|
|
group = new QActionGroup(this);
|
|
|
|
group->setExclusive(true);
|
|
|
|
for (int i=0; i<3; i++)
|
|
{
|
|
const char *txt;
|
|
|
|
if ( i == 1 )
|
|
{
|
|
txt = "&PAL";
|
|
}
|
|
else if ( i == 2 )
|
|
{
|
|
txt = "&Dendy";
|
|
}
|
|
else
|
|
{
|
|
txt = "&NTSC";
|
|
}
|
|
|
|
region[i] = new QAction(tr(txt), this);
|
|
region[i]->setCheckable(true);
|
|
|
|
group->addAction(region[i]);
|
|
subMenu->addAction(region[i]);
|
|
}
|
|
region[ FCEUI_GetRegion() ]->setChecked(true);
|
|
|
|
connect( region[0], SIGNAL(triggered(void)), this, SLOT(setRegionNTSC(void)) );
|
|
connect( region[1], SIGNAL(triggered(void)), this, SLOT(setRegionPAL(void)) );
|
|
connect( region[2], SIGNAL(triggered(void)), this, SLOT(setRegionDendy(void)) );
|
|
|
|
// Emulation -> RAM Init
|
|
subMenu = emuMenu->addMenu(tr("&RAM Init"));
|
|
group = new QActionGroup(this);
|
|
|
|
group->setExclusive(true);
|
|
|
|
for (int i=0; i<4; i++)
|
|
{
|
|
const char *txt;
|
|
|
|
switch (i)
|
|
{
|
|
default:
|
|
case 0:
|
|
txt = "&Default";
|
|
break;
|
|
case 1:
|
|
txt = "Fill $&FF";
|
|
break;
|
|
case 2:
|
|
txt = "Fill $&00";
|
|
break;
|
|
case 3:
|
|
txt = "&Random";
|
|
break;
|
|
}
|
|
|
|
ramInit[i] = new QAction(tr(txt), this);
|
|
ramInit[i]->setCheckable(true);
|
|
|
|
group->addAction(ramInit[i]);
|
|
subMenu->addAction(ramInit[i]);
|
|
}
|
|
|
|
g_config->getOption ("SDL.RamInitMethod", &RAMInitOption);
|
|
|
|
ramInit[ RAMInitOption ]->setChecked(true);
|
|
|
|
connect( ramInit[0], SIGNAL(triggered(void)), this, SLOT(setRamInit0(void)) );
|
|
connect( ramInit[1], SIGNAL(triggered(void)), this, SLOT(setRamInit1(void)) );
|
|
connect( ramInit[2], SIGNAL(triggered(void)), this, SLOT(setRamInit2(void)) );
|
|
connect( ramInit[3], SIGNAL(triggered(void)), this, SLOT(setRamInit3(void)) );
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> Enable Game Genie
|
|
gameGenieAct = new QAction(tr("Enable Game &Genie"), this);
|
|
//gameGenieAct->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
gameGenieAct->setCheckable(true);
|
|
gameGenieAct->setStatusTip(tr("Enable Game Genie"));
|
|
connect(gameGenieAct, SIGNAL(triggered(bool)), this, SLOT(toggleGameGenie(bool)) );
|
|
|
|
syncActionConfig( gameGenieAct, "SDL.GameGenie" );
|
|
|
|
emuMenu->addAction(gameGenieAct);
|
|
|
|
// Emulation -> Load Game Genie ROM
|
|
loadGgROMAct = new QAction(tr("Load Game Genie ROM"), this);
|
|
//loadGgROMAct->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
loadGgROMAct->setStatusTip(tr("Load Game Genie ROM"));
|
|
connect(loadGgROMAct, SIGNAL(triggered()), this, SLOT(loadGameGenieROM(void)) );
|
|
|
|
emuMenu->addAction(loadGgROMAct);
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> Virtual Family Keyboard
|
|
act = new QAction(tr("Virtual Family Keyboard"), this);
|
|
//act->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
act->setStatusTip(tr("Virtual Family Keyboard"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openFamilyKeyboard(void)) );
|
|
|
|
emuMenu->addAction(act);
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> Insert Coin
|
|
insCoinAct = new QAction(tr("&Insert Coin"), this);
|
|
//insCoinAct->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
insCoinAct->setStatusTip(tr("Insert Coin"));
|
|
connect(insCoinAct, SIGNAL(triggered()), this, SLOT(insertCoin(void)) );
|
|
|
|
emuMenu->addAction(insCoinAct);
|
|
|
|
Hotkeys[ HK_VS_INSERT_COIN ].setAction( insCoinAct );
|
|
connect( Hotkeys[ HK_VS_INSERT_COIN ].getShortcut(), SIGNAL(activated()), this, SLOT(insertCoin(void)) );
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> FDS
|
|
subMenu = emuMenu->addMenu(tr("&FDS"));
|
|
|
|
// Emulation -> FDS -> Switch Disk
|
|
fdsSwitchAct = new QAction(tr("&Switch Disk"), this);
|
|
//fdsSwitchAct->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
fdsSwitchAct->setStatusTip(tr("Switch Disk"));
|
|
connect(fdsSwitchAct, SIGNAL(triggered()), this, SLOT(fdsSwitchDisk(void)) );
|
|
|
|
Hotkeys[ HK_FDS_SELECT ].setAction( fdsSwitchAct );
|
|
connect( Hotkeys[ HK_FDS_SELECT ].getShortcut(), SIGNAL(activated()), this, SLOT(fdsSwitchDisk(void)) );
|
|
|
|
subMenu->addAction(fdsSwitchAct);
|
|
|
|
// Emulation -> FDS -> Eject Disk
|
|
fdsEjectAct = new QAction(tr("&Eject Disk"), this);
|
|
//fdsEjectAct->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
fdsEjectAct->setStatusTip(tr("Eject Disk"));
|
|
connect(fdsEjectAct, SIGNAL(triggered()), this, SLOT(fdsEjectDisk(void)) );
|
|
|
|
Hotkeys[ HK_FDS_EJECT ].setAction( fdsEjectAct );
|
|
connect( Hotkeys[ HK_FDS_EJECT ].getShortcut(), SIGNAL(activated()), this, SLOT(fdsEjectDisk(void)) );
|
|
|
|
subMenu->addAction(fdsEjectAct);
|
|
|
|
// Emulation -> FDS -> Load BIOS
|
|
fdsLoadBiosAct = new QAction(tr("&Load BIOS"), this);
|
|
//fdsLoadBiosAct->setShortcut( QKeySequence(tr("Ctrl+G")));
|
|
fdsLoadBiosAct->setStatusTip(tr("Load BIOS"));
|
|
connect(fdsLoadBiosAct, SIGNAL(triggered()), this, SLOT(fdsLoadBiosFile(void)) );
|
|
|
|
subMenu->addAction(fdsLoadBiosAct);
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> Speed
|
|
subMenu = emuMenu->addMenu(tr("&Speed"));
|
|
|
|
// Emulation -> Speed -> Speed Up
|
|
act = new QAction(tr("Speed &Up"), this);
|
|
//act->setShortcut( QKeySequence(tr("=")));
|
|
act->setStatusTip(tr("Speed Up"));
|
|
act->setIcon( style()->standardIcon( QStyle::SP_MediaSeekForward ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuSpeedUp(void)) );
|
|
|
|
Hotkeys[ HK_INCREASE_SPEED ].setAction( act );
|
|
connect( Hotkeys[ HK_INCREASE_SPEED ].getShortcut(), SIGNAL(activated()), this, SLOT(emuSpeedUp(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
// Emulation -> Speed -> Slow Down
|
|
act = new QAction(tr("Slow &Down"), this);
|
|
//act->setShortcut( QKeySequence(tr("-")));
|
|
act->setStatusTip(tr("Slow Down"));
|
|
act->setIcon( style()->standardIcon( QStyle::SP_MediaSeekBackward ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuSlowDown(void)) );
|
|
|
|
Hotkeys[ HK_DECREASE_SPEED ].setAction( act );
|
|
connect( Hotkeys[ HK_DECREASE_SPEED ].getShortcut(), SIGNAL(activated()), this, SLOT(emuSlowDown(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
subMenu->addSeparator();
|
|
|
|
// Emulation -> Speed -> Slowest Speed
|
|
act = new QAction(tr("&Slowest"), this);
|
|
//act->setShortcut( QKeySequence(tr("-")));
|
|
act->setStatusTip(tr("Slowest"));
|
|
act->setIcon( style()->standardIcon( QStyle::SP_MediaSkipBackward ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuSlowestSpd(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
// Emulation -> Speed -> Normal Speed
|
|
act = new QAction(tr("&Normal"), this);
|
|
//act->setShortcut( QKeySequence(tr("-")));
|
|
act->setStatusTip(tr("Normal"));
|
|
act->setIcon( style()->standardIcon( QStyle::SP_MediaPlay ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuNormalSpd(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
// Emulation -> Speed -> Fastest Speed
|
|
act = new QAction(tr("&Turbo"), this);
|
|
//act->setShortcut( QKeySequence(tr("-")));
|
|
act->setStatusTip(tr("Turbo (Fastest)"));
|
|
act->setIcon( style()->standardIcon( QStyle::SP_MediaSkipForward ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuFastestSpd(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
// Emulation -> Speed -> Custom Speed
|
|
act = new QAction(tr("&Custom"), this);
|
|
//act->setShortcut( QKeySequence(tr("-")));
|
|
act->setStatusTip(tr("Custom"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuCustomSpd(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
subMenu->addSeparator();
|
|
|
|
// Emulation -> Speed -> Set Frame Advance Delay
|
|
act = new QAction(tr("Set Frame &Advance Delay"), this);
|
|
//act->setShortcut( QKeySequence(tr("-")));
|
|
act->setStatusTip(tr("Set Frame Advance Delay"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(emuSetFrameAdvDelay(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
emuMenu->addSeparator();
|
|
|
|
// Emulation -> AutoFire Pattern
|
|
subMenu = emuMenu->addMenu(tr("&AutoFire Pattern"));
|
|
|
|
group = new QActionGroup(this);
|
|
group->setExclusive(true);
|
|
|
|
for (int i=1; i<6; i++)
|
|
{
|
|
char stmp[64];
|
|
|
|
for (int j=1; j<=(6-i); j++)
|
|
{
|
|
sprintf( stmp, "%i On, %i Off", i, j );
|
|
autoFireMenuAction *afAct = new autoFireMenuAction( i, j, tr(stmp), this);
|
|
afAct->setCheckable(true);
|
|
group->addAction(afAct);
|
|
subMenu->addAction(afAct);
|
|
afActList.push_back(afAct);
|
|
|
|
connect( afAct, SIGNAL(triggered(void)), afAct, SLOT(activateCB(void)) );
|
|
}
|
|
}
|
|
|
|
g_config->getOption("SDL.AutofireCustomOnFrames" , &customAutofireOnFrames );
|
|
g_config->getOption("SDL.AutofireCustomOffFrames" , &customAutofireOffFrames);
|
|
|
|
afActCustom = new autoFireMenuAction( customAutofireOnFrames, customAutofireOffFrames, tr("Custom"), this);
|
|
afActCustom->setCheckable(true);
|
|
group->addAction(afActCustom);
|
|
subMenu->addAction(afActCustom);
|
|
//afActList.push_back(afAct);
|
|
|
|
connect( afActCustom, SIGNAL(triggered(void)), afActCustom, SLOT(activateCB(void)) );
|
|
|
|
subMenu->addSeparator();
|
|
|
|
syncAutoFirePatternMenu();
|
|
|
|
// Emulation -> AutoFire Pattern -> Set Custom Pattern
|
|
act = new QAction(tr("Set Custom Pattern"), this);
|
|
act->setStatusTip(tr("Set Custom Pattern"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(setCustomAutoFire(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
//-----------------------------------------------------------------------
|
|
// NetPlay
|
|
|
|
connect( netPlayMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( netPlayMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// NetPlay -> Host
|
|
act = new QAction(tr("&Host"), this);
|
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
act->setStatusTip(tr("Host Game Window"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayHostWindow(void)) );
|
|
|
|
netPlayMenu->addAction(act);
|
|
|
|
// NetPlay -> Join
|
|
act = new QAction(tr("&Join"), this);
|
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
act->setStatusTip(tr("Join Game Window"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayJoinWindow(void)) );
|
|
|
|
netPlayMenu->addAction(act);
|
|
|
|
netPlayMenu->setEnabled(false);
|
|
//-----------------------------------------------------------------------
|
|
// Tools
|
|
|
|
connect( toolsMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( toolsMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// Tools -> Cheats
|
|
cheatsAct = new QAction(tr("&Cheats..."), this);
|
|
//cheatsAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
cheatsAct->setStatusTip(tr("Open Cheat Window"));
|
|
connect(cheatsAct, SIGNAL(triggered()), this, SLOT(openCheats(void)) );
|
|
|
|
Hotkeys[ HK_CHEAT_MENU ].setAction( cheatsAct );
|
|
connect( Hotkeys[ HK_CHEAT_MENU ].getShortcut(), SIGNAL(activated()), this, SLOT(openCheats(void)) );
|
|
|
|
toolsMenu->addAction(cheatsAct);
|
|
|
|
// Tools -> RAM Search
|
|
ramSearchAct = new QAction(tr("RAM &Search..."), this);
|
|
//ramSearchAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
ramSearchAct->setStatusTip(tr("Open RAM Search Window"));
|
|
connect(ramSearchAct, SIGNAL(triggered()), this, SLOT(openRamSearch(void)) );
|
|
|
|
toolsMenu->addAction(ramSearchAct);
|
|
|
|
// Tools -> RAM Watch
|
|
ramWatchAct = new QAction(tr("RAM &Watch..."), this);
|
|
//ramWatchAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
ramWatchAct->setStatusTip(tr("Open RAM Watch Window"));
|
|
connect(ramWatchAct, SIGNAL(triggered()), this, SLOT(openRamWatch(void)) );
|
|
|
|
toolsMenu->addAction(ramWatchAct);
|
|
|
|
// Tools -> Frame Timing
|
|
act = new QAction(tr("&Frame Timing ..."), this);
|
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
act->setStatusTip(tr("Open Frame Timing Window"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openTimingStatWin(void)) );
|
|
|
|
toolsMenu->addAction(act);
|
|
|
|
// Tools -> Palette Editor
|
|
act = new QAction(tr("&Palette Editor ..."), this);
|
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
act->setStatusTip(tr("Open Palette Editor Window"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openPaletteEditorWin(void)) );
|
|
|
|
toolsMenu->addAction(act);
|
|
|
|
// Tools -> AVI RIFF Viewer
|
|
act = new QAction(tr("&AVI RIFF Viewer ..."), this);
|
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
act->setStatusTip(tr("Open AVI RIFF Viewer Window"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openAviRiffViewer(void)) );
|
|
|
|
toolsMenu->addAction(act);
|
|
|
|
// Tools -> TAS Editor
|
|
tasEditorAct = act = new QAction(tr("&TAS Editor ..."), this);
|
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
act->setStatusTip(tr("Open TAS Editor Window"));
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openTasEditor(void)) );
|
|
|
|
toolsMenu->addAction(act);
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Debug
|
|
|
|
connect( debugMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( debugMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// Debug -> Debugger
|
|
debuggerAct = new QAction(tr("&Debugger..."), this);
|
|
//debuggerAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
debuggerAct->setStatusTip(tr("Open 6502 Debugger"));
|
|
connect(debuggerAct, SIGNAL(triggered()), this, SLOT(openDebugWindow(void)) );
|
|
|
|
debugMenu->addAction(debuggerAct);
|
|
|
|
// Debug -> Hex Editor
|
|
hexEditAct = new QAction(tr("&Hex Editor..."), this);
|
|
//hexEditAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
hexEditAct->setStatusTip(tr("Open Memory Hex Editor"));
|
|
connect(hexEditAct, SIGNAL(triggered()), this, SLOT(openHexEditor(void)) );
|
|
|
|
debugMenu->addAction(hexEditAct);
|
|
|
|
// Debug -> PPU Viewer
|
|
ppuViewAct = new QAction(tr("&PPU Viewer..."), this);
|
|
//ppuViewAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
ppuViewAct->setStatusTip(tr("Open PPU Viewer"));
|
|
connect(ppuViewAct, SIGNAL(triggered()), this, SLOT(openPPUViewer(void)) );
|
|
|
|
debugMenu->addAction(ppuViewAct);
|
|
|
|
// Debug -> Sprite Viewer
|
|
oamViewAct = new QAction(tr("&Sprite Viewer..."), this);
|
|
//oamViewAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
oamViewAct->setStatusTip(tr("Open Sprite Viewer"));
|
|
connect(oamViewAct, SIGNAL(triggered()), this, SLOT(openOAMViewer(void)) );
|
|
|
|
debugMenu->addAction(oamViewAct);
|
|
|
|
// Debug -> Name Table Viewer
|
|
ntViewAct = new QAction(tr("&Name Table Viewer..."), this);
|
|
//ntViewAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
ntViewAct->setStatusTip(tr("Open Name Table Viewer"));
|
|
connect(ntViewAct, SIGNAL(triggered()), this, SLOT(openNTViewer(void)) );
|
|
|
|
debugMenu->addAction(ntViewAct);
|
|
|
|
// Debug -> Trace Logger
|
|
traceLogAct = new QAction(tr("&Trace Logger..."), this);
|
|
//traceLogAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
traceLogAct->setStatusTip(tr("Open Trace Logger"));
|
|
connect(traceLogAct, SIGNAL(triggered()), this, SLOT(openTraceLogger(void)) );
|
|
|
|
debugMenu->addAction(traceLogAct);
|
|
|
|
// Debug -> Code/Data Logger
|
|
codeDataLogAct = new QAction(tr("&Code/Data Logger..."), this);
|
|
//codeDataLogAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
codeDataLogAct->setStatusTip(tr("Open Code Data Logger"));
|
|
connect(codeDataLogAct, SIGNAL(triggered()), this, SLOT(openCodeDataLogger(void)) );
|
|
|
|
debugMenu->addAction(codeDataLogAct);
|
|
|
|
// Debug -> Game Genie Encode/Decode Viewer
|
|
ggEncodeAct = new QAction(tr("&Game Genie Encode/Decode"), this);
|
|
//ggEncodeAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
ggEncodeAct->setStatusTip(tr("Open Game Genie Encode/Decode"));
|
|
connect(ggEncodeAct, SIGNAL(triggered()), this, SLOT(openGGEncoder(void)) );
|
|
|
|
debugMenu->addAction(ggEncodeAct);
|
|
|
|
// Debug -> NES Header Editor
|
|
iNesEditAct = new QAction(tr("NES Header Edito&r..."), this);
|
|
//iNesEditAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
iNesEditAct->setStatusTip(tr("Open NES Header Editor"));
|
|
connect(iNesEditAct, SIGNAL(triggered()), this, SLOT(openNesHeaderEditor(void)) );
|
|
|
|
debugMenu->addAction(iNesEditAct);
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Movie
|
|
|
|
connect( movieMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( movieMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// Movie -> Play
|
|
openMovAct = new QAction(tr("Movie &Play"), this);
|
|
//openMovAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
openMovAct->setStatusTip(tr("Play Movie File"));
|
|
openMovAct->setIcon( style()->standardIcon( QStyle::SP_MediaPlay ) );
|
|
connect(openMovAct, SIGNAL(triggered()), this, SLOT(openMovie(void)) );
|
|
|
|
Hotkeys[ HK_PLAY_MOVIE_FROM ].setAction( openMovAct );
|
|
connect( Hotkeys[ HK_PLAY_MOVIE_FROM ].getShortcut(), SIGNAL(activated()), this, SLOT(openMovie(void)) );
|
|
|
|
movieMenu->addAction(openMovAct);
|
|
|
|
// Movie -> Play From Beginning
|
|
playMovBeginAct = new QAction(tr("Movie Play From &Beginning"), this);
|
|
//playMovBeginAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
playMovBeginAct->setStatusTip(tr("Play Movie From Beginning"));
|
|
//playMovBeginAct->setIcon( style()->standardIcon( QStyle::SP_MediaPlay ) );
|
|
connect(playMovBeginAct, SIGNAL(triggered()), this, SLOT(playMovieFromBeginning(void)) );
|
|
|
|
Hotkeys[ HK_MOVIE_PLAY_RESTART ].setAction( playMovBeginAct );
|
|
connect( Hotkeys[ HK_MOVIE_PLAY_RESTART ].getShortcut(), SIGNAL(activated()), this, SLOT(playMovieFromBeginning(void)) );
|
|
|
|
movieMenu->addAction(playMovBeginAct);
|
|
|
|
// Movie -> Stop
|
|
stopMovAct = new QAction(tr("Movie &Stop"), this);
|
|
//stopMovAct->setShortcut( QKeySequence(tr("Shift+F7")));
|
|
stopMovAct->setStatusTip(tr("Stop Movie Recording"));
|
|
stopMovAct->setIcon( style()->standardIcon( QStyle::SP_MediaStop ) );
|
|
connect(stopMovAct, SIGNAL(triggered()), this, SLOT(stopMovie(void)) );
|
|
|
|
Hotkeys[ HK_STOP_MOVIE ].setAction( stopMovAct );
|
|
connect( Hotkeys[ HK_STOP_MOVIE ].getShortcut(), SIGNAL(activated()), this, SLOT(stopMovie(void)) );
|
|
|
|
movieMenu->addAction(stopMovAct);
|
|
|
|
movieMenu->addSeparator();
|
|
|
|
// Movie -> Record
|
|
recMovAct = new QAction(tr("Movie &Record"), this);
|
|
//recMovAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
recMovAct->setStatusTip(tr("Record Movie"));
|
|
recMovAct->setIcon( QIcon(":icons/media-record.png") );
|
|
connect(recMovAct, SIGNAL(triggered()), this, SLOT(recordMovie(void)) );
|
|
|
|
Hotkeys[ HK_RECORD_MOVIE_TO ].setAction( recMovAct );
|
|
connect( Hotkeys[ HK_RECORD_MOVIE_TO ].getShortcut(), SIGNAL(activated()), this, SLOT(recordMovie(void)) );
|
|
|
|
movieMenu->addAction(recMovAct);
|
|
|
|
movieMenu->addSeparator();
|
|
|
|
// Movie -> Avi Recording
|
|
|
|
// Movie -> Avi Recording -> Record
|
|
recAviAct = new QAction(tr("AVI &Record"), this);
|
|
//recAviAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
recAviAct->setStatusTip(tr("AVI Record Start"));
|
|
recAviAct->setIcon( QIcon(":icons/media-record.png") );
|
|
connect(recAviAct, SIGNAL(triggered()), this, SLOT(aviRecordStart(void)) );
|
|
|
|
Hotkeys[ HK_RECORD_AVI ].setAction( recAviAct );
|
|
connect( Hotkeys[ HK_RECORD_AVI ].getShortcut(), SIGNAL(activated()), this, SLOT(aviRecordStart(void)) );
|
|
|
|
movieMenu->addAction(recAviAct);
|
|
|
|
// Movie -> Avi Recording -> Record As
|
|
recAsAviAct = new QAction(tr("AVI Record &As"), this);
|
|
//recAsAviAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
recAsAviAct->setStatusTip(tr("AVI Record As Start"));
|
|
//recAsAviAct->setIcon( QIcon(":icons/media-record.png") );
|
|
connect(recAsAviAct, SIGNAL(triggered()), this, SLOT(aviRecordAsStart(void)) );
|
|
|
|
Hotkeys[ HK_RECORD_AVI_TO ].setAction( recAsAviAct );
|
|
connect( Hotkeys[ HK_RECORD_AVI_TO ].getShortcut(), SIGNAL(activated()), this, SLOT(aviRecordAsStart(void)) );
|
|
|
|
movieMenu->addAction(recAsAviAct);
|
|
|
|
// Movie -> Avi Recording -> Stop
|
|
stopAviAct = new QAction(tr("AVI &Stop"), this);
|
|
//stopAviAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
stopAviAct->setStatusTip(tr("AVI Record Stop"));
|
|
stopAviAct->setIcon( style()->standardIcon( QStyle::SP_MediaStop ) );
|
|
connect(stopAviAct, SIGNAL(triggered()), this, SLOT(aviRecordStop(void)) );
|
|
|
|
Hotkeys[ HK_STOP_AVI ].setAction( stopAviAct );
|
|
connect( Hotkeys[ HK_STOP_AVI ].getShortcut(), SIGNAL(activated()), this, SLOT(aviRecordStop(void)) );
|
|
|
|
movieMenu->addAction(stopAviAct);
|
|
|
|
movieMenu->addSeparator();
|
|
|
|
// Movie -> WAV Recording
|
|
|
|
// Movie -> WAV Recording -> Record
|
|
recWavAct = new QAction(tr("WAV &Record"), this);
|
|
//recWavAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
recWavAct->setStatusTip(tr("WAV Record Start"));
|
|
recWavAct->setIcon( QIcon(":icons/media-record.png") );
|
|
connect(recWavAct, SIGNAL(triggered()), this, SLOT(wavRecordStart(void)) );
|
|
|
|
Hotkeys[ HK_RECORD_WAV ].setAction( recWavAct );
|
|
connect( Hotkeys[ HK_RECORD_WAV ].getShortcut(), SIGNAL(activated()), this, SLOT(wavRecordStart(void)) );
|
|
|
|
movieMenu->addAction(recWavAct);
|
|
|
|
// Movie -> WAV Recording -> Record As
|
|
recAsWavAct = new QAction(tr("WAV Record &As"), this);
|
|
//recAsWavAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
recAsWavAct->setStatusTip(tr("WAV Record As Start"));
|
|
//recAsWavAct->setIcon( QIcon(":icons/media-record.png") );
|
|
connect(recAsWavAct, SIGNAL(triggered()), this, SLOT(wavRecordAsStart(void)) );
|
|
|
|
Hotkeys[ HK_RECORD_WAV_TO ].setAction( recAsWavAct );
|
|
connect( Hotkeys[ HK_RECORD_WAV_TO ].getShortcut(), SIGNAL(activated()), this, SLOT(wavRecordAsStart(void)) );
|
|
|
|
movieMenu->addAction(recAsWavAct);
|
|
|
|
// Movie -> WAV Recording -> Stop
|
|
stopWavAct = new QAction(tr("WAV &Stop"), this);
|
|
//stopWavAct->setShortcut( QKeySequence(tr("Shift+F5")));
|
|
stopWavAct->setStatusTip(tr("WAV Record Stop"));
|
|
stopWavAct->setIcon( style()->standardIcon( QStyle::SP_MediaStop ) );
|
|
connect(stopWavAct, SIGNAL(triggered()), this, SLOT(wavRecordStop(void)) );
|
|
|
|
Hotkeys[ HK_STOP_WAV ].setAction( stopWavAct );
|
|
connect( Hotkeys[ HK_STOP_WAV ].getShortcut(), SIGNAL(activated()), this, SLOT(wavRecordStop(void)) );
|
|
|
|
movieMenu->addAction(stopWavAct);
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Help
|
|
|
|
connect( helpMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
|
|
connect( helpMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
|
|
|
|
// Help -> About FCEUX
|
|
aboutAct = new QAction(tr("&About FCEUX"), this);
|
|
aboutAct->setStatusTip(tr("About FCEUX"));
|
|
aboutAct->setIcon( style()->standardIcon( QStyle::SP_MessageBoxInformation ) );
|
|
connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutFCEUX(void)) );
|
|
|
|
helpMenu->addAction(aboutAct);
|
|
|
|
// Help -> About Qt
|
|
aboutActQt = new QAction(tr("About &Qt"), this);
|
|
aboutActQt->setStatusTip(tr("About Qt"));
|
|
aboutActQt->setIcon( style()->standardIcon( QStyle::SP_TitleBarMenuButton ) );
|
|
connect(aboutActQt, SIGNAL(triggered()), this, SLOT(aboutQt(void)) );
|
|
|
|
helpMenu->addAction(aboutActQt);
|
|
|
|
// Help -> Message Log
|
|
msgLogAct = new QAction(tr("&Message Log"), this);
|
|
msgLogAct->setStatusTip(tr("Message Log"));
|
|
msgLogAct->setIcon( style()->standardIcon( QStyle::SP_MessageBoxWarning ) );
|
|
connect(msgLogAct, SIGNAL(triggered()), this, SLOT(openMsgLogWin(void)) );
|
|
|
|
helpMenu->addAction(msgLogAct);
|
|
|
|
// Help -> Documentation Online
|
|
subMenu = helpMenu->addMenu( tr("&Documentation") );
|
|
subMenu->setIcon( style()->standardIcon( QStyle::SP_DialogHelpButton ) );
|
|
|
|
// Help -> Documentation Online
|
|
act = new QAction(tr("&Online"), this);
|
|
act->setStatusTip(tr("Documentation"));
|
|
//act->setIcon( style()->standardIcon( QStyle::SP_DialogHelpButton ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openOnlineDocs(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
|
|
#if defined(WIN32) || defined(_USE_QHELP)
|
|
// Help -> Documentation Offline
|
|
act = new QAction(tr("&Local"), this);
|
|
act->setStatusTip(tr("Documentation"));
|
|
//act->setIcon( style()->standardIcon( QStyle::SP_DialogHelpButton ) );
|
|
connect(act, SIGNAL(triggered()), this, SLOT(openOfflineDocs(void)) );
|
|
|
|
subMenu->addAction(act);
|
|
#endif
|
|
};
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
int consoleWin_t::unloadVideoDriver(void)
|
|
{
|
|
viewport_Interface = NULL;
|
|
|
|
if (viewport_GL != NULL)
|
|
{
|
|
if ( viewport_GL == centralWidget() )
|
|
{
|
|
takeCentralWidget();
|
|
}
|
|
else
|
|
{
|
|
printf("Error: Central Widget Failed!\n");
|
|
}
|
|
viewport_GL->deleteLater();
|
|
|
|
viewport_GL = NULL;
|
|
}
|
|
|
|
if (viewport_SDL != NULL)
|
|
{
|
|
if ( viewport_SDL == centralWidget() )
|
|
{
|
|
takeCentralWidget();
|
|
}
|
|
else
|
|
{
|
|
printf("Error: Central Widget Failed!\n");
|
|
}
|
|
viewport_SDL->deleteLater();
|
|
|
|
viewport_SDL = NULL;
|
|
}
|
|
|
|
if (viewport_QWidget != NULL)
|
|
{
|
|
if ( viewport_QWidget == centralWidget() )
|
|
{
|
|
takeCentralWidget();
|
|
}
|
|
else
|
|
{
|
|
printf("Error: Central Widget Failed!\n");
|
|
}
|
|
viewport_QWidget->deleteLater();
|
|
|
|
viewport_QWidget = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::videoDriverDestroyed(QObject* obj)
|
|
{
|
|
if (viewport_GL == obj)
|
|
{
|
|
//printf("GL Video Driver Destroyed\n");
|
|
|
|
if (viewport_Interface == static_cast<ConsoleViewerBase*>(viewport_GL))
|
|
{
|
|
viewport_Interface = NULL;
|
|
}
|
|
viewport_GL = NULL;
|
|
}
|
|
|
|
if (viewport_SDL == obj)
|
|
{
|
|
//printf("SDL Video Driver Destroyedi\n");
|
|
|
|
if (viewport_Interface == static_cast<ConsoleViewerBase*>(viewport_SDL))
|
|
{
|
|
viewport_Interface = NULL;
|
|
}
|
|
viewport_SDL = NULL;
|
|
}
|
|
|
|
if (viewport_QWidget == obj)
|
|
{
|
|
//printf("QPainter Video Driver Destroyed\n");
|
|
|
|
if (viewport_Interface == static_cast<ConsoleViewerBase*>(viewport_QWidget))
|
|
{
|
|
viewport_Interface = NULL;
|
|
}
|
|
viewport_QWidget = NULL;
|
|
}
|
|
printf("Video Driver Destroyed: %p\n", obj);
|
|
//printf("viewport_GL: %p\n", viewport_GL);
|
|
//printf("viewport_SDL: %p\n", viewport_SDL);
|
|
//printf("viewport_Qt: %p\n", viewport_QWidget);
|
|
//printf("viewport_Interface: %p\n", viewport_Interface);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int consoleWin_t::loadVideoDriver( int driverId, bool force )
|
|
{
|
|
if (viewport_Interface)
|
|
{
|
|
if (viewport_Interface->driver() == driverId)
|
|
{ // Already Loaded
|
|
if (force)
|
|
{
|
|
unloadVideoDriver();
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch ( driverId )
|
|
{
|
|
case ConsoleViewerBase::VIDEO_DRIVER_SDL:
|
|
{
|
|
viewport_SDL = new ConsoleViewSDL_t(this);
|
|
|
|
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_SDL);
|
|
|
|
setCentralWidget(viewport_SDL);
|
|
|
|
setViewportAspect();
|
|
|
|
viewport_SDL->init();
|
|
|
|
connect( viewport_SDL, SIGNAL(destroyed(QObject*)), this, SLOT(videoDriverDestroyed(QObject*)) );
|
|
}
|
|
break;
|
|
case ConsoleViewerBase::VIDEO_DRIVER_OPENGL:
|
|
{
|
|
viewport_GL = new ConsoleViewGL_t(this);
|
|
|
|
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_GL);
|
|
|
|
setCentralWidget(viewport_GL);
|
|
|
|
setViewportAspect();
|
|
|
|
viewport_GL->init();
|
|
|
|
connect( viewport_GL, SIGNAL(destroyed(QObject*)), this, SLOT(videoDriverDestroyed(QObject*)) );
|
|
}
|
|
break;
|
|
default:
|
|
case ConsoleViewerBase::VIDEO_DRIVER_QPAINTER:
|
|
{
|
|
viewport_QWidget = new ConsoleViewQWidget_t(this);
|
|
|
|
viewport_Interface = static_cast<ConsoleViewerBase*>(viewport_QWidget);
|
|
|
|
setCentralWidget(viewport_QWidget);
|
|
|
|
setViewportAspect();
|
|
|
|
viewport_QWidget->init();
|
|
|
|
connect( viewport_QWidget, SIGNAL(destroyed(QObject*)), this, SLOT(videoDriverDestroyed(QObject*)) );
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Reload Viewport Cursor Type and Visibility
|
|
loadCursor();
|
|
|
|
return 0;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::clearRomList(void)
|
|
{
|
|
std::list <std::string*>::iterator it;
|
|
|
|
for (it=romList.begin(); it != romList.end(); it++)
|
|
{
|
|
delete *it;
|
|
}
|
|
romList.clear();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::buildRecentRomMenu(void)
|
|
{
|
|
QAction *act;
|
|
std::string s;
|
|
std::string *sptr;
|
|
char buf[128];
|
|
|
|
clearRomList();
|
|
recentRomMenu->clear();
|
|
|
|
for (int i=0; i<10; i++)
|
|
{
|
|
sprintf(buf, "SDL.RecentRom%02i", i);
|
|
|
|
g_config->getOption( buf, &s);
|
|
|
|
//printf("Recent Rom:%i '%s'\n", i, s.c_str() );
|
|
|
|
if ( s.size() > 0 )
|
|
{
|
|
act = new consoleRecentRomAction( tr(s.c_str()), recentRomMenu);
|
|
|
|
recentRomMenu->addAction( act );
|
|
|
|
connect(act, SIGNAL(triggered()), act, SLOT(activateCB(void)) );
|
|
|
|
sptr = new std::string();
|
|
|
|
sptr->assign( s.c_str() );
|
|
|
|
romList.push_front( sptr );
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::saveRecentRomMenu(void)
|
|
{
|
|
int i;
|
|
std::string *s;
|
|
std::list <std::string*>::iterator it;
|
|
char buf[128];
|
|
|
|
i = romList.size() - 1;
|
|
|
|
for (it=romList.begin(); it != romList.end(); it++)
|
|
{
|
|
s = *it;
|
|
sprintf(buf, "SDL.RecentRom%02i", i);
|
|
|
|
g_config->setOption( buf, s->c_str() );
|
|
|
|
//printf("Recent Rom:%u '%s'\n", i, s->c_str() );
|
|
i--;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::addRecentRom( const char *rom )
|
|
{
|
|
std::string *s;
|
|
std::list <std::string*>::iterator match_it;
|
|
|
|
for (match_it=romList.begin(); match_it != romList.end(); match_it++)
|
|
{
|
|
s = *match_it;
|
|
|
|
if ( s->compare( rom ) == 0 )
|
|
{
|
|
//printf("Found Match: %s\n", rom );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( match_it != romList.end() )
|
|
{
|
|
s = *match_it;
|
|
|
|
romList.erase(match_it);
|
|
|
|
romList.push_back(s);
|
|
}
|
|
else
|
|
{
|
|
s = new std::string();
|
|
|
|
s->assign( rom );
|
|
|
|
romList.push_back(s);
|
|
|
|
if ( romList.size() > 10 )
|
|
{
|
|
s = romList.front();
|
|
|
|
romList.pop_front();
|
|
|
|
delete s;
|
|
}
|
|
}
|
|
|
|
saveRecentRomMenu();
|
|
|
|
recentRomMenuReset = true;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::toggleMenuVis(void)
|
|
{
|
|
if ( menubar->isVisible() )
|
|
{
|
|
menubar->setVisible( false );
|
|
}
|
|
else
|
|
{
|
|
menubar->setVisible( true );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::toggleMenuAutoHide(bool checked)
|
|
{
|
|
autoHideMenuFullscreen = checked;
|
|
|
|
g_config->setOption( "SDL.AutoHideMenuFullsreen", autoHideMenuFullscreen );
|
|
g_config->save();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::toggleUseBgPaletteForVideo(bool checked)
|
|
{
|
|
usePaletteForVideoBg = checked;
|
|
|
|
g_config->setOption( "SDL.UseBgPaletteForVideo", usePaletteForVideoBg );
|
|
g_config->save();
|
|
|
|
if ( !usePaletteForVideoBg )
|
|
{
|
|
fceuLoadConfigColor( "SDL.VideoBgColor", &videoBgColor );
|
|
}
|
|
bgColorMenuItem->setEnabled( !usePaletteForVideoBg );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::closeApp(void)
|
|
{
|
|
nes_shm->runEmulator = 0;
|
|
|
|
gameTimer->stop();
|
|
|
|
closeGamePadConfWindow();
|
|
|
|
emulatorThread->quit();
|
|
emulatorThread->wait( 1000 );
|
|
|
|
aviDiskThread->requestInterruption();
|
|
aviDiskThread->quit();
|
|
aviDiskThread->wait( 10000 );
|
|
|
|
if ( tasWin != NULL )
|
|
{
|
|
tasWin->requestWindowClose();
|
|
}
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
fceuWrapperClose();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
// LoadGame() checks for an IP and if it finds one begins a network session
|
|
// clear the NetworkIP field so this doesn't happen unintentionally
|
|
g_config->setOption ("SDL.NetworkIP", "");
|
|
g_config->save ();
|
|
|
|
QApplication::closeAllWindows();
|
|
|
|
// Delay Application Quit to allow event processing to complete
|
|
QTimer::singleShot( 250, qApp, SLOT(quit(void)) );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void consoleWin_t::videoBgColorChanged( QColor &c )
|
|
{
|
|
//printf("Color Changed\n");
|
|
|
|
if ( viewport_Interface )
|
|
{
|
|
viewport_Interface->setBgColor(c);
|
|
viewport_Interface->queueRedraw();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int consoleWin_t::showListSelectDialog( const char *title, std::vector <std::string> &l )
|
|
{
|
|
if ( QThread::currentThread() == emulatorThread )
|
|
{
|
|
printf("Cannot display list selection dialog from within emulation thread...\n");
|
|
return 0;
|
|
}
|
|
int ret, idx = 0;
|
|
QDialog dialog(this);
|
|
QVBoxLayout *mainLayout;
|
|
QHBoxLayout *hbox;
|
|
QPushButton *okButton, *cancelButton;
|
|
QTreeWidget *tree;
|
|
QTreeWidgetItem *item;
|
|
QSettings settings;
|
|
|
|
dialog.setWindowTitle( tr(title) );
|
|
|
|
tree = new QTreeWidget();
|
|
|
|
tree->setColumnCount(1);
|
|
|
|
item = new QTreeWidgetItem();
|
|
item->setText( 0, QString::fromStdString( "File" ) );
|
|
item->setTextAlignment( 0, Qt::AlignLeft);
|
|
|
|
tree->setHeaderItem( item );
|
|
|
|
tree->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
|
|
|
|
for (size_t i=0; i<l.size(); i++)
|
|
{
|
|
item = new QTreeWidgetItem();
|
|
|
|
item->setText( 0, QString::fromStdString( l[i] ) );
|
|
|
|
item->setTextAlignment( 0, Qt::AlignLeft);
|
|
|
|
tree->addTopLevelItem( item );
|
|
}
|
|
|
|
mainLayout = new QVBoxLayout();
|
|
|
|
hbox = new QHBoxLayout();
|
|
okButton = new QPushButton( tr("OK") );
|
|
cancelButton = new QPushButton( tr("Cancel") );
|
|
|
|
mainLayout->addWidget( tree );
|
|
mainLayout->addLayout( hbox );
|
|
hbox->addWidget( cancelButton );
|
|
hbox->addWidget( okButton );
|
|
|
|
connect( okButton, SIGNAL(clicked(void)), &dialog, SLOT(accept(void)) );
|
|
connect( cancelButton, SIGNAL(clicked(void)), &dialog, SLOT(reject(void)) );
|
|
|
|
okButton->setIcon( style()->standardIcon( QStyle::SP_DialogOkButton ) );
|
|
cancelButton->setIcon( style()->standardIcon( QStyle::SP_DialogCancelButton ) );
|
|
|
|
okButton->setDefault(true);
|
|
|
|
dialog.setLayout( mainLayout );
|
|
|
|
// Restore Window Geometry
|
|
dialog.restoreGeometry(settings.value("ArchiveViewer/geometry").toByteArray());
|
|
|
|
// Run Dialog Execution Loop
|
|
ret = dialog.exec();
|
|
|
|
// Save Window Geometry
|
|
settings.setValue("ArchiveViewer/geometry", dialog.saveGeometry());
|
|
|
|
if ( ret == QDialog::Accepted )
|
|
{
|
|
idx = 0;
|
|
|
|
item = tree->currentItem();
|
|
|
|
if ( item != NULL )
|
|
{
|
|
idx = tree->indexOfTopLevelItem(item);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
idx = -1;
|
|
}
|
|
return idx;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void consoleWin_t::openROMFile(void)
|
|
{
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string last;
|
|
std::string dir;
|
|
const char *romDir;
|
|
QFileDialog dialog(this, tr("Open ROM File") );
|
|
QList<QUrl> urls;
|
|
QDir d;
|
|
|
|
const QStringList filters(
|
|
{ "All Useable files (*.nes *.NES *.nsf *.NSF *.fds *.FDS *.unf *.UNF *.unif *.UNIF *.zip *.ZIP, *.7z *.7zip)",
|
|
"NES files (*.nes *.NES)",
|
|
"NSF files (*.nsf *.NSF)",
|
|
"UNF files (*.unf *.UNF *.unif *.UNIF)",
|
|
"FDS files (*.fds *.FDS)",
|
|
"Any files (*)"
|
|
});
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
urls << QUrl::fromLocalFile( QDir( FCEUI_GetBaseDirectory() ).absolutePath() );
|
|
|
|
romDir = getenv("FCEUX_ROM_PATH");
|
|
|
|
if ( romDir != NULL )
|
|
{
|
|
d.setPath(romDir);
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
}
|
|
|
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
|
|
dialog.setNameFilters( filters );
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Open") );
|
|
|
|
g_config->getOption ("SDL.LastOpenFile", &last );
|
|
|
|
getDirFromFile( last.c_str(), dir);
|
|
|
|
dialog.setDirectory( tr(dir.c_str()) );
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
g_config->setOption ("SDL.LastOpenFile", filename.toLocal8Bit().constData() );
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
CloseGame ();
|
|
LoadGame ( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::loadRomRequestCB( QString s )
|
|
{
|
|
printf("Load ROM Req: '%s'\n", s.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_LOCK();
|
|
CloseGame ();
|
|
LoadGame ( s.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::closeROMCB(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
CloseGame();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::loadNSF(void)
|
|
{
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string last;
|
|
std::string dir;
|
|
const char *romDir;
|
|
QFileDialog dialog(this, tr("Load NSF File") );
|
|
QList<QUrl> urls;
|
|
QDir d;
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
urls << QUrl::fromLocalFile( QDir( FCEUI_GetBaseDirectory() ).absolutePath() );
|
|
|
|
romDir = getenv("FCEUX_ROM_PATH");
|
|
|
|
if ( romDir != NULL )
|
|
{
|
|
d.setPath(romDir);
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
}
|
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
|
|
dialog.setNameFilter(tr("NSF Sound Files (*.nsf *.NSF) ;; Zip Files (*.zip *.ZIP) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
|
|
|
g_config->getOption ("SDL.LastOpenNSF", &last );
|
|
|
|
getDirFromFile( last.c_str(), dir );
|
|
|
|
dialog.setDirectory( tr(dir.c_str()) );
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
g_config->setOption ("SDL.LastOpenNSF", filename.toLocal8Bit().constData() );
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
LoadGame( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::loadStateFrom(void)
|
|
{
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string last;
|
|
std::string dir;
|
|
const char *base;
|
|
QFileDialog dialog(this, tr("Load State From File") );
|
|
QList<QUrl> urls;
|
|
QDir d;
|
|
|
|
base = FCEUI_GetBaseDirectory();
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
|
|
if ( base )
|
|
{
|
|
urls << QUrl::fromLocalFile( QDir( base ).absolutePath() );
|
|
|
|
d.setPath( QString(base) + "/fcs");
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
|
|
d.setPath( QString(base) + "/sav");
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
}
|
|
|
|
|
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
|
|
dialog.setNameFilter(tr("FCS & SAV Files (*.sav *.SAV *.fc? *.FC?) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
|
|
|
g_config->getOption ("SDL.LastLoadStateFrom", &last );
|
|
|
|
getDirFromFile( last.c_str(), dir );
|
|
|
|
dialog.setDirectory( tr(dir.c_str()) );
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
g_config->setOption ("SDL.LastLoadStateFrom", filename.toLocal8Bit().constData() );
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_LoadState( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::saveStateAs(void)
|
|
{
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string last;
|
|
std::string dir;
|
|
const char *base;
|
|
QFileDialog dialog(this, tr("Save State To File") );
|
|
QList<QUrl> urls;
|
|
QDir d;
|
|
|
|
base = FCEUI_GetBaseDirectory();
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
|
|
if ( base )
|
|
{
|
|
urls << QUrl::fromLocalFile( QDir( base ).absolutePath() );
|
|
|
|
d.setPath( QString(base) + "/fcs");
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
|
|
d.setPath( QString(base) + "/sav");
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
}
|
|
|
|
dialog.setFileMode(QFileDialog::AnyFile);
|
|
|
|
dialog.setNameFilter(tr("SAV Files (*.sav *.SAV) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
|
dialog.setDefaultSuffix( tr(".sav") );
|
|
|
|
g_config->getOption ("SDL.LastSaveStateAs", &last );
|
|
|
|
if ( last.size() == 0 )
|
|
{
|
|
if ( base )
|
|
{
|
|
last = std::string(base) + "/sav";
|
|
}
|
|
}
|
|
getDirFromFile( last.c_str(), dir );
|
|
|
|
dialog.setDirectory( tr(dir.c_str()) );
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
g_config->setOption ("SDL.LastSaveStateAs", filename.toLocal8Bit().constData() );
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_SaveState( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::quickLoad(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_LoadState( NULL );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::loadState(int slot)
|
|
{
|
|
int prevState;
|
|
FCEU_WRAPPER_LOCK();
|
|
prevState = FCEUI_SelectState( slot, false );
|
|
FCEUI_LoadState( NULL, true );
|
|
FCEUI_SelectState( prevState, false );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
void consoleWin_t::loadState0(void){ loadState(0); }
|
|
void consoleWin_t::loadState1(void){ loadState(1); }
|
|
void consoleWin_t::loadState2(void){ loadState(2); }
|
|
void consoleWin_t::loadState3(void){ loadState(3); }
|
|
void consoleWin_t::loadState4(void){ loadState(4); }
|
|
void consoleWin_t::loadState5(void){ loadState(5); }
|
|
void consoleWin_t::loadState6(void){ loadState(6); }
|
|
void consoleWin_t::loadState7(void){ loadState(7); }
|
|
void consoleWin_t::loadState8(void){ loadState(8); }
|
|
void consoleWin_t::loadState9(void){ loadState(9); }
|
|
|
|
void consoleWin_t::loadPrevState(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEU_StateRecorderLoadPrevState();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::loadNextState(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEU_StateRecorderLoadNextState();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::quickSave(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_SaveState( NULL );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::saveState(int slot)
|
|
{
|
|
int prevState;
|
|
FCEU_WRAPPER_LOCK();
|
|
prevState = FCEUI_SelectState( slot, false );
|
|
FCEUI_SaveState( NULL, true );
|
|
FCEUI_SelectState( prevState, false );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
void consoleWin_t::saveState0(void){ saveState(0); }
|
|
void consoleWin_t::saveState1(void){ saveState(1); }
|
|
void consoleWin_t::saveState2(void){ saveState(2); }
|
|
void consoleWin_t::saveState3(void){ saveState(3); }
|
|
void consoleWin_t::saveState4(void){ saveState(4); }
|
|
void consoleWin_t::saveState5(void){ saveState(5); }
|
|
void consoleWin_t::saveState6(void){ saveState(6); }
|
|
void consoleWin_t::saveState7(void){ saveState(7); }
|
|
void consoleWin_t::saveState8(void){ saveState(8); }
|
|
void consoleWin_t::saveState9(void){ saveState(9); }
|
|
|
|
void consoleWin_t::changeState(int slot)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_SelectState( slot, true );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
state[slot]->setChecked(true);
|
|
}
|
|
void consoleWin_t::changeState0(void){ changeState(0); }
|
|
void consoleWin_t::changeState1(void){ changeState(1); }
|
|
void consoleWin_t::changeState2(void){ changeState(2); }
|
|
void consoleWin_t::changeState3(void){ changeState(3); }
|
|
void consoleWin_t::changeState4(void){ changeState(4); }
|
|
void consoleWin_t::changeState5(void){ changeState(5); }
|
|
void consoleWin_t::changeState6(void){ changeState(6); }
|
|
void consoleWin_t::changeState7(void){ changeState(7); }
|
|
void consoleWin_t::changeState8(void){ changeState(8); }
|
|
void consoleWin_t::changeState9(void){ changeState(9); }
|
|
|
|
void consoleWin_t::incrementState(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_SelectStateNext(1);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::decrementState(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_SelectStateNext(-1);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::mainMenuOpen(void)
|
|
{
|
|
//printf("Main Menu Open\n");
|
|
|
|
mainMenuEmuWasPaused = FCEUI_EmulationPaused() ? true : false;
|
|
|
|
if ( mainMenuPauseWhenActv && !mainMenuEmuPauseSet && !mainMenuEmuWasPaused )
|
|
{
|
|
FCEUI_ToggleEmulationPause();
|
|
mainMenuEmuPauseSet = true;
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::mainMenuClose(void)
|
|
{
|
|
//printf("Main Menu Close\n");
|
|
|
|
if ( mainMenuEmuPauseSet )
|
|
{
|
|
bool isPaused = FCEUI_EmulationPaused() ? true : false;
|
|
|
|
if ( isPaused != mainMenuEmuWasPaused )
|
|
{
|
|
FCEUI_ToggleEmulationPause();
|
|
}
|
|
mainMenuEmuPauseSet = false;
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::prepareScreenShot(void)
|
|
{
|
|
// Set a timer single shot to take the screen shot. This gives time
|
|
// for the GUI to remove the menu from view before taking the image.
|
|
QTimer::singleShot( 100, Qt::CoarseTimer, this, SLOT(takeScreenShot(void)) );
|
|
}
|
|
|
|
//void consoleWin_t::takeScreenShot(void)
|
|
//{
|
|
// FCEU_WRAPPER_LOCK();
|
|
// FCEUI_SaveSnapshot();
|
|
// FCEU_WRAPPER_UNLOCK();
|
|
//}
|
|
|
|
void consoleWin_t::takeScreenShot(void)
|
|
{
|
|
int u=0;
|
|
QPixmap image;
|
|
QScreen *screen = QGuiApplication::primaryScreen();
|
|
|
|
if (const QWindow *window = windowHandle())
|
|
{
|
|
screen = window->screen();
|
|
}
|
|
|
|
if (screen == NULL)
|
|
{
|
|
FCEU_DispMessage("Error saving screen snapshot.",0);
|
|
return;
|
|
}
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
|
|
if ( viewport_GL )
|
|
{
|
|
image = screen->grabWindow( viewport_GL->winId() );
|
|
}
|
|
else if ( viewport_SDL )
|
|
{
|
|
image = screen->grabWindow( viewport_SDL->winId() );
|
|
}
|
|
else if ( viewport_QWidget )
|
|
{
|
|
image = screen->grabWindow( viewport_QWidget->winId() );
|
|
}
|
|
|
|
for (u = 0; u < 99999; ++u)
|
|
{
|
|
FILE *pp = FCEUD_UTF8fopen( FCEU_MakeFName(FCEUMKF_SNAP,u,"png").c_str(), "rb");
|
|
|
|
if (pp == NULL)
|
|
{
|
|
break;
|
|
}
|
|
fclose(pp);
|
|
}
|
|
|
|
image.save( tr( FCEU_MakeFName(FCEUMKF_SNAP,u,"png").c_str() ), "png" );
|
|
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
FCEU_DispMessage("Screen snapshot %d saved.",0,u);
|
|
}
|
|
|
|
void consoleWin_t::loadLua(void)
|
|
{
|
|
#ifdef _S9XLUA_H
|
|
LuaControlDialog_t *luaCtrlWin;
|
|
|
|
//printf("Open Lua Control Window\n");
|
|
|
|
luaCtrlWin = new LuaControlDialog_t(this);
|
|
|
|
luaCtrlWin->show();
|
|
#endif
|
|
}
|
|
|
|
void consoleWin_t::loadJs(void)
|
|
{
|
|
#ifdef __FCEU_QSCRIPT_ENABLE__
|
|
QScriptDialog_t *jsCtrlWin;
|
|
|
|
//printf("Open JS Control Window\n");
|
|
|
|
jsCtrlWin = new QScriptDialog_t(this);
|
|
|
|
jsCtrlWin->show();
|
|
#endif
|
|
}
|
|
|
|
void consoleWin_t::openInputConfWin(void)
|
|
{
|
|
//printf("Open Input Config Window\n");
|
|
|
|
openInputConfWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openGamePadConfWin(void)
|
|
{
|
|
//printf("Open GamePad Config Window\n");
|
|
|
|
openGamePadConfWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openGameSndConfWin(void)
|
|
{
|
|
ConsoleSndConfDialog_t *sndConfWin;
|
|
|
|
//printf("Open Sound Config Window\n");
|
|
|
|
sndConfWin = new ConsoleSndConfDialog_t(this);
|
|
|
|
sndConfWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openGameVideoConfWin(void)
|
|
{
|
|
ConsoleVideoConfDialog_t *vidConfWin;
|
|
|
|
//printf("Open Video Config Window\n");
|
|
|
|
vidConfWin = new ConsoleVideoConfDialog_t(this);
|
|
|
|
vidConfWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openHotkeyConfWin(void)
|
|
{
|
|
HotKeyConfDialog_t *hkConfWin;
|
|
|
|
//printf("Open Hot Key Config Window\n");
|
|
|
|
hkConfWin = new HotKeyConfDialog_t(this);
|
|
|
|
hkConfWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openPaletteConfWin(void)
|
|
{
|
|
PaletteConfDialog_t *paletteConfWin;
|
|
|
|
//printf("Open Palette Config Window\n");
|
|
|
|
paletteConfWin = new PaletteConfDialog_t(this);
|
|
|
|
paletteConfWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openGuiConfWin(void)
|
|
{
|
|
GuiConfDialog_t *guiConfWin;
|
|
|
|
//printf("Open GUI Config Window\n");
|
|
|
|
guiConfWin = new GuiConfDialog_t(this);
|
|
|
|
guiConfWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openTimingConfWin(void)
|
|
{
|
|
TimingConfDialog_t *tmConfWin;
|
|
|
|
//printf("Open Timing Config Window\n");
|
|
|
|
tmConfWin = new TimingConfDialog_t(this);
|
|
|
|
tmConfWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openTimingStatWin(void)
|
|
{
|
|
FrameTimingDialog_t *tmStatWin;
|
|
|
|
//printf("Open Timing Statistics Window\n");
|
|
|
|
tmStatWin = new FrameTimingDialog_t(this);
|
|
|
|
tmStatWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openPaletteEditorWin(void)
|
|
{
|
|
PaletteEditorDialog_t *win;
|
|
|
|
//printf("Open Palette Editor Window\n");
|
|
|
|
win = new PaletteEditorDialog_t(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openNetPlayHostWindow(void)
|
|
{
|
|
NetPlayHostDialog *win;
|
|
|
|
//printf("Open NetPlay Host Window\n");
|
|
|
|
win = new NetPlayHostDialog(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openNetPlayJoinWindow(void)
|
|
{
|
|
NetPlayJoinDialog *win;
|
|
|
|
//printf("Open NetPlay Join Window\n");
|
|
|
|
win = new NetPlayJoinDialog(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openAviRiffViewer(void)
|
|
{
|
|
AviRiffViewerDialog *win;
|
|
|
|
//printf("Open AVI RIFF Viewer Window\n");
|
|
|
|
win = new AviRiffViewerDialog(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openTasEditor(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
|
|
if ( tasWindowIsOpen() )
|
|
{
|
|
tasWindowSetFocus(true);
|
|
}
|
|
else if (FCEU_IsValidUI(FCEUI_TASEDITOR))
|
|
{
|
|
TasEditorWindow *win;
|
|
|
|
win = new TasEditorWindow(this);
|
|
|
|
win->show();
|
|
|
|
connect(emulatorThread, SIGNAL(frameFinished(void)), win, SLOT(frameUpdate(void)) );
|
|
}
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::openMovieOptWin(void)
|
|
{
|
|
MovieOptionsDialog_t *win;
|
|
|
|
//printf("Open Movie Options Window\n");
|
|
|
|
win = new MovieOptionsDialog_t(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openCheats(void)
|
|
{
|
|
//printf("Open GUI Cheat Window\n");
|
|
|
|
openCheatDialog(this);
|
|
}
|
|
|
|
void consoleWin_t::openRamWatch(void)
|
|
{
|
|
RamWatchDialog_t *ramWatchWin;
|
|
|
|
//printf("Open GUI RAM Watch Window\n");
|
|
|
|
ramWatchWin = new RamWatchDialog_t(this);
|
|
|
|
ramWatchWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openRamSearch(void)
|
|
{
|
|
//printf("Open GUI RAM Search Window\n");
|
|
openRamSearchWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openDebugWindow(void)
|
|
{
|
|
//printf("Open GUI 6502 Debugger Window\n");
|
|
|
|
if ( debuggerWindowIsOpen() )
|
|
{
|
|
debuggerWindowSetFocus();
|
|
}
|
|
else
|
|
{
|
|
ConsoleDebugger *debugWin;
|
|
|
|
debugWin = new ConsoleDebugger(this);
|
|
|
|
debugWin->show();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::openHexEditor(void)
|
|
{
|
|
HexEditorDialog_t *hexEditWin;
|
|
|
|
//printf("Open GUI Hex Editor Window\n");
|
|
|
|
hexEditWin = new HexEditorDialog_t(this);
|
|
|
|
hexEditWin->show();
|
|
}
|
|
|
|
void consoleWin_t::openPPUViewer(void)
|
|
{
|
|
//printf("Open GUI PPU Viewer Window\n");
|
|
|
|
openPPUViewWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openOAMViewer(void)
|
|
{
|
|
//printf("Open GUI OAM Viewer Window\n");
|
|
|
|
openOAMViewWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openNTViewer(void)
|
|
{
|
|
//printf("Open GUI Name Table Viewer Window\n");
|
|
|
|
openNameTableViewWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openCodeDataLogger(void)
|
|
{
|
|
openCDLWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::openGGEncoder(void)
|
|
{
|
|
GameGenieDialog_t *win;
|
|
|
|
//printf("Open Game Genie Window\n");
|
|
|
|
win = new GameGenieDialog_t(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openNesHeaderEditor(void)
|
|
{
|
|
iNesHeaderEditor_t *win;
|
|
|
|
//printf("Open NES Header Editor Window\n");
|
|
|
|
win = new iNesHeaderEditor_t(this);
|
|
|
|
if ( win->isInitialized() )
|
|
{
|
|
win->show();
|
|
}
|
|
else
|
|
{
|
|
delete win;
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::openTraceLogger(void)
|
|
{
|
|
openTraceLoggerWindow(this);
|
|
}
|
|
|
|
void consoleWin_t::toggleAutoResume(void)
|
|
{
|
|
//printf("Auto Resume: %i\n", autoResume->isChecked() );
|
|
|
|
g_config->setOption ("SDL.AutoResume", (int) autoResume->isChecked() );
|
|
|
|
AutoResumePlay = autoResume->isChecked();
|
|
}
|
|
|
|
void consoleWin_t::winResizeIx(int iscale)
|
|
{
|
|
QSize w, v;
|
|
double xscale = 1.0, yscale = 1.0, aspectRatio = 1.0;
|
|
int texture_width = nes_shm->video.ncol;
|
|
int texture_height = nes_shm->video.nrow;
|
|
int l=0, r=texture_width;
|
|
int t=0, b=texture_height;
|
|
int dw=0, dh=0, rw, rh;
|
|
bool forceAspect = false;
|
|
|
|
xscale = (double)iscale;
|
|
yscale = (double)iscale;
|
|
|
|
w = size();
|
|
|
|
if ( viewport_Interface )
|
|
{
|
|
v = viewport_Interface->size();
|
|
aspectRatio = viewport_Interface->getAspectRatio();
|
|
forceAspect = viewport_Interface->getForceAspectOpt();
|
|
}
|
|
|
|
dw = w.width() - v.width();
|
|
dh = w.height() - v.height();
|
|
|
|
if ( forceAspect )
|
|
{
|
|
xscale = xscale / nes_shm->video.xscale;
|
|
yscale = xscale * (double)nes_shm->video.xyRatio;
|
|
}
|
|
else
|
|
{
|
|
xscale = xscale / nes_shm->video.xscale;
|
|
yscale = yscale / nes_shm->video.yscale;
|
|
}
|
|
rw=(int)((r-l)*xscale);
|
|
rh=(int)((b-t)*yscale);
|
|
|
|
if ( forceAspect )
|
|
{
|
|
double rr;
|
|
|
|
rr = (double)rh / (double)rw;
|
|
|
|
if ( rr > aspectRatio )
|
|
{
|
|
rw = (int)( (((double)rh) / aspectRatio) + 0.50);
|
|
}
|
|
else
|
|
{
|
|
rh = (int)( (((double)rw) * aspectRatio) + 0.50);
|
|
}
|
|
}
|
|
|
|
resize( rw + dw, rh + dh );
|
|
}
|
|
|
|
void consoleWin_t::toggleFullscreen(void)
|
|
{
|
|
if ( isFullScreen() )
|
|
{
|
|
showNormal();
|
|
|
|
if ( autoHideMenuFullscreen )
|
|
{
|
|
menubar->setVisible(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( autoHideMenuFullscreen )
|
|
{
|
|
menubar->setVisible(false);
|
|
}
|
|
showFullScreen();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::toggleFamKeyBrdEnable(void)
|
|
{
|
|
toggleFamilyKeyboardFunc();
|
|
}
|
|
|
|
extern int globalCheatDisabled;
|
|
|
|
void consoleWin_t::toggleGlobalCheatEnable(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_GlobalToggleCheat(globalCheatDisabled);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
g_config->setOption("SDL.CheatsDisabled", globalCheatDisabled);
|
|
g_config->save();
|
|
|
|
updateCheatDialog();
|
|
}
|
|
|
|
void consoleWin_t::warnAmbiguousShortcut( QShortcut *shortcut)
|
|
{
|
|
char stmp[256];
|
|
std::string msg;
|
|
int c = 0;
|
|
|
|
sprintf( stmp, "Error: Ambiguous Shortcut Activation for Key Sequence: '%s'\n", shortcut->key().toString().toLocal8Bit().constData() );
|
|
|
|
msg.assign( stmp );
|
|
|
|
for (int i = 0; i < HK_MAX; i++)
|
|
{
|
|
QShortcut *sc = Hotkeys[i].getShortcut();
|
|
|
|
if ( sc == NULL )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( (sc == shortcut) || (shortcut->key().matches( sc->key() ) == QKeySequence::ExactMatch) )
|
|
{
|
|
if ( c == 0 )
|
|
{
|
|
msg.append("Hot Key Conflict: "); c++;
|
|
}
|
|
else
|
|
{
|
|
msg.append(" and "); c++;
|
|
}
|
|
msg.append( Hotkeys[i].getConfigName() );
|
|
}
|
|
}
|
|
QueueErrorMsgWindow( msg.c_str() );
|
|
}
|
|
|
|
void consoleWin_t::powerConsoleCB(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_PowerNES();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::consoleHardReset(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
fceuWrapperHardReset();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::consoleSoftReset(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
fceuWrapperSoftReset();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::consolePause(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
fceuWrapperTogglePause();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
|
|
mainMenuEmuPauseSet = false;
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRegion(int region)
|
|
{
|
|
int currentRegion;
|
|
|
|
g_config->setOption ("SDL.PAL", region);
|
|
g_config->save ();
|
|
|
|
currentRegion = FCEUI_GetRegion();
|
|
|
|
if ( currentRegion != region )
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_SetRegion (region, true);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRegionNTSC(void)
|
|
{
|
|
setRegion(0);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRegionPAL(void)
|
|
{
|
|
setRegion(1);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRegionDendy(void)
|
|
{
|
|
setRegion(2);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRamInit0(void)
|
|
{
|
|
RAMInitOption = 0;
|
|
|
|
g_config->setOption ("SDL.RamInitMethod", RAMInitOption);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRamInit1(void)
|
|
{
|
|
RAMInitOption = 1;
|
|
|
|
g_config->setOption ("SDL.RamInitMethod", RAMInitOption);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRamInit2(void)
|
|
{
|
|
RAMInitOption = 2;
|
|
|
|
g_config->setOption ("SDL.RamInitMethod", RAMInitOption);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setRamInit3(void)
|
|
{
|
|
RAMInitOption = 3;
|
|
|
|
g_config->setOption ("SDL.RamInitMethod", RAMInitOption);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::toggleGameGenie(bool checked)
|
|
{
|
|
int gg_enabled;
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
g_config->getOption ("SDL.GameGenie", &gg_enabled);
|
|
g_config->setOption ("SDL.GameGenie", !gg_enabled);
|
|
g_config->save ();
|
|
FCEUI_SetGameGenie (gg_enabled);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::loadGameGenieROM(void)
|
|
{
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string last;
|
|
std::string dir;
|
|
QFileDialog dialog(this, tr("Open Game Genie ROM") );
|
|
QList<QUrl> urls;
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
|
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
|
|
dialog.setNameFilter(tr("GG ROM File (gg.rom *Genie*.nes) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
|
|
|
g_config->getOption ("SDL.LastOpenFile", &last );
|
|
|
|
getDirFromFile( last.c_str(), dir );
|
|
|
|
dialog.setDirectory( tr(dir.c_str()) );
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
g_config->setOption ("SDL.LastOpenFile", filename.toLocal8Bit().constData() );
|
|
|
|
// copy file to proper place (~/.fceux/gg.rom)
|
|
std::ifstream f1 ( filename.toLocal8Bit().constData(), std::fstream::binary);
|
|
std::string fn_out = FCEU_MakeFName (FCEUMKF_GGROM, 0, "");
|
|
std::ofstream f2 (fn_out.c_str (),
|
|
std::fstream::trunc | std::fstream::binary);
|
|
f2 << f1.rdbuf ();
|
|
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::openFamilyKeyboard(void)
|
|
{
|
|
openFamilyKeyboardDialog(this);
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::insertCoin(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_VSUniCoin();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::fdsSwitchDisk(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEU_FDSSelect();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::fdsEjectDisk(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEU_FDSInsert();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::fdsLoadBiosFile(void)
|
|
{
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string last;
|
|
std::string dir;
|
|
QFileDialog dialog(this, tr("Load FDS BIOS (disksys.rom)") );
|
|
QList<QUrl> urls;
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
|
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
|
|
dialog.setNameFilter(tr("ROM files (*.rom *.ROM) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
|
|
|
g_config->getOption ("SDL.LastOpenFile", &last );
|
|
|
|
getDirFromFile( last.c_str(), dir);
|
|
|
|
dialog.setDirectory( tr(dir.c_str()) );
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
// copy BIOS file to proper place (~/.fceux/disksys.rom)
|
|
std::ifstream fdsBios (filename.toLocal8Bit().constData(), std::fstream::binary);
|
|
std::string output_filename =
|
|
FCEU_MakeFName (FCEUMKF_FDSROM, 0, "");
|
|
std::ofstream outFile (output_filename.c_str (),
|
|
std::fstream::trunc | std::fstream::
|
|
binary);
|
|
outFile << fdsBios.rdbuf ();
|
|
if (outFile.fail ())
|
|
{
|
|
FCEUD_PrintError ("Error copying the FDS BIOS file.");
|
|
}
|
|
else
|
|
{
|
|
printf("Famicom Disk System BIOS loaded. If you are you having issues, make sure your BIOS file is 8KB in size.\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::emuSpeedUp(void)
|
|
{
|
|
IncreaseEmulationSpeed();
|
|
}
|
|
|
|
void consoleWin_t::emuSlowDown(void)
|
|
{
|
|
DecreaseEmulationSpeed();
|
|
}
|
|
|
|
void consoleWin_t::emuSlowestSpd(void)
|
|
{
|
|
FCEUD_SetEmulationSpeed( EMUSPEED_SLOWEST );
|
|
}
|
|
|
|
void consoleWin_t::emuNormalSpd(void)
|
|
{
|
|
FCEUD_SetEmulationSpeed( EMUSPEED_NORMAL );
|
|
}
|
|
|
|
void consoleWin_t::emuFastestSpd(void)
|
|
{
|
|
FCEUD_SetEmulationSpeed( EMUSPEED_FASTEST );
|
|
}
|
|
|
|
void consoleWin_t::emuCustomSpd(void)
|
|
{
|
|
int ret;
|
|
QInputDialog dialog(this);
|
|
|
|
dialog.setWindowTitle( tr("Emulation Speed") );
|
|
dialog.setLabelText( tr("Enter a percentage from 1 to 1000.") );
|
|
dialog.setOkButtonText( tr("Ok") );
|
|
dialog.setInputMode( QInputDialog::IntInput );
|
|
dialog.setIntRange( 1, 1000 );
|
|
dialog.setIntValue( 100 );
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( QDialog::Accepted == ret )
|
|
{
|
|
int spdPercent;
|
|
|
|
spdPercent = dialog.intValue();
|
|
|
|
CustomEmulationSpeed( spdPercent );
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::emuSetFrameAdvDelay(void)
|
|
{
|
|
int ret;
|
|
QInputDialog dialog(this);
|
|
|
|
dialog.setWindowTitle( tr("Frame Advance Delay") );
|
|
dialog.setLabelText( tr("How much time should elapse before holding the frame advance unpauses the simulation?") );
|
|
dialog.setOkButtonText( tr("Ok") );
|
|
dialog.setInputMode( QInputDialog::IntInput );
|
|
dialog.setIntRange( 0, 1000 );
|
|
dialog.setIntValue( frameAdvance_Delay );
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( QDialog::Accepted == ret )
|
|
{
|
|
frameAdvance_Delay = dialog.intValue();
|
|
|
|
g_config->setOption("SDL.FrameAdvanceDelay", frameAdvance_Delay );
|
|
g_config->save();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::syncAutoFirePatternMenu(void)
|
|
{
|
|
int on, off;
|
|
|
|
GetAutoFirePattern( &on, &off );
|
|
|
|
for (size_t i=0; i<afActList.size(); i++)
|
|
{
|
|
if ( afActList[i]->isMatch( on, off ) )
|
|
{
|
|
afActList[i]->setChecked(true);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// If we get here, then the custom option is selected.
|
|
afActCustom->setChecked(true);
|
|
|
|
}
|
|
void consoleWin_t::setCustomAutoFire(void)
|
|
{
|
|
int ret, autoFireOnFrames, autoFireOffFrames;
|
|
QDialog dialog(this);
|
|
QLabel *lbl;
|
|
QGridLayout *grid;
|
|
QVBoxLayout *vbox;
|
|
QSpinBox *onBox, *offBox;
|
|
QPushButton *okButton, *cancelButton;
|
|
|
|
autoFireOnFrames = afActCustom->getOnValue();
|
|
autoFireOffFrames = afActCustom->getOffValue();
|
|
|
|
dialog.setWindowTitle( tr("Custom AutoFire Pattern") );
|
|
|
|
onBox = new QSpinBox();
|
|
offBox = new QSpinBox();
|
|
|
|
onBox->setMinimum( 1);
|
|
offBox->setMinimum( 1);
|
|
onBox->setMaximum(30);
|
|
offBox->setMaximum(30);
|
|
|
|
onBox->setValue( autoFireOnFrames );
|
|
offBox->setValue( autoFireOffFrames );
|
|
|
|
vbox = new QVBoxLayout();
|
|
grid = new QGridLayout();
|
|
|
|
lbl = new QLabel( tr("# ON Frames") );
|
|
|
|
grid->addWidget( lbl, 0, 0 );
|
|
|
|
lbl = new QLabel( tr("# OFF Frames") );
|
|
|
|
grid->addWidget( lbl, 1, 0 );
|
|
|
|
grid->addWidget( onBox , 0, 1 );
|
|
grid->addWidget( offBox, 1, 1 );
|
|
|
|
okButton = new QPushButton( tr("Ok") );
|
|
cancelButton = new QPushButton( tr("Cancel") );
|
|
|
|
okButton->setIcon( style()->standardIcon( QStyle::SP_DialogApplyButton ) );
|
|
cancelButton->setIcon( style()->standardIcon( QStyle::SP_DialogCancelButton ) );
|
|
|
|
grid->addWidget( cancelButton , 2, 0 );
|
|
grid->addWidget( okButton , 2, 1 );
|
|
|
|
vbox->addLayout( grid );
|
|
|
|
dialog.setLayout( vbox );
|
|
|
|
connect( cancelButton, SIGNAL(clicked(void)), &dialog, SLOT(reject(void)) );
|
|
connect( okButton, SIGNAL(clicked(void)), &dialog, SLOT(accept(void)) );
|
|
|
|
okButton->setDefault(true);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( QDialog::Accepted == ret )
|
|
{
|
|
autoFireOnFrames = onBox->value();
|
|
autoFireOffFrames = offBox->value();
|
|
|
|
afActCustom->setPattern( autoFireOnFrames, autoFireOffFrames );
|
|
|
|
if ( afActCustom->isChecked() )
|
|
{
|
|
afActCustom->activateCB();
|
|
}
|
|
g_config->setOption("SDL.AutofireCustomOnFrames" , autoFireOnFrames );
|
|
g_config->setOption("SDL.AutofireCustomOffFrames" , autoFireOffFrames);
|
|
g_config->save();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::muteSoundVolume(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUD_SoundToggle();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::incrSoundVolume(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUD_SoundVolumeAdjust( 1);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::decrSoundVolume(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUD_SoundVolumeAdjust(-1);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleLagCounterDisplay(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
lagCounterDisplay = !lagCounterDisplay;
|
|
g_config->setOption("SDL.ShowLagCount", lagCounterDisplay);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleFrameAdvLagSkip(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
frameAdvanceLagSkip = !frameAdvanceLagSkip;
|
|
FCEUI_DispMessage ("Skipping lag in Frame Advance %sabled.", 0, frameAdvanceLagSkip ? "en" : "dis");
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleMovieBindSaveState(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
bindSavestate = !bindSavestate;
|
|
g_config->setOption("SDL.MovieBindSavestate", bindSavestate);
|
|
FCEUI_DispMessage ("Savestate binding to movie %sabled.", 0, bindSavestate ? "en" : "dis");
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleMovieFrameDisplay(void)
|
|
{
|
|
extern int frame_display;
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_MovieToggleFrameDisplay();
|
|
g_config->setOption("SDL.ShowFrameCount", frame_display );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleMovieReadWrite(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
//FCEUI_SetMovieToggleReadOnly (!FCEUI_GetMovieToggleReadOnly ());
|
|
FCEUI_MovieToggleReadOnly();
|
|
|
|
if ( tasWin != NULL )
|
|
{
|
|
tasWin->updateRecordStatus();
|
|
}
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleInputDisplay(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_ToggleInputDisplay();
|
|
g_config->setOption ("SDL.InputDisplay", input_display);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleBackground(void)
|
|
{
|
|
bool fgOn, bgOn;
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_GetRenderPlanes( fgOn, bgOn );
|
|
FCEUI_SetRenderPlanes( fgOn, !bgOn );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleForeground(void)
|
|
{
|
|
bool fgOn, bgOn;
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_GetRenderPlanes( fgOn, bgOn );
|
|
FCEUI_SetRenderPlanes( !fgOn, bgOn );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::toggleTurboMode(void)
|
|
{
|
|
NoWaiting ^= 1;
|
|
}
|
|
|
|
void consoleWin_t::openStateRecorderConfWin(void)
|
|
{
|
|
StateRecorderDialog_t *win;
|
|
|
|
win = new StateRecorderDialog_t(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::openMovie(void)
|
|
{
|
|
MoviePlayDialog_t *win;
|
|
|
|
win = new MoviePlayDialog_t(this);
|
|
|
|
win->show();
|
|
}
|
|
|
|
void consoleWin_t::playMovieFromBeginning(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_MoviePlayFromBeginning();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::stopMovie(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_StopMovie();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::recordMovie(void)
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
if (fceuWrapperGameLoaded())
|
|
{
|
|
MovieRecordDialog_t dialog(this);
|
|
dialog.exec();
|
|
}
|
|
FCEU_WRAPPER_UNLOCK();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::aviRecordStart(void)
|
|
{
|
|
if ( !aviRecordRunning() )
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
if ( aviRecordOpenFile(NULL) == 0 )
|
|
{
|
|
aviDiskThread->start();
|
|
}
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::aviRecordAsStart(void)
|
|
{
|
|
if ( aviRecordRunning() )
|
|
{
|
|
return;
|
|
}
|
|
std::string last;
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string lastPath;
|
|
//char dir[512];
|
|
const char *base, *rom;
|
|
QFileDialog dialog(this, tr("Save AVI Movie for Recording") );
|
|
QList<QUrl> urls;
|
|
QDir d;
|
|
|
|
dialog.setFileMode(QFileDialog::AnyFile);
|
|
|
|
dialog.setNameFilter(tr("AVI Movies (*.avi) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
|
|
|
base = FCEUI_GetBaseDirectory();
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
|
|
if ( base )
|
|
{
|
|
urls << QUrl::fromLocalFile( QDir( base ).absolutePath() );
|
|
|
|
d.setPath( QString(base) + "/avi");
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
|
|
dialog.setDirectory( d.absolutePath() );
|
|
}
|
|
dialog.setDefaultSuffix( tr(".avi") );
|
|
|
|
g_config->getOption ("SDL.AviFilePath", &lastPath);
|
|
if ( lastPath.size() > 0 )
|
|
{
|
|
dialog.setDirectory( QString::fromStdString(lastPath) );
|
|
}
|
|
|
|
rom = getRomFile();
|
|
|
|
if ( rom )
|
|
{
|
|
char baseName[512];
|
|
getFileBaseName( rom, baseName );
|
|
|
|
if ( baseName[0] != 0 )
|
|
{
|
|
dialog.selectFile(baseName);
|
|
}
|
|
}
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
FCEUI_printf ("AVI Recording movie to %s\n", filename.toLocal8Bit().constData() );
|
|
|
|
lastPath = QFileInfo(filename).absolutePath().toLocal8Bit().constData();
|
|
|
|
if ( lastPath.size() > 0 )
|
|
{
|
|
g_config->setOption ("SDL.AviFilePath", lastPath);
|
|
}
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
if ( aviRecordOpenFile( filename.toLocal8Bit().constData() ) == 0 )
|
|
{
|
|
aviDiskThread->start();
|
|
}
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::aviRecordStop(void)
|
|
{
|
|
if ( aviRecordRunning() )
|
|
{
|
|
QGuiApplication::setOverrideCursor( QCursor(Qt::BusyCursor) );
|
|
FCEU_WRAPPER_LOCK();
|
|
aviDiskThread->requestInterruption();
|
|
aviDiskThread->quit();
|
|
aviDiskThread->wait(10000);
|
|
FCEU_WRAPPER_UNLOCK();
|
|
QGuiApplication::restoreOverrideCursor();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::aviAudioEnableChange(bool checked)
|
|
{
|
|
aviSetAudioEnable( checked );
|
|
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::setAviHudEnable(bool checked)
|
|
{
|
|
FCEUI_SetAviEnableHUDrecording( checked );
|
|
|
|
g_config->setOption("SDL.RecordHUD", checked );
|
|
}
|
|
|
|
void consoleWin_t::setAviMsgEnable(bool checked)
|
|
{
|
|
FCEUI_SetAviDisableMovieMessages( !checked );
|
|
|
|
g_config->setOption("SDL.MovieMsg", checked );
|
|
}
|
|
|
|
void consoleWin_t::aviVideoFormatChanged(int idx)
|
|
{
|
|
aviSetSelVideoFormat(idx);
|
|
}
|
|
|
|
void consoleWin_t::wavRecordStart(void)
|
|
{
|
|
if ( !FCEUI_WaveRecordRunning() )
|
|
{
|
|
const char *romFile;
|
|
std::string fileName;
|
|
|
|
romFile = getRomFile();
|
|
|
|
if ( romFile )
|
|
{
|
|
char base[512];
|
|
const char *baseDir = FCEUI_GetBaseDirectory();
|
|
std::string lastPath;
|
|
|
|
getFileBaseName( romFile, base );
|
|
|
|
g_config->getOption ("SDL.WavFilePath", &lastPath);
|
|
|
|
if ( lastPath.size() > 0 )
|
|
{
|
|
fileName.assign( lastPath );
|
|
fileName.append( "/" );
|
|
}
|
|
else if ( baseDir )
|
|
{
|
|
fileName.assign( baseDir );
|
|
fileName.append( "/wav/" );
|
|
}
|
|
else
|
|
{
|
|
fileName.clear();
|
|
}
|
|
fileName.append( base );
|
|
fileName.append(".wav");
|
|
//printf("WAV Filepath:'%s'\n", fileName );
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_BeginWaveRecord( fileName.c_str() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::wavRecordAsStart(void)
|
|
{
|
|
if ( FCEUI_WaveRecordRunning() )
|
|
{
|
|
return;
|
|
}
|
|
int ret, useNativeFileDialogVal;
|
|
QString filename;
|
|
std::string lastPath;
|
|
const char *base, *rom;
|
|
QFileDialog dialog(this, tr("Save WAV Movie for Recording") );
|
|
QList<QUrl> urls;
|
|
QDir d;
|
|
|
|
dialog.setFileMode(QFileDialog::AnyFile);
|
|
|
|
dialog.setNameFilter(tr("WAV Movies (*.wav) ;; All files (*)"));
|
|
|
|
dialog.setViewMode(QFileDialog::List);
|
|
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
|
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
|
|
|
base = FCEUI_GetBaseDirectory();
|
|
|
|
urls << QUrl::fromLocalFile( QDir::rootPath() );
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first());
|
|
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
|
|
|
|
if ( base )
|
|
{
|
|
urls << QUrl::fromLocalFile( QDir( base ).absolutePath() );
|
|
|
|
d.setPath( QString(base) + "/wav");
|
|
|
|
if ( d.exists() )
|
|
{
|
|
urls << QUrl::fromLocalFile( d.absolutePath() );
|
|
}
|
|
|
|
dialog.setDirectory( d.absolutePath() );
|
|
}
|
|
dialog.setDefaultSuffix( tr(".wav") );
|
|
|
|
g_config->getOption ("SDL.WavFilePath", &lastPath);
|
|
if ( lastPath.size() > 0 )
|
|
{
|
|
dialog.setDirectory( QString::fromStdString(lastPath) );
|
|
}
|
|
|
|
rom = getRomFile();
|
|
|
|
if ( rom )
|
|
{
|
|
char baseName[512];
|
|
getFileBaseName( rom, baseName );
|
|
|
|
if ( baseName[0] != 0 )
|
|
{
|
|
dialog.selectFile(baseName);
|
|
}
|
|
}
|
|
|
|
// Check config option to use native file dialog or not
|
|
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
|
|
|
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
|
dialog.setSidebarUrls(urls);
|
|
|
|
ret = dialog.exec();
|
|
|
|
if ( ret )
|
|
{
|
|
QStringList fileList;
|
|
fileList = dialog.selectedFiles();
|
|
|
|
if ( fileList.size() > 0 )
|
|
{
|
|
filename = fileList[0];
|
|
}
|
|
}
|
|
|
|
if ( filename.isNull() )
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "selected file path : " << filename.toLocal8Bit();
|
|
|
|
FCEUI_printf ("WAV Recording movie to %s\n", filename.toLocal8Bit().constData() );
|
|
|
|
lastPath = QFileInfo(filename).absolutePath().toLocal8Bit().constData();
|
|
|
|
if ( lastPath.size() > 0 )
|
|
{
|
|
g_config->setOption ("SDL.WavFilePath", lastPath);
|
|
}
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_BeginWaveRecord( filename.toLocal8Bit().constData() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
void consoleWin_t::wavRecordStop(void)
|
|
{
|
|
if ( FCEUI_WaveRecordRunning() )
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
FCEUI_EndWaveRecord();
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::aboutFCEUX(void)
|
|
{
|
|
AboutWindow *aboutWin;
|
|
|
|
//printf("About FCEUX Window\n");
|
|
|
|
aboutWin = new AboutWindow(this);
|
|
|
|
aboutWin->show();
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::aboutQt(void)
|
|
{
|
|
//printf("About Qt Window\n");
|
|
|
|
QMessageBox::aboutQt(this);
|
|
|
|
//printf("About Qt Destroyed\n");
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::openMsgLogWin(void)
|
|
{
|
|
//printf("Open Message Log Window\n");
|
|
MsgLogViewDialog_t *msgLogWin;
|
|
|
|
msgLogWin = new MsgLogViewDialog_t(this);
|
|
|
|
msgLogWin->show();
|
|
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::openOnlineDocs(void)
|
|
{
|
|
if ( QDesktopServices::openUrl( QUrl("https://fceux.com/web/help/fceux.html") ) == false )
|
|
{
|
|
QueueErrorMsgWindow("Error: Failed to open link to: https://fceux.com/web/help/fceux.html");
|
|
}
|
|
return;
|
|
}
|
|
|
|
void consoleWin_t::openOfflineDocs(void)
|
|
{
|
|
OpenHelpWindow();
|
|
return;
|
|
}
|
|
|
|
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
|
|
int consoleWin_t::setNicePriority( int value )
|
|
{
|
|
int ret = 0;
|
|
#if defined(__linux__) || defined(__unix__)
|
|
|
|
if ( value < -20 )
|
|
{
|
|
value = -20;
|
|
}
|
|
else if ( value > 19 )
|
|
{
|
|
value = 19;
|
|
}
|
|
|
|
if ( ::setpriority( PRIO_PROCESS, getpid(), value ) )
|
|
{
|
|
perror("Emulator thread setpriority error: ");
|
|
ret = -1;
|
|
}
|
|
#elif defined(__APPLE__)
|
|
|
|
if ( value < -20 )
|
|
{
|
|
value = -20;
|
|
}
|
|
else if ( value > 20 )
|
|
{
|
|
value = 20;
|
|
}
|
|
|
|
if ( ::setpriority( PRIO_PROCESS, getpid(), value ) )
|
|
{
|
|
perror("Emulator thread setpriority error: ");
|
|
ret = -1;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int consoleWin_t::getNicePriority(void)
|
|
{
|
|
return ::getpriority( PRIO_PROCESS, getpid() );
|
|
}
|
|
|
|
int consoleWin_t::getMinSchedPriority(void)
|
|
{
|
|
int policy, prio;
|
|
|
|
if ( getSchedParam( policy, prio ) )
|
|
{
|
|
return 0;
|
|
}
|
|
return sched_get_priority_min( policy );
|
|
}
|
|
|
|
int consoleWin_t::getMaxSchedPriority(void)
|
|
{
|
|
int policy, prio;
|
|
|
|
if ( getSchedParam( policy, prio ) )
|
|
{
|
|
return 0;
|
|
}
|
|
return sched_get_priority_max( policy );
|
|
}
|
|
|
|
int consoleWin_t::getSchedParam( int &policy, int &priority )
|
|
{
|
|
int ret = 0;
|
|
|
|
#if defined(__linux__) || defined(__unix__) && !defined(__OpenBSD__)
|
|
struct sched_param p;
|
|
|
|
policy = sched_getscheduler( getpid() );
|
|
|
|
if ( sched_getparam( getpid(), &p ) )
|
|
{
|
|
perror("GUI thread sched_getparam error: ");
|
|
ret = -1;
|
|
priority = 0;
|
|
}
|
|
else
|
|
{
|
|
priority = p.sched_priority;
|
|
}
|
|
|
|
#elif defined(__APPLE__)
|
|
struct sched_param p;
|
|
|
|
if ( pthread_getschedparam( pthread_self(), &policy, &p ) )
|
|
{
|
|
perror("GUI thread pthread_getschedparam error: ");
|
|
ret = -1;
|
|
priority = 0;
|
|
}
|
|
else
|
|
{
|
|
priority = p.sched_priority;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int consoleWin_t::setSchedParam( int policy, int priority )
|
|
{
|
|
int ret = 0;
|
|
#if defined(__linux__) || defined(__unix__) && !defined(__OpenBSD__)
|
|
struct sched_param p;
|
|
int minPrio, maxPrio;
|
|
|
|
minPrio = sched_get_priority_min( policy );
|
|
maxPrio = sched_get_priority_max( policy );
|
|
|
|
if ( priority < minPrio )
|
|
{
|
|
priority = minPrio;
|
|
}
|
|
else if ( priority > maxPrio )
|
|
{
|
|
priority = maxPrio;
|
|
}
|
|
p.sched_priority = priority;
|
|
|
|
if ( sched_setscheduler( getpid(), policy, &p ) )
|
|
{
|
|
perror("GUI thread sched_setscheduler error");
|
|
ret = -1;
|
|
}
|
|
#elif defined(__APPLE__)
|
|
struct sched_param p;
|
|
int minPrio, maxPrio;
|
|
|
|
minPrio = sched_get_priority_min( policy );
|
|
maxPrio = sched_get_priority_max( policy );
|
|
|
|
if ( priority < minPrio )
|
|
{
|
|
priority = minPrio;
|
|
}
|
|
else if ( priority > maxPrio )
|
|
{
|
|
priority = maxPrio;
|
|
}
|
|
p.sched_priority = priority;
|
|
|
|
if ( ::pthread_setschedparam( pthread_self(), policy, &p ) != 0 )
|
|
{
|
|
perror("GUI thread pthread_setschedparam error: ");
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
void consoleWin_t::syncActionConfig( QAction *act, const char *property )
|
|
{
|
|
if ( act->isCheckable() )
|
|
{
|
|
int enable;
|
|
g_config->getOption ( property, &enable);
|
|
|
|
act->setChecked( enable ? true : false );
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::loadMostRecentROM(void)
|
|
{
|
|
if ( romList.size() <= 0 )
|
|
{
|
|
return;
|
|
}
|
|
FCEU_WRAPPER_LOCK();
|
|
CloseGame ();
|
|
LoadGame ( (romList.back())->c_str() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
int consoleWin_t::getPeriodicInterval(void)
|
|
{
|
|
return gameTimer->interval();
|
|
}
|
|
|
|
void consoleWin_t::transferVideoBuffer(bool allowRedraw)
|
|
{
|
|
FCEU_PROFILE_FUNC(prof, "VideoXfer");
|
|
|
|
{
|
|
FCEU::autoScopedLock lock(videoBufferMutex);
|
|
if ( nes_shm->blitUpdated )
|
|
{
|
|
nes_shm->blitUpdated = 0;
|
|
|
|
if (viewport_Interface != nullptr)
|
|
{
|
|
viewport_Interface->transfer2LocalBuffer();
|
|
redrawVideoRequest = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Don't queue redraw in mutex lock scope
|
|
if (allowRedraw && redrawVideoRequest && (viewport_Interface != nullptr))
|
|
{
|
|
viewport_Interface->queueRedraw();
|
|
redrawVideoRequest = false;
|
|
}
|
|
}
|
|
|
|
void consoleWin_t::emuFrameFinish(void)
|
|
{
|
|
//static bool eventProcessingInProg = false;
|
|
|
|
guiSignalRecvMark();
|
|
|
|
//if ( eventProcessingInProg )
|
|
//{ // Prevent recursion as processEvents function can double back on us
|
|
// return;
|
|
//}
|
|
// Prevent recursion as processEvents function can double back on us
|
|
//if ( !eventProcessingInProg )
|
|
//{
|
|
// eventProcessingInProg = true;
|
|
// // Process all events before attempting to render viewport
|
|
// QCoreApplication::processEvents();
|
|
// eventProcessingInProg = false;
|
|
//}
|
|
|
|
// Update Input Devices
|
|
//FCEUD_UpdateInput();
|
|
|
|
//printf("EMU Frame Finish\n");
|
|
|
|
//#ifdef __FCEU_QSCRIPT_ENABLE__
|
|
// QtScriptManager::getInstance()->frameFinishedUpdate();
|
|
//#endif
|
|
|
|
transferVideoBuffer(false);
|
|
}
|
|
|
|
void consoleWin_t::updatePeriodic(void)
|
|
{
|
|
FCEU_PROFILE_FUNC(prof, "updatePeriodic");
|
|
static bool eventProcessingInProg = false;
|
|
|
|
//if ( eventProcessingInProg )
|
|
//{ // Prevent recursion as processEvents function can double back on us
|
|
// return;
|
|
//}
|
|
// Prevent recursion as processEvents function can double back on us
|
|
if ( !eventProcessingInProg )
|
|
{
|
|
eventProcessingInProg = true;
|
|
// Process all events before attempting to render viewport
|
|
QCoreApplication::processEvents();
|
|
eventProcessingInProg = false;
|
|
}
|
|
|
|
// Update Input Devices
|
|
FCEUD_UpdateInput();
|
|
|
|
// RePaint Game Viewport
|
|
transferVideoBuffer(true);
|
|
|
|
// Low Rate Updates
|
|
if ( (updateCounter % 30) == 0 )
|
|
{
|
|
// Keep region menu selection sync'd to actual state
|
|
int actRegion = FCEUI_GetRegion();
|
|
|
|
if ( !region[ actRegion ]->isChecked() )
|
|
{
|
|
region[ actRegion ]->setChecked(true);
|
|
}
|
|
|
|
powerAct->setEnabled( FCEU_IsValidUI( FCEUI_POWER ) );
|
|
resetAct->setEnabled( FCEU_IsValidUI( FCEUI_RESET ) );
|
|
sresetAct->setEnabled( FCEU_IsValidUI( FCEUI_RESET ) );
|
|
playMovBeginAct->setEnabled( FCEU_IsValidUI( FCEUI_PLAYFROMBEGINNING ) );
|
|
insCoinAct->setEnabled( FCEU_IsValidUI( FCEUI_INSERT_COIN ) );
|
|
fdsSwitchAct->setEnabled( FCEU_IsValidUI( FCEUI_SWITCH_DISK ) );
|
|
fdsEjectAct->setEnabled( FCEU_IsValidUI( FCEUI_EJECT_DISK ) );
|
|
stopMovAct->setEnabled( FCEU_IsValidUI( FCEUI_STOPMOVIE ) );
|
|
recentRomMenu->setEnabled( !recentRomMenu->isEmpty() );
|
|
quickLoadAct->setEnabled( FCEU_IsValidUI( FCEUI_QUICKLOAD ) );
|
|
quickSaveAct->setEnabled( FCEU_IsValidUI( FCEUI_QUICKSAVE ) );
|
|
loadStateAct->setEnabled( FCEU_IsValidUI( FCEUI_LOADSTATE ) );
|
|
saveStateAct->setEnabled( FCEU_IsValidUI( FCEUI_SAVESTATE ) );
|
|
openMovAct->setEnabled( FCEU_IsValidUI( FCEUI_PLAYMOVIE ) );
|
|
recMovAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) );
|
|
recAviAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEU_IsValidUI( FCEUI_STOPAVI ) );
|
|
recAsAviAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEU_IsValidUI( FCEUI_STOPAVI ) );
|
|
stopAviAct->setEnabled( FCEU_IsValidUI( FCEUI_STOPAVI ) );
|
|
recWavAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEUI_WaveRecordRunning() );
|
|
recAsWavAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEUI_WaveRecordRunning() );
|
|
stopWavAct->setEnabled( FCEUI_WaveRecordRunning() );
|
|
tasEditorAct->setEnabled( FCEU_IsValidUI(FCEUI_TASEDITOR) );
|
|
}
|
|
|
|
if ( errorMsgValid )
|
|
{
|
|
showErrorMsgWindow();
|
|
errorMsgValid = false;
|
|
}
|
|
|
|
if ( recentRomMenuReset )
|
|
{
|
|
FCEU_WRAPPER_LOCK();
|
|
buildRecentRomMenu();
|
|
recentRomMenuReset = false;
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
|
|
if ( closeRequested )
|
|
{
|
|
closeApp();
|
|
closeRequested = false;
|
|
}
|
|
|
|
NetPlayPeriodicUpdate();
|
|
|
|
updateCounter++;
|
|
|
|
#ifdef __FCEU_PROFILER_ENABLE__
|
|
FCEU_profiler_log_thread_activity();
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
emulatorThread_t::emulatorThread_t( QObject *parent )
|
|
: QThread(parent)
|
|
{
|
|
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
|
|
pself = 0;
|
|
#endif
|
|
|
|
setObjectName( QString("EmulationThread") );
|
|
}
|
|
|
|
#if defined(__linux__)
|
|
#ifndef SYS_gettid
|
|
#error "SYS_gettid unavailable on this system"
|
|
#endif
|
|
|
|
#define gettid() ((pid_t)syscall(SYS_gettid))
|
|
#endif
|
|
|
|
|
|
void emulatorThread_t::init(void)
|
|
{
|
|
int opt;
|
|
|
|
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
|
|
if ( pthread_self() == (pthread_t)QThread::currentThreadId() )
|
|
{
|
|
pself = pthread_self();
|
|
//printf("EMU is using PThread: %p\n", (void*)pself);
|
|
}
|
|
#endif
|
|
|
|
#if defined(__linux__)
|
|
pid = gettid();
|
|
#elif defined(__APPLE__) || defined(__unix__)
|
|
pid = getpid();
|
|
#endif
|
|
|
|
g_config->getOption( "SDL.SetSchedParam", &opt );
|
|
|
|
if ( opt )
|
|
{
|
|
#ifndef WIN32
|
|
int policy, prio, nice;
|
|
|
|
g_config->getOption( "SDL.EmuSchedPolicy", &policy );
|
|
g_config->getOption( "SDL.EmuSchedPrioRt", &prio );
|
|
g_config->getOption( "SDL.EmuSchedNice" , &nice );
|
|
|
|
setNicePriority( nice );
|
|
|
|
setSchedParam( policy, prio );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void emulatorThread_t::setPriority( QThread::Priority priority_req )
|
|
{
|
|
//printf("New Priority: %i \n", priority_req );
|
|
//printf("Old Priority: %i \n", priority() );
|
|
|
|
QThread::setPriority( priority_req );
|
|
|
|
//printf("Set Priority: %i \n", priority() );
|
|
}
|
|
|
|
#if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
|
|
int emulatorThread_t::setNicePriority( int value )
|
|
{
|
|
int ret = 0;
|
|
#if defined(__linux__) || defined(__unix__)
|
|
|
|
if ( value < -20 )
|
|
{
|
|
value = -20;
|
|
}
|
|
else if ( value > 19 )
|
|
{
|
|
value = 19;
|
|
}
|
|
|
|
if ( ::setpriority( PRIO_PROCESS, pid, value ) )
|
|
{
|
|
perror("Emulator thread setpriority error: ");
|
|
ret = -1;
|
|
}
|
|
#elif defined(__APPLE__)
|
|
|
|
if ( value < -20 )
|
|
{
|
|
value = -20;
|
|
}
|
|
else if ( value > 20 )
|
|
{
|
|
value = 20;
|
|
}
|
|
|
|
if ( ::setpriority( PRIO_PROCESS, pid, value ) )
|
|
{
|
|
perror("Emulator thread setpriority error: ");
|
|
ret = -1;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int emulatorThread_t::getNicePriority(void)
|
|
{
|
|
return ::getpriority( PRIO_PROCESS, pid );
|
|
}
|
|
|
|
int emulatorThread_t::getMinSchedPriority(void)
|
|
{
|
|
int policy, prio;
|
|
|
|
if ( getSchedParam( policy, prio ) )
|
|
{
|
|
return 0;
|
|
}
|
|
return sched_get_priority_min( policy );
|
|
}
|
|
|
|
int emulatorThread_t::getMaxSchedPriority(void)
|
|
{
|
|
int policy, prio;
|
|
|
|
if ( getSchedParam( policy, prio ) )
|
|
{
|
|
return 0;
|
|
}
|
|
return sched_get_priority_max( policy );
|
|
}
|
|
|
|
int emulatorThread_t::getSchedParam( int &policy, int &priority )
|
|
{
|
|
struct sched_param p;
|
|
|
|
if ( pthread_getschedparam( pself, &policy, &p ) )
|
|
{
|
|
perror("Emulator thread pthread_getschedparam error: ");
|
|
return -1;
|
|
}
|
|
priority = p.sched_priority;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int emulatorThread_t::setSchedParam( int policy, int priority )
|
|
{
|
|
int ret = 0;
|
|
#if defined(__linux__) || defined(__unix__)
|
|
struct sched_param p;
|
|
int minPrio, maxPrio;
|
|
|
|
minPrio = sched_get_priority_min( policy );
|
|
maxPrio = sched_get_priority_max( policy );
|
|
|
|
if ( priority < minPrio )
|
|
{
|
|
priority = minPrio;
|
|
}
|
|
else if ( priority > maxPrio )
|
|
{
|
|
priority = maxPrio;
|
|
}
|
|
p.sched_priority = priority;
|
|
|
|
if ( ::pthread_setschedparam( pself, policy, &p ) != 0 )
|
|
{
|
|
perror("Emulator thread pthread_setschedparam error: ");
|
|
ret = -1;
|
|
}
|
|
|
|
#elif defined(__APPLE__)
|
|
struct sched_param p;
|
|
int minPrio, maxPrio;
|
|
|
|
minPrio = sched_get_priority_min( policy );
|
|
maxPrio = sched_get_priority_max( policy );
|
|
|
|
if ( priority < minPrio )
|
|
{
|
|
priority = minPrio;
|
|
}
|
|
else if ( priority > maxPrio )
|
|
{
|
|
priority = maxPrio;
|
|
}
|
|
p.sched_priority = priority;
|
|
|
|
if ( ::pthread_setschedparam( pself, policy, &p ) != 0 )
|
|
{
|
|
perror("Emulator thread pthread_setschedparam error: ");
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
void emulatorThread_t::run(void)
|
|
{
|
|
printf("Emulator Start\n");
|
|
nes_shm->runEmulator = 1;
|
|
|
|
init();
|
|
|
|
while ( nes_shm->runEmulator )
|
|
{
|
|
fceuWrapperUpdate();
|
|
}
|
|
printf("Emulator Exit\n");
|
|
emit finished();
|
|
}
|
|
|
|
void emulatorThread_t::signalFrameFinished(void)
|
|
{
|
|
emuSignalSendMark();
|
|
emit frameFinished();
|
|
}
|
|
|
|
void emulatorThread_t::signalRomLoad( const char *path )
|
|
{
|
|
emit loadRomRequest( QString(path) );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Custom QMenuBar for Console
|
|
//-----------------------------------------------------------------------------
|
|
consoleMenuBar::consoleMenuBar(QWidget *parent)
|
|
: QMenuBar(parent)
|
|
{
|
|
|
|
}
|
|
consoleMenuBar::~consoleMenuBar(void)
|
|
{
|
|
|
|
}
|
|
|
|
void consoleMenuBar::keyPressEvent(QKeyEvent *event)
|
|
{
|
|
QMenuBar::keyPressEvent(event);
|
|
|
|
pushKeyEvent( event, 1 );
|
|
|
|
// Force de-focus of menu bar when escape key is pressed.
|
|
// This prevents the menubar from hi-jacking keyboard input focus
|
|
// when using menu accelerators
|
|
if ( event->key() == Qt::Key_Escape )
|
|
{
|
|
((QWidget*)parent())->setFocus();
|
|
}
|
|
event->accept();
|
|
}
|
|
|
|
void consoleMenuBar::keyReleaseEvent(QKeyEvent *event)
|
|
{
|
|
QMenuBar::keyReleaseEvent(event);
|
|
|
|
pushKeyEvent( event, 0 );
|
|
|
|
event->accept();
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
consoleRecentRomAction::consoleRecentRomAction(QString desc, QWidget *parent)
|
|
: QAction( desc, parent )
|
|
{
|
|
QString txt;
|
|
QFileInfo fi(desc);
|
|
|
|
path = desc.toLocal8Bit().constData();
|
|
|
|
txt = fi.fileName();
|
|
txt += QString("\t");
|
|
txt += desc;
|
|
|
|
setText( txt );
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
consoleRecentRomAction::~consoleRecentRomAction(void)
|
|
{
|
|
//printf("Recent ROM Menu Action Deleted\n");
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
void consoleRecentRomAction::activateCB(void)
|
|
{
|
|
printf("Activate Recent ROM: %s \n", path.c_str() );
|
|
|
|
FCEU_WRAPPER_LOCK();
|
|
CloseGame ();
|
|
LoadGame ( path.c_str() );
|
|
FCEU_WRAPPER_UNLOCK();
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
autoFireMenuAction::autoFireMenuAction(int on, int off, QString name, QWidget *parent)
|
|
: QAction( name, parent)
|
|
{
|
|
onFrames = on; offFrames = off;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
autoFireMenuAction::~autoFireMenuAction(void)
|
|
{
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void autoFireMenuAction::activateCB(void)
|
|
{
|
|
g_config->setOption("SDL.AutofireOnFrames" , onFrames );
|
|
g_config->setOption("SDL.AutofireOffFrames" , offFrames);
|
|
g_config->save();
|
|
|
|
SetAutoFirePattern( onFrames, offFrames );
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
bool autoFireMenuAction::isMatch( int on, int off )
|
|
{
|
|
return ( (on == onFrames) && (off == offFrames) );
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void autoFireMenuAction::setPattern(int on, int off)
|
|
{
|
|
onFrames = on; offFrames = off;
|
|
}
|
|
//-----------------------------------------------------------------------------
|