For Qt GUI fixed region auto detection logic to preserve dendy mode if an NTSC game is loaded. Also, added an option to enable/disable region auto detection functionality. This allows for the users selection via the GUI to be strictly enforced. Also, added a region select sub menu to the emulation main menu. Fixes issue #335.

This commit is contained in:
mjbudd77 2021-02-25 19:36:08 -05:00
parent 67c6386688
commit ffc7e70b0d
8 changed files with 188 additions and 9 deletions

View File

@ -125,6 +125,7 @@ void FCEUI_SetVidSystem(int a);
//Set variables for NTSC(0) / PAL(1) / Dendy(2) //Set variables for NTSC(0) / PAL(1) / Dendy(2)
//Dendy has PAL framerate and resolution, but ~NTSC timings, and has 50 dummy scanlines to force 50 fps //Dendy has PAL framerate and resolution, but ~NTSC timings, and has 50 dummy scanlines to force 50 fps
void FCEUI_SetRegion(int region, int notify = 1); void FCEUI_SetRegion(int region, int notify = 1);
int FCEUI_GetRegion(void);
//Convenience function; returns currently emulated video system(0=NTSC, 1=PAL). //Convenience function; returns currently emulated video system(0=NTSC, 1=PAL).
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend); int FCEUI_GetCurrentVidSystem(int *slstart, int *slend);

View File

