Added input device selection/configuration window for Qt GUI. Still TODO, button config windows for non-gamepad devices.

This commit is contained in:
Matthew Budd 2020-11-23 13:50:26 -05:00
parent 30b3a92c38
commit 396029743a
7 changed files with 421 additions and 1 deletions

View File

@ -427,6 +427,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleWindow.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerGL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerSDL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/InputConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/PaletteConf.cpp

View File

@ -20,6 +20,7 @@
#include "Qt/dface.h"
#include "Qt/input.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/InputConf.h"
#include "Qt/GamePadConf.h"
#include "Qt/HotKeyConf.h"
#include "Qt/PaletteConf.h"
@ -347,6 +348,14 @@ void consoleWin_t::createMainMenu(void)
// Options
optMenu = menuBar()->addMenu(tr("Options"));
// Options -> Input Config
gamePadConfig = new QAction(tr("Input Config"), this);
//gamePadConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
gamePadConfig->setStatusTip(tr("Input Configure"));
connect(gamePadConfig, SIGNAL(triggered()), this, SLOT(openInputConfWin(void)) );
optMenu->addAction(gamePadConfig);
// Options -> GamePad Config
gamePadConfig = new QAction(tr("GamePad Config"), this);
//gamePadConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
@ -1174,6 +1183,13 @@ void consoleWin_t::loadLua(void)
#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");

View File

@ -130,6 +130,7 @@ class consoleWin_t : public QMainWindow
public slots:
void openDebugWindow(void);
void openHexEditor(void);
void openGamePadConfWin(void);
private slots:
void closeApp(void);
void openROMFile(void);
@ -141,7 +142,7 @@ class consoleWin_t : public QMainWindow
void closeROMCB(void);
void aboutFCEUX(void);
void aboutQt(void);
void openGamePadConfWin(void);
void openInputConfWin(void);
void openGameSndConfWin(void);
void openGameVideoConfWin(void);
void openHotkeyConfWin(void);

View File

