Updated rumble for nJoy, fixed a few glitches with half press button and deadzones too.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2840 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
sl1nk3.s
2009-04-02 21:13:58 +00:00
parent e24e2db1a1
commit b0852c1bef
10 changed files with 365 additions and 334 deletions
+1
View File
@@ -92,6 +92,7 @@ struct CONTROLLER_MAPPING // GC PAD MAPPING
int triggertype; // Triggers range
std::string SDiagonal;
bool bSquareToCircle;
bool rumble;
int eventnum; // Linux Event Number, Can't be found dynamically yet
};
@@ -271,13 +271,15 @@ void DInput_Read(int _numPAD, SPADStatus* _pPADStatus)
if (dinput.diks[pad[_numPAD].keyForControl[CTL_L]] & 0xFF)
{
_pPADStatus->button |= PAD_TRIGGER_L;
if (triggervalue > 230)
_pPADStatus->button |= PAD_TRIGGER_L;
_pPADStatus->triggerLeft = triggervalue;
}
if (dinput.diks[pad[_numPAD].keyForControl[CTL_R]] & 0xFF)
{
_pPADStatus->button |= PAD_TRIGGER_R;
if (triggervalue > 230)
_pPADStatus->button |= PAD_TRIGGER_R;
_pPADStatus->triggerRight = triggervalue;
}
@@ -111,6 +111,7 @@ void Config::Save(int Slot)
file.Set("General", "SaveByID", g_Config.bSaveByID);
file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
file.Set("General", "RumbleStrength", g_Config.RumbleStrength);
#ifdef RERECORDING
file.Set("General", "Recording", g_Config.bRecording);
file.Set("General", "Playback", g_Config.bPlayback);
@@ -171,6 +172,7 @@ void Config::Save(int Slot)
file.Set(SectionName.c_str(), "controllertype", PadMapping[i].controllertype);
file.Set(SectionName.c_str(), "TriggerType", PadMapping[i].triggertype);
file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum);
file.Set(SectionName.c_str(), "use_rumble", PadMapping[i].rumble);
file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
@@ -203,6 +205,7 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
file.Get("General", "RumbleStrength", &g_Config.RumbleStrength, 8);
#ifdef RERECORDING
file.Get("General", "Recording", &g_Config.bRecording, false);
file.Get("General", "Playback", &g_Config.bPlayback, false);
@@ -263,6 +266,7 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
file.Get(SectionName.c_str(), "controllertype", &PadMapping[i].controllertype, 0);
file.Get(SectionName.c_str(), "TriggerType", &PadMapping[i].triggertype, 0);
file.Get(SectionName.c_str(), "eventnum", &PadMapping[i].eventnum, 0);
file.Get(SectionName.c_str(), "use_rumble", &PadMapping[i].rumble, false);
file.Get(SectionName.c_str(), "Diagonal", &PadMapping[i].SDiagonal, "100%");
file.Get(SectionName.c_str(), "SquareToCircle", &Tmp, false); PadMapping[i].bSquareToCircle = Tmp;
@@ -30,6 +30,7 @@ struct Config
bool bSaveByID;
bool bCheckFocus;
bool bNoTriggerFilter;
int RumbleStrength;
#ifdef RERECORDING
bool bRecording;
bool bPlayback;
@@ -6,7 +6,7 @@
//
// Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
//
//////////////////////////////////////////////////////////////////////////////////////////
//
@@ -80,6 +80,10 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
EVT_COMBOBOX(IDC_TRIGGERTYPE, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDC_DEADZONE, ConfigBox::ChangeSettings)
// Rumble settings
EVT_CHECKBOX(IDC_ENABLERUMBLE, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDC_RUMBLESTRENGTH, ConfigBox::ChangeSettings)
// Advanced settings
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings)
@@ -203,7 +207,6 @@ void ConfigBox::OKClick(wxCommandEvent& event)
if (event.GetId() == ID_OK)
{
DoSave(); // Save settings
//g_Config.Load(); // Reload settings to PadMapping
if(Debugging) PanicAlert("Done");
Close(); // Call OnClose()
}
@@ -217,7 +220,6 @@ void ConfigBox::CancelClick(wxCommandEvent& event)
{
// Forget all potential changes to PadMapping by loading the last saved settings
g_Config.Load();
Close(); // Call OnClose()
}
}
@@ -485,7 +487,13 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event )
UpdateGUI(notebookpage);
}
break;
case IDC_ENABLERUMBLE:
PadMapping[notebookpage].rumble = m_Rumble[notebookpage]->IsChecked();
UpdateGUI(notebookpage);
break;
case IDC_RUMBLESTRENGTH:
g_Config.RumbleStrength = m_RStrength[notebookpage]->GetSelection();
break;
case IDC_JOYNAME:
DoChangeJoystick();
break;
@@ -555,17 +563,17 @@ void ConfigBox::UpdateGUI(int _notebookpage)
m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced);
m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus);
m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter);
m_RStrength[_notebookpage]->SetSelection(g_Config.RumbleStrength);
#ifdef RERECORDING
m_CheckRecording[_notebookpage]->SetValue(g_Config.bRecording);
m_CheckPlayback[_notebookpage]->SetValue(g_Config.bPlayback);
#endif
//LogMsg("Update: %i\n", g_Config.bSaveByID);
// Disabled pages
bool Enabled = PadMapping[_notebookpage].enabled == 1 ? true : false;
// There is no FindItem in linux so this doesn't work
#ifdef _WIN32
// Disabled pages
bool Enabled = PadMapping[_notebookpage].enabled == 1 ? true : false;
// Enable or disable all buttons
for(int i = IDB_ANALOG_MAIN_X; i <= IDB_BUTTONHALFPRESS; i++)
m_Controller[_notebookpage]->FindItem(i)->Enable(Enabled);
@@ -680,11 +688,20 @@ void ConfigBox::CreateGUIControls()
wxArrayString wxAS_TriggerType;
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_SDL]));
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_XINPUT]));
// --------------------------------------------------------------------
// Populate the deadzone list
// Populate the deadzone list and the Rumble Strength
// -----------------------------
char buffer [8];
char buffer[8];
wxArrayString wxAS_RumbleStrength;
for (int i = 1; i < 11; i++)
{
sprintf (buffer, "%d %%", i*10);
wxAS_RumbleStrength.Add(wxString::FromAscii(buffer));
}
wxArrayString arrayStringFor_Deadzone;
for(int x = 1; x <= 100; x++)
{
@@ -692,7 +709,6 @@ void ConfigBox::CreateGUIControls()
arrayStringFor_Deadzone.Add(wxString::FromAscii(buffer));
}
// Populate all four pages
for(int i = 0; i < 4; i++)
{
@@ -880,6 +896,17 @@ void ConfigBox::CreateGUIControls()
m_gGenSettingsID[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 3);
m_gGenSettingsID[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3);
// Create objects for Rumble settings (general 4)
m_RStrength[i] = new wxComboBox(m_Controller[i], IDC_RUMBLESTRENGTH, wxAS_RumbleStrength[0], wxDefaultPosition, wxSize(85, 20), wxAS_RumbleStrength, wxCB_READONLY);
m_Rumble[i] = new wxCheckBox(m_Controller[i], IDC_ENABLERUMBLE, wxT("Enable Rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Populate general settings 4
m_gRumble[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Rumble Settings"));
m_gGBRumble[i] = new wxGridBagSizer(0, 0);
m_gGBRumble[i]->Add(m_Rumble[i], wxGBPosition(0, 0), wxGBSpan(1, 1), (wxTOP), 1);
m_gGBRumble[i]->Add(m_RStrength[i], wxGBPosition(1, 0), wxGBSpan(1, 1), (wxTOP), 6);
m_gRumble[i]->Add(m_gGBRumble[i], 0, wxEXPAND | wxALL, 3);
// Create tooltips
m_ControlType[i]->SetToolTip(wxT(
"Use a 'hat' on your gamepad or configure a custom button for each direction."
@@ -899,6 +926,8 @@ void ConfigBox::CreateGUIControls()
m_sSettings[i]->Add(m_gExtrasettings[i], 0, wxEXPAND | wxALL, 0);
m_sSettings[i]->Add(m_gGenSettings[i], 0, wxEXPAND | wxLEFT, 5);
m_sSettings[i]->Add(m_gGenSettingsID[i], 0, wxEXPAND | wxLEFT, 5);
m_sSettings[i]->Add(m_gRumble[i], 0, wxEXPAND | wxLEFT, 5);
// -------------------------
//////////////////////////// General settings
@@ -112,16 +112,21 @@ class ConfigBox : public wxDialog
wxStaticBoxSizer *m_gGenSettings[4];
wxStaticBoxSizer *m_gGenSettingsID[4];
wxGridBagSizer * m_gGBGenSettings[4];
wxGridBagSizer *m_gGBGenSettings[4];
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4];
wxStaticText *m_TSControltype[4], *m_TSTriggerType[4];
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4], *m_gStatusAdvancedSettings[4]; // Advanced settings
wxBoxSizer *m_gStatusInSettingsH[4];
wxGridBagSizer * m_GBAdvancedMainStick[4];
wxGridBagSizer *m_GBAdvancedMainStick[4];
wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_STDiagonal[4];
wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4];
wxCheckBox *m_CBCheckFocus[4], *m_AdvancedMapFilter[4];
wxCheckBox *m_Rumble[4]; // Rumble settings
wxComboBox *m_RStrength[4];
wxStaticBoxSizer *m_gRumble[4];
wxGridBagSizer *m_gGBRumble[4];
wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers
wxStaticText *m_TStatusTriggers[4];
@@ -218,6 +223,8 @@ class ConfigBox : public wxDialog
IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type
IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings
IDC_ENABLERUMBLE, IDC_RUMBLESTRENGTH, IDT_RUMBLESTRENGTH, // Rumble
ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status
ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4,
@@ -80,11 +80,12 @@ void ConfigBox::UpdateGUIButtonMapping(int controller)
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
// Update Rumble checkbox
m_Rumble[controller]->SetValue(PadMapping[controller].rumble);
#ifdef RERECORDING
m_CheckRecording[controller]->SetValue(g_Config.bRecording);
m_CheckPlayback[controller]->SetValue(g_Config.bPlayback);
#endif
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
// Update D-Pad
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
@@ -99,8 +100,6 @@ void ConfigBox::UpdateGUIButtonMapping(int controller)
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
}
// Replace "-1" with "" in the GUI controls
//if(ControlsCreated) ToBlank();
}
/* Populate the PadMapping array with the dialog items settings (for example
File diff suppressed because it is too large Load Diff
+41 -40
View File
@@ -6,7 +6,7 @@
//
// Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
//
//////////////////////////////////////////////////////////////////////////////////////////
//
@@ -38,6 +38,7 @@
The StrangeHack in ConfigAdvanced.cpp doesn't work in Linux, it still wont resize the
window correctly. So currently in Linux you have to have advanced controls enabled when
you open the window to see them.
// TODO : we should not need a Hack in the first place :/
////////////////////////*/
@@ -80,7 +81,6 @@
// Variables
// ¯¯¯¯¯¯¯¯¯
// Rumble in windows
#define _EXCLUDE_MAIN_ // Avoid certain declarations in nJoy.h
FILE *pFile;
HINSTANCE nJoy_hInst = NULL;
@@ -95,14 +95,11 @@ int NumPads = 0, NumGoodPads = 0, LastPad = 0;
SPADInitialize *g_PADInitialize = NULL;
PLUGIN_GLOBALS* globals = NULL;
// Rumble
#ifdef _WIN32
#elif defined(__linux__)
// Rumble
#if defined(__linux__)
extern int fd;
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// wxWidgets
// ¯¯¯¯¯¯¯¯¯
@@ -249,15 +246,15 @@ void Initialize(void *init)
INFO_LOG(CONSOLE, "Initialize: %i\n", SDL_WasInit(0));
g_PADInitialize = (SPADInitialize*)init;
g_EmulatorRunning = true;
#ifdef _WIN32
m_hWnd = (HWND)g_PADInitialize->hWnd;
#endif
#ifdef _DEBUG
DEBUG_INIT();
#endif
#ifdef _WIN32
m_hWnd = (HWND)g_PADInitialize->hWnd;
#endif
// Populate joyinfo for all attached devices if the configuration window is not already open
#if defined(HAVE_WX) && HAVE_WX
if(!m_frame)
@@ -327,9 +324,7 @@ void Shutdown()
g_PADInitialize = NULL;
#ifdef _WIN32
#ifdef USE_RUMBLE_DINPUT_HACK
FreeDirectInput();
#endif
FreeDirectInput();
#elif defined(__linux__)
close(fd);
#endif
@@ -415,6 +410,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
return;
}
#endif
// ----------------------
// Clear pad status
@@ -426,6 +422,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Get type
int TriggerType = PadMapping[_numPAD].triggertype;
int TriggerValue = PadState[_numPAD].halfpress ? 100 : 255;
///////////////////////////////////////////////////
// The analog controls
@@ -440,7 +437,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
int TriggerRight = PadState[_numPAD].axis[InputCommon::CTL_R_SHOULDER];
// Check if we should make adjustments
if(PadMapping[_numPAD].bSquareToCircle)
if (PadMapping[_numPAD].bSquareToCircle)
{
std::vector<int> main_xy = InputCommon::Square2Circle(i_main_stick_x, i_main_stick_y, _numPAD, PadMapping[_numPAD].SDiagonal);
i_main_stick_x = main_xy.at(0);
@@ -454,54 +451,61 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
u8 sub_stick_y = InputCommon::Pad_Convert(i_sub_stick_y);
// Convert the triggers values, if we are using analog triggers at all
if(PadMapping[_numPAD].triggertype == InputCommon::CTL_TRIGGER_SDL)
if (PadMapping[_numPAD].triggertype == InputCommon::CTL_TRIGGER_SDL)
{
if(PadMapping[_numPAD].buttons[InputCommon::CTL_L_SHOULDER] >= 1000) TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
if(PadMapping[_numPAD].buttons[InputCommon::CTL_R_SHOULDER] >= 1000) TriggerRight = InputCommon::Pad_Convert(TriggerRight);
if (PadMapping[_numPAD].buttons[InputCommon::CTL_L_SHOULDER] >= 1000) TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
if (PadMapping[_numPAD].buttons[InputCommon::CTL_R_SHOULDER] >= 1000) TriggerRight = InputCommon::Pad_Convert(TriggerRight);
}
// Set Deadzones (perhaps out of function?)
int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone + 1));
int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone + 1));
// Set Deadzone
float deadzone = (128.00 * (float)(PadMapping[_numPAD].deadzone + 1.00)) / 100.00;
float distance_main = (float)sqrt((float)(main_stick_x * main_stick_x) + (float)(main_stick_y * main_stick_y));
float distance_sub = (float)sqrt((float)(sub_stick_x * sub_stick_x) + (float)(sub_stick_y * sub_stick_y));
// Send values to Dolpin if they are outside the deadzone
if ((main_stick_x < deadzone2) || (main_stick_x > deadzone)) _pPADStatus->stickX = main_stick_x;
if ((main_stick_y < deadzone2) || (main_stick_y > deadzone)) _pPADStatus->stickY = main_stick_y;
if ((sub_stick_x < deadzone2) || (sub_stick_x > deadzone)) _pPADStatus->substickX = sub_stick_x;
if ((sub_stick_y < deadzone2) || (sub_stick_y > deadzone)) _pPADStatus->substickY = sub_stick_y;
if (distance_main > deadzone)
{
_pPADStatus->stickX = main_stick_x;
_pPADStatus->stickY = main_stick_y;
}
if (distance_sub > deadzone)
{
_pPADStatus->substickX = sub_stick_x;
_pPADStatus->substickY = sub_stick_y;
}
///////////////////////////////////////////////////
// The L and R triggers
// -----------
int TriggerValue = 255;
if (PadState[_numPAD].halfpress) TriggerValue = 100;
// -----------
_pPADStatus->button |= PAD_USE_ORIGIN; // Neutral value, no button pressed
// Neutral value, no button pressed
_pPADStatus->button |= PAD_USE_ORIGIN;
// Check if the digital L button is pressed
if (PadState[_numPAD].buttons[InputCommon::CTL_L_SHOULDER])
{
_pPADStatus->button |= PAD_TRIGGER_L;
if (!PadState[_numPAD].halfpress)
_pPADStatus->button |= PAD_TRIGGER_L;
_pPADStatus->triggerLeft = TriggerValue;
}
// no the digital L button is not pressed, but the analog left trigger is
else if(TriggerLeft > 0)
else if (TriggerLeft > 0)
_pPADStatus->triggerLeft = TriggerLeft;
// Check if the digital R button is pressed
if (PadState[_numPAD].buttons[InputCommon::CTL_R_SHOULDER])
{
_pPADStatus->button |= PAD_TRIGGER_R;
if (!PadState[_numPAD].halfpress)
_pPADStatus->button |= PAD_TRIGGER_R;
_pPADStatus->triggerRight = TriggerValue;
}
// no the digital R button is not pressed, but the analog right trigger is
else if(TriggerRight > 0)
else if (TriggerRight > 0)
_pPADStatus->triggerRight = TriggerRight;
// Update the buttons in analog mode to
if(TriggerLeft == 0xff) _pPADStatus->button |= PAD_TRIGGER_L;
if(TriggerRight == 0xff) _pPADStatus->button |= PAD_TRIGGER_R;
// Update the buttons in analog mode too
if (TriggerLeft > 0xf0) _pPADStatus->button |= PAD_TRIGGER_L;
if (TriggerRight > 0xf0) _pPADStatus->button |= PAD_TRIGGER_R;
///////////////////////////////////////////////////
@@ -548,9 +552,6 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Update error code
_pPADStatus->err = PAD_ERR_NONE;
// Use rumble
Pad_Use_Rumble(_numPAD, _pPADStatus);
// -------------------------------------------
// Rerecording
// ----------------------
+9 -20
View File
@@ -33,15 +33,6 @@
#ifndef __NJOY_h__
#define __NJOY_h__
//////////////////////////////////////////////////////////////////////////////////////////
// Settings
// ¯¯¯¯¯¯¯¯¯¯
// Set this if you want to use the rumble 'hack' for controller one
//#define USE_RUMBLE_DINPUT_HACK
//////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Includes
// ¯¯¯¯¯¯¯¯¯¯
@@ -71,13 +62,12 @@
#define DIRECTINPUT_VERSION 0x0800
#define WIN32_LEAN_AND_MEAN
#ifdef USE_RUMBLE_DINPUT_HACK
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "winmm.lib")
#include <dinput.h>
VOID FreeDirectInput(); // Needed in both nJoy.cpp and Rumble.cpp
#endif
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "winmm.lib")
#include <dinput.h>
void FreeDirectInput(); // Needed in both nJoy.cpp and Rumble.cpp
#endif // _WIN32
#ifdef _WIN32
@@ -142,11 +132,10 @@ void DEBUG_INIT();
void DEBUG_QUIT();
bool IsFocus();
bool ReloadDLL();
#ifdef _WIN32
HRESULT InitRumble(HWND hWnd);
#endif
void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble
//void SaveConfig();
//void LoadConfig();
////////////////////////////////