@ -140,6 +140,9 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
vbox1->addLayout( hbox1 ); vbox1->addLayout( hbox1 );
// Enable Region Auto Detection Logic
autoRegion = new QCheckBox( tr("Region Auto Detect") );
// Enable New PPU Checkbox // Enable New PPU Checkbox
new_PPU_ena = new QCheckBox( tr("Enable New PPU") ); new_PPU_ena = new QCheckBox( tr("Enable New PPU") );
@ -161,6 +164,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
// Square Pixels // Square Pixels
sqrPixCbx = new QCheckBox( tr("Square Pixels") ); sqrPixCbx = new QCheckBox( tr("Square Pixels") );
setCheckBoxFromProperty( autoRegion , "SDL.AutoDetectPAL");
setCheckBoxFromProperty( new_PPU_ena , "SDL.NewPPU"); setCheckBoxFromProperty( new_PPU_ena , "SDL.NewPPU");
setCheckBoxFromProperty( frmskipcbx , "SDL.Frameskip"); setCheckBoxFromProperty( frmskipcbx , "SDL.Frameskip");
setCheckBoxFromProperty( sprtLimCbx , "SDL.DisableSpriteLimit"); setCheckBoxFromProperty( sprtLimCbx , "SDL.DisableSpriteLimit");
@ -181,6 +185,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
} }
} }
connect(autoRegion , SIGNAL(stateChanged(int)), this, SLOT(autoRegionChanged(int)) );
connect(new_PPU_ena , SIGNAL(stateChanged(int)), this, SLOT(use_new_PPU_changed(int)) ); connect(new_PPU_ena , SIGNAL(stateChanged(int)), this, SLOT(use_new_PPU_changed(int)) );
connect(frmskipcbx , SIGNAL(stateChanged(int)), this, SLOT(frameskip_changed(int)) ); connect(frmskipcbx , SIGNAL(stateChanged(int)), this, SLOT(frameskip_changed(int)) );
connect(sprtLimCbx , SIGNAL(stateChanged(int)), this, SLOT(useSpriteLimitChanged(int)) ); connect(sprtLimCbx , SIGNAL(stateChanged(int)), this, SLOT(useSpriteLimitChanged(int)) );
@ -189,6 +194,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
connect(sqrPixCbx , SIGNAL(stateChanged(int)), this, SLOT(sqrPixChanged(int)) ); connect(sqrPixCbx , SIGNAL(stateChanged(int)), this, SLOT(sqrPixChanged(int)) );
connect(autoScaleCbx, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)) ); connect(autoScaleCbx, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)) );
vbox1->addWidget( autoRegion );
vbox1->addWidget( new_PPU_ena ); vbox1->addWidget( new_PPU_ena );
vbox1->addWidget( frmskipcbx ); vbox1->addWidget( frmskipcbx );
vbox1->addWidget( sprtLimCbx ); vbox1->addWidget( sprtLimCbx );
@ -387,6 +393,18 @@ void ConsoleVideoConfDialog_t::closeEvent(QCloseEvent *event)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void ConsoleVideoConfDialog_t::periodicUpdate(void) void ConsoleVideoConfDialog_t::periodicUpdate(void)
{ {
int actRegion, selRegion;
// Keep region menu selection sync'd to actual state
actRegion = FCEUI_GetRegion();
selRegion = regionSelect->currentIndex();
if ( actRegion != selRegion )
{
regionSelect->setCurrentIndex(actRegion);
}
// Update Window Size Readouts
updateReadouts(); updateReadouts();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -577,6 +595,13 @@ void ConsoleVideoConfDialog_t::autoScaleChanged( int value )
} }
} }
//----------------------------------------------------
void ConsoleVideoConfDialog_t::autoRegionChanged( int value )
{
//printf("Value:%i \n", value );
g_config->setOption("SDL.AutoDetectPAL", (value == Qt::Checked) );
g_config->save ();
}
//---------------------------------------------------- //----------------------------------------------------
void ConsoleVideoConfDialog_t::use_new_PPU_changed( int value ) void ConsoleVideoConfDialog_t::use_new_PPU_changed( int value )
{ {
@ -682,18 +707,21 @@ void ConsoleVideoConfDialog_t::scalerChanged(int index)
void ConsoleVideoConfDialog_t::regionChanged(int index) void ConsoleVideoConfDialog_t::regionChanged(int index)
{ {
int region; int region;
int actRegion = FCEUI_GetRegion();
//printf("Region: %i : %i \n", index, regionSelect->itemData(index).toInt() ); //printf("Region: %i : %i \n", index, regionSelect->itemData(index).toInt() );
region = regionSelect->itemData(index).toInt(); region = regionSelect->itemData(index).toInt();
g_config->setOption ("SDL.PAL", region); g_config->setOption ("SDL.PAL", region);
g_config->save (); g_config->save ();
// reset sound subsystem for changes to take effect // reset sound subsystem for changes to take effect
if ( actRegion != region )
{
fceuWrapperLock(); fceuWrapperLock();
FCEUI_SetRegion (region, true); FCEUI_SetRegion (region, true);
fceuWrapperUnLock(); fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
QSize ConsoleVideoConfDialog_t::calcNewScreenSize(void) QSize ConsoleVideoConfDialog_t::calcNewScreenSize(void)

View File

@ -33,6 +33,7 @@ class ConsoleVideoConfDialog_t : public QDialog
QComboBox *driverSelect; QComboBox *driverSelect;
QComboBox *scalerSelect; QComboBox *scalerSelect;
QComboBox *regionSelect; QComboBox *regionSelect;
QCheckBox *autoRegion;
QCheckBox *gl_LF_chkBox; QCheckBox *gl_LF_chkBox;
QCheckBox *new_PPU_ena; QCheckBox *new_PPU_ena;
QCheckBox *frmskipcbx; QCheckBox *frmskipcbx;
@ -65,6 +66,7 @@ class ConsoleVideoConfDialog_t : public QDialog
private slots: private slots:
void periodicUpdate(void); void periodicUpdate(void);
void autoRegionChanged( int value );
void openGL_linearFilterChanged( int value ); void openGL_linearFilterChanged( int value );
void autoScaleChanged( int value ); void autoScaleChanged( int value );
void sqrPixChanged( int value ); void sqrPixChanged( int value );

View File

@ -183,6 +183,7 @@ consoleWin_t::consoleWin_t(QWidget *parent)
this->showFullScreen(); this->showFullScreen();
} }
updateCounter = 0;
recentRomMenuReset = false; recentRomMenuReset = false;
} }
@ -679,6 +680,43 @@ void consoleWin_t::createMainMenu(void)
emuMenu->addSeparator(); 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)) );
emuMenu->addSeparator();
// Emulation -> Enable Game Genie // Emulation -> Enable Game Genie
gameGenieAct = new QAction(tr("Enable Game &Genie"), this); gameGenieAct = new QAction(tr("Enable Game &Genie"), this);
//gameGenieAct->setShortcut( QKeySequence(tr("Ctrl+G"))); //gameGenieAct->setShortcut( QKeySequence(tr("Ctrl+G")));
@ -1953,6 +1991,42 @@ void consoleWin_t::consolePause(void)
return; return;
} }
void consoleWin_t::setRegion(int region)
{
int currentRegion;
g_config->setOption ("SDL.PAL", region);
g_config->save ();
currentRegion = FCEUI_GetRegion();
if ( currentRegion != region )
{
fceuWrapperLock();
FCEUI_SetRegion (region, true);
fceuWrapperUnLock();
}
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::toggleGameGenie(bool checked) void consoleWin_t::toggleGameGenie(bool checked)
{ {
int gg_enabled; int gg_enabled;
@ -2567,6 +2641,18 @@ void consoleWin_t::updatePeriodic(void)
} }
} }
// Low Rate Updates
if ( (updateCounter % 20) == 0 )
{
// Keep region menu selection sync'd to actual state
int actRegion = FCEUI_GetRegion();
if ( !region[ actRegion ]->isChecked() )
{
region[ actRegion ]->setChecked(true);
}
}
if ( errorMsgValid ) if ( errorMsgValid )
{ {
showErrorMsgWindow(); showErrorMsgWindow();
@ -2587,6 +2673,8 @@ void consoleWin_t::updatePeriodic(void)
closeRequested = false; closeRequested = false;
} }
updateCounter++;
return; return;
} }

