port input subsystem
This commit is contained in:
parent
daf981e7c2
commit
d50f01b774
|
@ -9,6 +9,7 @@ set(SOURCES_QT_SDL
|
||||||
Window.cpp
|
Window.cpp
|
||||||
EmuInstance.cpp
|
EmuInstance.cpp
|
||||||
EmuInstanceAudio.cpp
|
EmuInstanceAudio.cpp
|
||||||
|
EmuInstanceInput.cpp
|
||||||
EmuThread.cpp
|
EmuThread.cpp
|
||||||
CheatsDialog.cpp
|
CheatsDialog.cpp
|
||||||
Config.cpp
|
Config.cpp
|
||||||
|
@ -30,7 +31,6 @@ set(SOURCES_QT_SDL
|
||||||
ROMInfoDialog.cpp
|
ROMInfoDialog.cpp
|
||||||
RAMInfoDialog.cpp
|
RAMInfoDialog.cpp
|
||||||
TitleManagerDialog.cpp
|
TitleManagerDialog.cpp
|
||||||
Input.cpp
|
|
||||||
LAN_PCap.cpp
|
LAN_PCap.cpp
|
||||||
LAN_Socket.cpp
|
LAN_Socket.cpp
|
||||||
LocalMP.cpp
|
LocalMP.cpp
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "FrontendUtil.h"
|
#include "FrontendUtil.h"
|
||||||
#include "Screen.h"
|
#include "main.h"
|
||||||
|
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
@ -37,14 +37,6 @@ namespace Config
|
||||||
{
|
{
|
||||||
using namespace melonDS;
|
using namespace melonDS;
|
||||||
|
|
||||||
int KeyMapping[12];
|
|
||||||
int JoyMapping[12];
|
|
||||||
|
|
||||||
int HKKeyMapping[HK_MAX];
|
|
||||||
int HKJoyMapping[HK_MAX];
|
|
||||||
|
|
||||||
int JoystickID;
|
|
||||||
|
|
||||||
int WindowWidth;
|
int WindowWidth;
|
||||||
int WindowHeight;
|
int WindowHeight;
|
||||||
bool WindowMaximized;
|
bool WindowMaximized;
|
||||||
|
|
|
@ -35,45 +35,6 @@ class value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
HK_Lid = 0,
|
|
||||||
HK_Mic,
|
|
||||||
HK_Pause,
|
|
||||||
HK_Reset,
|
|
||||||
HK_FastForward,
|
|
||||||
HK_FastForwardToggle,
|
|
||||||
HK_FullscreenToggle,
|
|
||||||
HK_SwapScreens,
|
|
||||||
HK_SwapScreenEmphasis,
|
|
||||||
HK_SolarSensorDecrease,
|
|
||||||
HK_SolarSensorIncrease,
|
|
||||||
HK_FrameStep,
|
|
||||||
HK_PowerButton,
|
|
||||||
HK_VolumeUp,
|
|
||||||
HK_VolumeDown,
|
|
||||||
HK_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
micInputType_Silence,
|
|
||||||
micInputType_External,
|
|
||||||
micInputType_Noise,
|
|
||||||
micInputType_Wav,
|
|
||||||
micInputType_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
renderer3D_Software = 0,
|
|
||||||
#ifdef OGLRENDERER_ENABLED
|
|
||||||
renderer3D_OpenGL,
|
|
||||||
renderer3D_OpenGLCompute,
|
|
||||||
#endif
|
|
||||||
renderer3D_Max,
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Config
|
namespace Config
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -188,14 +149,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern int KeyMapping[12];
|
|
||||||
extern int JoyMapping[12];
|
|
||||||
|
|
||||||
extern int HKKeyMapping[HK_MAX];
|
|
||||||
extern int HKJoyMapping[HK_MAX];
|
|
||||||
|
|
||||||
extern int JoystickID;
|
|
||||||
|
|
||||||
extern int WindowWidth;
|
extern int WindowWidth;
|
||||||
extern int WindowHeight;
|
extern int WindowHeight;
|
||||||
extern bool WindowMaximized;
|
extern bool WindowMaximized;
|
||||||
|
|
|
@ -72,6 +72,7 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
|
||||||
updateConsole(nullptr, nullptr);
|
updateConsole(nullptr, nullptr);
|
||||||
|
|
||||||
audioInit();
|
audioInit();
|
||||||
|
inputInit();
|
||||||
|
|
||||||
emuThread = new EmuThread(this);
|
emuThread = new EmuThread(this);
|
||||||
|
|
||||||
|
@ -96,6 +97,7 @@ EmuInstance::~EmuInstance()
|
||||||
delete emuThread;
|
delete emuThread;
|
||||||
|
|
||||||
audioDeInit();
|
audioDeInit();
|
||||||
|
inputDeInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,48 @@
|
||||||
|
|
||||||
const int kMaxWindows = 16;
|
const int kMaxWindows = 16;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HK_Lid = 0,
|
||||||
|
HK_Mic,
|
||||||
|
HK_Pause,
|
||||||
|
HK_Reset,
|
||||||
|
HK_FastForward,
|
||||||
|
HK_FastForwardToggle,
|
||||||
|
HK_FullscreenToggle,
|
||||||
|
HK_SwapScreens,
|
||||||
|
HK_SwapScreenEmphasis,
|
||||||
|
HK_SolarSensorDecrease,
|
||||||
|
HK_SolarSensorIncrease,
|
||||||
|
HK_FrameStep,
|
||||||
|
HK_PowerButton,
|
||||||
|
HK_VolumeUp,
|
||||||
|
HK_VolumeDown,
|
||||||
|
HK_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
micInputType_Silence,
|
||||||
|
micInputType_External,
|
||||||
|
micInputType_Noise,
|
||||||
|
micInputType_Wav,
|
||||||
|
micInputType_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
renderer3D_Software = 0,
|
||||||
|
#ifdef OGLRENDERER_ENABLED
|
||||||
|
renderer3D_OpenGL,
|
||||||
|
renderer3D_OpenGLCompute,
|
||||||
|
#endif
|
||||||
|
renderer3D_Max,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isRightModKey(QKeyEvent* event);
|
||||||
|
int getEventKeyVal(QKeyEvent* event);
|
||||||
|
|
||||||
class EmuInstance
|
class EmuInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -61,6 +103,17 @@ public:
|
||||||
melonDS::u32 (&animatedIconRef)[64][32*32],
|
melonDS::u32 (&animatedIconRef)[64][32*32],
|
||||||
std::vector<int> &animatedSequenceRef);
|
std::vector<int> &animatedSequenceRef);
|
||||||
|
|
||||||
|
static const char* buttonNames[12];
|
||||||
|
static const char* hotkeyNames[HK_MAX];
|
||||||
|
|
||||||
|
void inputInit();
|
||||||
|
void inputDeInit();
|
||||||
|
void inputLoadConfig();
|
||||||
|
|
||||||
|
void setJoystick(int id);
|
||||||
|
int getJoystickID() { return joystickID; }
|
||||||
|
SDL_Joystick* getJoystick() { return joystick; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int lastSep(const std::string& path);
|
static int lastSep(const std::string& path);
|
||||||
std::string getAssetPath(bool gba, const std::string& configpath, const std::string& ext, const std::string& file);
|
std::string getAssetPath(bool gba, const std::string& configpath, const std::string& ext, const std::string& file);
|
||||||
|
@ -130,6 +183,20 @@ private:
|
||||||
static void audioCallback(void* data, Uint8* stream, int len);
|
static void audioCallback(void* data, Uint8* stream, int len);
|
||||||
static void micCallback(void* data, Uint8* stream, int len);
|
static void micCallback(void* data, Uint8* stream, int len);
|
||||||
|
|
||||||
|
void onKeyPress(QKeyEvent* event);
|
||||||
|
void onKeyRelease(QKeyEvent* event);
|
||||||
|
void keyReleaseAll();
|
||||||
|
|
||||||
|
void openJoystick();
|
||||||
|
void closeJoystick();
|
||||||
|
bool joystickButtonDown(int val);
|
||||||
|
|
||||||
|
void inputProcess();
|
||||||
|
|
||||||
|
bool hotkeyDown(int id) { return hotkeyMask & (1<<id); }
|
||||||
|
bool hotkeyPressed(int id) { return hotkeyPress & (1<<id); }
|
||||||
|
bool hotkeyReleased(int id) { return hotkeyRelease & (1<<id); }
|
||||||
|
|
||||||
int instanceID;
|
int instanceID;
|
||||||
|
|
||||||
EmuThread* emuThread;
|
EmuThread* emuThread;
|
||||||
|
@ -192,6 +259,21 @@ private:
|
||||||
std::string micDeviceName;
|
std::string micDeviceName;
|
||||||
std::string micWavPath;
|
std::string micWavPath;
|
||||||
|
|
||||||
|
int keyMapping[12];
|
||||||
|
int joyMapping[12];
|
||||||
|
int hkKeyMapping[HK_MAX];
|
||||||
|
int hkJoyMapping[HK_MAX];
|
||||||
|
|
||||||
|
int joystickID;
|
||||||
|
SDL_Joystick* joystick;
|
||||||
|
|
||||||
|
melonDS::u32 keyInputMask, joyInputMask;
|
||||||
|
melonDS::u32 keyHotkeyMask, joyHotkeyMask;
|
||||||
|
melonDS::u32 hotkeyMask, lastHotkeyMask;
|
||||||
|
melonDS::u32 hotkeyPress, hotkeyRelease;
|
||||||
|
|
||||||
|
melonDS::u32 inputMask;
|
||||||
|
|
||||||
friend class EmuThread;
|
friend class EmuThread;
|
||||||
friend class MainWindow;
|
friend class MainWindow;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "SPU.h"
|
#include "SPU.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Input.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include "mic_blow.h"
|
#include "mic_blow.h"
|
||||||
|
@ -265,7 +264,7 @@ void EmuInstance::micLoadWav(const std::string& name)
|
||||||
void EmuInstance::micProcess()
|
void EmuInstance::micProcess()
|
||||||
{
|
{
|
||||||
int type = micInputType;
|
int type = micInputType;
|
||||||
bool cmd = Input::HotkeyDown(HK_Mic);
|
bool cmd = hotkeyDown(HK_Mic);
|
||||||
|
|
||||||
if (type != micInputType_External && !cmd)
|
if (type != micInputType_External && !cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,307 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016-2023 melonDS team
|
||||||
|
|
||||||
|
This file is part of melonDS.
|
||||||
|
|
||||||
|
melonDS 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 3 of the License, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
using namespace melonDS;
|
||||||
|
|
||||||
|
const char* EmuInstance::buttonNames[12] =
|
||||||
|
{
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"Select",
|
||||||
|
"Start",
|
||||||
|
"Right",
|
||||||
|
"Left",
|
||||||
|
"Up",
|
||||||
|
"Down",
|
||||||
|
"R",
|
||||||
|
"L",
|
||||||
|
"X",
|
||||||
|
"Y"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* EmuInstance::hotkeyNames[HK_MAX] =
|
||||||
|
{
|
||||||
|
"HK_Lid",
|
||||||
|
"HK_Mic",
|
||||||
|
"HK_Pause",
|
||||||
|
"HK_Reset",
|
||||||
|
"HK_FastForward",
|
||||||
|
"HK_FastForwardToggle",
|
||||||
|
"HK_FullscreenToggle",
|
||||||
|
"HK_SwapScreens",
|
||||||
|
"HK_SwapScreenEmphasis",
|
||||||
|
"HK_SolarSensorDecrease",
|
||||||
|
"HK_SolarSensorIncrease",
|
||||||
|
"HK_FrameStep",
|
||||||
|
"HK_PowerButton",
|
||||||
|
"HK_VolumeUp",
|
||||||
|
"HK_VolumeDown"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void EmuInstance::inputInit()
|
||||||
|
{
|
||||||
|
keyInputMask = 0xFFF;
|
||||||
|
joyInputMask = 0xFFF;
|
||||||
|
inputMask = 0xFFF;
|
||||||
|
|
||||||
|
keyHotkeyMask = 0;
|
||||||
|
joyHotkeyMask = 0;
|
||||||
|
hotkeyMask = 0;
|
||||||
|
lastHotkeyMask = 0;
|
||||||
|
|
||||||
|
joystick = nullptr;
|
||||||
|
inputLoadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::inputDeInit()
|
||||||
|
{
|
||||||
|
closeJoystick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::inputLoadConfig()
|
||||||
|
{
|
||||||
|
Config::Table keycfg = localCfg.GetTable("Keyboard");
|
||||||
|
Config::Table joycfg = localCfg.GetTable("Joystick");
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
keyMapping[i] = keycfg.GetInt(buttonNames[i]);
|
||||||
|
joyMapping[i] = joycfg.GetInt(buttonNames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < HK_MAX; i++)
|
||||||
|
{
|
||||||
|
hkKeyMapping[i] = keycfg.GetInt(hotkeyNames[i]);
|
||||||
|
hkJoyMapping[i] = joycfg.GetInt(hotkeyNames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setJoystick(localCfg.GetInt("JoystickID"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EmuInstance::setJoystick(int id)
|
||||||
|
{
|
||||||
|
joystickID = id;
|
||||||
|
openJoystick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::openJoystick()
|
||||||
|
{
|
||||||
|
if (joystick) SDL_JoystickClose(joystick);
|
||||||
|
|
||||||
|
int num = SDL_NumJoysticks();
|
||||||
|
if (num < 1)
|
||||||
|
{
|
||||||
|
joystick = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joystickID >= num)
|
||||||
|
joystickID = 0;
|
||||||
|
|
||||||
|
joystick = SDL_JoystickOpen(joystickID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::closeJoystick()
|
||||||
|
{
|
||||||
|
if (joystick)
|
||||||
|
{
|
||||||
|
SDL_JoystickClose(joystick);
|
||||||
|
joystick = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// distinguish between left and right modifier keys (Ctrl, Alt, Shift)
|
||||||
|
// Qt provides no real cross-platform way to do this, so here we go
|
||||||
|
// for Windows and Linux we can distinguish via scancodes (but both
|
||||||
|
// provide different scancodes)
|
||||||
|
bool isRightModKey(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
#ifdef __WIN32__
|
||||||
|
quint32 scan = event->nativeScanCode();
|
||||||
|
return (scan == 0x11D || scan == 0x138 || scan == 0x36);
|
||||||
|
#elif __APPLE__
|
||||||
|
quint32 scan = event->nativeVirtualKey();
|
||||||
|
return (scan == 0x36 || scan == 0x3C || scan == 0x3D || scan == 0x3E);
|
||||||
|
#else
|
||||||
|
quint32 scan = event->nativeScanCode();
|
||||||
|
return (scan == 0x69 || scan == 0x6C || scan == 0x3E);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int getEventKeyVal(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
int key = event->key();
|
||||||
|
int mod = event->modifiers();
|
||||||
|
bool ismod = (key == Qt::Key_Control ||
|
||||||
|
key == Qt::Key_Alt ||
|
||||||
|
key == Qt::Key_AltGr ||
|
||||||
|
key == Qt::Key_Shift ||
|
||||||
|
key == Qt::Key_Meta);
|
||||||
|
|
||||||
|
if (!ismod)
|
||||||
|
key |= mod;
|
||||||
|
else if (isRightModKey(event))
|
||||||
|
key |= (1<<31);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EmuInstance::onKeyPress(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
int keyHK = getEventKeyVal(event);
|
||||||
|
int keyKP = keyHK;
|
||||||
|
if (event->modifiers() != Qt::KeypadModifier)
|
||||||
|
keyKP &= ~event->modifiers();
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
if (keyKP == keyMapping[i])
|
||||||
|
keyInputMask &= ~(1<<i);
|
||||||
|
|
||||||
|
for (int i = 0; i < HK_MAX; i++)
|
||||||
|
if (keyHK == hkKeyMapping[i])
|
||||||
|
keyHotkeyMask |= (1<<i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::onKeyRelease(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
int keyHK = getEventKeyVal(event);
|
||||||
|
int keyKP = keyHK;
|
||||||
|
if (event->modifiers() != Qt::KeypadModifier)
|
||||||
|
keyKP &= ~event->modifiers();
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
if (keyKP == keyMapping[i])
|
||||||
|
keyInputMask |= (1<<i);
|
||||||
|
|
||||||
|
for (int i = 0; i < HK_MAX; i++)
|
||||||
|
if (keyHK == hkKeyMapping[i])
|
||||||
|
keyHotkeyMask &= ~(1<<i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::keyReleaseAll()
|
||||||
|
{
|
||||||
|
keyInputMask = 0xFFF;
|
||||||
|
keyHotkeyMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmuInstance::joystickButtonDown(int val)
|
||||||
|
{
|
||||||
|
if (val == -1) return false;
|
||||||
|
|
||||||
|
bool hasbtn = ((val & 0xFFFF) != 0xFFFF);
|
||||||
|
|
||||||
|
if (hasbtn)
|
||||||
|
{
|
||||||
|
if (val & 0x100)
|
||||||
|
{
|
||||||
|
int hatnum = (val >> 4) & 0xF;
|
||||||
|
int hatdir = val & 0xF;
|
||||||
|
Uint8 hatval = SDL_JoystickGetHat(joystick, hatnum);
|
||||||
|
|
||||||
|
bool pressed = false;
|
||||||
|
if (hatdir == 0x1) pressed = (hatval & SDL_HAT_UP);
|
||||||
|
else if (hatdir == 0x4) pressed = (hatval & SDL_HAT_DOWN);
|
||||||
|
else if (hatdir == 0x2) pressed = (hatval & SDL_HAT_RIGHT);
|
||||||
|
else if (hatdir == 0x8) pressed = (hatval & SDL_HAT_LEFT);
|
||||||
|
|
||||||
|
if (pressed) return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int btnnum = val & 0xFFFF;
|
||||||
|
Uint8 btnval = SDL_JoystickGetButton(joystick, btnnum);
|
||||||
|
|
||||||
|
if (btnval) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val & 0x10000)
|
||||||
|
{
|
||||||
|
int axisnum = (val >> 24) & 0xF;
|
||||||
|
int axisdir = (val >> 20) & 0xF;
|
||||||
|
Sint16 axisval = SDL_JoystickGetAxis(joystick, axisnum);
|
||||||
|
|
||||||
|
switch (axisdir)
|
||||||
|
{
|
||||||
|
case 0: // positive
|
||||||
|
if (axisval > 16384) return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // negative
|
||||||
|
if (axisval < -16384) return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // trigger
|
||||||
|
if (axisval > 0) return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuInstance::inputProcess()
|
||||||
|
{
|
||||||
|
SDL_JoystickUpdate();
|
||||||
|
|
||||||
|
if (joystick)
|
||||||
|
{
|
||||||
|
if (!SDL_JoystickGetAttached(joystick))
|
||||||
|
{
|
||||||
|
SDL_JoystickClose(joystick);
|
||||||
|
joystick = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!joystick && (SDL_NumJoysticks() > 0))
|
||||||
|
{
|
||||||
|
openJoystick();
|
||||||
|
}
|
||||||
|
|
||||||
|
joyInputMask = 0xFFF;
|
||||||
|
if (joystick)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
if (joystickButtonDown(joyMapping[i]))
|
||||||
|
joyInputMask &= ~(1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
inputMask = keyInputMask & joyInputMask;
|
||||||
|
|
||||||
|
joyHotkeyMask = 0;
|
||||||
|
if (joystick)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < HK_MAX; i++)
|
||||||
|
if (joystickButtonDown(hkJoyMapping[i]))
|
||||||
|
joyHotkeyMask |= (1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
hotkeyMask = keyHotkeyMask | joyHotkeyMask;
|
||||||
|
hotkeyPress = hotkeyMask & ~lastHotkeyMask;
|
||||||
|
hotkeyRelease = lastHotkeyMask & ~hotkeyMask;
|
||||||
|
lastHotkeyMask = hotkeyMask;
|
||||||
|
}
|
|
@ -29,7 +29,6 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "Input.h"
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -172,8 +171,6 @@ void EmuThread::run()
|
||||||
|
|
||||||
updateRenderer();
|
updateRenderer();
|
||||||
|
|
||||||
Input::Init();
|
|
||||||
|
|
||||||
u32 nframes = 0;
|
u32 nframes = 0;
|
||||||
double perfCountsSec = 1.0 / SDL_GetPerformanceFrequency();
|
double perfCountsSec = 1.0 / SDL_GetPerformanceFrequency();
|
||||||
double lastTime = SDL_GetPerformanceCounter() * perfCountsSec;
|
double lastTime = SDL_GetPerformanceCounter() * perfCountsSec;
|
||||||
|
@ -196,25 +193,25 @@ void EmuThread::run()
|
||||||
|
|
||||||
while (EmuRunning != emuStatus_Exit)
|
while (EmuRunning != emuStatus_Exit)
|
||||||
{
|
{
|
||||||
Input::Process();
|
emuInstance->inputProcess();
|
||||||
|
|
||||||
if (Input::HotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange();
|
if (emuInstance->hotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange();
|
||||||
|
|
||||||
if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause();
|
if (emuInstance->hotkeyPressed(HK_Pause)) emit windowEmuPause();
|
||||||
if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset();
|
if (emuInstance->hotkeyPressed(HK_Reset)) emit windowEmuReset();
|
||||||
if (Input::HotkeyPressed(HK_FrameStep)) emit windowEmuFrameStep();
|
if (emuInstance->hotkeyPressed(HK_FrameStep)) emit windowEmuFrameStep();
|
||||||
|
|
||||||
if (Input::HotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle();
|
if (emuInstance->hotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle();
|
||||||
|
|
||||||
if (Input::HotkeyPressed(HK_SwapScreens)) emit swapScreensToggle();
|
if (emuInstance->hotkeyPressed(HK_SwapScreens)) emit swapScreensToggle();
|
||||||
if (Input::HotkeyPressed(HK_SwapScreenEmphasis)) emit screenEmphasisToggle();
|
if (emuInstance->hotkeyPressed(HK_SwapScreenEmphasis)) emit screenEmphasisToggle();
|
||||||
|
|
||||||
if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep)
|
if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep)
|
||||||
{
|
{
|
||||||
EmuStatus = emuStatus_Running;
|
EmuStatus = emuStatus_Running;
|
||||||
if (EmuRunning == emuStatus_FrameStep) EmuRunning = emuStatus_Paused;
|
if (EmuRunning == emuStatus_FrameStep) EmuRunning = emuStatus_Paused;
|
||||||
|
|
||||||
if (Input::HotkeyPressed(HK_SolarSensorDecrease))
|
if (emuInstance->hotkeyPressed(HK_SolarSensorDecrease))
|
||||||
{
|
{
|
||||||
int level = emuInstance->nds->GBACartSlot.SetInput(GBACart::Input_SolarSensorDown, true);
|
int level = emuInstance->nds->GBACartSlot.SetInput(GBACart::Input_SolarSensorDown, true);
|
||||||
if (level != -1)
|
if (level != -1)
|
||||||
|
@ -222,7 +219,7 @@ void EmuThread::run()
|
||||||
//mainWindow->osdAddMessage(0, "Solar sensor level: %d", level);
|
//mainWindow->osdAddMessage(0, "Solar sensor level: %d", level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Input::HotkeyPressed(HK_SolarSensorIncrease))
|
if (emuInstance->hotkeyPressed(HK_SolarSensorIncrease))
|
||||||
{
|
{
|
||||||
int level = emuInstance->nds->GBACartSlot.SetInput(GBACart::Input_SolarSensorUp, true);
|
int level = emuInstance->nds->GBACartSlot.SetInput(GBACart::Input_SolarSensorUp, true);
|
||||||
if (level != -1)
|
if (level != -1)
|
||||||
|
@ -237,30 +234,30 @@ void EmuThread::run()
|
||||||
double currentTime = SDL_GetPerformanceCounter() * perfCountsSec;
|
double currentTime = SDL_GetPerformanceCounter() * perfCountsSec;
|
||||||
|
|
||||||
// Handle power button
|
// Handle power button
|
||||||
if (Input::HotkeyDown(HK_PowerButton))
|
if (emuInstance->hotkeyDown(HK_PowerButton))
|
||||||
{
|
{
|
||||||
dsi->I2C.GetBPTWL()->SetPowerButtonHeld(currentTime);
|
dsi->I2C.GetBPTWL()->SetPowerButtonHeld(currentTime);
|
||||||
}
|
}
|
||||||
else if (Input::HotkeyReleased(HK_PowerButton))
|
else if (emuInstance->hotkeyReleased(HK_PowerButton))
|
||||||
{
|
{
|
||||||
dsi->I2C.GetBPTWL()->SetPowerButtonReleased(currentTime);
|
dsi->I2C.GetBPTWL()->SetPowerButtonReleased(currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle volume buttons
|
// Handle volume buttons
|
||||||
if (Input::HotkeyDown(HK_VolumeUp))
|
if (emuInstance->hotkeyDown(HK_VolumeUp))
|
||||||
{
|
{
|
||||||
dsi->I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Up);
|
dsi->I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Up);
|
||||||
}
|
}
|
||||||
else if (Input::HotkeyReleased(HK_VolumeUp))
|
else if (emuInstance->hotkeyReleased(HK_VolumeUp))
|
||||||
{
|
{
|
||||||
dsi->I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Up);
|
dsi->I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Up);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input::HotkeyDown(HK_VolumeDown))
|
if (emuInstance->hotkeyDown(HK_VolumeDown))
|
||||||
{
|
{
|
||||||
dsi->I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Down);
|
dsi->I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Down);
|
||||||
}
|
}
|
||||||
else if (Input::HotkeyReleased(HK_VolumeDown))
|
else if (emuInstance->hotkeyReleased(HK_VolumeDown))
|
||||||
{
|
{
|
||||||
dsi->I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Down);
|
dsi->I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Down);
|
||||||
}
|
}
|
||||||
|
@ -275,7 +272,7 @@ void EmuThread::run()
|
||||||
// HACK:
|
// HACK:
|
||||||
// once the fast forward hotkey is released, we need to update vsync
|
// once the fast forward hotkey is released, we need to update vsync
|
||||||
// to the old setting again
|
// to the old setting again
|
||||||
if (videoSettingsDirty || Input::HotkeyReleased(HK_FastForward))
|
if (videoSettingsDirty || emuInstance->hotkeyReleased(HK_FastForward))
|
||||||
{
|
{
|
||||||
if (useOpenGL)
|
if (useOpenGL)
|
||||||
{
|
{
|
||||||
|
@ -297,9 +294,9 @@ void EmuThread::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// process input and hotkeys
|
// process input and hotkeys
|
||||||
emuInstance->nds->SetKeyMask(Input::InputMask);
|
emuInstance->nds->SetKeyMask(emuInstance->inputMask);
|
||||||
|
|
||||||
if (Input::HotkeyPressed(HK_Lid))
|
if (emuInstance->hotkeyPressed(HK_Lid))
|
||||||
{
|
{
|
||||||
bool lid = !emuInstance->nds->IsLidClosed();
|
bool lid = !emuInstance->nds->IsLidClosed();
|
||||||
emuInstance->nds->SetLidClosed(lid);
|
emuInstance->nds->SetLidClosed(lid);
|
||||||
|
@ -388,7 +385,7 @@ void EmuThread::run()
|
||||||
winUpdateCount = 0;
|
winUpdateCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fastforward = Input::HotkeyDown(HK_FastForward);
|
bool fastforward = emuInstance->hotkeyDown(HK_FastForward);
|
||||||
|
|
||||||
if (fastforward && useOpenGL && Config::ScreenVSync)
|
if (fastforward && useOpenGL && Config::ScreenVSync)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,265 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016-2023 melonDS team
|
|
||||||
|
|
||||||
This file is part of melonDS.
|
|
||||||
|
|
||||||
melonDS 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 3 of the License, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
#include "Input.h"
|
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
using namespace melonDS;
|
|
||||||
|
|
||||||
namespace Input
|
|
||||||
{
|
|
||||||
|
|
||||||
int JoystickID;
|
|
||||||
SDL_Joystick* Joystick = nullptr;
|
|
||||||
|
|
||||||
u32 KeyInputMask, JoyInputMask;
|
|
||||||
u32 KeyHotkeyMask, JoyHotkeyMask;
|
|
||||||
u32 HotkeyMask, LastHotkeyMask;
|
|
||||||
u32 HotkeyPress, HotkeyRelease;
|
|
||||||
|
|
||||||
u32 InputMask;
|
|
||||||
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
KeyInputMask = 0xFFF;
|
|
||||||
JoyInputMask = 0xFFF;
|
|
||||||
InputMask = 0xFFF;
|
|
||||||
|
|
||||||
KeyHotkeyMask = 0;
|
|
||||||
JoyHotkeyMask = 0;
|
|
||||||
HotkeyMask = 0;
|
|
||||||
LastHotkeyMask = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OpenJoystick()
|
|
||||||
{
|
|
||||||
if (Joystick) SDL_JoystickClose(Joystick);
|
|
||||||
|
|
||||||
int num = SDL_NumJoysticks();
|
|
||||||
if (num < 1)
|
|
||||||
{
|
|
||||||
Joystick = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JoystickID >= num)
|
|
||||||
JoystickID = 0;
|
|
||||||
|
|
||||||
Joystick = SDL_JoystickOpen(JoystickID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseJoystick()
|
|
||||||
{
|
|
||||||
if (Joystick)
|
|
||||||
{
|
|
||||||
SDL_JoystickClose(Joystick);
|
|
||||||
Joystick = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int GetEventKeyVal(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
int key = event->key();
|
|
||||||
int mod = event->modifiers();
|
|
||||||
bool ismod = (key == Qt::Key_Control ||
|
|
||||||
key == Qt::Key_Alt ||
|
|
||||||
key == Qt::Key_AltGr ||
|
|
||||||
key == Qt::Key_Shift ||
|
|
||||||
key == Qt::Key_Meta);
|
|
||||||
|
|
||||||
if (!ismod)
|
|
||||||
key |= mod;
|
|
||||||
else if (Input::IsRightModKey(event))
|
|
||||||
key |= (1<<31);
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyPress(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
int keyHK = GetEventKeyVal(event);
|
|
||||||
int keyKP = keyHK;
|
|
||||||
if (event->modifiers() != Qt::KeypadModifier)
|
|
||||||
keyKP &= ~event->modifiers();
|
|
||||||
|
|
||||||
for (int i = 0; i < 12; i++)
|
|
||||||
if (keyKP == Config::KeyMapping[i])
|
|
||||||
KeyInputMask &= ~(1<<i);
|
|
||||||
|
|
||||||
for (int i = 0; i < HK_MAX; i++)
|
|
||||||
if (keyHK == Config::HKKeyMapping[i])
|
|
||||||
KeyHotkeyMask |= (1<<i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyRelease(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
int keyHK = GetEventKeyVal(event);
|
|
||||||
int keyKP = keyHK;
|
|
||||||
if (event->modifiers() != Qt::KeypadModifier)
|
|
||||||
keyKP &= ~event->modifiers();
|
|
||||||
|
|
||||||
for (int i = 0; i < 12; i++)
|
|
||||||
if (keyKP == Config::KeyMapping[i])
|
|
||||||
KeyInputMask |= (1<<i);
|
|
||||||
|
|
||||||
for (int i = 0; i < HK_MAX; i++)
|
|
||||||
if (keyHK == Config::HKKeyMapping[i])
|
|
||||||
KeyHotkeyMask &= ~(1<<i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyReleaseAll()
|
|
||||||
{
|
|
||||||
KeyInputMask = 0xFFF;
|
|
||||||
KeyHotkeyMask = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JoystickButtonDown(int val)
|
|
||||||
{
|
|
||||||
if (val == -1) return false;
|
|
||||||
|
|
||||||
bool hasbtn = ((val & 0xFFFF) != 0xFFFF);
|
|
||||||
|
|
||||||
if (hasbtn)
|
|
||||||
{
|
|
||||||
if (val & 0x100)
|
|
||||||
{
|
|
||||||
int hatnum = (val >> 4) & 0xF;
|
|
||||||
int hatdir = val & 0xF;
|
|
||||||
Uint8 hatval = SDL_JoystickGetHat(Joystick, hatnum);
|
|
||||||
|
|
||||||
bool pressed = false;
|
|
||||||
if (hatdir == 0x1) pressed = (hatval & SDL_HAT_UP);
|
|
||||||
else if (hatdir == 0x4) pressed = (hatval & SDL_HAT_DOWN);
|
|
||||||
else if (hatdir == 0x2) pressed = (hatval & SDL_HAT_RIGHT);
|
|
||||||
else if (hatdir == 0x8) pressed = (hatval & SDL_HAT_LEFT);
|
|
||||||
|
|
||||||
if (pressed) return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int btnnum = val & 0xFFFF;
|
|
||||||
Uint8 btnval = SDL_JoystickGetButton(Joystick, btnnum);
|
|
||||||
|
|
||||||
if (btnval) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0x10000)
|
|
||||||
{
|
|
||||||
int axisnum = (val >> 24) & 0xF;
|
|
||||||
int axisdir = (val >> 20) & 0xF;
|
|
||||||
Sint16 axisval = SDL_JoystickGetAxis(Joystick, axisnum);
|
|
||||||
|
|
||||||
switch (axisdir)
|
|
||||||
{
|
|
||||||
case 0: // positive
|
|
||||||
if (axisval > 16384) return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // negative
|
|
||||||
if (axisval < -16384) return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // trigger
|
|
||||||
if (axisval > 0) return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Process()
|
|
||||||
{
|
|
||||||
SDL_JoystickUpdate();
|
|
||||||
|
|
||||||
if (Joystick)
|
|
||||||
{
|
|
||||||
if (!SDL_JoystickGetAttached(Joystick))
|
|
||||||
{
|
|
||||||
SDL_JoystickClose(Joystick);
|
|
||||||
Joystick = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Joystick && (SDL_NumJoysticks() > 0))
|
|
||||||
{
|
|
||||||
JoystickID = Config::JoystickID;
|
|
||||||
OpenJoystick();
|
|
||||||
}
|
|
||||||
|
|
||||||
JoyInputMask = 0xFFF;
|
|
||||||
if (Joystick)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 12; i++)
|
|
||||||
if (JoystickButtonDown(Config::JoyMapping[i]))
|
|
||||||
JoyInputMask &= ~(1 << i);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputMask = KeyInputMask & JoyInputMask;
|
|
||||||
|
|
||||||
JoyHotkeyMask = 0;
|
|
||||||
if (Joystick)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < HK_MAX; i++)
|
|
||||||
if (JoystickButtonDown(Config::HKJoyMapping[i]))
|
|
||||||
JoyHotkeyMask |= (1 << i);
|
|
||||||
}
|
|
||||||
|
|
||||||
HotkeyMask = KeyHotkeyMask | JoyHotkeyMask;
|
|
||||||
HotkeyPress = HotkeyMask & ~LastHotkeyMask;
|
|
||||||
HotkeyRelease = LastHotkeyMask & ~HotkeyMask;
|
|
||||||
LastHotkeyMask = HotkeyMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool HotkeyDown(int id) { return HotkeyMask & (1<<id); }
|
|
||||||
bool HotkeyPressed(int id) { return HotkeyPress & (1<<id); }
|
|
||||||
bool HotkeyReleased(int id) { return HotkeyRelease & (1<<id); }
|
|
||||||
|
|
||||||
|
|
||||||
// distinguish between left and right modifier keys (Ctrl, Alt, Shift)
|
|
||||||
// Qt provides no real cross-platform way to do this, so here we go
|
|
||||||
// for Windows and Linux we can distinguish via scancodes (but both
|
|
||||||
// provide different scancodes)
|
|
||||||
#ifdef __WIN32__
|
|
||||||
bool IsRightModKey(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
quint32 scan = event->nativeScanCode();
|
|
||||||
return (scan == 0x11D || scan == 0x138 || scan == 0x36);
|
|
||||||
}
|
|
||||||
#elif __APPLE__
|
|
||||||
bool IsRightModKey(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
quint32 scan = event->nativeVirtualKey();
|
|
||||||
return (scan == 0x36 || scan == 0x3C || scan == 0x3D || scan == 0x3E);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bool IsRightModKey(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
quint32 scan = event->nativeScanCode();
|
|
||||||
return (scan == 0x69 || scan == 0x6C || scan == 0x3E);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016-2023 melonDS team
|
|
||||||
|
|
||||||
This file is part of melonDS.
|
|
||||||
|
|
||||||
melonDS 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 3 of the License, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INPUT_H
|
|
||||||
#define INPUT_H
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
namespace Input
|
|
||||||
{
|
|
||||||
|
|
||||||
using namespace melonDS;
|
|
||||||
extern int JoystickID;
|
|
||||||
extern SDL_Joystick* Joystick;
|
|
||||||
|
|
||||||
extern u32 InputMask;
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
// set joystickID before calling openJoystick()
|
|
||||||
void OpenJoystick();
|
|
||||||
void CloseJoystick();
|
|
||||||
|
|
||||||
void KeyPress(QKeyEvent* event);
|
|
||||||
void KeyRelease(QKeyEvent* event);
|
|
||||||
void KeyReleaseAll();
|
|
||||||
|
|
||||||
void Process();
|
|
||||||
|
|
||||||
bool HotkeyDown(int id);
|
|
||||||
bool HotkeyPressed(int id);
|
|
||||||
bool HotkeyReleased(int id);
|
|
||||||
|
|
||||||
bool IsRightModKey(QKeyEvent* event);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // INPUT_H
|
|
|
@ -26,10 +26,9 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
|
||||||
#include "MapButton.h"
|
|
||||||
#include "Input.h"
|
|
||||||
#include "InputConfigDialog.h"
|
#include "InputConfigDialog.h"
|
||||||
#include "ui_InputConfigDialog.h"
|
#include "ui_InputConfigDialog.h"
|
||||||
|
#include "MapButton.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace melonDS;
|
using namespace melonDS;
|
||||||
|
@ -43,31 +42,42 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
emuInstance = ((MainWindow*)parent)->getEmuInstance();
|
||||||
|
|
||||||
|
Config::Table& instcfg = emuInstance->getLocalConfig();
|
||||||
|
Config::Table keycfg = instcfg.GetTable("Keyboard");
|
||||||
|
Config::Table joycfg = instcfg.GetTable("Joystick");
|
||||||
|
|
||||||
for (int i = 0; i < keypad_num; i++)
|
for (int i = 0; i < keypad_num; i++)
|
||||||
{
|
{
|
||||||
keypadKeyMap[i] = Config::KeyMapping[dskeyorder[i]];
|
const char* btn = EmuInstance::buttonNames[dskeyorder[i]];
|
||||||
keypadJoyMap[i] = Config::JoyMapping[dskeyorder[i]];
|
keypadKeyMap[i] = keycfg.GetInt(btn);
|
||||||
|
keypadJoyMap[i] = joycfg.GetInt(btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int hotkey : hk_addons)
|
for (int hotkey : hk_addons)
|
||||||
{
|
{
|
||||||
addonsKeyMap[i] = Config::HKKeyMapping[hotkey];
|
const char* btn = EmuInstance::hotkeyNames[hotkey];
|
||||||
addonsJoyMap[i] = Config::HKJoyMapping[hotkey];
|
addonsKeyMap[i] = keycfg.GetInt(btn);
|
||||||
|
addonsJoyMap[i] = joycfg.GetInt(btn);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (int hotkey : hk_general)
|
for (int hotkey : hk_general)
|
||||||
{
|
{
|
||||||
hkGeneralKeyMap[i] = Config::HKKeyMapping[hotkey];
|
const char* btn = EmuInstance::hotkeyNames[hotkey];
|
||||||
hkGeneralJoyMap[i] = Config::HKJoyMapping[hotkey];
|
hkGeneralKeyMap[i] = keycfg.GetInt(btn);
|
||||||
|
hkGeneralJoyMap[i] = joycfg.GetInt(btn);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
populatePage(ui->tabAddons, hk_addons_labels, addonsKeyMap, addonsJoyMap);
|
populatePage(ui->tabAddons, hk_addons_labels, addonsKeyMap, addonsJoyMap);
|
||||||
populatePage(ui->tabHotkeysGeneral, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap);
|
populatePage(ui->tabHotkeysGeneral, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap);
|
||||||
|
|
||||||
|
joystickID = instcfg.GetInt("JoystickID");
|
||||||
|
|
||||||
int njoy = SDL_NumJoysticks();
|
int njoy = SDL_NumJoysticks();
|
||||||
if (njoy > 0)
|
if (njoy > 0)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +86,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
|
||||||
const char* name = SDL_JoystickNameForIndex(i);
|
const char* name = SDL_JoystickNameForIndex(i);
|
||||||
ui->cbxJoystick->addItem(QString(name));
|
ui->cbxJoystick->addItem(QString(name));
|
||||||
}
|
}
|
||||||
ui->cbxJoystick->setCurrentIndex(Input::JoystickID);
|
ui->cbxJoystick->setCurrentIndex(joystickID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -86,7 +96,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
|
||||||
|
|
||||||
setupKeypadPage();
|
setupKeypadPage();
|
||||||
|
|
||||||
int inst = Platform::InstanceID();
|
int inst = emuInstance->getInstanceID();
|
||||||
if (inst > 0)
|
if (inst > 0)
|
||||||
ui->lblInstanceNum->setText(QString("Configuring mappings for instance %1").arg(inst+1));
|
ui->lblInstanceNum->setText(QString("Configuring mappings for instance %1").arg(inst+1));
|
||||||
else
|
else
|
||||||
|
@ -174,38 +184,47 @@ void InputConfigDialog::populatePage(QWidget* page,
|
||||||
|
|
||||||
void InputConfigDialog::on_InputConfigDialog_accepted()
|
void InputConfigDialog::on_InputConfigDialog_accepted()
|
||||||
{
|
{
|
||||||
|
Config::Table& instcfg = emuInstance->getLocalConfig();
|
||||||
|
Config::Table keycfg = instcfg.GetTable("Keyboard");
|
||||||
|
Config::Table joycfg = instcfg.GetTable("Joystick");
|
||||||
|
|
||||||
for (int i = 0; i < keypad_num; i++)
|
for (int i = 0; i < keypad_num; i++)
|
||||||
{
|
{
|
||||||
Config::KeyMapping[dskeyorder[i]] = keypadKeyMap[i];
|
const char* btn = EmuInstance::buttonNames[dskeyorder[i]];
|
||||||
Config::JoyMapping[dskeyorder[i]] = keypadJoyMap[i];
|
keycfg.SetInt(btn, keypadKeyMap[i]);
|
||||||
|
joycfg.SetInt(btn, keypadJoyMap[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int hotkey : hk_addons)
|
for (int hotkey : hk_addons)
|
||||||
{
|
{
|
||||||
Config::HKKeyMapping[hotkey] = addonsKeyMap[i];
|
const char* btn = EmuInstance::hotkeyNames[hotkey];
|
||||||
Config::HKJoyMapping[hotkey] = addonsJoyMap[i];
|
keycfg.SetInt(btn, addonsKeyMap[i]);
|
||||||
|
joycfg.SetInt(btn, addonsJoyMap[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (int hotkey : hk_general)
|
for (int hotkey : hk_general)
|
||||||
{
|
{
|
||||||
Config::HKKeyMapping[hotkey] = hkGeneralKeyMap[i];
|
const char* btn = EmuInstance::hotkeyNames[hotkey];
|
||||||
Config::HKJoyMapping[hotkey] = hkGeneralJoyMap[i];
|
keycfg.SetInt(btn, hkGeneralKeyMap[i]);
|
||||||
|
joycfg.SetInt(btn, hkGeneralJoyMap[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::JoystickID = Input::JoystickID;
|
instcfg.SetInt("JoystickID", joystickID);
|
||||||
Config::Save();
|
Config::Save();
|
||||||
|
|
||||||
|
emuInstance->inputLoadConfig();
|
||||||
|
|
||||||
closeDlg();
|
closeDlg();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputConfigDialog::on_InputConfigDialog_rejected()
|
void InputConfigDialog::on_InputConfigDialog_rejected()
|
||||||
{
|
{
|
||||||
Input::JoystickID = Config::JoystickID;
|
Config::Table& instcfg = emuInstance->getLocalConfig();
|
||||||
Input::OpenJoystick();
|
emuInstance->setJoystick(instcfg.GetInt("JoystickID"));
|
||||||
|
|
||||||
closeDlg();
|
closeDlg();
|
||||||
}
|
}
|
||||||
|
@ -225,6 +244,11 @@ void InputConfigDialog::on_cbxJoystick_currentIndexChanged(int id)
|
||||||
// prevent a spurious change
|
// prevent a spurious change
|
||||||
if (ui->cbxJoystick->count() < 2) return;
|
if (ui->cbxJoystick->count() < 2) return;
|
||||||
|
|
||||||
Input::JoystickID = id;
|
joystickID = id;
|
||||||
Input::OpenJoystick();
|
emuInstance->setJoystick(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Joystick* InputConfigDialog::getJoystick()
|
||||||
|
{
|
||||||
|
return emuInstance->getJoystick();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
#include "EmuInstance.h"
|
||||||
|
|
||||||
static constexpr int keypad_num = 12;
|
static constexpr int keypad_num = 12;
|
||||||
|
|
||||||
|
@ -89,6 +90,8 @@ public:
|
||||||
explicit InputConfigDialog(QWidget* parent);
|
explicit InputConfigDialog(QWidget* parent);
|
||||||
~InputConfigDialog();
|
~InputConfigDialog();
|
||||||
|
|
||||||
|
SDL_Joystick* getJoystick();
|
||||||
|
|
||||||
static InputConfigDialog* currentDlg;
|
static InputConfigDialog* currentDlg;
|
||||||
static InputConfigDialog* openDlg(QWidget* parent)
|
static InputConfigDialog* openDlg(QWidget* parent)
|
||||||
{
|
{
|
||||||
|
@ -123,9 +126,12 @@ private:
|
||||||
|
|
||||||
Ui::InputConfigDialog* ui;
|
Ui::InputConfigDialog* ui;
|
||||||
|
|
||||||
|
EmuInstance* emuInstance;
|
||||||
|
|
||||||
int keypadKeyMap[12], keypadJoyMap[12];
|
int keypadKeyMap[12], keypadJoyMap[12];
|
||||||
int addonsKeyMap[hk_addons.size()], addonsJoyMap[hk_addons.size()];
|
int addonsKeyMap[hk_addons.size()], addonsJoyMap[hk_addons.size()];
|
||||||
int hkGeneralKeyMap[hk_general.size()], hkGeneralJoyMap[hk_general.size()];
|
int hkGeneralKeyMap[hk_general.size()], hkGeneralJoyMap[hk_general.size()];
|
||||||
|
int joystickID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,10 @@
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "Input.h"
|
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
#include "EmuInstance.h"
|
||||||
|
|
||||||
|
class InputConfigDialog;
|
||||||
|
|
||||||
class KeyMapButton : public QPushButton
|
class KeyMapButton : public QPushButton
|
||||||
{
|
{
|
||||||
|
@ -76,7 +78,7 @@ protected:
|
||||||
|
|
||||||
if (!ismod)
|
if (!ismod)
|
||||||
key |= mod;
|
key |= mod;
|
||||||
else if (Input::IsRightModKey(event))
|
else if (isRightModKey(event))
|
||||||
key |= (1<<31);
|
key |= (1<<31);
|
||||||
|
|
||||||
*mapping = key;
|
*mapping = key;
|
||||||
|
@ -162,6 +164,9 @@ public:
|
||||||
this->mapping = mapping;
|
this->mapping = mapping;
|
||||||
this->isHotkey = hotkey;
|
this->isHotkey = hotkey;
|
||||||
|
|
||||||
|
// the parent will be set later when this button is added to a layout
|
||||||
|
parentDialog = nullptr;
|
||||||
|
|
||||||
setCheckable(true);
|
setCheckable(true);
|
||||||
setText(mappingText());
|
setText(mappingText());
|
||||||
setFocusPolicy(Qt::StrongFocus); //Fixes binding keys in macOS
|
setFocusPolicy(Qt::StrongFocus); //Fixes binding keys in macOS
|
||||||
|
@ -176,6 +181,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void showEvent(QShowEvent* event) override
|
||||||
|
{
|
||||||
|
if (event->spontaneous()) return;
|
||||||
|
|
||||||
|
QWidget* w = parentWidget();
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
parentDialog = qobject_cast<InputConfigDialog*>(w);
|
||||||
|
if (parentDialog) break;
|
||||||
|
w = w->parentWidget();
|
||||||
|
if (!w) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* event) override
|
void keyPressEvent(QKeyEvent* event) override
|
||||||
{
|
{
|
||||||
if (!isChecked()) return QPushButton::keyPressEvent(event);
|
if (!isChecked()) return QPushButton::keyPressEvent(event);
|
||||||
|
@ -203,7 +222,7 @@ protected:
|
||||||
|
|
||||||
void timerEvent(QTimerEvent* event) override
|
void timerEvent(QTimerEvent* event) override
|
||||||
{
|
{
|
||||||
SDL_Joystick* joy = Input::Joystick;
|
SDL_Joystick* joy = parentDialog->getJoystick();
|
||||||
if (!joy) { click(); return; }
|
if (!joy) { click(); return; }
|
||||||
if (!SDL_JoystickGetAttached(joy)) { click(); return; }
|
if (!SDL_JoystickGetAttached(joy)) { click(); return; }
|
||||||
|
|
||||||
|
@ -279,13 +298,15 @@ private slots:
|
||||||
timerID = startTimer(50);
|
timerID = startTimer(50);
|
||||||
|
|
||||||
memset(axesRest, 0, sizeof(axesRest));
|
memset(axesRest, 0, sizeof(axesRest));
|
||||||
if (Input::Joystick && SDL_JoystickGetAttached(Input::Joystick))
|
|
||||||
|
SDL_Joystick* joy = parentDialog->getJoystick();
|
||||||
|
if (joy && SDL_JoystickGetAttached(joy))
|
||||||
{
|
{
|
||||||
int naxes = SDL_JoystickNumAxes(Input::Joystick);
|
int naxes = SDL_JoystickNumAxes(joy);
|
||||||
if (naxes > 16) naxes = 16;
|
if (naxes > 16) naxes = 16;
|
||||||
for (int a = 0; a < naxes; a++)
|
for (int a = 0; a < naxes; a++)
|
||||||
{
|
{
|
||||||
axesRest[a] = SDL_JoystickGetAxis(Input::Joystick, a);
|
axesRest[a] = SDL_JoystickGetAxis(joy, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,6 +370,8 @@ private:
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputConfigDialog* parentDialog;
|
||||||
|
|
||||||
int* mapping;
|
int* mapping;
|
||||||
bool isHotkey;
|
bool isHotkey;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
#include "VideoSettingsDialog.h"
|
#include "VideoSettingsDialog.h"
|
||||||
#include "ui_VideoSettingsDialog.h"
|
#include "ui_VideoSettingsDialog.h"
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "Input.h"
|
|
||||||
#include "CheatsDialog.h"
|
#include "CheatsDialog.h"
|
||||||
#include "DateTimeDialog.h"
|
#include "DateTimeDialog.h"
|
||||||
#include "EmuSettingsDialog.h"
|
#include "EmuSettingsDialog.h"
|
||||||
|
@ -846,14 +845,14 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
|
||||||
// TODO!! REMOVE ME IN RELEASE BUILDS!!
|
// TODO!! REMOVE ME IN RELEASE BUILDS!!
|
||||||
//if (event->key() == Qt::Key_F11) emuThread->NDS->debug(0);
|
//if (event->key() == Qt::Key_F11) emuThread->NDS->debug(0);
|
||||||
|
|
||||||
Input::KeyPress(event);
|
emuInstance->onKeyPress(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::keyReleaseEvent(QKeyEvent* event)
|
void MainWindow::keyReleaseEvent(QKeyEvent* event)
|
||||||
{
|
{
|
||||||
if (event->isAutoRepeat()) return;
|
if (event->isAutoRepeat()) return;
|
||||||
|
|
||||||
Input::KeyRelease(event);
|
emuInstance->onKeyRelease(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -955,7 +954,7 @@ void MainWindow::onAppStateChanged(Qt::ApplicationState state)
|
||||||
{
|
{
|
||||||
if (state == Qt::ApplicationInactive)
|
if (state == Qt::ApplicationInactive)
|
||||||
{
|
{
|
||||||
Input::KeyReleaseAll();
|
emuInstance->keyReleaseAll();
|
||||||
if (Config::PauseLostFocus && emuThread->emuIsRunning())
|
if (Config::PauseLostFocus && emuThread->emuIsRunning())
|
||||||
emuThread->emuPause();
|
emuThread->emuPause();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,48 +56,19 @@
|
||||||
#include "duckstation/gl/context.h"
|
#include "duckstation/gl/context.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "Input.h"
|
|
||||||
#include "CheatsDialog.h"
|
#include "CheatsDialog.h"
|
||||||
#include "DateTimeDialog.h"
|
#include "DateTimeDialog.h"
|
||||||
#include "EmuSettingsDialog.h"
|
#include "EmuSettingsDialog.h"
|
||||||
#include "InputConfig/InputConfigDialog.h"
|
#include "InputConfig/InputConfigDialog.h"
|
||||||
#include "VideoSettingsDialog.h"
|
#include "VideoSettingsDialog.h"
|
||||||
#include "CameraSettingsDialog.h"
|
|
||||||
#include "AudioSettingsDialog.h"
|
|
||||||
#include "FirmwareSettingsDialog.h"
|
|
||||||
#include "PathSettingsDialog.h"
|
|
||||||
#include "MPSettingsDialog.h"
|
|
||||||
#include "WifiSettingsDialog.h"
|
|
||||||
#include "InterfaceSettingsDialog.h"
|
|
||||||
#include "ROMInfoDialog.h"
|
#include "ROMInfoDialog.h"
|
||||||
#include "RAMInfoDialog.h"
|
#include "RAMInfoDialog.h"
|
||||||
#include "TitleManagerDialog.h"
|
|
||||||
#include "PowerManagement/PowerManagementDialog.h"
|
#include "PowerManagement/PowerManagementDialog.h"
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "FrontendUtil.h"
|
|
||||||
|
|
||||||
#include "Args.h"
|
|
||||||
#include "NDS.h"
|
|
||||||
#include "NDSCart.h"
|
|
||||||
#include "GBACart.h"
|
|
||||||
#include "GPU.h"
|
|
||||||
#include "SPU.h"
|
|
||||||
#include "Wifi.h"
|
|
||||||
#include "Platform.h"
|
|
||||||
#include "LocalMP.h"
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "RTC.h"
|
|
||||||
#include "DSi.h"
|
#include "DSi.h"
|
||||||
#include "DSi_I2C.h"
|
|
||||||
#include "GPU3D_Soft.h"
|
|
||||||
#include "GPU3D_OpenGL.h"
|
|
||||||
|
|
||||||
#include "Savestate.h"
|
|
||||||
|
|
||||||
//#include "main_shaders.h"
|
|
||||||
|
|
||||||
#include "EmuInstance.h"
|
#include "EmuInstance.h"
|
||||||
#include "ArchiveUtil.h"
|
#include "ArchiveUtil.h"
|
||||||
|
@ -369,9 +340,6 @@ int main(int argc, char** argv)
|
||||||
QApplication::setStyle(QString::fromStdString(Config::UITheme));
|
QApplication::setStyle(QString::fromStdString(Config::UITheme));
|
||||||
}
|
}
|
||||||
|
|
||||||
Input::JoystickID = Config::JoystickID;
|
|
||||||
Input::OpenJoystick();
|
|
||||||
|
|
||||||
/* mainWindow = new MainWindow();
|
/* mainWindow = new MainWindow();
|
||||||
if (options->fullscreen)
|
if (options->fullscreen)
|
||||||
ToggleFullscreen(mainWindow);
|
ToggleFullscreen(mainWindow);
|
||||||
|
@ -422,8 +390,6 @@ int main(int argc, char** argv)
|
||||||
delete emuThread;*/
|
delete emuThread;*/
|
||||||
delete testinst;
|
delete testinst;
|
||||||
|
|
||||||
Input::CloseJoystick();
|
|
||||||
|
|
||||||
//AudioInOut::DeInit();
|
//AudioInOut::DeInit();
|
||||||
delete camManager[0];
|
delete camManager[0];
|
||||||
delete camManager[1];
|
delete camManager[1];
|
||||||
|
|
Loading…
Reference in New Issue