Add an option to automatically map controller buttons
This uses SDL's GameController API to map buttons to the DS ones automatically based on their controller database.
This commit is contained in:
parent
d6d820c013
commit
79dc510366
|
@ -103,6 +103,7 @@ DefaultList<bool> DefaultBools =
|
|||
{"Emu.DirectBoot", true},
|
||||
{"Instance*.DS.Battery.LevelOkay", true},
|
||||
{"Instance*.DSi.Battery.Charging", true},
|
||||
{"Instance*.Joystick.AutoMap", true},
|
||||
#ifdef JIT_ENABLED
|
||||
{"JIT.BranchOptimisations", true},
|
||||
{"JIT.LiteralOptimisations", true},
|
||||
|
|
|
@ -146,6 +146,7 @@ public:
|
|||
void setJoystick(int id);
|
||||
int getJoystickID() { return joystickID; }
|
||||
SDL_Joystick* getJoystick() { return joystick; }
|
||||
bool autoJoystickMapping;
|
||||
|
||||
void touchScreen(int x, int y);
|
||||
void releaseScreen();
|
||||
|
|
|
@ -40,6 +40,24 @@ const char* EmuInstance::buttonNames[12] =
|
|||
"Y"
|
||||
};
|
||||
|
||||
SDL_GameControllerButton sdlButtons[12] =
|
||||
{
|
||||
// SDL uses A/B for south/east, X/Y for west/north, opposite of the DS
|
||||
// so we swap the buttons so they map to where they are on the DS positionally
|
||||
SDL_CONTROLLER_BUTTON_B,
|
||||
SDL_CONTROLLER_BUTTON_A,
|
||||
SDL_CONTROLLER_BUTTON_BACK,
|
||||
SDL_CONTROLLER_BUTTON_START,
|
||||
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
|
||||
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
|
||||
SDL_CONTROLLER_BUTTON_DPAD_UP,
|
||||
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
|
||||
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
|
||||
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
|
||||
SDL_CONTROLLER_BUTTON_Y,
|
||||
SDL_CONTROLLER_BUTTON_X
|
||||
};
|
||||
|
||||
const char* EmuInstance::hotkeyNames[HK_MAX] =
|
||||
{
|
||||
"HK_Lid",
|
||||
|
@ -107,6 +125,8 @@ void EmuInstance::inputLoadConfig()
|
|||
hkJoyMapping[i] = joycfg.GetInt(hotkeyNames[i]);
|
||||
}
|
||||
|
||||
autoJoystickMapping = joycfg.GetBool("AutoMap");
|
||||
|
||||
setJoystick(localCfg.GetInt("JoystickID"));
|
||||
}
|
||||
|
||||
|
@ -335,7 +355,14 @@ void EmuInstance::inputProcess()
|
|||
}
|
||||
|
||||
joyInputMask = 0xFFF;
|
||||
if (joystick)
|
||||
|
||||
if (autoJoystickMapping && controller != nullptr)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
if (SDL_GameControllerGetButton(controller, sdlButtons[i]))
|
||||
joyInputMask &= ~(1 << i);
|
||||
}
|
||||
else if (joystick)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
if (joystickButtonDown(joyMapping[i]))
|
||||
|
|
|
@ -94,6 +94,8 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
|
|||
ui->cbxJoystick->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->cbAutoMap->setChecked(joycfg.GetBool("AutoMap"));
|
||||
|
||||
setupKeypadPage();
|
||||
|
||||
int inst = emuInstance->getInstanceID();
|
||||
|
@ -124,7 +126,7 @@ void InputConfigDialog::setupKeypadPage()
|
|||
delete pushButtonKey;
|
||||
delete pushButtonJoy;
|
||||
|
||||
if (ui->cbxJoystick->isEnabled())
|
||||
if (ui->cbxJoystick->isEnabled() && !ui->cbAutoMap->isChecked())
|
||||
{
|
||||
ui->stackMapping->setCurrentIndex(1);
|
||||
}
|
||||
|
@ -214,6 +216,7 @@ void InputConfigDialog::on_InputConfigDialog_accepted()
|
|||
}
|
||||
|
||||
instcfg.SetInt("JoystickID", joystickID);
|
||||
joycfg.SetBool("AutoMap", ui->cbAutoMap->isChecked());
|
||||
Config::Save();
|
||||
|
||||
emuInstance->inputLoadConfig();
|
||||
|
@ -246,6 +249,25 @@ void InputConfigDialog::on_cbxJoystick_currentIndexChanged(int id)
|
|||
|
||||
joystickID = id;
|
||||
emuInstance->setJoystick(id);
|
||||
setJoyMappingEnabled(ui->cbAutoMap->isChecked());
|
||||
}
|
||||
|
||||
void InputConfigDialog::on_cbAutoMap_checkStateChanged(Qt::CheckState state)
|
||||
{
|
||||
setJoyMappingEnabled(state);
|
||||
}
|
||||
|
||||
void InputConfigDialog::setJoyMappingEnabled(bool enable)
|
||||
{
|
||||
if (enable && SDL_IsGameController(emuInstance->getJoystickID()))
|
||||
{
|
||||
ui->stackMapping->setCurrentIndex(0);
|
||||
ui->btnJoyMapSwitch->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->btnJoyMapSwitch->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Joystick* InputConfigDialog::getJoystick()
|
||||
|
|
|
@ -123,6 +123,7 @@ private slots:
|
|||
void on_btnKeyMapSwitch_clicked();
|
||||
void on_btnJoyMapSwitch_clicked();
|
||||
void on_cbxJoystick_currentIndexChanged(int id);
|
||||
void on_cbAutoMap_checkStateChanged(Qt::CheckState state);
|
||||
|
||||
private:
|
||||
void populatePage(QWidget* page,
|
||||
|
@ -130,6 +131,8 @@ private:
|
|||
int* keymap, int* joymap);
|
||||
void setupKeypadPage();
|
||||
|
||||
void setJoyMappingEnabled(bool enabled);
|
||||
|
||||
Ui::InputConfigDialog* ui;
|
||||
|
||||
EmuInstance* emuInstance;
|
||||
|
|
|
@ -2280,7 +2280,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -2293,7 +2293,20 @@
|
|||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="cbxJoystick">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>Selects which joystick will be used for joystick input, if any is present.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
|
@ -2306,16 +2319,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbxJoystick">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="cbAutoMap">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Automatically map joystick buttons to their closest equivalents on the DS for controllers that are known to SDL's game controller database.</p><p>The joystick mappings page will be disabled when automatic mapping is in effect.</p></body></html></string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>Selects which joystick will be used for joystick input, if any is present.</p></body></html></string>
|
||||
<property name="text">
|
||||
<string>Automatically map joystick buttons</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -298,6 +298,9 @@ int main(int argc, char** argv)
|
|||
|
||||
// http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
// Use position-based button mapping instead of label-based
|
||||
// Needed to make auto mapping map the face buttons correctly regardless of layout
|
||||
SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0");
|
||||
|
||||
SDL_SetHint(SDL_HINT_APP_NAME, "melonDS");
|
||||
|
||||
|
|
Loading…
Reference in New Issue