View File

@ -180,6 +180,7 @@ class consoleWin_t : public QMainWindow
QAction *stopMovAct; QAction *stopMovAct;
QAction *recMovAct; QAction *recMovAct;
QAction *recAsMovAct; QAction *recAsMovAct;
QAction *region[3];
QTimer *gameTimer; QTimer *gameTimer;
@ -190,6 +191,7 @@ class consoleWin_t : public QMainWindow
std::list <std::string*> romList; std::list <std::string*> romList;
unsigned int updateCounter;
protected: protected:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
void keyPressEvent(QKeyEvent *event); void keyPressEvent(QKeyEvent *event);
@ -202,6 +204,7 @@ class consoleWin_t : public QMainWindow
void buildRecentRomMenu(void); void buildRecentRomMenu(void);
void saveRecentRomMenu(void); void saveRecentRomMenu(void);
void clearRomList(void); void clearRomList(void);
void setRegion(int region);
public slots: public slots:
void openDebugWindow(void); void openDebugWindow(void);
@ -254,6 +257,9 @@ class consoleWin_t : public QMainWindow
void consolePause(void); void consolePause(void);
void toggleGameGenie(bool checked); void toggleGameGenie(bool checked);
void loadGameGenieROM(void); void loadGameGenieROM(void);
void setRegionNTSC(void);
void setRegionPAL(void);
void setRegionDendy(void);
void insertCoin(void); void insertCoin(void);
void fdsSwitchDisk(void); void fdsSwitchDisk(void);
void fdsEjectDisk(void); void fdsEjectDisk(void);

View File

@ -229,6 +229,7 @@ InitConfig()
config->addOption('g', "gamegenie", "SDL.GameGenie", 0); config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
config->addOption("pal", "SDL.PAL", 0); config->addOption("pal", "SDL.PAL", 0);
config->addOption("autoPal", "SDL.AutoDetectPAL", 1);
config->addOption("frameskip", "SDL.Frameskip", 0); config->addOption("frameskip", "SDL.Frameskip", 0);
config->addOption("clipsides", "SDL.ClipSides", 0); config->addOption("clipsides", "SDL.ClipSides", 0);
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1); config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);

View File

@ -313,10 +313,43 @@ int LoadGame(const char *path, bool silent)
} }
// set pal/ntsc // set pal/ntsc
int id; int id, region, autoDetectPAL;
g_config->getOption("SDL.PAL", &region);
g_config->getOption("SDL.AutoDetectPAL", &autoDetectPAL);
if ( autoDetectPAL )
{
id = FCEUI_GetCurrentVidSystem(NULL, NULL); id = FCEUI_GetCurrentVidSystem(NULL, NULL);
if ( region == 2 )
{ // Dendy mode:
// Run PAL Games as PAL
// Run NTSC Games as Dendy
if ( id == 1 )
{
g_config->setOption("SDL.PAL", id); g_config->setOption("SDL.PAL", id);
FCEUI_SetRegion(id); FCEUI_SetRegion(id);
}
else
{
FCEUI_SetRegion(region);
}
}
else
{ // Run NTSC games as NTSC and PAL games as PAL
g_config->setOption("SDL.PAL", id);
FCEUI_SetRegion(id);
}
}
else
{
// If not Auto-detection of region,
// Strictly enforce region GUI selection
// Does not matter what type of game is
// loaded, the current region selection is used
FCEUI_SetRegion(region);
}
g_config->getOption("SDL.SwapDuty", &id); g_config->getOption("SDL.SwapDuty", &id);
swapDuty = id; swapDuty = id;

View File

@ -1073,7 +1073,27 @@ int FCEUI_GetCurrentVidSystem(int *slstart, int *slend) {
return(PAL); return(PAL);
} }
void FCEUI_SetRegion(int region, int notify) { int FCEUI_GetRegion(void)
{
int region;
if ( pal_emulation )
{
region = 1;
}
else if ( dendy )
{
region = 2;
}
else
{
region = 0;
}
return region;
}
void FCEUI_SetRegion(int region, int notify)
{
switch (region) { switch (region) {
case 0: // NTSC case 0: // NTSC
normalscanlines = 240; normalscanlines = 240;