@ -0,0 +1,321 @@
// InputConf.cpp
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <SDL.h>
#include <QHeaderView>
#include <QCloseEvent>
#include <QGroupBox>
#include "Qt/main.h"
#include "Qt/dface.h"
#include "Qt/input.h"
#include "Qt/config.h"
#include "Qt/keyscan.h"
#include "Qt/fceuWrapper.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/InputConf.h"
static InputConfDialog_t *win = NULL;
//----------------------------------------------------------------------------
void openInputConfWindow( QWidget *parent )
{
if ( win != NULL )
{
return;
}
win = new InputConfDialog_t(parent);
win->show();
}
//----------------------------------------------------------------------------
InputConfDialog_t::InputConfDialog_t(QWidget *parent)
: QDialog( parent )
{
QVBoxLayout *mainLayout, *vbox1, *vbox;
QHBoxLayout *hbox;
QGroupBox *nesInputFrame, *port1Frame, *port2Frame;
QGroupBox *presetFrame, *expansionPortFrame;
QPalette pal;
QColor color;
char stmp[256];
pal = this->palette();
setWindowTitle("Input Configuration");
mainLayout = new QVBoxLayout();
nesInputFrame = new QGroupBox( tr("NES-Style Input Ports") );
vbox1 = new QVBoxLayout();
hbox = new QHBoxLayout();
fourScoreEna = new QCheckBox( tr("Attach 4-Score (Implies four gamepads)") );
port2Mic = new QCheckBox( tr("Replace Port 2 Start with Microphone") );
hbox->addWidget( fourScoreEna );
hbox->addWidget( port2Mic );
vbox1->addLayout( hbox );
hbox = new QHBoxLayout();
port1Frame = new QGroupBox( tr("Port 1:") );
port2Frame = new QGroupBox( tr("Port 2:") );
hbox->addWidget( port1Frame );
hbox->addWidget( port2Frame );
vbox1->addLayout( hbox );
nesPortComboxBox[0] = new QComboBox();
nesPortComboxBox[1] = new QComboBox();
expPortComboxBox = new QComboBox();
vbox = new QVBoxLayout();
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
hbox->addWidget( nesPortLabel[0] = new QLabel( tr("<None>") ) );
hbox->addWidget( nesPortConfButton[0] = new QPushButton( tr("Configure") ) );
vbox->addWidget( nesPortComboxBox[0] );
port1Frame->setLayout( vbox );
vbox = new QVBoxLayout();
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
hbox->addWidget( nesPortLabel[1] = new QLabel( tr("<None>") ) );
hbox->addWidget( nesPortConfButton[1] = new QPushButton( tr("Configure") ) );
vbox->addWidget( nesPortComboxBox[1] );
port2Frame->setLayout( vbox );
nesInputFrame->setLayout( vbox1 );
nesPortConfButton[0]->setEnabled(false);
nesPortConfButton[1]->setEnabled(false);
mainLayout->addWidget( nesInputFrame );
hbox = new QHBoxLayout();
presetFrame = new QGroupBox( tr("Input Presets:") );
expansionPortFrame = new QGroupBox( tr("Famicom Expansion Port:") );
hbox->addWidget( presetFrame );
hbox->addWidget( expansionPortFrame );
mainLayout->addLayout( hbox );
vbox = new QVBoxLayout();
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
hbox->addWidget( expPortLabel = new QLabel( tr("<None>") ) );
hbox->addWidget( expPortConfButton = new QPushButton( tr("Configure") ) );
vbox->addWidget( expPortComboxBox );
expPortConfButton->setEnabled(false);
expansionPortFrame->setLayout( vbox );
color = pal.color(QPalette::WindowText);
sprintf( stmp, "border: 2px solid #%02X%02X%02X", color.red(), color.green(), color.blue() );
printf("%s\n", stmp);
nesPortLabel[0]->setAlignment(Qt::AlignCenter);
nesPortLabel[1]->setAlignment(Qt::AlignCenter);
expPortLabel->setAlignment(Qt::AlignCenter);
nesPortLabel[0]->setStyleSheet( stmp );
nesPortLabel[1]->setStyleSheet( stmp );
expPortLabel->setStyleSheet( stmp );
setLayout( mainLayout );
for (int i=0; i<2; i++)
{
getInputSelection( i, &curNesInput[i], &usrNesInput[i] );
nesPortComboxBox[i]->addItem( tr("<None>") , SI_NONE );
nesPortComboxBox[i]->addItem( tr("Gamepad") , SI_GAMEPAD );
nesPortComboxBox[i]->addItem( tr("Zapper") , SI_ZAPPER );
nesPortComboxBox[i]->addItem( tr("Power Pad A") , SI_POWERPADA );
nesPortComboxBox[i]->addItem( tr("Power Pad B") , SI_POWERPADB );
nesPortComboxBox[i]->addItem( tr("Arkanoid Paddle") , SI_ARKANOID );
for (int j=0; j<nesPortComboxBox[i]->count(); j++)
{
if ( nesPortComboxBox[i]->itemData(j).toInt() == usrNesInput[i] )
{
nesPortComboxBox[i]->setCurrentIndex( j );
}
if ( nesPortComboxBox[i]->itemData(j).toInt() == curNesInput[i] )
{
nesPortLabel[i]->setText( nesPortComboxBox[i]->itemText(j) );
}
}
}
getInputSelection( 2, &curNesInput[2], &usrNesInput[2] );
expPortComboxBox->addItem( tr("<None>") , SIFC_NONE );
expPortComboxBox->addItem( tr("Arkanoid Paddle") , SIFC_ARKANOID );
expPortComboxBox->addItem( tr("Shadow") , SIFC_SHADOW );
expPortComboxBox->addItem( tr("Hyper Shot Gun") , SIFC_HYPERSHOT );
expPortComboxBox->addItem( tr("Family Keyboard") , SIFC_FKB );
expPortComboxBox->addItem( tr("Mahjong") , SIFC_MAHJONG );
expPortComboxBox->addItem( tr("Quiz King Buzzers"), SIFC_QUIZKING );
expPortComboxBox->addItem( tr("Family Trainer A") , SIFC_FTRAINERA );
expPortComboxBox->addItem( tr("Family Trainer B") , SIFC_FTRAINERB );
expPortComboxBox->addItem( tr("Oeka Kids Tablet") , SIFC_OEKAKIDS );
expPortComboxBox->addItem( tr("Top Rider") , SIFC_TOPRIDER );
for (int j=0; j<expPortComboxBox->count(); j++)
{
if ( expPortComboxBox->itemData(j).toInt() == usrNesInput[2] )
{
expPortComboxBox->setCurrentIndex( j );
}
if ( expPortComboxBox->itemData(j).toInt() == curNesInput[2] )
{
expPortLabel->setText( expPortComboxBox->itemText(j) );
}
}
connect( nesPortComboxBox[0], SIGNAL(activated(int)), this, SLOT(port1Select(int)) );
connect( nesPortComboxBox[1], SIGNAL(activated(int)), this, SLOT(port2Select(int)) );
connect( expPortComboxBox , SIGNAL(activated(int)), this, SLOT(expSelect(int)) );
connect( nesPortConfButton[0], SIGNAL(clicked(void)), this, SLOT(port1Configure(void)) );
connect( nesPortConfButton[1], SIGNAL(clicked(void)), this, SLOT(port2Configure(void)) );
updatePortLabels();
}
//----------------------------------------------------------------------------
InputConfDialog_t::~InputConfDialog_t(void)
{
printf("Destroy Input Config Window\n");
if ( win == this )
{
win = NULL;
}
}
//----------------------------------------------------------------------------
void InputConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("Hot Key Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void InputConfDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void InputConfDialog_t::setInputs(void)
{
int idx[3];
ESI port[2];
ESIFC fcexp;
int fourscore = false, microphone = false;
g_config->getOption("SDL.FourScore", &fourscore);
idx[0] = nesPortComboxBox[0]->currentIndex();
idx[1] = nesPortComboxBox[1]->currentIndex();
idx[2] = expPortComboxBox->currentIndex();
port[0] = (ESI)nesPortComboxBox[0]->itemData( idx[0] ).toInt();
port[1] = (ESI)nesPortComboxBox[1]->itemData( idx[1] ).toInt();
fcexp = (ESIFC)expPortComboxBox->itemData( idx[2] ).toInt();
FCEUD_SetInput( fourscore, microphone, port[0], port[1], fcexp );
}
//----------------------------------------------------------------------------
void InputConfDialog_t::updatePortLabels(void)
{
for (int i=0; i<2; i++)
{
getInputSelection( i, &curNesInput[i], &usrNesInput[i] );
for (int j=0; j<nesPortComboxBox[i]->count(); j++)
{
if ( nesPortComboxBox[i]->itemData(j).toInt() == curNesInput[i] )
{
nesPortLabel[i]->setText( nesPortComboxBox[i]->itemText(j) );
}
}
nesPortConfButton[i]->setEnabled( curNesInput[i] == SI_GAMEPAD );
}
getInputSelection( 2, &curNesInput[2], &usrNesInput[2] );
for (int j=0; j<expPortComboxBox->count(); j++)
{
if ( expPortComboxBox->itemData(j).toInt() == curNesInput[2] )
{
expPortLabel->setText( expPortComboxBox->itemText(j) );
}
}
}
//----------------------------------------------------------------------------
void InputConfDialog_t::port1Select(int index)
{
//printf("Port 1 Number:%i \n", index);
setInputs();
updatePortLabels();
}
//----------------------------------------------------------------------------
void InputConfDialog_t::port2Select(int index)
{
//printf("Port 2 Number:%i \n", index);
setInputs();
updatePortLabels();
}
//----------------------------------------------------------------------------
void InputConfDialog_t::expSelect(int index)
{
//printf("Expansion Port Number:%i \n", index);
setInputs();
updatePortLabels();
}
//----------------------------------------------------------------------------
void InputConfDialog_t::openPortConfig(int portNum)
{
switch ( curNesInput[portNum] )
{
default:
case SI_NONE:
case SI_ZAPPER:
// Do Nothing
break;
case SI_GAMEPAD:
consoleWindow->openGamePadConfWin();
break;
}
}
//----------------------------------------------------------------------------
void InputConfDialog_t::port1Configure(void)
{
openPortConfig(0);
}
//----------------------------------------------------------------------------
void InputConfDialog_t::port2Configure(void)
{
openPortConfig(1);
}
//----------------------------------------------------------------------------
//void InputConfDialog_t::keyPressEvent(QKeyEvent *event)
//{
// //printf("Hotkey Window Key Press: 0x%x \n", event->key() );
//}
////----------------------------------------------------------------------------
//void InputConfDialog_t::keyReleaseEvent(QKeyEvent *event)
//{
// //printf("Hotkey Window Key Release: 0x%x \n", event->key() );
//}
//----------------------------------------------------------------------------

View File

@ -0,0 +1,62 @@
// InputConf.h
//
#pragma once
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QFrame>
#include <QGroupBox>
#include <QTreeView>
#include <QTreeWidget>
#include "Qt/main.h"
class InputConfDialog_t : public QDialog
{
Q_OBJECT
public:
InputConfDialog_t(QWidget *parent = 0);
~InputConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
//void keyPressEvent(QKeyEvent *event);
//void keyReleaseEvent(QKeyEvent *event);
QCheckBox *fourScoreEna;
QCheckBox *port2Mic;
QLabel *nesPortLabel[2];
QPushButton *nesPortConfButton[2];
QComboBox *nesPortComboxBox[2];
QLabel *expPortLabel;
QPushButton *expPortConfButton;
QComboBox *expPortComboxBox;
int curNesInput[3];
int usrNesInput[3];
private:
void setInputs(void);
void updatePortLabels(void);
void openPortConfig(int portNum);
public slots:
void closeWindow(void);
private slots:
void port1Configure(void);
void port2Configure(void);
void port1Select(int index);
void port2Select(int index);
void expSelect(int index);
};
void openInputConfWindow( QWidget *parent );

View File

@ -98,6 +98,22 @@ ParseGIInput (FCEUGI * gi)
cspec = gi->cspecial;
}
int getInputSelection( int port, int *cur, int *usr )
{
if ( (port >= 0) && (port < 3) )
{
if ( cur )
{
*cur = CurInputType[port];
}
if ( usr )
{
*usr = UsrInputType[port];
}
}
return 0;
}
static uint8 QuizKingData = 0;
static uint8 HyperShotData = 0;

View File

@ -78,5 +78,8 @@ void UpdateInput(Config *config);
std::string GetUserText(const char* title);
const char* ButtonName(const ButtConfig* bc);
int getInputSelection( int port, int *cur, int *usr );
#endif