summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Common/Src/ConsoleListener.cpp6
-rw-r--r--Source/Core/Common/Src/LogManager.h1
-rw-r--r--Source/Core/DolphinWX/DolphinWX.vcproj14
-rw-r--r--Source/Core/DolphinWX/Src/FrameAui.cpp8
-rw-r--r--Source/Core/DolphinWX/Src/LogWindow.cpp7
-rw-r--r--Source/Core/InputCommon/Src/SDL.cpp254
-rw-r--r--Source/Core/InputCommon/Src/SDL.h24
-rw-r--r--Source/Dolphin.sln19
-rw-r--r--Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj2
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/Config.cpp82
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/Config.h2
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp16
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h2
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp124
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.cpp109
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.h21
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp3
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h3
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp122
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp52
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuMain.h12
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp157
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp3
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/main.cpp20
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/main.h2
-rw-r--r--Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h2
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj2
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp62
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/Config.h3
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp122
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp175
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h24
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp49
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp165
-rw-r--r--Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h14
35 files changed, 1208 insertions, 475 deletions
diff --git a/Source/Core/Common/Src/ConsoleListener.cpp b/Source/Core/Common/Src/ConsoleListener.cpp
index 87f69c86e9..ff4e0b3c90 100644
--- a/Source/Core/Common/Src/ConsoleListener.cpp
+++ b/Source/Core/Common/Src/ConsoleListener.cpp
@@ -251,6 +251,12 @@ void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool
#endif
}
+void ConsoleListener::CustomLog(const char *Text)
+{
+ DWORD cCharsWritten;
+ WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL);
+}
+
void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
{
#if defined(_WIN32)
diff --git a/Source/Core/Common/Src/LogManager.h b/Source/Core/Common/Src/LogManager.h
index 232bf6901f..e6772b9535 100644
--- a/Source/Core/Common/Src/LogManager.h
+++ b/Source/Core/Common/Src/LogManager.h
@@ -83,6 +83,7 @@ public:
#ifdef _WIN32
COORD GetCoordinates(int BytesRead, int BufferWidth);
#endif
+ void CustomLog(const char *Text);
void Log(LogTypes::LOG_LEVELS, const char *Text);
void ClearScreen(bool Cursor = true);
diff --git a/Source/Core/DolphinWX/DolphinWX.vcproj b/Source/Core/DolphinWX/DolphinWX.vcproj
index 44b5fd08a5..e0eb891852 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcproj
+++ b/Source/Core/DolphinWX/DolphinWX.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9.00"
+ Version="9,00"
Name="Dolphin"
ProjectGUID="{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}"
RootNamespace="DolphinWX"
@@ -91,7 +91,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib rpcrt4.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib wxmsw28u_adv.lib wxmsw28u_aui.lib Bochs_disasm.lib LZO.lib SFML_Network.lib zlib.lib"
- OutputFile="../../../Binary/Win32/Dolphin.exe"
+ OutputFile="../../../Binary/$(PlatformName)/Dolphin.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(SolutionDir)\$(ConfigurationName)\$(PlatformName);..\..\..\Externals\wxWidgets\lib\vc_lib\$(PlatformName)"
@@ -208,13 +208,13 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib rpcrt4.lib wxbase28u.lib wxmsw28u_core.lib wxmsw28u_adv.lib wxmsw28u_aui.lib"
- OutputFile="../../../Binary/x64/Dolphin.exe"
+ OutputFile="../../../Binary/$(PlatformName)/Dolphin.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="$(SolutionDir)\$(ConfigurationName)\$(PlatformName);..\..\..\Externals\wxWidgets\lib\vc_lib\$(PlatformName)"
IgnoreAllDefaultLibraries="false"
IgnoreDefaultLibraryNames=""
- GenerateDebugInformation="true"
+ GenerateDebugInformation="false"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
SubSystem="2"
BaseAddress="0x00400000"
@@ -546,7 +546,7 @@
Name="VCLinkerTool"
AdditionalOptions="/NODEFAULTLIB:msvcrt.lib&#x0D;&#x0A;/NODEFAULTLIB:libcmtd.lib"
AdditionalDependencies="comctl32.lib rpcrt4.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib wxmsw28u_adv.lib wxmsw28u_aui.lib Bochs_disasm.lib LZO.lib SFML_Network.lib zlib.lib"
- OutputFile="../../../Binary/Win32/DolphinDF.exe"
+ OutputFile="&quot;$(SolutionDir)/../../../Binary/$(PlatformName)/DolphinDF.exe&quot;"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="&quot;$(SolutionDir)\Release\$(PlatformName)&quot;;&quot;..\..\..\Externals\wxWidgets\lib\vc_lib\$(PlatformName)&quot;"
@@ -659,7 +659,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib rpcrt4.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib wxmsw28u_adv.lib wxmsw28u_aui.lib Bochs_disasm.lib LZO.lib SFML_Network.lib zlib.lib"
- OutputFile="../../../Binary/x64/DolphinDF.exe"
+ OutputFile="../../../Binary/$(PlatformName)/DolphinDF.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="&quot;$(SolutionDir)\Release\$(PlatformName)&quot;;&quot;..\..\..\Externals\wxWidgets\lib\vc_lib\$(PlatformName)&quot;"
@@ -773,7 +773,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib rpcrt4.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib wxmsw28u_adv.lib wxmsw28u_aui.lib Bochs_disasm.lib LZO.lib SFML_Network.lib zlib.lib"
- OutputFile="../../../Binary/Win32/DolphinIL.exe"
+ OutputFile="../../../Binary/$(PlatformName)/DolphinIL.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="&quot;$(SolutionDir)\Release\$(PlatformName)&quot;;&quot;..\..\..\Externals\wxWidgets\lib\vc_lib\$(PlatformName)&quot;"
diff --git a/Source/Core/DolphinWX/Src/FrameAui.cpp b/Source/Core/DolphinWX/Src/FrameAui.cpp
index 466e62ac7b..eb9af94a37 100644
--- a/Source/Core/DolphinWX/Src/FrameAui.cpp
+++ b/Source/Core/DolphinWX/Src/FrameAui.cpp
@@ -127,6 +127,12 @@ void CFrame::ToggleConsole(bool bShow, int i)
#ifdef _WIN32
ConsoleListener *Console = LogManager::GetInstance()->getConsoleListener();
+ // For developers: Use this to get a regular separate console window
+ /*
+ if(!GetConsoleWindow()) Console->Open(); else ShowWindow(GetConsoleWindow(), SW_SHOW);
+ return;
+ */
+
if (bShow)
{
//Console->Log(LogTypes::LNOTICE, StringFromFormat(" >>> Show\n").c_str());
@@ -748,7 +754,7 @@ void CFrame::ResizeConsole()
wxBorder = 2;
Border = 4;
LowerBorder = 6;
- MenuBar = 30; // Including upper border
+ MenuBar = 26; // Including upper border
ScrollBar = 19;
}
else // XP
diff --git a/Source/Core/DolphinWX/Src/LogWindow.cpp b/Source/Core/DolphinWX/Src/LogWindow.cpp
index af7f873dbb..cd6990befe 100644
--- a/Source/Core/DolphinWX/Src/LogWindow.cpp
+++ b/Source/Core/DolphinWX/Src/LogWindow.cpp
@@ -234,7 +234,7 @@ void CLogWindow::OnClear(wxCommandEvent& WXUNUSED (event))
for (int i = 0; i < msgQueueSize; i++)
msgQueue.pop();
m_LogSection.Leave();
-
+
m_console->ClearScreen();
NOTICE_LOG(CONSOLE, "Console cleared");
NotifyUpdate();
@@ -517,11 +517,12 @@ void CLogWindow::UpdateLog()
m_LogTimer->Start(UPDATETIME);
}
+// Receive log messages
void CLogWindow::Log(LogTypes::LOG_LEVELS level, const char *text)
{
m_LogSection.Enter();
- if (msgQueue.size() >= 100)
- msgQueue.pop();
+ // Remove the first message if the queue is big
+ //if (msgQueue.size() >= 200) msgQueue.pop();
msgQueue.push(std::pair<u8, wxString>((u8)level, wxString::FromAscii(text)));
m_LogSection.Leave();
}
diff --git a/Source/Core/InputCommon/Src/SDL.cpp b/Source/Core/InputCommon/Src/SDL.cpp
index 0caf01ccd3..0edfe524cb 100644
--- a/Source/Core/InputCommon/Src/SDL.cpp
+++ b/Source/Core/InputCommon/Src/SDL.cpp
@@ -35,46 +35,63 @@
#define _SDL_MAIN_ // Avoid certain declarations in SDL.h
#include "SDL.h" // Local
#include "XInput.h"
+#ifdef _WIN32
+#include <windows.h>
+#include <dinput.h>
+#pragma comment(lib, "dxguid.lib")
+#pragma comment(lib, "dinput8.lib")
+#endif
-// Definitions
-// -------------------
-int g_LastPad = 0;
-
-
-
namespace InputCommon
{
// Definitions
// -------------------
+int g_LastPad = 0;
+int NumDIDevices = 0;
+// Reset and search for devices
+// -----------------------
+bool SearchDevicesReset(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads)
+{
+ // This is needed to update SDL_NumJoysticks
+ if (SDL_WasInit(0))
+ SDL_Quit();
+
+ return SearchDevices(_joyinfo, _NumPads);
+}
-
-
-// Search attached devices. Populate joyinfo for all attached physical devices.
+// Initialize if not previously initialized
// -----------------------
-bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
+bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads)
{
+ // Init Joystick + Haptic (force feedback) subsystem on SDL 1.3
if (!SDL_WasInit(0))
-#if SDL_VERSION_ATLEAST(1, 3, 0)
+ {
+#if SDL_VERSION_ATLEAST(1, 3, 0) && !defined(_WIN32)
+ NOTICE_LOG(PAD, "SDL_Init | HAPTIC");
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) < 0)
#else
+ //NOTICE_LOG(PAD, "SDL_Init");
if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
#endif
{
PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return false;
}
+ }
+ // Clear joyinfo
+ _joyinfo.clear();
// Get device status
int numjoy = SDL_NumJoysticks();
for (int i = 0; i < numjoy; i++ )
- {
+ {
CONTROLLER_INFO Tmp;
Tmp.joy = SDL_JoystickOpen(i);
@@ -86,39 +103,160 @@ bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_
Tmp.Name = SDL_JoystickName(i);
// Check if the device is okay
- if ( Tmp.NumAxes == 0
+ if ( !( Tmp.NumAxes == 0
&& Tmp.NumBalls == 0
&& Tmp.NumButtons == 0
- && Tmp.NumHats == 0
+ && Tmp.NumHats == 0)
)
{
- Tmp.Good = false;
+ _joyinfo.push_back(Tmp);
}
else
{
- _NumGoodPads++;
- Tmp.Good = true;
- }
-
- _joyinfo.push_back(Tmp);
-
- // We have now read the values we need so we close the device
- if (SDL_JoystickOpened(i)) SDL_JoystickClose(_joyinfo[i].joy);
+ //if (SDL_JoystickOpened(i)) SDL_JoystickClose(Tmp.joy);
+ }
}
_NumPads = (int)_joyinfo.size();
-
return true;
}
+// Show the current pad status
+// -----------------
+std::string ShowStatus(int Slot, int Device, CONTROLLER_MAPPING PadMapping[], CONTROLLER_STATE PadState[],
+ std::vector<InputCommon::CONTROLLER_INFO> joyinfo)
+{
+ CONTROLLER_MAPPING_NEW _PadMapping[4];
+ CONTROLLER_STATE_NEW _PadState[4];
+ for (int i = 0; i < 4; i++)
+ {
+ _PadMapping[i].ID = PadMapping[i].ID;
+ _PadMapping[i].Name = PadMapping[i].Name;
+ _PadState[i].joy = PadState[i].joy;
+ }
+ return DoShowStatus(Slot, Device, _PadMapping, _PadState, joyinfo);
+}
+std::string DoShowStatus(int Slot, int Device,
+ CONTROLLER_MAPPING_NEW PadMapping[], CONTROLLER_STATE_NEW PadState[],
+ std::vector<InputCommon::CONTROLLER_INFO> joyinfo)
+{
+ // Save the physical device
+ int ID = PadMapping[Slot].ID;
+ // Make local shortcut
+ SDL_Joystick *joy = PadState[Slot].joy;
+
+ // Make shortcuts for all pads
+ SDL_Joystick *joy0 = PadState[0].joy;
+ SDL_Joystick *joy1 = PadState[1].joy;
+ SDL_Joystick *joy2 = PadState[2].joy;
+ SDL_Joystick *joy3 = PadState[3].joy;
+
+ // Temporary storage
+ std::string
+ StrAllHandles, StrAllName,
+ StrHandles, StrId, StrName,
+ StrAxes, StrHats, StrBut;
+ int value;
+
+ // All devices
+ int numjoy = SDL_NumJoysticks();
+ for (int i = 0; i < numjoy; i++ )
+ {
+ SDL_Joystick *AllJoy = SDL_JoystickOpen(i);
+ StrAllHandles += StringFromFormat(" %i:%06i", i, AllJoy);
+ StrAllName += StringFromFormat("Name %i: %s\n", i, SDL_JoystickName(i));
+ }
+
+ // Get handles
+ for(int i = 0; i < joyinfo.size(); i++)
+ {
+ StrHandles += StringFromFormat(" %i:%06i", i, joyinfo.at(i).joy);
+ StrId += StringFromFormat(" %i:%i", i, joyinfo.at(i).ID);
+ StrName += StringFromFormat("Name %i:%s\n", i, joyinfo.at(i).Name.c_str());
+ }
+
+ // Get status
+ int Axes = joyinfo[Device].NumAxes;
+ int Balls = joyinfo[Device].NumBalls;
+ int Hats = joyinfo[Device].NumHats;
+ int Buttons = joyinfo[Device].NumButtons;
+
+ // Update the internal values
+ SDL_JoystickUpdate();
+
+ // Go through all axes and read out their values
+ for(int i = 0; i < Axes; i++)
+ {
+ value = SDL_JoystickGetAxis(joy, i);
+ StrAxes += StringFromFormat(" %i:%06i", i, value);
+ }
+ for(int i = 0;i < Hats; i++)
+ {
+ value = SDL_JoystickGetHat(joy, i);
+ StrHats += StringFromFormat(" %i:%i", i, value);
+ }
+ for(int i = 0;i < Buttons; i++)
+ {
+ value = SDL_JoystickGetButton(joy, i);
+ StrBut += StringFromFormat(" %i:%i", i+1, value);
+ }
+
+ return StringFromFormat(
+ "All devices:\n"
+ "Handles: %s\n"
+ "%s"
+
+ "\nAll pads:\n"
+ "Handles: %s\n"
+ "ID: %s\n"
+ "%s"
+
+ "\nAll slots:\n"
+ "ID: %i %i %i %i\n"
+ "Name: '%s' '%s' '%s' '%s'\n"
+ //"Controllertype: %i %i %i %i\n"
+ //"SquareToCircle: %i %i %i %i\n\n"
+ #ifdef _WIN32
+ "Handles: %i %i %i %i\n"
+ //"XInput: %i %i %i\n"
+ #endif
+
+ "\nThis pad:\n"
+ "Handle: %06i\n"
+ "ID: %i\n"
+ //"Slot: %i\n"
+ "Axes: %s\n"
+ "Hats: %s\n"
+ "But: %s\n"
+ "Device: Ax: %i Balls:%i Hats:%i But:%i",
+ StrAllHandles.c_str(), StrAllName.c_str(),
+ StrHandles.c_str(), StrId.c_str(), StrName.c_str(),
+
+ PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID,
+ PadMapping[0].Name.c_str(), PadMapping[1].Name.c_str(), PadMapping[2].Name.c_str(), PadMapping[3].Name.c_str(),
+ //PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype,
+ //PadMapping[0].bSquareToCircle, PadMapping[1].bSquareToCircle, PadMapping[2].bSquareToCircle, PadMapping[3].bSquareToCircle,
+ #ifdef _WIN32
+ joy0, joy1, joy2, joy3,
+ //PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy,
+ //XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R),
+ joy,
+ #endif
+ //Slot,
+ ID,
+ StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
+ Axes, Balls, Hats, Buttons
+ );
+}
+
// Supporting functions
-// ----------------
+// ====================
// Read current joystick status
-/* ----------------
+/* --------------------
The value PadMapping[].buttons[] is the number of the assigned joypad button,
PadState[].buttons[] is the status of the button, it becomes 0 (no pressed) or 1 (pressed) */
@@ -140,10 +278,15 @@ void ReadButton(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int
Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input value "controller" is
for a virtual controller 0 to 3. */
-void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int Controller, int NumButtons)
-{
+void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping)
+{
+ if (SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE) return;
+ //NOTICE_LOG(PAD, "SDL_JoystickEventState: %s", (SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE) ? "SDL_ENABLE" : "SDL_IGNORE");
+
// Update the gamepad status
SDL_JoystickUpdate();
+ // Read info
+ int NumButtons = SDL_JoystickNumButtons(_PadState.joy);
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
_PadState.axis[CTL_MAIN_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_X]);
@@ -206,12 +349,13 @@ void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, in
}
#ifdef SHOW_PAD_STATUS
+ /*
// Show the status of all connected pads
//ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
- //if ((g_LastPad == 0 && Controller == 0) || Controller < g_LastPad) Console->ClearScreen();
+ //if ((g_LastPad == 0 && _PadMapping.ID == 0) || Controller < g_LastPad) Console->ClearScreen();
g_LastPad = Controller;
NOTICE_LOG(CONSOLE,
- "Pad | Number:%i Enabled:%i Handle:%i\n"
+ "Pad | Number:%i Handle:%i\n"
"Main Stick | X:%03i Y:%03i\n"
"C Stick | X:%03i Y:%03i\n"
"Trigger | Type:%s DigitalL:%i DigitalR:%i AnalogL:%03i AnalogR:%03i HalfPress:%i\n"
@@ -219,7 +363,7 @@ void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, in
"D-Pad | Type:%s Hat:%i U:%i D:%i\n"
"======================================================\n",
- Controller, _PadMapping.enabled, _PadState.joy,
+ _PadMapping.ID, _PadState.joy,
_PadState.axis[InputCommon::CTL_MAIN_X], _PadState.axis[InputCommon::CTL_MAIN_Y],
_PadState.axis[InputCommon::CTL_SUB_X], _PadState.axis[InputCommon::CTL_SUB_Y],
@@ -235,6 +379,7 @@ void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, in
_PadState.dpad,
_PadState.dpad2[InputCommon::CTL_D_PAD_UP], _PadState.dpad2[InputCommon::CTL_D_PAD_DOWN]
);
+ */
#endif
}
@@ -263,18 +408,23 @@ bool AvoidValues(int value, bool NoTriggerFilter)
// Detect a pressed button
// ---------------------
-void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int hats,
+void GetButton(SDL_Joystick *joy, int ControllerID,
int &KeyboardKey, int &value, int &type, int &pressed, bool &Succeed, bool &Stop,
bool LeftRight, bool Axis, bool XInput, bool Button, bool Hat, bool NoTriggerFilter)
{
// It needs the wxWidgets excape keycode
static const int WXK_ESCAPE = 27;
+ // Save info
+ int buttons = SDL_JoystickNumButtons(joy);
+ int axes = SDL_JoystickNumAxes(joy);;
+ int hats = SDL_JoystickNumHats(joy);;
+
// Update the internal status
SDL_JoystickUpdate();
// For the triggers we accept both a digital or an analog button
- if(Axis)
+ if (Axis)
{
for(int i = 0; i < axes; i++)
{
@@ -289,7 +439,7 @@ void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int h
}
// Check for a hat
- if(Hat)
+ if (Hat)
{
for(int i = 0; i < hats; i++)
{
@@ -370,5 +520,41 @@ void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int h
+// **********************************************
+
+
+
+// Search for DirectInput devices
+// ----------------
+#ifdef _WIN32
+BOOL CALLBACK EnumDICallback(const DIDEVICEINSTANCE* pInst, VOID* pContext)
+{
+ NumDIDevices++;
+ return true;
+}
+#endif
+int SearchDIDevices()
+{
+ #ifdef _WIN32
+ LPDIRECTINPUT8 g_pObject;
+ LPDIRECTINPUTDEVICE8 g_pDevice;
+ DIPROPDWORD dipdw;
+ HRESULT hr;
+ NumDIDevices = 0;
+
+ // Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use.
+ if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_pObject, NULL)))
+ return 0;
+
+ // Look for a device
+ if (FAILED(hr = g_pObject->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumDICallback, NULL, DIEDFL_ATTACHEDONLY)))
+ return 0;
+ return NumDIDevices;
+ #else
+ return 0;
+ #endif
+}
+
+
} // InputCommon
diff --git a/Source/Core/InputCommon/Src/SDL.h b/Source/Core/InputCommon/Src/SDL.h
index 40c121f96f..e49b8aab33 100644
--- a/Source/Core/InputCommon/Src/SDL.h
+++ b/Source/Core/InputCommon/Src/SDL.h
@@ -53,7 +53,7 @@
#endif
#include "Common.h" // Common
-
+#include "StringUtil.h"
namespace InputCommon
@@ -62,7 +62,7 @@ namespace InputCommon
// Settings
// ----------
-// Show a status window with the detected axes, buttons and so on
+// Show a status window with the detected devices etc
//#define SHOW_PAD_STATUS
@@ -82,7 +82,7 @@ struct CONTROLLER_STATE // GC PAD INFO/STATE
int dpad; // Automatic SDL D-Pad (8 directions + neutral)
int dpad2[4]; // D-pad using buttons
int axis[6]; // 2 x 2 Axes (Main & Sub)
- int halfpress; // Halfpress... you know, like not fully pressed ;)...
+ int halfpress; // L and R triggers half pressed
SDL_Joystick *joy; // SDL joystick device
};
@@ -95,6 +95,7 @@ struct CONTROLLER_MAPPING // GC PAD MAPPING
int halfpress; // (See above)
int deadzone; // Deadzone... what else?
int ID; // SDL joystick device ID
+ std::string Name; // SDL joystick device name
int controllertype; // Hat: Hat or custom buttons
int triggertype; // Triggers range
std::string SRadius, SDiagonal, SRadiusC, SDiagonalC;
@@ -111,7 +112,6 @@ struct CONTROLLER_INFO // CONNECTED WINDOWS DEVICES INFO
int NumHats; // Amount of Hats (POV)
std::string Name; // Joypad/stickname
int ID; // SDL joystick device ID
- bool Good; // Pad is good (it has at least one button or axis)
SDL_Joystick *joy; // SDL joystick device
};
enum
@@ -220,6 +220,7 @@ struct CONTROLLER_MAPPING_NEW // GC PAD MAPPING
int DeadZoneL; // Analog 1 Deadzone
int DeadZoneR; // Analog 2 Deadzone
int ID; // SDL joystick device ID
+ std::string Name; // SDL joystick device name
int controllertype; // D-Pad type: Hat or custom buttons
int triggertype; // SDL or XInput trigger
std::string SDiagonal;
@@ -236,9 +237,14 @@ struct CONTROLLER_MAPPING_NEW // GC PAD MAPPING
// ---------
// General functions
-bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &NumPads, int &NumGoodPads);
-void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int controller, int NumButtons);
-void GetButton(SDL_Joystick*, int,int,int,int, int&,int&,int&,int&,bool&,bool&, bool,bool,bool,bool,bool,bool);
+bool SearchDevicesReset(std::vector<CONTROLLER_INFO> &_joyinfo, int &NumPads);
+bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &NumPads);
+std::string ShowStatus(int Slot, int Device, CONTROLLER_MAPPING PadMapping[], CONTROLLER_STATE PadState[],
+ std::vector<InputCommon::CONTROLLER_INFO> joyinfo);
+std::string DoShowStatus(int Slot, int Device, CONTROLLER_MAPPING_NEW PadMapping[], CONTROLLER_STATE_NEW PadState[],
+ std::vector<InputCommon::CONTROLLER_INFO> joyinfo);
+void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping);
+void GetButton(SDL_Joystick*, int, int&,int&,int&,int&,bool&,bool&, bool,bool,bool,bool,bool,bool);
// Value conversion
float Deg2Rad(float Deg);
@@ -256,7 +262,9 @@ std::string VKToString(int keycode);
extern int g_LastPad;
#endif
-
+// DirectInput
+extern int NumDIDevices;
+int SearchDIDevices();
} // InputCommon
diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln
index c8b14c01dd..821a04a023 100644
--- a/Source/Dolphin.sln
+++ b/Source/Dolphin.sln
@@ -95,6 +95,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_nJoy_SDL", "Plugins\
ProjectSection(ProjectDependencies) = postProject
{C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA}
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
EndProjectSection
EndProject
@@ -114,6 +115,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_Wiimote", "Plugins\P
ProjectSection(ProjectDependencies) = postProject
{C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA}
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}
{0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E} = {0E231FB1-F3C9-4724-ACCB-DE8BCB3C089E}
{1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
@@ -199,6 +201,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_VideoSoftware", "Plu
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "..\Externals\SDL\VisualC\SDL\SDL_VS2008.vcproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -696,6 +700,21 @@ Global
{66A4E7BD-E2E8-4373-9B75-8750EB5AE683}.Release|Win32.Build.0 = Release|Win32
{66A4E7BD-E2E8-4373-9B75-8750EB5AE683}.Release|x64.ActiveCfg = Release|x64
{66A4E7BD-E2E8-4373-9B75-8750EB5AE683}.Release|x64.Build.0 = Release|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.ActiveCfg = Debug|Win32
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.Build.0 = Debug|Win32
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.DebugFast|Win32.ActiveCfg = Debug|Win32
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.DebugFast|Win32.Build.0 = Debug|Win32
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.DebugFast|x64.ActiveCfg = Debug|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.DebugFast|x64.Build.0 = Debug|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release_JITIL|Win32.ActiveCfg = Release|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release_JITIL|x64.ActiveCfg = Release|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release_JITIL|x64.Build.0 = Release|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.ActiveCfg = Release|Win32
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.Build.0 = Release|Win32
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj b/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj
index 983bbfd74f..7ebb7631c0 100644
--- a/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj
+++ b/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj
@@ -67,7 +67,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="SDL.lib xinput.lib comctl32.lib winmm.lib wiiuse.lib rpcrt4.lib wxbase28ud.lib wxmsw28ud_core.lib"
+ AdditionalDependencies="xinput.lib comctl32.lib winmm.lib wiiuse.lib rpcrt4.lib wxbase28ud.lib wxmsw28ud_core.lib"
OutputFile="..\..\..\Binary\Win32/Plugins\Plugin_WiimoteD.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\Externals\SDL\win32;..\..\..\Externals\WiiUse\win32;..\..\..\Externals\wxWidgets\lib\vc_lib\Win32"
diff --git a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp
index 7b57ed9836..9fa2395776 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp
@@ -24,6 +24,7 @@
#include "Config.h"
#include "EmuDefinitions.h" // for PadMapping
+#include "EmuMain.h"
#include "main.h"
// Configuration file control names
@@ -242,10 +243,13 @@ Config::Config()
{
// Set all default values to zero
memset(this, 0, sizeof(Config));
+ Loaded = false;
}
void Config::Load(bool ChangePad)
{
+ Loaded = true;
+
std::string temp;
IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini");
@@ -273,6 +277,7 @@ void Config::Load(bool ChangePad)
sprintf(SectionName, "Wiimote%i", i + 1);
iniFile.Get(SectionName, "NoTriggerFilter", &bNoTriggerFilter, false);
iniFile.Get(SectionName, "TriggerType", &Trigger.Type, Trigger.TRIGGER_OFF);
+ iniFile.Get(SectionName, "TriggerUpright", &Trigger.Upright, false);
iniFile.Get(SectionName, "TriggerRollRange", &Trigger.Range.Roll, 50);
iniFile.Get(SectionName, "TriggerPitchRange", &Trigger.Range.Pitch, false);
@@ -295,38 +300,49 @@ void Config::Load(bool ChangePad)
iniFile.Get(SectionName, gh3ControlNames[x], &WiiMoteEmu::PadMapping[i].GH3c.keyForControls[x], GH3DefaultControls[x]);
// Don't update this when we are loading settings from the ConfigBox
- if(!ChangePad)
+ if (!ChangePad)
{
// This pad Id could possibly be higher than the number of pads that are connected,
// but we check later, when needed, that that is not the case
iniFile.Get(SectionName, "DeviceID", &WiiMoteEmu::PadMapping[i].ID, 0);
+ iniFile.Get(SectionName, "DeviceName", &WiiMoteEmu::PadMapping[i].Name, 0);
iniFile.Get(SectionName, "Enabled", &WiiMoteEmu::PadMapping[i].enabled, true);
}
// Joypad specific settings
- // Current joypad device ID: PadMapping[i].ID
- // Current joypad name: joyinfo[PadMapping[i].ID].Name
-
- // Prevent a crash from illegal access to joyinfo that will only have values for
- // the current amount of connected PadMapping
- if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue;
+ // Current joypad device ID: PadMapping[i].ID
+ // Current joypad name: PadMapping[i].Name
// Create a section name
- std::string joySectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name;
-
- iniFile.Get(joySectionName.c_str(), "left_x", &WiiMoteEmu::PadMapping[i].Axis.Lx, 0);
- iniFile.Get(joySectionName.c_str(), "left_y", &WiiMoteEmu::PadMapping[i].Axis.Ly, 1);
- iniFile.Get(joySectionName.c_str(), "right_x", &WiiMoteEmu::PadMapping[i].Axis.Rx, 2);
- iniFile.Get(joySectionName.c_str(), "right_y", &WiiMoteEmu::PadMapping[i].Axis.Ry, 3);
- iniFile.Get(joySectionName.c_str(), "l_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tl, 1004);
- iniFile.Get(joySectionName.c_str(), "r_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tr, 1005);
- iniFile.Get(joySectionName.c_str(), "DeadZoneL", &WiiMoteEmu::PadMapping[i].DeadZoneL, 0);
- iniFile.Get(joySectionName.c_str(), "DeadZoneR", &WiiMoteEmu::PadMapping[i].DeadZoneR, 0);
- iniFile.Get(joySectionName.c_str(), "TriggerType", &WiiMoteEmu::PadMapping[i].triggertype, 0);
- iniFile.Get(joySectionName.c_str(), "Diagonal", &WiiMoteEmu::PadMapping[i].SDiagonal, "100%");
- iniFile.Get(joySectionName.c_str(), "Circle2Square", &WiiMoteEmu::PadMapping[i].bCircle2Square, false);
- iniFile.Get(joySectionName.c_str(), "RollInvert", &WiiMoteEmu::PadMapping[i].bRollInvert, false);
- iniFile.Get(joySectionName.c_str(), "PitchInvert", &WiiMoteEmu::PadMapping[i].bPitchInvert, false);
+ std::string JoySectionName = WiiMoteEmu::PadMapping[i].Name;
+ // Don't load settings for a non-connected device
+ if (!WiiMoteEmu::IsConnected(JoySectionName))
+ {
+ ERROR_LOG(PAD, "Slot %i: The device '%s' is not connected, will not load settings", i, JoySectionName.c_str());
+ continue;
+ }
+ // Don't load a blank ID
+ if (JoySectionName == "")
+ {
+ ERROR_LOG(PAD, "Slot %i has no device name, will not load settings", i);
+ continue;
+ }
+
+ iniFile.Get(JoySectionName.c_str(), "left_x", &WiiMoteEmu::PadMapping[i].Axis.Lx, 0);
+ iniFile.Get(JoySectionName.c_str(), "left_y", &WiiMoteEmu::PadMapping[i].Axis.Ly, 1);
+ iniFile.Get(JoySectionName.c_str(), "right_x", &WiiMoteEmu::PadMapping[i].Axis.Rx, 2);
+ iniFile.Get(JoySectionName.c_str(), "right_y", &WiiMoteEmu::PadMapping[i].Axis.Ry, 3);
+ iniFile.Get(JoySectionName.c_str(), "l_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tl, 1004);
+ iniFile.Get(JoySectionName.c_str(), "r_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tr, 1005);
+ iniFile.Get(JoySectionName.c_str(), "DeadZoneL", &WiiMoteEmu::PadMapping[i].DeadZoneL, 0);
+ iniFile.Get(JoySectionName.c_str(), "DeadZoneR", &WiiMoteEmu::PadMapping[i].DeadZoneR, 0);
+ iniFile.Get(JoySectionName.c_str(), "TriggerType", &WiiMoteEmu::PadMapping[i].triggertype, 0);
+ iniFile.Get(JoySectionName.c_str(), "Diagonal", &WiiMoteEmu::PadMapping[i].SDiagonal, "100%");
+ iniFile.Get(JoySectionName.c_str(), "Circle2Square", &WiiMoteEmu::PadMapping[i].bCircle2Square, false);
+ iniFile.Get(JoySectionName.c_str(), "RollInvert", &WiiMoteEmu::PadMapping[i].bRollInvert, false);
+ iniFile.Get(JoySectionName.c_str(), "PitchInvert", &WiiMoteEmu::PadMapping[i].bPitchInvert, false);
+
+ NOTICE_LOG(WIIMOTE, "Slot %i: Load settings for ID %i '%s'", i, WiiMoteEmu::PadMapping[i].ID, JoySectionName.c_str());
}
// Load the IR cursor settings if it's avaliable for the GameId, if not load the default settings
iniFile.Load(FULL_CONFIG_DIR "IR Pointer.ini");
@@ -375,6 +391,7 @@ void Config::Save(int Slot)
iniFile.Set(SectionName, "Enabled", WiiMoteEmu::PadMapping[i].enabled);
iniFile.Set(SectionName, "NoTriggerFilter", bNoTriggerFilter);
iniFile.Set(SectionName, "TriggerType", Trigger.Type);
+ iniFile.Set(SectionName, "TriggerUpright", Trigger.Upright);
iniFile.Set(SectionName, "TriggerRollRange", Trigger.Range.Roll);
iniFile.Set(SectionName, "TriggerPitchRange", Trigger.Range.Pitch);
@@ -400,18 +417,23 @@ void Config::Save(int Slot)
// Save the physical device ID number
iniFile.Set(SectionName, "DeviceID", WiiMoteEmu::PadMapping[i].ID);
+ iniFile.Set(SectionName, "DeviceName", WiiMoteEmu::PadMapping[i].Name);
// Joypad specific settings
- // Current joypad device ID: PadMapping[i].ID
- // Current joypad name: joyinfo[PadMapping[i].ID].Name
-
- // Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to
- // avoid reading a joyinfo that does't exist
- if((u32)WiiMoteEmu::PadMapping[i].ID >= WiiMoteEmu::joyinfo.size()) continue;
+ // Current joypad device ID: PadMapping[i].ID
+ // Current joypad name: IDToName(PadMapping[i].ID])
// Create a new section name after the joypad name
- std::string joySectionName = WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name;
-
+ std::string joySectionName = WiiMoteEmu::IDToName(WiiMoteEmu::PadMapping[i].ID);
+ // Don't save a blank name
+ if (SectionName == "")
+ {
+ ERROR_LOG(WIIMOTE, "ID %i has no name, will not load", WiiMoteEmu::PadMapping[i].ID);
+ continue;
+ }
+
+ NOTICE_LOG(WIIMOTE, "Save settings for ID %i '%s' from PadMapping[%i]", WiiMoteEmu::PadMapping[i].ID, joySectionName.c_str(), i);
+
iniFile.Set(joySectionName.c_str(), "left_x", WiiMoteEmu::PadMapping[i].Axis.Lx);
iniFile.Set(joySectionName.c_str(), "left_y", WiiMoteEmu::PadMapping[i].Axis.Ly);
iniFile.Set(joySectionName.c_str(), "right_x", WiiMoteEmu::PadMapping[i].Axis.Rx);
diff --git a/Source/Plugins/Plugin_Wiimote/Src/Config.h b/Source/Plugins/Plugin_Wiimote/Src/Config.h
index c392e6b308..c2b0a93667 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/Config.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/Config.h
@@ -41,6 +41,7 @@ struct Config
Config();
void Load(bool ChangePad = false);
void Save(int Slot = -1);
+ bool Loaded;
struct PadRange
{
@@ -59,6 +60,7 @@ struct Config
TRIGGER
};
int Type;
+ bool Upright;
PadRange Range;
};
struct PadNunchuck
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp
index e3ced1e631..b23b91e211 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp
@@ -34,6 +34,7 @@ BEGIN_EVENT_TABLE(WiimoteBasicConfigDialog,wxDialog)
EVT_CHECKBOX(ID_CONNECT_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_USE_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_SIDEWAYSDPAD, WiimoteBasicConfigDialog::GeneralSettingsChanged)
+ EVT_CHECKBOX(ID_UPRIGHTWIIMOTE, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_MOTIONPLUSCONNECTED, WiimoteBasicConfigDialog::GeneralSettingsChanged)
EVT_CHOICE(ID_EXTCONNECTED, WiimoteBasicConfigDialog::GeneralSettingsChanged)
// IR cursor
@@ -207,9 +208,9 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
// Emulated Wiimote
m_SidewaysDPad[i] = new wxCheckBox(m_Controller[i], ID_SIDEWAYSDPAD, wxT("Sideways D-Pad"));
m_SidewaysDPad[i]->SetValue(g_Config.bSidewaysDPad);
-
- m_SizeEmu[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Wiimote"));
- m_SizeEmu[i]->Add(m_SidewaysDPad[i], 0, wxEXPAND | wxALL, 5);
+ m_UprightWiimote[i] = new wxCheckBox(m_Controller[i], ID_UPRIGHTWIIMOTE, wxT("Upright Wiimote"));
+ m_UprightWiimote[i]->SetValue(g_Config.Trigger.Upright);
+ m_UprightWiimote[i]->SetToolTip(wxT("Treat the upright position as neutral for roll and pitch"));
//IR Pointer
m_TextScreenWidth[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Width: 000"));
@@ -251,6 +252,12 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_CheckAR169[i]->Enable(false);
m_Crop[i]->Enable(false);
+ // Sizers
+
+ m_SizeEmu[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Wiimote"));
+ m_SizeEmu[i]->Add(m_SidewaysDPad[i], 0, wxEXPAND | wxALL, 5);
+ m_SizeEmu[i]->Add(m_UprightWiimote[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5);
+
m_SizerIRPointerScreen[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerScreen[i]->Add(m_TextAR[i], 0, wxEXPAND | (wxTOP), 0);
m_SizerIRPointerScreen[i]->Add(m_CheckAR43[i], 0, wxEXPAND | (wxLEFT), 5);
@@ -391,6 +398,9 @@ void WiimoteBasicConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
case ID_SIDEWAYSDPAD:
g_Config.bSidewaysDPad = m_SidewaysDPad[Page]->IsChecked();
+ break;
+ case ID_UPRIGHTWIIMOTE:
+ g_Config.Trigger.Upright = m_UprightWiimote[Page]->IsChecked();
break;
case ID_MOTIONPLUSCONNECTED:
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h
index 4a4f48aaab..794f2f28c4 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h
@@ -79,6 +79,7 @@ class WiimoteBasicConfigDialog : public wxDialog
// Emulated Wiimote settings
wxCheckBox *m_SidewaysDPad[4],
+ *m_UprightWiimote[4],
*m_WiimoteOnline[4],
*m_WiiMotionPlusConnected[4],
*m_CheckAR43[4],
@@ -126,6 +127,7 @@ class WiimoteBasicConfigDialog : public wxDialog
// Emulated Wiimote
ID_SIDEWAYSDPAD,
+ ID_UPRIGHTWIIMOTE,
ID_MOTIONPLUSCONNECTED,
ID_EXTCONNECTED,
IDC_WIMOTE_ON,
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp
index 5fbd1802f4..c4f11df9b8 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp
@@ -30,36 +30,15 @@
is only used the first time the pads are checked. */
void WiimotePadConfigDialog::DoChangeJoystick()
{
- // Close the current pad, unless it's used by another slot
- //if (PadMapping[notebookpage].enabled) PadClose(notebookpage);
+ WARN_LOG(WIIMOTE, "---- DoChangeJoystick ----");
// Before changing the pad we save potential changes to the current pad
DoSave(true);
// Load the settings for the new Id
g_Config.Load(true);
- UpdateGUI(Page); // Update the GUI
-
- // Open the new pad
- if (WiiMoteEmu::PadMapping[Page].enabled) PadOpen(Page);
-}
-void WiimotePadConfigDialog::PadOpen(int Open) // Open for slot 1, 2, 3 or 4
-{
- // Check that we got a good pad
- if (!WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Open].ID).Good)
- {
- DEBUG_LOG(WIIMOTE, "A bad pad was selected");
- WiiMoteEmu::PadState[Open].joy = NULL;
- return;
- }
-
- DEBUG_LOG(WIIMOTE, "Update the Slot %i handle to Id %i", Page, WiiMoteEmu::PadMapping[Open].ID);
- WiiMoteEmu::PadState[Open].joy = SDL_JoystickOpen(WiiMoteEmu::PadMapping[Open].ID);
-}
-void WiimotePadConfigDialog::PadClose(int _Close) // Close for slot 1, 2, 3 or 4
-{
- if (SDL_JoystickOpened(WiiMoteEmu::PadMapping[_Close].ID)) SDL_JoystickClose(WiiMoteEmu::PadState[_Close].joy);
- WiiMoteEmu::PadState[_Close].joy = NULL;
+ // Update the GUI
+ UpdateGUI(Page);
}
void WiimotePadConfigDialog::DoChangeDeadZone(bool Left)
@@ -90,30 +69,29 @@ void WiimotePadConfigDialog::DoChangeDeadZone(bool Left)
// Set the button text for all four Wiimotes
void WiimotePadConfigDialog::SetButtonTextAll(int id, char text[128])
{
- for (int i = 0; i < 1; i++)
+ for (int i = 0; i < MAX_WIIMOTES; i++)
{
- // Safety check to avoid crash
- if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID)
- if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Page].ID].Name)
- SetButtonText(id, text, i);
+ if (WiiMoteEmu::IDToName(WiiMoteEmu::PadMapping[i].ID) == WiiMoteEmu::IDToName(WiiMoteEmu::PadMapping[Page].ID))
+ {
+ SetButtonText(id, text, i);
+ DEBUG_LOG(PAD, "Updated button text for slot %i", i);
+ }
};
}
-
-
void WiimotePadConfigDialog::SaveButtonMappingAll(int Slot)
{
- for (int i = 0; i < 4; i++)
- {
- // This can occur when no gamepad is detected
- if ((int)WiiMoteEmu::joyinfo.size() > WiiMoteEmu::PadMapping[i].ID && WiiMoteEmu::PadMapping[i].ID >= 0)
- if (WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[i].ID].Name == WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Slot].ID].Name)
- SaveButtonMapping(i, false, Slot);
+ for (int i = 0; i < MAX_WIIMOTES; i++)
+ {
+ if (WiiMoteEmu::IDToName(WiiMoteEmu::PadMapping[i].ID) == WiiMoteEmu::IDToName(WiiMoteEmu::PadMapping[Slot].ID))
+ SaveButtonMapping(i, false, Slot);
}
}
// Set dialog items from saved values
void WiimotePadConfigDialog::UpdateGUIButtonMapping(int controller)
{
+ NOTICE_LOG(WIIMOTE, "Load ButtonMapping | controller:%i", controller);
+
// Temporary storage
wxString tmp;
@@ -204,12 +182,19 @@ void WiimotePadConfigDialog::UpdateGUIButtonMapping(int controller)
void WiimotePadConfigDialog::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot)
{
+ // Log
+ NOTICE_LOG(WIIMOTE, "SaveButtonMapping | controller:%i FromSlot:%i", controller, FromSlot);
+
// Temporary storage
wxString tmp;
long value;
// Save from or to the same or different slots
if (FromSlot == -1) FromSlot = controller;
+
+ // TEMPORARY
+ // There is only one slot at the moment
+ if (FromSlot > MAX_WIIMOTES-1) FromSlot = MAX_WIIMOTES-1;
// Replace "" with "-1" in the GUI controls
ToBlank(false);
@@ -218,7 +203,10 @@ void WiimotePadConfigDialog::SaveButtonMapping(int controller, bool DontChangeId
-1 that's a bug that should be fixed. Because the m_Joyname[] combo box should always show <No Gamepad Detected>, or a gamepad name, not a
a blank selection. */
if (!DontChangeId)
- WiiMoteEmu::PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection();
+ {
+ WiiMoteEmu::PadMapping[controller].ID = WiiMoteEmu::joyinfo.at(m_Joyname[FromSlot]->GetSelection()).ID;
+ WiiMoteEmu::PadMapping[controller].Name = m_Joyname[FromSlot]->GetValue().mb_str();
+ }
// Set enabled or disable status
if (FromSlot == controller)
WiiMoteEmu::PadMapping[controller].enabled = true; //m_Joyattach[FromSlot]->GetValue(); // Only enable one
@@ -372,6 +360,11 @@ void WiimotePadConfigDialog::GetButtons(wxCommandEvent& event)
void WiimotePadConfigDialog::DoGetButtons(int _GetId)
{
+ DEBUG_LOG(WIIMOTE, "DoGetButtons");
+
+ bool _LiveUpdates = LiveUpdates;
+ LiveUpdates = false;
+
// Collect the starting values
// Get the current controller
@@ -399,7 +392,7 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
// Values used in this function
char format[128];
int Seconds = 4; // Seconds to wait for
- int TimesPerSecond = 40; // How often to run the check
+ int TimesPerSecond = 60; // How often to run the check
// Values returned from InputCommon::GetButton()
int value; // Axis value
@@ -438,7 +431,7 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
DEBUG_LOG(WIIMOTE, "Timer Started for Pad:%i _GetId:%i"
- "Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i\n",
+ " Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i\n",
WiiMoteEmu::PadMapping[Controller].ID, _GetId,
Axis, LeftRight, XInput, Button, Hat);
}
@@ -449,7 +442,7 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
else
{
InputCommon::GetButton(
- WiiMoteEmu::joyinfo[PadID].joy, PadID, WiiMoteEmu::joyinfo[PadID].NumButtons, WiiMoteEmu::joyinfo[PadID].NumAxes, WiiMoteEmu::joyinfo[PadID].NumHats,
+ WiiMoteEmu::PadState[Page].joy, PadID,
g_Pressed, value, type, pressed, Succeed, Stop,
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
}
@@ -482,7 +475,7 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
}
// If we got a button
- if(Succeed)
+ if (Succeed)
{
Stop = true;
// Write the number of the pressed button to the text box
@@ -491,10 +484,11 @@ void WiimotePadConfigDialog::DoGetButtons(int _GetId)
}
// Stop the timer
- if(Stop)
+ if (Stop)
{
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
+ LiveUpdates = _LiveUpdates;
/* Update the button mapping for all slots that use this device. (It
doesn't make sense to have several slots controlled by the same
@@ -545,12 +539,12 @@ void WiimotePadConfigDialog::Convert2Box(int &x)
// Update the input status boxes
void WiimotePadConfigDialog::PadGetStatus()
{
- //DEBUG_LOG(WIIMOTE, "SDL_WasInit: %i", SDL_WasInit(0));
+ //DEBUG_LOG(WIIMOTE, "PadGetStatus");
/* Return if it's not detected. The ID should never be less than zero here,
it can only be that because of a manual ini file change, but we make
that check anway. */
- if(WiiMoteEmu::PadMapping[Page].ID < 0 || WiiMoteEmu::PadMapping[Page].ID >= SDL_NumJoysticks())
+ if (WiiMoteEmu::PadMapping[Page].ID < 0 || WiiMoteEmu::PadMapping[Page].ID >= SDL_NumJoysticks())
{
m_TStatusLeftIn[Page]->SetLabel(wxT("Not connected"));
m_TStatusLeftOut[Page]->SetLabel(wxT("Not connected"));
@@ -574,15 +568,13 @@ void WiimotePadConfigDialog::PadGetStatus()
}
// Get physical device status
- int PhysicalDevice = WiiMoteEmu::PadMapping[Page].ID;
+ int ID = WiiMoteEmu::PadMapping[Page].ID;
int TriggerType = WiiMoteEmu::PadMapping[Page].triggertype;
// Check that Dolphin is in focus, otherwise don't update the pad status
//if (IsFocus())
- WiiMoteEmu::GetJoyState(WiiMoteEmu::PadState[Page], WiiMoteEmu::PadMapping[Page], Page, WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Page].ID).NumButtons);
-
+ WiiMoteEmu::GetJoyState(WiiMoteEmu::PadState[Page], WiiMoteEmu::PadMapping[Page], Page);
-
// Analog stick
// Set Deadzones perhaps out of function
//int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
@@ -695,16 +687,40 @@ void WiimotePadConfigDialog::PadGetStatus()
wxT("%03i"), TriggerRight));
}
+// Slow timer, once a second
+void WiimotePadConfigDialog::Update(wxTimerEvent& WXUNUSED(event))
+{
+ if (!LiveUpdates) return;
+
+ // Search for connected devices and update dialog
+ int OldNumDIDevices = WiiMoteEmu::NumDIDevices;
+ WiiMoteEmu::NumDIDevices = InputCommon::SearchDIDevices();
+
+ // Update if a pad has been connected/disconnected. Todo: Add a better check that also takes into consideration the pad id
+ // and other things to ensure nothing has changed
+ //DEBUG_LOG(WIIMOTE, "Found %i devices", WiiMoteEmu::NumDIDevices);
+ //DEBUG_LOG(WIIMOTE, "Update: %i %i", OldNumPads, WiiMoteEmu::NumPads);
+ if (OldNumDIDevices != WiiMoteEmu::NumDIDevices)
+ {
+ WiiMoteEmu::LocalSearchDevicesReset(WiiMoteEmu::joyinfo, WiiMoteEmu::NumPads);
+ WiimotePadConfigDialog::UpdateDeviceList();
+ }
+}
+
// Populate the advanced tab
void WiimotePadConfigDialog::UpdatePad(wxTimerEvent& WXUNUSED(event))
{
+ if (!WiiMoteEmu::IsPolling()) return;
+
+ //DEBUG_LOG(WIIMOTE, "UpdatePad");
+
// Show the current status
- /*
#ifdef SHOW_PAD_STATUS
- m_pStatusBar->SetLabel(wxString::Format(
- "%s", ShowStatus(notebookpage).c_str()
- ));
- #endif*/
+ m_pStatusBar->SetLabel(wxString::FromAscii(InputCommon::DoShowStatus(
+ Page, m_Joyname[Page]->GetSelection(),
+ WiiMoteEmu::PadMapping, WiiMoteEmu::PadState, WiiMoteEmu::joyinfo
+ ).c_str()));
+ #endif
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.cpp
index a9df2b6efe..44bd586247 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.cpp
@@ -98,6 +98,7 @@ BEGIN_EVENT_TABLE(WiimotePadConfigDialog,wxDialog)
EVT_BUTTON(IDB_TRIGGER_L, WiimotePadConfigDialog::GetButtons)
EVT_BUTTON(IDB_TRIGGER_R, WiimotePadConfigDialog::GetButtons)
EVT_TIMER(IDTM_BUTTON, WiimotePadConfigDialog::OnButtonTimer)
+ EVT_TIMER(IDTM_UPDATE, WiimotePadConfigDialog::Update)
EVT_TIMER(IDTM_UPDATE_PAD, WiimotePadConfigDialog::UpdatePad)
END_EVENT_TABLE()
@@ -107,14 +108,25 @@ WiimotePadConfigDialog::WiimotePadConfigDialog(wxWindow *parent, wxWindowID id,
{
#if wxUSE_TIMER
m_ButtonMappingTimer = new wxTimer(this, IDTM_BUTTON);
- m_UpdatePad = new wxTimer(this, IDTM_UPDATE_PAD);
+ m_Update = new wxTimer(this, IDTM_UPDATE);
+ m_UpdatePad = new wxTimer(this, IDTM_UPDATE_PAD);
// Reset values
GetButtonWaitingID = 0;
GetButtonWaitingTimer = 0;
+ // Settings
+ // Only tested in Windows
+ #ifdef _WIN32
+ LiveUpdates = true;
+ #else
+ LiveUpdates = false;
+ #endif
- // Start the permanent timer
- const int TimesPerSecond = 30;
+ // Start the slow timer
+ int TimesPerSecond = 2;
+ m_Update->Start( floor((double)(1000 / TimesPerSecond)) );
+ // Start the fast timer
+ TimesPerSecond = 30;
m_UpdatePad->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
@@ -128,6 +140,9 @@ WiimotePadConfigDialog::WiimotePadConfigDialog(wxWindow *parent, wxWindowID id,
// Set control values
UpdateGUI();
+
+ // Update device list
+ UpdateDeviceList();
wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN, // Keyboard
wxKeyEventHandler(WiimotePadConfigDialog::OnKeyDown),
@@ -204,9 +219,13 @@ void WiimotePadConfigDialog::OnClose(wxCloseEvent& event)
{
g_FrameOpen = false;
SaveButtonMappingAll(Page);
- if(m_UpdatePad)
- m_UpdatePad->Stop();
+ // Stop timers
+ if(m_Update) m_Update->Stop();
+ if(m_UpdatePad) m_UpdatePad->Stop();
+ if(m_ButtonMappingTimer) m_ButtonMappingTimer->Stop();
+ INFO_LOG(WIIMOTE, "All timers stopped");
g_Config.Save();
+
event.Skip();
}
@@ -228,18 +247,20 @@ void WiimotePadConfigDialog::CloseClick(wxCommandEvent& event)
void WiimotePadConfigDialog::DoSave(bool ChangePad, int Slot)
{
+ WARN_LOG(WIIMOTE, "DoSave - %i slot %i", ChangePad, Slot);
+
// Replace "" with "-1" before we are saving
ToBlank(false);
if(ChangePad)
{
// Since we are selecting the pad to save to by the Id we can't update it when we change the pad
- for(int i = 0; i < 4; i++)
+ for(int i = 0; i < MAX_WIIMOTES; i++)
SaveButtonMapping(i, true);
// Save the settings for the current pad
g_Config.Save(Slot);
// Now we can update the ID
- WiiMoteEmu::PadMapping[Page].ID = m_Joyname[Page]->GetSelection();
+ UpdateID();
}
else
{
@@ -251,8 +272,14 @@ void WiimotePadConfigDialog::DoSave(bool ChangePad, int Slot)
// Then change it back to ""
ToBlank();
-
- DEBUG_LOG(WIIMOTE, "WiiMoteEmu::PadMapping[%i].ID = %i", Page, m_Joyname[Page]->GetSelection());
+}
+void WiimotePadConfigDialog::UpdateID()
+{
+ INFO_LOG(WIIMOTE, "PadMapping[%i].ID = %i from %i",
+ Page, WiiMoteEmu::joyinfo.at(m_Joyname[Page]->GetSelection()).ID, WiiMoteEmu::PadMapping[Page].ID);
+ WiiMoteEmu::PadMapping[Page].ID = WiiMoteEmu::joyinfo.at(m_Joyname[Page]->GetSelection()).ID;
+ WiiMoteEmu::PadMapping[Page].Name = m_Joyname[Page]->GetValue().mb_str();
+ WiiMoteEmu::PadState[Page].joy = WiiMoteEmu::joyinfo.at(m_Joyname[Page]->GetSelection()).joy;
}
// Bitmap box and dot
@@ -325,24 +352,40 @@ wxBitmap WiimotePadConfigDialog::CreateBitmapClear()
return bitmap;
}
-
-
-void WiimotePadConfigDialog::CreatePadGUIControls()
+void WiimotePadConfigDialog::UpdateDeviceList()
{
+ if (!ControlsCreated) return;
+ DEBUG_LOG(WIIMOTE, "UpdateDeviceList");
- // Search for devices and add them to the device list
- wxArrayString StrJoyname; // The string array
- if (WiiMoteEmu::NumGoodPads > 0)
- {
- for (int x = 0; x < (int)WiiMoteEmu::joyinfo.size(); x++)
- StrJoyname.Add(wxString::FromAscii(WiiMoteEmu::joyinfo[x].Name.c_str()));
- }
- else
+ for (int i = 0; i < MAX_WIIMOTES; i++)
{
- StrJoyname.Add(wxString::FromAscii("<No Gamepad Detected>"));
- }
+ // Save current selection
+ //std::string CurrentSel = m_Joyname[i]->GetValue().mb_str();
+ m_Joyname[i]->Clear();
+ // Search for devices and add them to the device list
+ if (WiiMoteEmu::NumPads > 0)
+ {
+ for (int j = 0; j < WiiMoteEmu::NumPads; j++)
+ m_Joyname[i]->Append(wxString::FromAscii(WiiMoteEmu::joyinfo.at(j).Name.c_str()));
+ // Set selection
+ for (int j = 0; j < WiiMoteEmu::NumPads; j++)
+ if (WiiMoteEmu::joyinfo.at(j).Name == WiiMoteEmu::PadMapping[i].Name) m_Joyname[i]->SetSelection(j);
+ if (m_Joyname[i]->GetSelection() == -1) m_Joyname[i]->SetSelection(0);
+ // Load settings
+ DoChangeJoystick();
+ }
+ else
+ {
+ m_Joyname[i]->Append(wxString::FromAscii("<No Gamepad Detected>"));
+ m_Joyname[i]->SetSelection(0);
+ }
+ }
+}
+
+void WiimotePadConfigDialog::CreatePadGUIControls()
+{
// The tilt list
wxArrayString StrTilt;
StrTilt.Add(wxString::FromAscii("<Off>"));
@@ -372,13 +415,17 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
wxArrayString StrCcTriggers;
StrCcTriggers.Add(wxString::FromAscii("Keyboard"));
StrCcTriggers.Add(wxString::FromAscii("Triggers"));
-
-
+
+ #ifdef SHOW_PAD_STATUS
+ m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxSize(-1, 600));
+ m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(250, 250), wxDefaultSize);
+ #else
m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
+ #endif
for (int i = 0; i < MAX_WIIMOTES; i++)
- {
- m_Controller[i] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1 + i, wxDefaultPosition, wxDefaultSize);
+ {
+ m_Controller[i] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1 + i, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[i], wxString::Format(wxT("Wiimote %d"), i+1));
// A small type font
@@ -387,9 +434,8 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// Configuration controls sizes
static const int TxtW = 50, TxtH = 19, BtW = 75, BtH = 20;
-
// Controller
- m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, StrJoyname[0], wxDefaultPosition, wxSize(200, -1), StrJoyname, wxCB_READONLY);
+ m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, wxEmptyString, wxDefaultPosition, wxSize(200, -1), 0, NULL, wxCB_READONLY);
// Circle to square
m_CheckC2S[i] = new wxCheckBox(m_Controller[i], IDC_LEFT_C2S, wxT("Circle To Square"));
@@ -946,7 +992,6 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
}
-
m_Apply = new wxButton(this, ID_APPLY, wxT("Apply"));
m_Close = new wxButton(this, ID_CLOSE, wxT("Close"));
m_Close->SetToolTip(wxT("Apply and Close"));
@@ -1037,14 +1082,16 @@ void WiimotePadConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
void WiimotePadConfigDialog::UpdateGUI(int Slot)
{
+ DEBUG_LOG(WIIMOTE, "UpdateGUI");
+
UpdateGUIButtonMapping(Page);
DoChangeDeadZone(true); DoChangeDeadZone(false);
// Linux has no FindItem()
// Disable all pad items if no pads are detected
- if(ControlsCreated)
+ if (ControlsCreated)
{
- bool PadEnabled = WiiMoteEmu::NumGoodPads != 0;
+ bool PadEnabled = WiiMoteEmu::NumPads != 0;
#ifdef _WIN32
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++) m_Notebook->FindItem(i)->Enable(PadEnabled);
m_Notebook->FindItem(IDC_JOYNAME)->Enable(PadEnabled);
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.h
index ad200aa3cb..149e6304f8 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigPadDlg.h
@@ -59,9 +59,11 @@ class WiimotePadConfigDialog : public wxDialog
void Convert2Box(int &x);
void ConvertToString();
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
+ void Update(wxTimerEvent& WXUNUSED(event));
void UpdatePad(wxTimerEvent& WXUNUSED(event));
- wxTimer *m_UpdatePad,
+ wxTimer *m_Update,
+ *m_UpdatePad,
*m_ButtonMappingTimer;
wxStaticBitmap *m_bmpDotLeftIn[4],
@@ -74,6 +76,7 @@ class WiimotePadConfigDialog : public wxDialog
DECLARE_EVENT_TABLE();
bool ControlsCreated;
+ bool LiveUpdates;
int Page, BoxW, BoxH, g_Pressed;
wxNotebook *m_Notebook;
@@ -142,7 +145,9 @@ class WiimotePadConfigDialog : public wxDialog
*m_Button_GH3[GH3_CONTROLS][4],
*m_bGH3_Analog[4];
- wxStaticText *m_TextScreenWidth[4], *m_TextScreenHeight[4], *m_TextScreenLeft[4], *m_TextScreenTop[4], *m_TextAR[4],
+ wxStaticText
+ *m_pStatusBar,
+ *m_TextScreenWidth[4], *m_TextScreenHeight[4], *m_TextScreenLeft[4], *m_TextScreenTop[4], *m_TextAR[4],
*m_tAnalogX[8], *m_tAnalogY[8], *m_TiltTextRoll[4], *m_TiltTextPitch[4],
*m_CheckC2SLabel[4], *m_ComboDeadZoneLabel[4], *m_TStatusLeftIn[4], *m_TStatusLeftOut[4], *m_TStatusRightIn[4], *m_TStatusRightOut[4],
*m_TriggerStatusL[4], *m_TriggerStatusR[4], *m_TriggerStatusLx[4], *m_TriggerStatusRx[4],
@@ -178,10 +183,12 @@ class WiimotePadConfigDialog : public wxDialog
{
ID_CLOSE = 1000,
ID_APPLY,
- IDTM_EXIT,
+ IDTM_EXIT, // Timer
IDTM_BUTTON,
- IDTM_UPDATE_PAD, // Timer
-
+ IDTM_UPDATE,
+ IDTM_UPDATE_PAD,
+
+ IDT_DEBUGGING,
ID_NOTEBOOK,
ID_CONTROLLERPAGE1,
ID_CONTROLLERPAGE2,
@@ -246,6 +253,7 @@ class WiimotePadConfigDialog : public wxDialog
};
void OnClose(wxCloseEvent& event);
+ void UpdateDeviceList();
void CreatePadGUIControls();
void GeneralSettingsChanged(wxCommandEvent& event);
@@ -257,8 +265,9 @@ class WiimotePadConfigDialog : public wxDialog
void SaveKeyboardMapping(int Controller, int Id, int Key);
void ToBlank(bool ToBlank = true);
void PadGetStatus();
+ void UpdateID();
void DoSave(bool ChangePad = false, int Slot = -1);
- void DoChangeJoystick(); void PadOpen(int Open); void PadClose(int Close); void DoChangeDeadZone(bool Left);
+ void DoChangeJoystick(); void DoChangeDeadZone(bool Left);
void OnButtonClick(wxCommandEvent& event);
// Configure buttons
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp
index fd3af76015..d08b209f85 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.cpp
@@ -57,7 +57,8 @@ wiimote_key g_ExtKey; // The extension encryption key
bool g_Encryption; // Encryption on or off
// Gamepad input
-int NumPads = 0, NumGoodPads = 0; // Number of goods pads
+int NumPads = 0, NumDIDevices = 0; // Number of pads
+bool SDLPolling = true;
std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
InputCommon::CONTROLLER_STATE_NEW PadState[4];
InputCommon::CONTROLLER_MAPPING_NEW PadMapping[4];
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h
index 84ea66ca71..b69433528a 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h
@@ -182,7 +182,8 @@ static const u8 partially_id[] =
};
// Gamepad input
-extern int NumPads, NumGoodPads; // Number of goods pads
+extern int NumPads, NumDIDevices; // Number of pads
+extern bool SDLPolling; // Turn off polling
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
extern InputCommon::CONTROLLER_STATE_NEW PadState[4];
extern InputCommon::CONTROLLER_MAPPING_NEW PadMapping[4];
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp
index b2f8c11703..4383ceee07 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp
@@ -22,6 +22,7 @@
#include "../../../Core/InputCommon/Src/XInput.h"
#include "Common.h" // Common
+#include "LogManager.h"
#include "MathUtil.h"
#include "StringUtil.h" // for ArrayToString()
#include "IniFile.h"
@@ -59,7 +60,8 @@ void TiltTest(u8 x, u8 y, u8 z)
std::string To = StringFromFormat("%s\nTo: X:%i Y:%i Z:%i Roll:%s Pitch:%s", From.c_str(), x, y, z,
(_Roll >= 0) ? StringFromFormat(" %03i", (int)_Roll).c_str() : StringFromFormat("%04i", (int)_Roll).c_str(),
(_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str());
- DEBUG_LOG(WIIMOTE, "%s", To.c_str());
+ ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
+ Console->CustomLog(StringFromFormat("\n%s", To.c_str()).c_str());
}
@@ -100,14 +102,29 @@ void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_
// In these cases we can use the simple and accurate formula
if(g_Config.Trigger.Range.Pitch == 0)
{
- x = sin(_Roll);
- z = cos(_Roll);
+ if (!g_Config.Trigger.Upright)
+ {
+ x = sin(_Roll);
+ z = cos(_Roll);
+ }
+ else
+ {
+ z = sin(_Roll);
+ y = -cos(_Roll);
+ }
}
else if (g_Config.Trigger.Range.Roll == 0)
{
-
- y = sin(_Pitch);
- z = cos(_Pitch);
+ if (!g_Config.Trigger.Upright)
+ {
+ y = sin(_Pitch);
+ z = cos(_Pitch);
+ }
+ else
+ {
+ x = -sin(_Pitch);
+ y = -cos(_Pitch);
+ }
}
else
{
@@ -118,16 +135,28 @@ void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_
and Pitch. But if we select a Z from the smallest of the absolute
value of cos(Roll) and cos (Pitch) we get the right values. */
// ---------
- if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch);
- /* I got these from reversing the calculation in
- PitchAccelerometerToDegree() in a math program I don't know if we
- can derive these from some kind of matrix or something */
- float x_num = 2 * tanf(0.5f * _Roll) * z;
- float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
- x = - (x_num / x_den);
- float y_num = 2 * tanf(0.5f * _Pitch) * z;
- float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
- y = - (y_num / y_den);
+ if (!g_Config.Trigger.Upright)
+ {
+ if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch);
+ /* I got these from reversing the calculation in
+ PitchAccelerometerToDegree() in a math program. */
+ float x_num = 2 * tanf(0.5f * _Roll) * z;
+ float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
+ x = - (x_num / x_den);
+ float y_num = 2 * tanf(0.5f * _Pitch) * z;
+ float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
+ y = - (y_num / y_den);
+ }
+ else
+ {
+ if (abs(-cos(_Roll)) < abs(-cos(_Pitch))) y = -cos(_Roll); else y = -cos(_Pitch);
+ float z_num = 2 * tanf(0.5f * _Roll) * y;
+ float z_den = pow2f(tanf(0.5f * _Roll)) - 1;
+ z = (z_num / z_den);
+ float x_num = 2 * tanf(0.5f * _Pitch) * y;
+ float x_den = pow2f(tanf(0.5f * _Pitch)) - 1;
+ x = - (x_num / x_den);
+ }
}
// Multiply with the neutral of z and its g
@@ -145,9 +174,18 @@ void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_
if (ix < 0) ix = 0; if (ix > 255) ix = 255;
if (iy < 0) iy = 0; if (iy > 255) iy = 255;
if (iz < 0) iz = 0; if (iz > 255) iz = 255;
- if(g_Config.Trigger.Range.Roll != 0) _x = ix;
- if(g_Config.Trigger.Range.Pitch != 0) _y = iy;
- _z = iz;
+ if (!g_Config.Trigger.Upright)
+ {
+ if(g_Config.Trigger.Range.Roll != 0) _x = ix;
+ if(g_Config.Trigger.Range.Pitch != 0) _y = iy;
+ _z = iz;
+ }
+ else
+ {
+ if(g_Config.Trigger.Range.Roll != 0) _z = iz;
+ if(g_Config.Trigger.Range.Pitch != 0) _x = ix;
+ _y = iy;
+ }
}
// Accelerometer to roll and pitch angles
@@ -167,17 +205,34 @@ void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, in
float y = AccelerometerToG((float)_y, (float)g_wm.cal_zero.y, (float)g_wm.cal_g.y);
float z = AccelerometerToG((float)_z, (float)g_wm.cal_zero.z, (float)g_wm.cal_g.z);
- // If it is over 1g then it is probably accelerating and may not reliable
- //if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x)
+ if (!g_Config.Trigger.Upright)
{
- // Calculate the degree
- Roll = InputCommon::Rad2Deg(atan2(x, z));
- }
+ // If it is over 1g then it is probably accelerating and may not reliable
+ //if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x)
+ {
+ // Calculate the degree
+ Roll = InputCommon::Rad2Deg(atan2(x, z));
+ }
- //if (abs(_y - g_wm.cal_zero.y) <= g_wm.cal_g.y)
+ //if (abs(_y - g_wm.cal_zero.y) <= g_wm.cal_g.y)
+ {
+ // Calculate the degree
+ Pitch = InputCommon::Rad2Deg(atan2(y, z));
+ }
+ }
+ else
{
- // Calculate the degree
- Pitch = InputCommon::Rad2Deg(atan2(y, z));
+ //if (abs(accel->z - ac->cal_zero.z) <= ac->cal_g.x)
+ {
+ // Calculate the degree
+ Roll = InputCommon::Rad2Deg(atan2(z, -y));
+ }
+
+ //if (abs(_x - g_wm.cal_zero.x) <= g_wm.cal_g.x)
+ {
+ // Calculate the degree
+ Pitch = InputCommon::Rad2Deg(atan2(-x, -y));
+ }
}
_Roll = (int)Roll;
@@ -187,9 +242,16 @@ void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, in
if (x < -1.0) x = -1.0; else if (x > 1.0) x = 1.0;
if (y < -1.0) y = -1.0; else if (y > 1.0) y = 1.0;
if (z < -1.0) z = -1.0; else if (z > 1.0) z = 1.0;
- Roll = InputCommon::Rad2Deg(atan2(x, z));
- Pitch = InputCommon::Rad2Deg(atan2(y, z));
-
+ if (!g_Config.Trigger.Upright)
+ {
+ Roll = InputCommon::Rad2Deg(atan2(x, z));
+ Pitch = InputCommon::Rad2Deg(atan2(y, z));
+ }
+ else
+ {
+ Roll = InputCommon::Rad2Deg(atan2(z, -y));
+ Pitch = InputCommon::Rad2Deg(atan2(-x, -y));
+ }
_RollAdj = (int)Roll;
_PitchAdj = (int)Pitch;
}
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp
index 236b98cebd..7d993163ab 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp
@@ -34,7 +34,12 @@
#include "Encryption.h" // for extension encryption
#include "Config.h" // for g_Config
+#if defined(HAVE_WX) && HAVE_WX
+ #include "ConfigPadDlg.h"
+#endif
+
extern SWiimoteInitialize g_WiimoteInitialize;
+extern WiimotePadConfigDialog *m_PadConfigFrame;
namespace WiiMoteEmu
{
@@ -438,9 +443,9 @@ void Initialize()
/* Populate joyinfo for all attached devices and do g_Config.Load() if the
configuration window is not already open, if it's already open we
continue with the settings we have */
- if(!g_FrameOpen)
+ if (!m_PadConfigFrame)
{
- Search_Devices(joyinfo, NumPads, NumGoodPads);
+ LocalSearchDevices(joyinfo, NumPads);
}
// Copy extension id and calibration to its register, g_Config.Load() is needed before this
@@ -486,7 +491,6 @@ void DoState(PointerWrap &p)
p.Do(g_Encryption);
p.Do(NumPads);
- p.Do(NumGoodPads);
p.Do(joyinfo);
p.DoArray(PadState, 4);
p.DoArray(PadMapping, 4);
@@ -509,20 +513,16 @@ void Shutdown(void)
for (int i = 0; i < 1; i++)
{
if (PadMapping[i].enabled && joyinfo.size() > (u32)PadMapping[i].ID)
- if (joyinfo.at(PadMapping[i].ID).Good)
- {
- INFO_LOG(WIIMOTE, "ShutDown: %i", PadState[i].joy);
- /* SDL_JoystickClose() crashes for some reason so I avoid this
- for now, SDL_Quit() should close the pads to I think */
- //if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);
- //PadState[i].joy = NULL;
- }
+ INFO_LOG(WIIMOTE, "ShutDown: %i", PadState[i].joy);
+ /* SDL_JoystickClose() crashes for some reason so I avoid this
+ for now, SDL_Quit() should close the pads to I think */
+ //if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);
+ //PadState[i].joy = NULL;
}
// Clear the physical device info
joyinfo.clear();
NumPads = 0;
- NumGoodPads = 0;
// Finally close SDL
if (SDL_WasInit(0)) SDL_Quit();
@@ -693,21 +693,8 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
of times per second. */
void Update()
{
- readKeyboard();
- //LOG(WIIMOTE, "Wiimote_Update");
//INFO_LOG(WIIMOTE, "Emu Update: %i", g_ReportingMode);
- // Check if the pad state should be updated
- if ((g_Config.Trigger.Type == g_Config.Trigger.TRIGGER || g_Config.Trigger.Type == g_Config.Trigger.ANALOG1 || g_Config.Trigger.Type == g_Config.Trigger.ANALOG2
- || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1 || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG2
- || g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG2
- || g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG2)
- && NumGoodPads > 0 && joyinfo.size() > (u32)PadMapping[0].ID)
- {
- const int Page = 0;
- WiiMoteEmu::GetJoyState(PadState[Page], PadMapping[Page], Page, joyinfo[PadMapping[Page].ID].NumButtons);
- }
-
switch(g_ReportingMode)
{
case 0:
@@ -721,9 +708,22 @@ void Update()
// Potentially send a delayed acknowledgement to an InterruptChannel() Output
CheckAckDelay();
+
+ ReadKeyboard();
+
+ // Check if the pad state should be updated
+ if ((g_Config.Trigger.Type == g_Config.Trigger.TRIGGER || g_Config.Trigger.Type == g_Config.Trigger.ANALOG1 || g_Config.Trigger.Type == g_Config.Trigger.ANALOG2
+ || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1 || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG2
+ || g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG2
+ || g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG1 || g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG2)
+ && NumPads > 0 && joyinfo.size() > (u32)PadMapping[0].ID)
+ {
+ const int Page = 0;
+ WiiMoteEmu::GetJoyState(PadState[Page], PadMapping[Page], Page);
+ }
}
-void readKeyboard()
+void ReadKeyboard()
{
#if defined(HAVE_X11) && HAVE_X11
XEvent E;
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h
index 0878cd43db..f2664299ea 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h
@@ -41,7 +41,7 @@ void Shutdown(void);
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
void Update();
-void readKeyboard();
+void ReadKeyboard();
// Recordings
void LoadRecordedMovements();
@@ -52,8 +52,14 @@ void UpdateEeprom();
void UpdateExtRegisterBlocks();
// Gamepad
-bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
-void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons);
+bool LocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads);
+bool LocalSearchDevicesReset(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads);
+bool DoLocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads);
+bool IsConnected(std::string Name);
+bool IsPolling();
+void EnablePolling(bool Enable);
+std::string IDToName(int ID);
+void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller);
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr);
// Accelerometer
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp
index f100b43f76..302589d440 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp
@@ -23,6 +23,7 @@
#include "../../../Core/InputCommon/Src/XInput.h"
#include "Common.h" // Common
+#include "LogManager.h"
#include "StringUtil.h" // for ArrayToString()
#include "IniFile.h"
#include "pluginspecs_wiimote.h"
@@ -35,37 +36,138 @@
#include "Encryption.h" // for extension encryption
#include "Config.h" // for g_Config
+#if defined(HAVE_WX) && HAVE_WX
+ #include "ConfigPadDlg.h"
+#endif
+
extern SWiimoteInitialize g_WiimoteInitialize;
+extern WiimotePadConfigDialog *m_PadConfigFrame;
namespace WiiMoteEmu
{
+
+bool LocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads)
+{
+ //DEBUG_LOG(PAD, "LocalSearchDevices");
+ bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads);
+
+ DoLocalSearchDevices(_joyinfo, _NumPads);
+
+ return Success;
+}
+
+bool LocalSearchDevicesReset(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads)
+{
+ DEBUG_LOG(CONSOLE, "LocalSearchDevicesReset");
+
+ // Turn off device polling while resetting
+ EnablePolling(false);
+
+ bool Success = InputCommon::SearchDevicesReset(_joyinfo, _NumPads);
+
+ EnablePolling(true);
+
+ DoLocalSearchDevices(_joyinfo, _NumPads);
+
+ return Success;
+}
+
// Fill joyinfo with the current connected devices
-bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
+bool DoLocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads)
{
- bool WasGotten = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
+ //DEBUG_LOG(WIIMOTE, "LocalSearchDevices");
+
+ // Turn off device polling while searching
+ WiiMoteEmu::EnablePolling(false);
+
+ bool bReturn = InputCommon::SearchDevices(_joyinfo, _NumPads);
// Warn the user if no gamepads are detected
- if (_NumGoodPads == 0 && g_EmulatorRunning)
+ if (_NumPads == 0 && g_EmulatorRunning)
{
- //PanicAlert("nJoy: No Gamepad Detected");
+ //PanicAlert("Wiimote: No Gamepad Detected");
//return false;
}
- // Load PadMapping[] etc
- g_Config.Load();
+ // Load the first time
+ if (!g_Config.Loaded) g_Config.Load();
// Update the PadState[].joy handle
- for (int i = 0; i < 1; i++)
+ // If the saved ID matches, select this device for this slot
+ bool Match = false;
+ for (int i = 0; i < MAX_WIIMOTES; i++)
+ {
+ for (int j = 0; j < joyinfo.size(); j++)
+ {
+ if (joyinfo.at(j).Name == PadMapping[i].Name)
+ {
+ PadState[i].joy = joyinfo.at(j).joy;
+ Match = true;
+ //INFO_LOG(WIIMOTE, "Slot %i: '%s' %06i", i, joyinfo.at(j).Name.c_str(), PadState[i].joy);
+ }
+ }
+ if (!Match) PadState[i].joy = NULL;
+ }
+
+ WiiMoteEmu::EnablePolling(true);
+
+ return bReturn;
+}
+
+// Is the device connected?
+// ----------------
+bool IsConnected(std::string Name)
+{
+ for (int i = 0; i < joyinfo.size(); i++)
+ {
+ DEBUG_LOG(WIIMOTE, "Pad %i: IsConnected checking '%s' against '%s'", i, joyinfo.at(i).Name.c_str(), Name.c_str());
+ if (joyinfo.at(i).Name == Name)
+ return true;
+ }
+}
+// See description of the equivalent functions in nJoy.cpp...
+// ----------------
+bool IsPolling()
+{
+ return true;
+ /*
+ if (!SDLPolling || SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE)
+ return false;
+ else
+ return true;
+ */
+}
+void EnablePolling(bool Enable)
+{
+ /*
+ if (Enable)
{
- if (PadMapping[i].enabled && joyinfo.size() > (u32)PadMapping[i].ID)
- if(joyinfo.at(PadMapping[i].ID).Good)
- PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
+ SDLPolling = true;
+ SDL_JoystickEventState(SDL_IGNORE);
}
+ else
+ {
+ SDLPolling = false;
+ SDL_JoystickEventState(SDL_ENABLE);
+ }
+ */
+}
- return WasGotten;
+// ID to Name
+// ----------------
+std::string IDToName(int ID)
+{
+ for (int i = 0; i < joyinfo.size(); i++)
+ {
+ //DEBUG_LOG(WIIMOTE, "IDToName: ID %i id %i %s", ID, i, joyinfo.at(i).Name.c_str());
+ if (joyinfo.at(i).ID == ID)
+ return joyinfo.at(i).Name;
+ }
+ return "";
}
+
// Return adjusted input values
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
{
@@ -119,11 +221,20 @@ void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
Function: Updates the PadState struct with the current pad status. The input
value "controller" is for a virtual controller 0 to 3. */
-void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
+void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller)
{
- // Return if we have no pads
- if (NumGoodPads == 0) return;
+ //DEBUG_LOG(WIIMOTE, "GetJoyState: Polling:%i NumPads:%i", SDLPolling, NumPads);
+ // Return if polling is off
+ if (!IsPolling) return;
+ // Update joyinfo handles. This is in case the Wiimote plugin has restarted SDL after a pad was conencted/disconnected
+ // so that the handles are updated. We don't need to run this this often. Once a second would be enough.
+ LocalSearchDevices(joyinfo, NumPads);
+ // Return if we have no pads
+ if (NumPads == 0) return;
+ // Read info
+ int NumButtons = SDL_JoystickNumButtons(_PadState.joy);
+
// Update the gamepad status
SDL_JoystickUpdate();
@@ -152,14 +263,13 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
}
#endif
- /* Debugging
-// Console::ClearScreen();
- DEBUG_LOG(CONSOLE,
- "Controller and handle: %i %i\n"
-
- "Triggers:%i %i %i %i %i\n"
-
- "Analog:%06i %06i \n",
+ /* Debugging
+ ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
+ Console->ClearScreen();
+ Console->CustomLog(StringFromFormat(
+ "Controller: %i Handle: %i\n"
+ "Triggers: %i %i %i %i %i\n"
+ "Analog: %06i %06i \n",
controller, (int)_PadState.joy,
@@ -168,7 +278,8 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
_PadState.Axis.Tl, _PadState.Axis.Tr,
_PadState.Axis.Lx, _PadState.Axis.Ly
- );*/
+ ).c_str());
+ */
}
diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp
index aa46c800fe..29a7044866 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp
@@ -21,6 +21,7 @@
#include <string>
#include "Common.h" // Common
+#include "LogManager.h"
#include "Timer.h"
#include "pluginspecs_wiimote.h"
#include "StringUtil.h" // For ArrayToString
@@ -440,7 +441,7 @@ void SingleShake(u8 &_y, u8 &_z, int i)
void TiltWiimoteGamepad(float &Roll, float &Pitch)
{
// Return if we have no pads
- if (NumGoodPads == 0) return;
+ if (NumPads == 0) return;
// This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0;
diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp
index 1f9dae90ef..fc009f7ff0 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp
@@ -420,11 +420,13 @@ bool IsFocus()
HWND Parent = GetParent(RenderingWindow);
HWND TopLevel = GetParent(Parent);
// Allow updates when the config window is in focus to
- HWND Config = NULL;
- if (m_BasicConfigFrame)
- Config = (HWND)m_BasicConfigFrame->GetHWND();
+ HWND Config = NULL, ConfigPad = NULL, ConfigRecording = NULL;
+ if (m_BasicConfigFrame) Config = (HWND)m_BasicConfigFrame->GetHWND();
+ if (m_PadConfigFrame) ConfigPad = (HWND)m_PadConfigFrame->GetHWND();
+ if (m_RecordingConfigFrame) ConfigRecording = (HWND)m_RecordingConfigFrame->GetHWND();
// Support both rendering to main window and not
- if (GetForegroundWindow() == TopLevel || GetForegroundWindow() == RenderingWindow || GetForegroundWindow() == Config)
+ if (GetForegroundWindow() == TopLevel || GetForegroundWindow() == RenderingWindow || GetForegroundWindow() == Config
+ || GetForegroundWindow() == ConfigPad || GetForegroundWindow() == ConfigRecording)
return true;
else
return false;
@@ -757,12 +759,14 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
// ---------------------------------------------
// Test the angles to x, y, z values formula by calculating the values back and forth
// -----------
- /* //Console::ClearScreen();
+ /**/
+ ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
+ Console->ClearScreen();
// Show a test of our calculations
WiiMoteEmu::TiltTest(data[4], data[5], data[6]);
- u8 x, y, z;
- WiiMoteEmu::Tilt(x, y, z);
- WiiMoteEmu::TiltTest(x, y, z);*/
+ //u8 x, y, z;
+ //WiiMoteEmu::Tilt(x, y, z);
+ //WiiMoteEmu::TiltTest(x, y, z);
// -------------------------
// ---------------------------------------------
diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.h b/Source/Plugins/Plugin_Wiimote/Src/main.h
index 197e351ea2..8cfcfb31c0 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/main.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/main.h
@@ -35,7 +35,7 @@ int GetUpdateRate();
void InterruptDebugging(bool Emu, const void* _pData);
void ReadDebugging(bool Emu, const void* _pData, int Size);
bool IsFocus();
-
+#define MAX_WIIMOTES 1
// Movement recording
#define RECORDING_ROWS 15
diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h
index d422785f5e..d3892a9fb9 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h
@@ -26,8 +26,6 @@
namespace WiiMoteReal
{
-#define MAX_WIIMOTES 1
-
int Initialize();
void DoState(PointerWrap &p);
void Shutdown(void);
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj
index 315b60edfd..1bc24c3873 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj
+++ b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj
@@ -471,7 +471,7 @@
AdditionalDependencies="SDL.lib comctl32.lib rpcrt4.lib xinput.lib winmm.lib wxbase28u.lib wxmsw28u_core.lib"
OutputFile="..\..\..\Binary\x64\Plugins\$(ProjectName)DF.dll"
LinkIncremental="1"
- AdditionalLibraryDirectories="..\..\..\Externals\SDL\x64;..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
+ AdditionalLibraryDirectories="..\..\..\Externals\wxWidgets\lib\vc_lib\x64"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp
index 28862c8248..ed030d1b2d 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp
@@ -46,6 +46,7 @@ Config::Config()
{
// Clear the memory
//memset(this, 0, sizeof(Config));
+ Loaded = false;
}
@@ -95,7 +96,7 @@ void DEBUG_QUIT()
void Config::Save(int Slot)
{
// If there are no good pads don't save
- if (NumGoodPads == 0) return;
+ if (NumPads == 0) return;
// Load ini file
IniFile file;
@@ -127,22 +128,27 @@ void Config::Save(int Slot)
// Save the physical device ID
file.Set(SectionName.c_str(), "joy_id", PadMapping[i].ID);
+ file.Set(SectionName.c_str(), "joy_name", PadMapping[i].Name);
// ===================
// ==================================================================
// Joypad or slot specific settings
// -----------------
- // Current joypad device ID: PadMapping[i].ID
- // Current joypad name: joyinfo[PadMapping[i].ID].Name
+ // Current joypad device ID: PadMapping[i].ID
+ // Current joypad name: IDToName(PadMapping[i].ID])
if(g_Config.bSaveByID)
{
- /* Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to
- avoid reading a joyinfo that does't exist */
- if((u32)PadMapping[i].ID >= joyinfo.size()) continue;
-
// Create a new section name after the joypad name
- SectionName = joyinfo[PadMapping[i].ID].Name;
+ SectionName = IDToName(PadMapping[i].ID);
+ // Don't save a blank name
+ if (SectionName == "")
+ {
+ ERROR_LOG(PAD, "ID %i has no name, will not save", PadMapping[i].ID);
+ continue;
+ }
}
+
+ NOTICE_LOG(PAD, "Save settings for ID %i '%s' from PadMapping[%i]", PadMapping[i].ID, SectionName.c_str(), i);
file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER]);
file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER]);
@@ -180,8 +186,6 @@ void Config::Save(int Slot)
file.Set(SectionName.c_str(), "SquareToCircleC", PadMapping[i].bSquareToCircleC);
}
- INFO_LOG(CONSOLE, "%i: Save: %i\n", 0, PadMapping[0].halfpress);
-
file.Save(FULL_CONFIG_DIR "nJoy.ini");
}
@@ -189,8 +193,7 @@ void Config::Save(int Slot)
// -----------------------
void Config::Load(bool ChangePad, bool ChangeSaveByID)
{
- // If there are no good pads don't load
- if (NumGoodPads == 0) return;
+ Loaded = true;
// Load file
IniFile file;
@@ -211,6 +214,9 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
}
// =============
+ // If there are no good pads don't load anymore
+ if (NumPads == 0) return;
+
for (int i = 0; i < 4; i++)
{
std::string SectionName = StringFromFormat("PAD%i", i+1);
@@ -219,23 +225,32 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
if (!ChangePad)
{
file.Get(SectionName.c_str(), "joy_id", &PadMapping[i].ID, 0);
+ file.Get(SectionName.c_str(), "joy_name", &PadMapping[i].Name, "");
}
// ==================================================================
// Joypad or slot specific settings
// -----------------
- // Current joypad device ID: PadMapping[i].ID
- // Current joypad name: joyinfo[PadMapping[i].ID].Name
- if(g_Config.bSaveByID)
+ // Current joypad device ID: PadMapping[i].ID
+ // Current joypad name: IDToName(PadMapping[i].ID)
+ if (g_Config.bSaveByID)
{
- // Prevent a crash from illegal access to joyinfo that will only have values for
- // the current amount of connected pads
- if((u32)PadMapping[i].ID >= joyinfo.size()) continue;
-
// Create a section name
- SectionName = joyinfo[PadMapping[i].ID].Name;
+ SectionName = PadMapping[i].Name;
+ // Don't load settings for a non-connected device
+ if (!IsConnected(SectionName))
+ {
+ ERROR_LOG(PAD, "Slot %i: The device '%s' is not connected, will not load settings", SectionName.c_str());
+ continue;
+ }
+ // Don't load a blank ID
+ if (SectionName == "")
+ {
+ ERROR_LOG(PAD, "Slot %i has no device name, will not load settings", i);
+ continue;
+ }
}
-
+
file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER], 4);
file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER], 5);
file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[InputCommon::CTL_A_BUTTON], 0);
@@ -269,8 +284,11 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
file.Get(SectionName.c_str(), "RadiusOnOffC", &Tmp, false); PadMapping[i].bRadiusOnOffC = Tmp;
file.Get(SectionName.c_str(), "DiagonalC", &PadMapping[i].SDiagonalC, "100%");
file.Get(SectionName.c_str(), "SquareToCircleC", &Tmp, false); PadMapping[i].bSquareToCircleC = Tmp;
+
+ NOTICE_LOG(PAD, "Slot %i: Load settings for ID %i '%s'", i, PadMapping[i].ID, SectionName.c_str());
+
}
- INFO_LOG(CONSOLE, "%i: Load: %i\n", 0, PadMapping[0].halfpress);
+ //INFO_LOG(PAD, "%i: Load: %i\n", 0, PadMapping[0].halfpress);
}
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h
index 3b20ba8919..9bcb23524d 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h
@@ -23,9 +23,10 @@ struct Config
Config();
void Load(bool ChangePad = false, bool ChangeSaveByID = false);
void Save(int Slot = -1);
+ bool Loaded;
int CheckForDuplicateJoypads(bool OK);
- // General
+ // Settings
bool bShowAdvanced; // Only allow one of these
bool bSaveByID;
bool bCheckFocus;
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp
index c9b590d2c2..57e286491e 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp
@@ -1,4 +1,3 @@
-
// Project description
// -------------------
// Name: nJoy
@@ -32,14 +31,15 @@
// ---------
#include "ConfigBox.h"
#include "../nJoy.h"
+#include "LogManager.h"
#include "Images/controller.xpm"
extern bool g_EmulatorRunning;
// Set PAD status
// --------------
-void PADConfigDialognJoy::PadGetStatus()
-{
+void PADConfigDialognJoy::PadShowStatus()
+{
// Return if it's not detected. The ID should never be less than zero here, it can only be that
// because of a manual ini file change, but we make that check anway.
if(PadMapping[notebookpage].ID < 0 || PadMapping[notebookpage].ID >= SDL_NumJoysticks())
@@ -51,7 +51,7 @@ void PADConfigDialognJoy::PadGetStatus()
}
// Get physical device status
- int PhysicalDevice = PadMapping[notebookpage].ID;
+ int ID = PadMapping[notebookpage].ID;
int TriggerType = PadMapping[notebookpage].triggertype;
// Get original values
@@ -105,7 +105,6 @@ void PADConfigDialognJoy::PadGetStatus()
m_bmpDotOutC[notebookpage]->SetPosition(wxPoint(sub_x_out, sub_y_out));
///////////////////// Analog stick
-
// Triggers
// -----------------
@@ -143,84 +142,12 @@ void PADConfigDialognJoy::PadGetStatus()
///////////////////// Triggers
}
-// Show the current pad status
-// -----------------
-std::string ShowStatus(int VirtualController)
-{
- // Save the physical device
- int PhysicalDevice = PadMapping[VirtualController].ID;
-
- // Make local shortcut
- SDL_Joystick *joy = PadState[VirtualController].joy;
-
- // Make shortcuts for all pads
- SDL_Joystick *joy0 = PadState[0].joy;
- SDL_Joystick *joy1 = PadState[1].joy;
- SDL_Joystick *joy2 = PadState[2].joy;
- SDL_Joystick *joy3 = PadState[3].joy;
-
- // Temporary storage
- std::string StrAxes, StrHats, StrBut;
- int value;
-
- // Get status
- int Axes = joyinfo[PhysicalDevice].NumAxes;
- int Balls = joyinfo[PhysicalDevice].NumBalls;
- int Hats = joyinfo[PhysicalDevice].NumHats;
- int Buttons = joyinfo[PhysicalDevice].NumButtons;
-
- // Update the internal values
- SDL_JoystickUpdate();
-
- // Go through all axes and read out their values
- for(int i = 0; i < Axes; i++)
- {
- value = SDL_JoystickGetAxis(joy, i);
- StrAxes += StringFromFormat(" %i:%06i", i, value);
- }
- for(int i = 0;i < Hats; i++)
- {
- value = SDL_JoystickGetHat(joy, i);
- StrHats += StringFromFormat(" %i:%i", i, value);
- }
- for(int i = 0;i < Buttons; i++)
- {
- value = SDL_JoystickGetButton(joy, i);
- StrBut += StringFromFormat(" %i:%i", i+1, value);
- }
-
- return StringFromFormat(
- "All pads:\n"
- "ID: %i %i %i %i\n"
- "Controllertype: %i %i %i %i\n"
- "SquareToCircle: %i %i %i %i\n\n"
- #ifdef _WIN32
- "Handles: %i %i %i %i\n"
- "XInput: %i %i %i\n"
- #endif
-
- "This pad:\n"
- "Axes: %s\n"
- "Hats: %s\n"
- "But: %s\n"
- "Device: Ax: %i Balls:%i Hats:%i But:%i",
- PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID,
- PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype,
- PadMapping[0].bSquareToCircle, PadMapping[1].bSquareToCircle, PadMapping[2].bSquareToCircle, PadMapping[3].bSquareToCircle,
- #ifdef _WIN32
- joy0, joy1, joy2, joy3,
- //PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy,
- XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R),
- #endif
- StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
- Axes, Balls, Hats, Buttons
- );
-}
-
-// Populate the advanced tab
+// Update the advanced tab
// -----------------
void PADConfigDialognJoy::Update()
-{
+{
+ if (!IsPolling()) return;
+
// Check that Dolphin is in focus, otherwise don't update the pad status
/* If the emulator is running and unpaused GetJoyState() is run a little more often than needed,
but I allow that since it can confuse the user if the input status in the configuration window
@@ -228,17 +155,41 @@ void PADConfigDialognJoy::Update()
if (g_Config.bCheckFocus || IsFocus()) // && !g_EmulatorRunning)
{
for (int i = 0; (u32)i < joyinfo.size(); i++)
- InputCommon::GetJoyState(PadState[i], PadMapping[i], i, joyinfo[PadMapping[i].ID].NumButtons);
+ InputCommon::GetJoyState(PadState[notebookpage], PadMapping[notebookpage]);
+ PadShowStatus();
}
// Show the current status in a window in the wxPanel
#ifdef SHOW_PAD_STATUS
- m_pStatusBar->SetLabel(wxString::Format(
- "%s", ShowStatus(notebookpage).c_str()
- ));
+ m_pStatusBar->SetLabel(wxString::FromAscii(InputCommon::ShowStatus(
+ notebookpage, m_Joyname[notebookpage]->GetSelection(),
+ PadMapping, PadState, joyinfo
+ ).c_str()));
#endif
}
+// Search for devices
+void PADConfigDialognJoy::UpdateSlow()
+{
+ if (!LiveUpdates) return;
+
+ // Search for connected devices and update dialog
+ int OldNumDIDevices = NumDIDevices;
+ NumDIDevices = InputCommon::SearchDIDevices();
+
+ // Update if a pad has been connected/disconnected. Todo: Add a better check that also takes into consideration the pad id
+ // and other things to better ensure that nothing has changed
+ //DEBUG_LOG(PAD, "Found %i devices", NumDIDevices);
+ //DEBUG_LOG(PAD, "UpdateSlow: %i %i", OldNumPads, NumPads);
+ if (OldNumDIDevices != NumDIDevices)
+ {
+ WARN_LOG(PAD, "\n---- %s ----", (NumDIDevices > OldNumDIDevices) ? "Pad connected" : "Pad disconnected");
+ LocalSearchDevicesReset(joyinfo, NumPads);
+ UpdateDeviceList();
+ // Enable controls again, if disabled
+ UpdateGUIAll();
+ }
+}
// Populate the advanced tab
// -----------------
@@ -368,6 +319,5 @@ wxBitmap PADConfigDialognJoy::CreateBitmapArea(int Max, int Diagonal)
Points[7].x = (int)(-Diagonal * Adj + iAdj); Points[7].y = (int)(Diagonal * Adj + iAdj);
// Draw polygon
dc.DrawPolygon(8, Points);
-
return bitmap;
} \ No newline at end of file
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp
index d4a342a48f..357c583ea9 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp
@@ -103,6 +103,7 @@ BEGIN_EVENT_TABLE(PADConfigDialognJoy,wxDialog)
EVT_BUTTON(IDB_ANALOG_SUB_Y, PADConfigDialognJoy::GetButtons)
#if wxUSE_TIMER
+ EVT_TIMER(IDTM_SLOW, PADConfigDialognJoy::OnSlowTimer)
EVT_TIMER(IDTM_CONSTANT, PADConfigDialognJoy::OnTimer)
EVT_TIMER(IDTM_BUTTON, PADConfigDialognJoy::OnButtonTimer)
#endif
@@ -112,26 +113,40 @@ PADConfigDialognJoy::PADConfigDialognJoy(wxWindow *parent, wxWindowID id, const
const wxPoint &position, const wxSize& size, long style)
: wxDialog(parent, id, title, position, size, style)
{
- // Define values
+ // Initialize values
notebookpage = 0;
- g_Pressed = 0;
- Debugging = false;
+ g_Pressed = 0;
m_TCDebugging = NULL;
ControlsCreated = false;
+
+ // Settings
+ Debugging = false;
+ // Only tested in Windows
+ #ifdef _WIN32
+ LiveUpdates = true;
+ #else
+ LiveUpdates = false;
+ #endif
// Create controls
CreateGUIControls();
+
+ // Update GUI
+ UpdateGUIAll();
+
+ // Update device list
+ UpdateDeviceList();
#if wxUSE_TIMER
+ m_SlowTimer = new wxTimer(this, IDTM_SLOW);
m_ConstantTimer = new wxTimer(this, IDTM_CONSTANT);
m_ButtonMappingTimer = new wxTimer(this, IDTM_BUTTON);
// Reset values
GetButtonWaitingID = 0; GetButtonWaitingTimer = 0;
- // Start the constant timer
- int TimesPerSecond = 30;
- m_ConstantTimer->Start( floor((double)(1000 / TimesPerSecond)) );
+ // Start timers
+ StartTimer();
#endif
// wxEVT_KEY_DOWN is blocked for enter, tab and the directional keys
@@ -148,6 +163,24 @@ PADConfigDialognJoy::~PADConfigDialognJoy()
#endif
}
+void PADConfigDialognJoy::DoShow()
+{
+ // Start timers
+ StartTimer();
+ // Show
+ ShowModal();
+}
+
+void PADConfigDialognJoy::StartTimer()
+{
+ // Start the slow timer
+ double TimesPerSecond = 2;
+ m_SlowTimer->Start( floor((double)(1000.0 / TimesPerSecond)) );
+ // Start the constant timer
+ TimesPerSecond = 30;
+ m_ConstantTimer->Start( floor((double)(1000 / TimesPerSecond)) );
+}
+
void PADConfigDialognJoy::OnKeyDown(wxKeyEvent& event)
{
g_Pressed = event.GetKeyCode();
@@ -160,7 +193,9 @@ void PADConfigDialognJoy::OnClose(wxCloseEvent& event)
event.Skip();
// Stop the timer
+ m_SlowTimer->Stop();
m_ConstantTimer->Stop();
+ m_ButtonMappingTimer->Stop();
// Close pads, unless we are running a game
if (!g_EmulatorRunning) Shutdown();
@@ -256,7 +291,7 @@ void PADConfigDialognJoy::DoSave(bool ChangePad, int Slot)
g_Config.Save(Slot);
// Now we can update the ID
- PadMapping[notebookpage].ID = m_Joyname[notebookpage]->GetSelection();
+ UpdateID();
}
else
{
@@ -268,6 +303,21 @@ void PADConfigDialognJoy::DoSave(bool ChangePad, int Slot)
// Then change it back to ""
ToBlank();
}
+void PADConfigDialognJoy::UpdateID()
+{
+ INFO_LOG(PAD, "Slot %i: Changed PadMapping ID from %i to %i", notebookpage, PadMapping[notebookpage].ID, m_Joyname[notebookpage]->GetSelection());
+ PadMapping[notebookpage].ID = joyinfo.at(m_Joyname[notebookpage]->GetSelection()).ID;
+ PadMapping[notebookpage].Name = joyinfo.at(m_Joyname[notebookpage]->GetSelection()).Name;
+ // Update all handles
+ for(int i = 0; i < 4; i++)
+ {
+ if (PadMapping[i].Name == PadMapping[notebookpage].Name)
+ {
+ if (m_Joyname[i]->GetSelection() >= 0 && joyinfo.size() > m_Joyname[i]->GetSelection())
+ PadState[i].joy = joyinfo.at(m_Joyname[i]->GetSelection()).joy;
+ }
+ }
+}
// On changing the SaveById option we update all pages
void PADConfigDialognJoy::OnSaveById()
@@ -290,11 +340,52 @@ void PADConfigDialognJoy::OnSaveById()
void PADConfigDialognJoy::DoChangeJoystick()
{
// Before changing the pad we save potential changes to the current pad (to support SaveByID)
+ WARN_LOG(PAD, "\n--- DoChangeJoystick ----");
+ WARN_LOG(PAD, "DoSave");
DoSave(true);
- // Load the settings for the new Id
+ // Load the settings for the new ID
+ WARN_LOG(PAD, "Load");
g_Config.Load(true);
- UpdateGUI(notebookpage); // Update the GUI
+ // Update the GUI
+ WARN_LOG(PAD, "UpdateGUI");
+ UpdateGUI(notebookpage);
+ WARN_LOG(PAD, "");
+}
+// Pads have been connected/disconnected
+void PADConfigDialognJoy::UpdateDeviceList()
+{
+ if (!ControlsCreated) return;
+
+ DEBUG_LOG(PAD, "UpdateDeviceList");
+
+ for (int i = 0; i < 4; i++)
+ {
+ // Save current selection
+ //std::string CurrentSel = m_Joyname[i]->GetValue().mb_str();
+ m_Joyname[i]->Clear();
+
+ // Search for devices and add them to the device list
+ if (NumPads > 0)
+ {
+ for (int j = 0; j < NumPads; j++)
+ m_Joyname[i]->Append(wxString::FromAscii(joyinfo.at(j).Name.c_str()));
+ // Set selection
+ //PanicAlert("%s", PadMapping[i].Name.c_str());
+ for (int j = 0; j < NumPads; j++)
+ {
+ if (joyinfo.at(j).Name == PadMapping[i].Name) m_Joyname[i]->SetSelection(j);
+ }
+ if (m_Joyname[i]->GetSelection() == -1) m_Joyname[i]->SetSelection(0);
+ // Load settings
+ DoChangeJoystick();
+ }
+ else
+ {
+ m_Joyname[i]->Append(wxString::FromAscii("<No Gamepad Detected>"));
+ m_Joyname[i]->SetSelection(0);
+ }
+ }
}
// Notebook page changed
@@ -303,7 +394,7 @@ void PADConfigDialognJoy::NotebookPageChanged(wxNotebookEvent& event)
// Save current settings now, don't wait for OK
if (ControlsCreated && !g_Config.bSaveByID) DoSave(false, notebookpage);
- // Update the global variable
+ // Update the global variable
notebookpage = event.GetSelection();
// Update GUI
@@ -335,28 +426,28 @@ void PADConfigDialognJoy::ToBlank(bool ToBlank)
}
-// Change settings
+// Change settings for all slots that have this pad selected
+// -----------------------
void PADConfigDialognJoy::SetButtonTextAll(int id, const char *text)
{
for (int i = 0; i < 4; i++)
{
- // Safety check to avoid crash
- if (joyinfo.size() > (u32)PadMapping[i].ID)
- if (joyinfo[PadMapping[i].ID].Name == joyinfo[PadMapping[notebookpage].ID].Name)
- SetButtonText(id, text, i);
+ if (IDToName(PadMapping[i].ID) == IDToName(PadMapping[notebookpage].ID))
+ {
+ SetButtonText(id, text, i);
+ DEBUG_LOG(PAD, "Updated button text for slot %i", i);
+ }
};
}
-
void PADConfigDialognJoy::SaveButtonMappingAll(int Slot)
{
for (int i = 0; i < 4; i++)
{
- // This can occur when no gamepad is detected
- if (joyinfo.size() > (u32)PadMapping[i].ID)
- if (joyinfo[PadMapping[i].ID].Name == joyinfo[PadMapping[Slot].ID].Name)
- SaveButtonMapping(i, false, Slot);
+ if (IDToName(PadMapping[i].ID) == IDToName(PadMapping[Slot].ID))
+ SaveButtonMapping(i, false, Slot);
}
}
+// -----------------------
void PADConfigDialognJoy::UpdateGUIAll(int Slot)
{
@@ -368,10 +459,8 @@ void PADConfigDialognJoy::UpdateGUIAll(int Slot)
{
for (int i = 0; i < 4; i++)
{
- // Safety check to avoid crash
- if (joyinfo.size() > (u32)PadMapping[i].ID)
- if (joyinfo[PadMapping[i].ID].Name == joyinfo[PadMapping[Slot].ID].Name)
- UpdateGUI(i);
+ if (IDToName(PadMapping[i].ID) == IDToName(PadMapping[Slot].ID))
+ UpdateGUI(i);
}
}
}
@@ -438,8 +527,10 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
}
// Update all slots that use this device
- if(g_Config.bSaveByID) SaveButtonMappingAll(notebookpage);
- if(g_Config.bSaveByID) UpdateGUIAll(notebookpage);
+ //if(g_Config.bSaveByID)
+ SaveButtonMappingAll(notebookpage);
+ //if(g_Config.bSaveByID)
+ UpdateGUIAll(notebookpage);
}
@@ -447,12 +538,18 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
// Called from: CreateGUIControls(), ChangeControllertype()
void PADConfigDialognJoy::UpdateGUI(int _notebookpage)
{
+ DEBUG_LOG(PAD, "UpdateGUI for slot %i, %i pads connected", _notebookpage, NumPads);
+
// If there are no good pads disable the entire notebook
- if (NumGoodPads == 0)
+ if (NumPads == 0)
{
m_Notebook->Enable(false);
return;
}
+ else
+ {
+ m_Notebook->Enable(true);
+ }
// Update the GUI from PadMapping[]
UpdateGUIButtonMapping(_notebookpage);
@@ -505,6 +602,8 @@ void PADConfigDialognJoy::UpdateGUI(int _notebookpage)
else m_CoBRadiusC[_notebookpage]->Enable(false);
if (PadMapping[_notebookpage].bSquareToCircleC) m_CoBDiagonalC[_notebookpage]->Enable(true);
else m_CoBDiagonalC[_notebookpage]->Enable(false);
+
+ DEBUG_LOG(PAD, "Main radius %s", PadMapping[_notebookpage].bRadiusOnOff ? "enabled" : "disabled");
}
// Repaint the background
@@ -565,24 +664,9 @@ void PADConfigDialognJoy::CreateGUIControls()
m_Controller[3] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE4, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[3], wxT("Controller 4"));
-
// Define bitmap for EVT_PAINT
WxStaticBitmap1_BITMAP = wxBitmap(ConfigBox_WxStaticBitmap1_XPM);
- // Search for devices and add them to the device list
- wxArrayString arrayStringFor_Joyname; // The string array
- if (NumGoodPads > 0)
- {
- for(int x = 0; (u32)x < joyinfo.size(); x++)
- {
- arrayStringFor_Joyname.Add(wxString::FromAscii(joyinfo[x].Name.c_str()));
- }
- }
- else
- {
- arrayStringFor_Joyname.Add(wxString::FromAscii("<No Gamepad Detected>"));
- }
-
// Populate the DPad type and Trigger type list
wxArrayString wxAS_DPadType;
wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_HAT]));
@@ -721,7 +805,7 @@ void PADConfigDialognJoy::CreateGUIControls()
// Populate Controller sizer
// Groups
#ifdef _WIN32
- m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, arrayStringFor_Joyname[0], wxDefaultPosition, wxSize(476, 21), arrayStringFor_Joyname, wxCB_READONLY);
+ m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, wxEmptyString, wxDefaultPosition, wxSize(476, 21), 0, NULL, wxCB_READONLY);
#else
m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, arrayStringFor_Joyname[0], wxDefaultPosition, wxSize(450, 25), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname"));
#endif
@@ -954,9 +1038,6 @@ void PADConfigDialognJoy::CreateGUIControls()
// Show or hide it. We have to do this after we add it to its sizer
m_sMainRight[i]->Show(g_Config.bShowAdvanced);
-
- // Update GUI
- UpdateGUI(i);
} // end of loop
// Populate buttons sizer.
@@ -975,7 +1056,7 @@ void PADConfigDialognJoy::CreateGUIControls()
// Debugging
#ifdef SHOW_PAD_STATUS
- m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize);
+ m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxSize(200, -1));
#endif
// Set window size
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h
index a0a5fa7b84..041bf77e9c 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h
@@ -62,12 +62,17 @@ class PADConfigDialognJoy : public wxDialog
long style = wxDEFAULT_DIALOG_STYLE);
virtual ~PADConfigDialognJoy();
+ // Timers
#if wxUSE_TIMER
+ void OnSlowTimer(wxTimerEvent& WXUNUSED(event)) { UpdateSlow(); }
void OnTimer(wxTimerEvent& WXUNUSED(event)) { Update(); }
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
- wxTimer *m_ConstantTimer, *m_ButtonMappingTimer;
+ wxTimer *m_SlowTimer, *m_ConstantTimer, *m_ButtonMappingTimer;
#endif
+ // Functions
+ void DoShow();
+
// Debugging
wxStaticText* m_pStatusBar, * m_pStatusBar2;
wxTextCtrl* m_TCDebugging;
@@ -195,7 +200,10 @@ class PADConfigDialognJoy : public wxDialog
*m_bmpSquare[4], *m_bmpDot[4], *m_bmpSquareOut[4], *m_bmpDotOut[4], *m_bmpAreaOut[4],
*m_bmpSquareC[4], *m_bmpDotC[4], *m_bmpSquareOutC[4], *m_bmpDotOutC[4], *m_bmpAreaOutC[4];
- int notebookpage; bool ControlsCreated;
+ // Settings
+ int notebookpage;
+ bool ControlsCreated;
+ bool LiveUpdates;
private:
enum
@@ -233,7 +241,7 @@ class PADConfigDialognJoy : public wxDialog
IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
// Timers
- IDTM_CONSTANT, IDTM_BUTTON,
+ IDTM_SLOW, IDTM_CONSTANT, IDTM_BUTTON,
// ==============================================
@@ -316,6 +324,8 @@ class PADConfigDialognJoy : public wxDialog
void OKClick(wxCommandEvent& event);
void CancelClick(wxCommandEvent& event);
void DoSave(bool ChangePad = false, int Slot = -1);
+ void UpdateID();
+ void StartTimer();
void DoChangeJoystick();
@@ -323,20 +333,22 @@ class PADConfigDialognJoy : public wxDialog
void ChangeSettings(wxCommandEvent& event);
void ComboChange(wxCommandEvent& event);
-
+
void OnClose(wxCloseEvent& event);
+ void UpdateDeviceList();
void CreateGUIControls();
void CreateAdvancedControls(int i);
wxBitmap CreateBitmap();
wxBitmap CreateBitmapDot();
wxBitmap CreateBitmapArea(int,int);
- void PadGetStatus();
+ void PadShowStatus();
+ void UpdateSlow();
void Update();
void UpdateGUIButtonMapping(int controller);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1);
void SaveButtonMappingAll(int Slot);
- void UpdateGUIAll(int Slot);
+ void UpdateGUIAll(int Slot = -1);
void ToBlank(bool ToBlank = true);
void OnSaveById();
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
index e0dc1341e0..68c69b1fb8 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
@@ -50,8 +50,11 @@ void PADConfigDialognJoy::UpdateGUIButtonMapping(int controller)
// http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString
wxString tmp;
+ // Assert
+ //if (!ControlsCreated[i]) return;
+
// Update selected gamepad
- m_Joyname[controller]->SetSelection(PadMapping[controller].ID);
+ m_Joyname[controller]->SetValue(wxString::FromAscii(PadMapping[controller].Name.c_str()));
tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear();
@@ -99,7 +102,8 @@ void PADConfigDialognJoy::UpdateGUIButtonMapping(int controller)
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
}
-
+
+ NOTICE_LOG(PAD, "Loaded from PadMapping[%i] to slot %i", controller, controller);
}
/* Populate the PadMapping array with the dialog items settings (for example
@@ -117,7 +121,21 @@ void PADConfigDialognJoy::SaveButtonMapping(int controller, bool DontChangeId, i
ToBlank(false);
// Set other settings
- if(!DontChangeId) PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection();
+ if(!DontChangeId)
+ {
+ if (joyinfo.size() > m_Joyname[FromSlot]->GetSelection())
+ {
+ INFO_LOG(PAD, "%i: Changed PadMapping ID from %i to %i", controller, PadMapping[controller].ID, joyinfo.at(m_Joyname[FromSlot]->GetSelection()).ID);
+ PadMapping[controller].ID = joyinfo.at(m_Joyname[FromSlot]->GetSelection()).ID;
+ }
+ //else
+ // Assert
+ PadMapping[controller].Name = m_Joyname[FromSlot]->GetValue().mb_str();
+ }
+
+ NOTICE_LOG(PAD, "Saved PadMapping[%i] from slot %i", controller, FromSlot);
+
+ // Settings
PadMapping[controller].controllertype = m_ControlType[FromSlot]->GetSelection();
PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection();
@@ -264,6 +282,13 @@ void PADConfigDialognJoy::GetButtons(wxCommandEvent& event)
void PADConfigDialognJoy::DoGetButtons(int GetId)
{
+ //INFO_LOG(PAD, "DoGetButtons: %i", GetId);
+
+ if (!SDLPolling || SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE) return;
+
+ // Turn off live updates because the change the joy handles
+ LiveUpdates = false;
+
// =============================================
// Collect the starting values
// ----------------
@@ -280,7 +305,7 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
int Axes = SDL_JoystickNumAxes(joy);
int Hats = SDL_JoystickNumHats(joy);
- INFO_LOG(CONSOLE, "PadID: %i Axes: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy);
+ //NOTICE_LOG(PAD, "PadID: %i Axes: %i Handle: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy);
// Get the controller and trigger type
int ControllerType = PadMapping[Controller].controllertype;
@@ -343,6 +368,8 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
#if wxUSE_TIMER
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
+
+ //INFO_LOG(PAD, "Timer started");
}
// ===============================================
@@ -353,7 +380,7 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
else
{
InputCommon::GetButton(
- joy, PadID, Buttons, Axes, Hats,
+ joy, PadID,
g_Pressed, value, type, pressed, Succeed, Stop,
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
}
@@ -368,7 +395,7 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
GetButtonWaitingTimer++;
// This is run every second
- if(GetButtonWaitingTimer % TimesPerSecond == 0)
+ if (GetButtonWaitingTimer % TimesPerSecond == 0)
{
// Current time
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
@@ -379,7 +406,7 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
}
// Time's up
- if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
+ if ( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
{
Stop = true;
// Leave a blank mapping
@@ -387,8 +414,10 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
}
// If we got a button
- if(Succeed)
+ if (Succeed)
{
+ //INFO_LOG(PAD, "Button mapping succeeded: %i", pressed);
+
Stop = true;
// Write the number of the pressed button to the text box
sprintf(format, "%d", pressed);
@@ -396,10 +425,12 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
}
// Stop the timer
- if(Stop)
+ if (Stop)
{
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
+ LiveUpdates = true;
+ //INFO_LOG(PAD, "Timer stopped");
/* Update the button mapping for all slots that use this device. (It doesn't make sense to have several slots
controlled by the same device, but several DirectInput instances of different but identical devices may possible
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
index df25836922..d97c9de45d 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
@@ -48,7 +48,8 @@ std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
InputCommon::CONTROLLER_STATE PadState[4];
InputCommon::CONTROLLER_MAPPING PadMapping[4];
bool g_EmulatorRunning = false;
-int NumPads = 0, NumGoodPads = 0, LastPad = 0;
+bool SDLPolling = true;
+int NumPads = 0, NumDIDevices = 0, LastPad = 0;
#ifdef _WIN32
HWND m_hWnd = NULL, m_hConsole = NULL; // Handle to window
#endif
@@ -154,11 +155,9 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
// ------------------
void DllConfig(HWND _hParent)
{
- // Init Joystick + Haptic (force feedback) subsystem on SDL 1.3
// Populate joyinfo for all attached devices
- Search_Devices(joyinfo, NumPads, NumGoodPads);
-
- g_Config.Load(); // load settings
+ LocalSearchDevices(joyinfo, NumPads);
+ //g_Config.Load(); // load settings
#if defined(HAVE_WX) && HAVE_WX
if (!m_ConfigFrame)
@@ -168,9 +167,9 @@ void DllConfig(HWND _hParent)
// Only allow one open at a time
if (!m_ConfigFrame->IsShown())
- m_ConfigFrame->ShowModal();
+ m_ConfigFrame->DoShow();
else
- m_ConfigFrame->Hide();
+ m_ConfigFrame->Hide();
#endif
}
@@ -194,7 +193,7 @@ void Initialize(void *init)
#endif
// Populate joyinfo for all attached devices
- Search_Devices(joyinfo, NumPads, NumGoodPads);
+ LocalSearchDevices(joyinfo, NumPads);
}
// Shutdown PAD (stop emulation)
@@ -221,18 +220,16 @@ void Shutdown()
for (int i = 0; i < 4; i++)
{
if (joyinfo.size() > (u32)PadMapping[i].ID)
- if (joyinfo.at(PadMapping[i].ID).Good)
- if(SDL_JoystickOpened(PadMapping[i].ID))
- {
- SDL_JoystickClose(PadState[i].joy);
- PadState[i].joy = NULL;
- }
+ if(SDL_JoystickOpened(PadMapping[i].ID))
+ {
+ SDL_JoystickClose(PadState[i].joy);
+ PadState[i].joy = NULL;
+ }
}
// Clear the physical device info
joyinfo.clear();
NumPads = 0;
- NumGoodPads = 0;
// Finally close SDL
SDL_Quit();
@@ -283,6 +280,12 @@ void DoState(unsigned char **ptr, int mode)
// Function: Gives the current pad status to the Core
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
{
+ if (!IsPolling()) return;
+
+ // Update joyinfo handles. This is in case the Wiimote plugin has restarted SDL after a pad was conencted/disconnected
+ // so that the handles are updated.
+ LocalSearchDevices(joyinfo, NumPads);
+
// Check if the pad is avaliable, currently we don't disable pads just because they are
// disconnected
if (!PadState[_numPAD].joy) return;
@@ -292,7 +295,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Check that Dolphin is in focus, otherwise don't update the pad status
if (g_Config.bCheckFocus || IsFocus())
- GetJoyState(PadState[_numPAD], PadMapping[_numPAD], _numPAD, joyinfo[PadMapping[_numPAD].ID].NumButtons);
+ GetJoyState(PadState[_numPAD], PadMapping[_numPAD]);
// Get type
int TriggerType = PadMapping[_numPAD].triggertype;
@@ -439,29 +442,137 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Search for SDL devices
// ----------------
-bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
+
+bool LocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads)
{
- bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
+ // Turn off device polling while searching
+ EnablePolling(false);
+
+ //DEBUG_LOG(PAD, "LocalSearchDevices");
+ bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads);
+
+ DoLocalSearchDevices(_joyinfo, _NumPads);
+
+ EnablePolling(true);
+
+ return Success;
+}
- // Warn the user if no gamepads are detected
- if (_NumGoodPads == 0 && g_EmulatorRunning)
+bool LocalSearchDevicesReset(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads)
+{
+ //DEBUG_LOG(PAD, "LocalSearchDevicesUpdate: %i", IsPolling());
+
+ bool Success = InputCommon::SearchDevicesReset(_joyinfo, _NumPads);
+
+ DoLocalSearchDevices(_joyinfo, _NumPads);
+
+ return Success;
+}
+
+
+bool DoLocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads)
+{
+ // Don't warn the user if no gamepads are detected. If the pad doesn't respond he will open the configuration and fix it.
+ // Also, if he's using a Wii game he may not care that the gamepad is turned off.
+ if (_NumPads == 0 && g_EmulatorRunning)
{
- PanicAlert("nJoy: No Gamepad Detected");
+ //PanicAlert("nJoy: No Gamepad Detected");
return false;
}
- // Load PadMapping[] etc
- g_Config.Load();
+ // Load the first time
+ if (!g_Config.Loaded) g_Config.Load();
// Update the PadState[].joy handle
for (int i = 0; i < 4; i++)
{
- if (joyinfo.size() > (u32)PadMapping[i].ID)
- if(joyinfo.at(PadMapping[i].ID).Good)
- PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
+ for (int j = 0; j < joyinfo.size(); j++)
+ {
+ if (joyinfo.at(j).Name == PadMapping[i].Name)
+ {
+ PadState[i].joy = joyinfo.at(j).joy;
+ //DEBUG_LOG(PAD, "Slot %i: %s", i, joyinfo.at(j).Name.c_str());
+ }
+ }
}
- return Success;
+ return true;
+}
+
+
+// Is the device connected?
+// ----------------
+bool IsConnected(std::string Name)
+{
+ for (int i = 0; i < joyinfo.size(); i++)
+ {
+ //DEBUG_LOG(PAD, "IDToName: ID %i id %i %s", ID, i, joyinfo.at(i).Name.c_str());
+ if (joyinfo.at(i).Name == Name)
+ return true;
+ }
+}
+
+// Earlier versions of SDL could crash if SDL functions were called during SDL_Quit/SDL_Init. I could not get
+// such a crash in the new version even with frequent SDL_Quit/SDL_Init so thse functions are disabled now.
+// ----------------
+bool IsPolling()
+{
+ return true;
+ /*
+ if (!SDLPolling || SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE)
+ return false;
+ else
+ return true;
+ */
+}
+void EnablePolling(bool Enable)
+{
+ /*
+ if (Enable)
+ {
+ SDLPolling = true;
+ SDL_JoystickEventState(SDL_IGNORE);
+ }
+ else
+ {
+ SDLPolling = false;
+ SDL_JoystickEventState(SDL_ENABLE);
+ }
+ */
+}
+
+// ID to Name
+// ----------------
+std::string IDToName(int ID)
+{
+ for (int i = 0; i < joyinfo.size(); i++)
+ {
+ //DEBUG_LOG(PAD, "IDToName: ID %i id %i %s", ID, i, joyinfo.at(i).Name.c_str());
+ if (joyinfo.at(i).ID == ID)
+ return joyinfo.at(i).Name;
+ }
+ return "";
+}
+
+// ID to id - Get the gamepad id from a device ID (the ids will be all or some of the IDs)
+// ----------------
+int IDToid(int ID)
+{
+ for (int i = 0; i < joyinfo.size(); i++)
+ {
+ if (joyinfo.at(i).ID == ID)
+ return i;
+ }
+ if (joyinfo.size() > 0)
+ {
+ ERROR_LOG(PAD, "IDToid error");
+ return 0;
+ }
+ else
+ {
+ PanicAlert("Error in IDToid. The plugin may crash.");
+ return -1;
+ }
}
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
index 54e274a3ed..fea488b47d 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
@@ -95,13 +95,23 @@
#ifdef _WIN32
extern HWND m_hWnd, m_hConsole; // Handle to window
#endif
- extern int NumPads, NumGoodPads, LastPad; // Number of goods pads
+ extern int NumPads, NumDIDevices, LastPad; // Number of pads
+ extern bool SDLPolling;
#endif
// Custom Functions
// ----------------
-bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
+bool LocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads);
+bool LocalSearchDevicesReset(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads);
+bool DoLocalSearchDevices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads);
+int SearchDIDevices();
+bool IsConnected(std::string Name);
+bool IsPolling();
+void EnablePolling(bool Enable);
+std::string IDToName(int ID);
+bool IsConnected(std::string Name);
+int IDToid(int ID);
void DEBUG_INIT();
void DEBUG_QUIT();
bool IsFocus();