mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
nJoy: First implementation of an analog stick radius adjustment. Converting a square radius to a circle radius.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1698 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Project description
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
@ -30,18 +30,42 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variables guide
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
The arrays joysticks[] and joystate[] are numbered 0 to 3 for the four different virtual
|
||||
controllers. Joysticks[].ID will have the number of the inputs device mapped to that controller,
|
||||
this value can be between 0 and the total number of connected physical devices. The mapping
|
||||
is done by PAD_Initialize(), if we want to change that we have to run PAD_Shutdown() and then
|
||||
run PAD_Initialize() again.
|
||||
|
||||
The joyinfo[] array is for a certain physical device. It's therefore used as
|
||||
joyinfo[joysticks[controller].ID].
|
||||
|
||||
////////////////////////*/
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#include "nJoy.h"
|
||||
|
||||
// Declare config window so that we can write debugging info to it from functions in this file
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
ConfigBox* m_frame;
|
||||
#endif
|
||||
/////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
// Rumble in windows
|
||||
#define _CONTROLLER_STATE_H // avoid certain declarations in nJoy.h
|
||||
#define _CONTROLLER_STATE_H // Avoid certain declarations in nJoy.h
|
||||
FILE *pFile;
|
||||
HINSTANCE nJoy_hInst = NULL;
|
||||
CONTROLLER_INFO *joyinfo = 0;
|
||||
@ -64,7 +88,7 @@ void __Logv(int log, int v, const char *format, ...) {}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// wxWidgets
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
class wxDLLApp : public wxApp
|
||||
{
|
||||
@ -81,7 +105,7 @@ void __Logv(int log, int v, const char *format, ...) {}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DllMain
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#ifdef _WIN32
|
||||
BOOL APIENTRY DllMain( HINSTANCE hinstDLL, // DLL module handle
|
||||
DWORD dwReason, // reason called
|
||||
@ -117,10 +141,10 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, // DLL module handle
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Input Plugin Functions (from spec's)
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
// Get properties of plugin
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
||||
{
|
||||
_PluginInfo->Version = 0x0100;
|
||||
@ -138,7 +162,7 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
||||
}
|
||||
|
||||
// Call config dialog
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void DllConfig(HWND _hParent)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -148,13 +172,26 @@ void DllConfig(HWND _hParent)
|
||||
return;
|
||||
}
|
||||
|
||||
LoadConfig(); // load settings
|
||||
// Start the pads so we can use them in the configuration and advanced controls
|
||||
if(!emulator_running)
|
||||
{
|
||||
SPADInitialize _PADInitialize;
|
||||
_PADInitialize.hWnd = NULL;
|
||||
_PADInitialize.pLog = NULL;
|
||||
PAD_Initialize(_PADInitialize);
|
||||
emulator_running = FALSE; // Set it back to false
|
||||
}
|
||||
|
||||
wxWindow win;
|
||||
win.SetHWND(_hParent);
|
||||
ConfigBox frame(&win);
|
||||
frame.ShowModal();
|
||||
win.SetHWND(0);
|
||||
g_Config.Load(); // Load settings
|
||||
|
||||
// We don't need a parent for this wxDialog
|
||||
//wxWindow win;
|
||||
//win.SetHWND(_hParent);
|
||||
//ConfigBox frame(&win);
|
||||
//win.SetHWND(0);
|
||||
|
||||
m_frame = new ConfigBox(NULL);
|
||||
m_frame->ShowModal();
|
||||
|
||||
#else
|
||||
if (SDL_Init(SDL_INIT_JOYSTICK ) < 0)
|
||||
@ -163,7 +200,7 @@ void DllConfig(HWND _hParent)
|
||||
return;
|
||||
}
|
||||
|
||||
LoadConfig(); // load settings
|
||||
g_Config.Load(); // load settings
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
ConfigBox frame(NULL);
|
||||
@ -176,8 +213,9 @@ void DllConfig(HWND _hParent)
|
||||
void DllDebugger(HWND _hParent, bool Show) {
|
||||
}
|
||||
|
||||
|
||||
// Init PAD (start emulation)
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void PAD_Initialize(SPADInitialize _PADInitialize)
|
||||
{
|
||||
emulator_running = TRUE;
|
||||
@ -185,7 +223,7 @@ void PAD_Initialize(SPADInitialize _PADInitialize)
|
||||
DEBUG_INIT();
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_JOYSTICK ) < 0)
|
||||
if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MessageBox(NULL, SDL_GetError(), "Could not initialize SDL!", MB_ICONERROR);
|
||||
@ -199,8 +237,8 @@ void PAD_Initialize(SPADInitialize _PADInitialize)
|
||||
m_hWnd = (HWND)_PADInitialize.hWnd;
|
||||
#endif
|
||||
|
||||
LoadConfig(); // Load joystick mapping
|
||||
Search_Devices();
|
||||
Search_Devices(); // Populate joyinfo for all attached devices
|
||||
g_Config.Load(); // Load joystick mapping, joysticks[].ID etc
|
||||
if (joysticks[0].enabled)
|
||||
joystate[0].joy = SDL_JoystickOpen(joysticks[0].ID);
|
||||
if (joysticks[1].enabled)
|
||||
@ -211,8 +249,74 @@ void PAD_Initialize(SPADInitialize _PADInitialize)
|
||||
joystate[3].joy = SDL_JoystickOpen(joysticks[3].ID);
|
||||
}
|
||||
|
||||
|
||||
// Search attached devices. Populate joyinfo for all attached physical devices.
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int Search_Devices()
|
||||
{
|
||||
// load config
|
||||
#ifdef _DEBUG
|
||||
DEBUG_INIT();
|
||||
#endif
|
||||
|
||||
int numjoy = SDL_NumJoysticks();
|
||||
|
||||
if (joyinfo)
|
||||
{
|
||||
delete [] joyinfo;
|
||||
joyinfo = new CONTROLLER_INFO [numjoy];
|
||||
}
|
||||
else
|
||||
{
|
||||
joyinfo = new CONTROLLER_INFO [numjoy];
|
||||
}
|
||||
|
||||
// Warn the user if no joysticks are detected
|
||||
if (numjoy == 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
//MessageBox(NULL, "No Joystick detected!", NULL, MB_ICONWARNING);
|
||||
#else
|
||||
printf("No Joystick detected!\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(pFile, "Scanning for devices\n");
|
||||
fprintf(pFile, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < numjoy; i++ )
|
||||
{
|
||||
// Open the device to be able to read the values
|
||||
joyinfo[i].joy = SDL_JoystickOpen(i);
|
||||
joyinfo[i].ID = i;
|
||||
joyinfo[i].NumAxes = SDL_JoystickNumAxes(joyinfo[i].joy);
|
||||
joyinfo[i].NumButtons = SDL_JoystickNumButtons(joyinfo[i].joy);
|
||||
joyinfo[i].NumBalls = SDL_JoystickNumBalls(joyinfo[i].joy);
|
||||
joyinfo[i].NumHats = SDL_JoystickNumHats(joyinfo[i].joy);
|
||||
joyinfo[i].Name = SDL_JoystickName(i);
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(pFile, "ID: %d\n", i);
|
||||
fprintf(pFile, "Name: %s\n", joyinfo[i].Name);
|
||||
fprintf(pFile, "Buttons: %d\n", joyinfo[i].NumButtons);
|
||||
fprintf(pFile, "Axes: %d\n", joyinfo[i].NumAxes);
|
||||
fprintf(pFile, "Hats: %d\n", joyinfo[i].NumHats);
|
||||
fprintf(pFile, "Balls: %d\n\n", joyinfo[i].NumBalls);
|
||||
#endif
|
||||
|
||||
// We have now read the values we need so we close the device
|
||||
if (SDL_JoystickOpened(i)) SDL_JoystickClose(joyinfo[i].joy);
|
||||
}
|
||||
|
||||
return numjoy;
|
||||
}
|
||||
|
||||
|
||||
// Shutdown PAD (stop emulation)
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void PAD_Shutdown()
|
||||
{
|
||||
if (joysticks[0].enabled)
|
||||
@ -244,8 +348,8 @@ void PAD_Shutdown()
|
||||
}
|
||||
|
||||
|
||||
// Set PAD status
|
||||
//
|
||||
// Set PAD status. This is called from SerialInterface_Devices.cpp
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
||||
{
|
||||
if (!joysticks[_numPAD].enabled)
|
||||
@ -257,57 +361,53 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
||||
// Get pad status
|
||||
GetJoyState(_numPAD);
|
||||
|
||||
// Reset!
|
||||
int base = 0x80;
|
||||
_pPADStatus->stickY = base;
|
||||
_pPADStatus->stickX = base;
|
||||
_pPADStatus->substickX = base;
|
||||
_pPADStatus->substickY = base;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Set analog controllers
|
||||
// -----------
|
||||
|
||||
// Read values
|
||||
int i_main_stick_x = joystate[_numPAD].axis[CTL_MAIN_X];
|
||||
int i_main_stick_y = -joystate[_numPAD].axis[CTL_MAIN_Y];
|
||||
int i_sub_stick_x = joystate[_numPAD].axis[CTL_SUB_X];
|
||||
int i_sub_stick_y = -joystate[_numPAD].axis[CTL_SUB_Y];
|
||||
|
||||
// Check if we should make adjustments
|
||||
if(g_Config.bSquareToCircle)
|
||||
{
|
||||
std::vector<int> main_xy = Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y);
|
||||
i_main_stick_x = main_xy.at(0);
|
||||
i_main_stick_y = main_xy.at(1);
|
||||
}
|
||||
|
||||
// Convert button values from 0xffff to 0xff
|
||||
u8 main_stick_x = Pad_Convert(i_main_stick_x);
|
||||
u8 main_stick_y = Pad_Convert(i_main_stick_y);
|
||||
u8 sub_stick_x = Pad_Convert(i_sub_stick_x);
|
||||
u8 sub_stick_y = Pad_Convert(i_sub_stick_y);
|
||||
|
||||
// Set Deadzones perhaps out of function
|
||||
int deadzone = (int)(((float)(128.00/100.00)) * (float)(joysticks[_numPAD].deadzone + 1));
|
||||
int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(joysticks[_numPAD].deadzone + 1));
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Set buttons
|
||||
// -----------
|
||||
|
||||
// The L and R trigger values
|
||||
int triggervalue = 255;
|
||||
if (joystate[_numPAD].halfpress) triggervalue = 100;
|
||||
|
||||
// Neutral button value, no button pressed
|
||||
_pPADStatus->button |= PAD_USE_ORIGIN;
|
||||
|
||||
// Set analog controllers
|
||||
// Set Deadzones perhaps out of function
|
||||
int deadzone = (int)(((float)(128.00/100.00)) * (float)(joysticks[_numPAD].deadzone+1));
|
||||
int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(joysticks[_numPAD].deadzone+1));
|
||||
|
||||
// Adjust range
|
||||
// The value returned by SDL_JoystickGetAxis is a signed integer (-32768 to 32768)
|
||||
// The value used for the gamecube controller is an unsigned char (0 to 255)
|
||||
int main_stick_x = (joystate[_numPAD].axis[CTL_MAIN_X] >> 8);
|
||||
int main_stick_y = -(joystate[_numPAD].axis[CTL_MAIN_Y] >> 8);
|
||||
int sub_stick_x = (joystate[_numPAD].axis[CTL_SUB_X] >> 8);
|
||||
int sub_stick_y = -(joystate[_numPAD].axis[CTL_SUB_Y] >> 8);
|
||||
|
||||
// Quick fix
|
||||
if (main_stick_x > 127)
|
||||
main_stick_x = 127;
|
||||
if (main_stick_y > 127)
|
||||
main_stick_y = 127;
|
||||
if (sub_stick_x > 127)
|
||||
sub_stick_x = 127;
|
||||
if (sub_stick_y > 127)
|
||||
sub_stick_y = 127;
|
||||
|
||||
if (main_stick_x < -128)
|
||||
main_stick_x = -128;
|
||||
if (main_stick_y < -128)
|
||||
main_stick_y = -128;
|
||||
if (sub_stick_x < -128)
|
||||
sub_stick_x = -128;
|
||||
if (sub_stick_y < -128)
|
||||
sub_stick_y = -128;
|
||||
|
||||
// Send values to Dolpin
|
||||
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;
|
||||
|
||||
int triggervalue = 255;
|
||||
if (joystate[_numPAD].halfpress)
|
||||
triggervalue = 100;
|
||||
|
||||
// Set buttons
|
||||
if (joystate[_numPAD].buttons[CTL_L_SHOULDER])
|
||||
{
|
||||
_pPADStatus->button|=PAD_TRIGGER_L;
|
||||
@ -345,41 +445,143 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
||||
else
|
||||
{
|
||||
if (joystate[_numPAD].dpad2[CTL_D_PAD_UP])
|
||||
_pPADStatus->button|=PAD_BUTTON_UP;
|
||||
_pPADStatus->button |= PAD_BUTTON_UP;
|
||||
if (joystate[_numPAD].dpad2[CTL_D_PAD_DOWN])
|
||||
_pPADStatus->button|=PAD_BUTTON_DOWN;
|
||||
_pPADStatus->button |= PAD_BUTTON_DOWN;
|
||||
if (joystate[_numPAD].dpad2[CTL_D_PAD_LEFT])
|
||||
_pPADStatus->button|=PAD_BUTTON_LEFT;
|
||||
_pPADStatus->button |= PAD_BUTTON_LEFT;
|
||||
if (joystate[_numPAD].dpad2[CTL_D_PAD_RIGHT])
|
||||
_pPADStatus->button|=PAD_BUTTON_RIGHT;
|
||||
_pPADStatus->button |= PAD_BUTTON_RIGHT;
|
||||
}
|
||||
|
||||
//
|
||||
_pPADStatus->err = PAD_ERR_NONE;
|
||||
|
||||
// Use rumble
|
||||
PAD_Use_Rumble(_numPAD, _pPADStatus);
|
||||
Pad_Use_Rumble(_numPAD, _pPADStatus);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert stick values, for example from circle to square analog stick radius
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
/* Convert stick values.
|
||||
|
||||
The value returned by SDL_JoystickGetAxis is a signed integer s16
|
||||
(-32768 to 32767). The value used for the gamecube controller is an unsigned
|
||||
char u8 (0 to 255) with neutral at 0x80 (128), so that it's equivalent to a signed
|
||||
-128 to 127. */
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
u8 Pad_Convert(int _val)
|
||||
{
|
||||
/* If the limits on joystate[].axis[] actually is a u16 then we don't need this
|
||||
but if it's not actually limited to that we need to apply these limits */
|
||||
if(_val > 32767) _val = 32767; // upper limit
|
||||
if(_val < -32768) _val = -32768; // lower limit
|
||||
|
||||
// Convert (-32768 to 32767) to (-128 to 127)
|
||||
_val = _val >> 8;
|
||||
|
||||
// Convert (-128 to 127) to (0 to 255)
|
||||
u8 val = 0x80 + _val;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/* Convert the stick raidus from a circular to a square. I don't know what input values
|
||||
the actual GC controller produce for the GC, it may be a square, a circle or something
|
||||
in between. But one thing that is certain is that PC pads differ in their output (as
|
||||
shown in the list below), so it may be beneficiary to convert whatever radius they
|
||||
produce to the radius the GC games expect. This is the first implementation of this
|
||||
that convert a square radius to a circual radius. Use the advanced settings to enable
|
||||
and calibrate it.
|
||||
|
||||
Observed diagonals:
|
||||
Perfect circle: 71% = sin(45)
|
||||
Logitech Dual Action: 100%
|
||||
Dual Shock 2 (Original) with Super Dual Box Pro: 90%
|
||||
XBox 360 Wireless: 85%
|
||||
GameCube Controller (Third Party) with EMS TrioLinker Plus II: 60%
|
||||
*/
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
float SquareDistance(float deg)
|
||||
{
|
||||
// See if we have to adjust the angle
|
||||
deg = abs(deg);
|
||||
if( (deg > 45 && deg < 135) ) deg = deg - 90;
|
||||
|
||||
float rad = deg * M_PI / 180;
|
||||
|
||||
float val = abs(cos(rad));
|
||||
float dist = 1 / val; // Calculate distance from center
|
||||
|
||||
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist));
|
||||
|
||||
return dist;
|
||||
}
|
||||
std::vector<int> Pad_Square_to_Circle(int _x, int _y)
|
||||
{
|
||||
/* Do we need this? */
|
||||
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
|
||||
if(_x < -32768) _x = -32768; if(_y > 32767) _y = 32767; // lower limit
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Convert to circle
|
||||
// -----------
|
||||
int Tmp = atoi (g_Config.SDiagonal.substr(0, g_Config.SDiagonal.length() - 1).c_str());
|
||||
float Diagonal = Tmp / 100.0;
|
||||
|
||||
// First make a perfect square in case we don't have one already
|
||||
float OrigDist = sqrt( pow((float)_y, 2) + pow((float)_x, 2) ); // Get current distance
|
||||
float rad = atan2((float)_y, (float)_x); // Get current angle
|
||||
float deg = rad * 180 / M_PI;
|
||||
|
||||
// A diagonal of 85% means a distance of 1.20
|
||||
float corner_circle_dist = ( Diagonal / sin(45 * M_PI / 180) );
|
||||
float SquareDist = SquareDistance(deg);
|
||||
float adj_ratio1; // The original-to-square distance adjustment
|
||||
float adj_ratio2 = SquareDist; // The circle-to-square distance adjustment
|
||||
float final_ratio; // The final adjustment to the current distance
|
||||
float result_dist; // The resulting distance
|
||||
|
||||
// Calculate the corner-to-square adjustment ratio
|
||||
if(corner_circle_dist < SquareDist) adj_ratio1 = SquareDist / corner_circle_dist;
|
||||
else adj_ratio1 = 1;
|
||||
|
||||
// Calculate the resulting distance
|
||||
result_dist = OrigDist * adj_ratio1 / adj_ratio2;
|
||||
|
||||
float x = result_dist * cos(rad); // calculate x
|
||||
float y = result_dist * sin(rad); // calculate y
|
||||
|
||||
int int_x = (int)floor(x);
|
||||
int int_y = (int)floor(y);
|
||||
|
||||
// Debugging
|
||||
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("%f %f %i", corner_circle_dist, Diagonal, Tmp));
|
||||
|
||||
std::vector<int> vec;
|
||||
vec.push_back(int_x);
|
||||
vec.push_back(int_y);
|
||||
return vec;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Set PAD attached pads
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
unsigned int PAD_GetAttachedPads()
|
||||
{
|
||||
unsigned int connected = 0;
|
||||
|
||||
LoadConfig();
|
||||
g_Config.Load();
|
||||
|
||||
if (joysticks[0].enabled)
|
||||
connected |= 1;
|
||||
if (joysticks[1].enabled)
|
||||
connected |= 2;
|
||||
if (joysticks[2].enabled)
|
||||
connected |= 4;
|
||||
if (joysticks[3].enabled)
|
||||
connected |= 8;
|
||||
if (joysticks[0].enabled) connected |= 1;
|
||||
if (joysticks[1].enabled) connected |= 2;
|
||||
if (joysticks[2].enabled) connected |= 4;
|
||||
if (joysticks[3].enabled) connected |= 8;
|
||||
|
||||
return connected;
|
||||
}
|
||||
@ -387,11 +589,11 @@ unsigned int PAD_GetAttachedPads()
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Custom Functions
|
||||
//
|
||||
// Read current joystick status
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
// Read buttons status. Called from GetJoyState().
|
||||
//
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void ReadButton(int controller, int button)
|
||||
{
|
||||
int ctl_button = joysticks[controller].buttons[button];
|
||||
@ -401,8 +603,8 @@ void ReadButton(int controller, int button)
|
||||
}
|
||||
}
|
||||
|
||||
// Request joystick state
|
||||
//
|
||||
// Request joystick state. The input value "controller" is for a virtual controller 0 to 3.
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void GetJoyState(int controller)
|
||||
{
|
||||
SDL_JoystickUpdate();
|
||||
@ -420,8 +622,6 @@ void GetJoyState(int controller)
|
||||
ReadButton(controller, CTL_Y_BUTTON);
|
||||
ReadButton(controller, CTL_Z_TRIGGER);
|
||||
ReadButton(controller, CTL_START);
|
||||
// Is there a purpose to this alert?
|
||||
// PanicAlert("%i", CTL_A_BUTTON);
|
||||
|
||||
//
|
||||
if (joysticks[controller].halfpress < joyinfo[controller].NumButtons)
|
||||
@ -440,67 +640,4 @@ void GetJoyState(int controller)
|
||||
joystate[controller].dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(joystate[controller].joy, joysticks[controller].dpad2[CTL_D_PAD_RIGHT]);
|
||||
}
|
||||
}
|
||||
|
||||
// Search attached devices
|
||||
//
|
||||
int Search_Devices()
|
||||
{
|
||||
// load config
|
||||
#ifdef _DEBUG
|
||||
DEBUG_INIT();
|
||||
#endif
|
||||
|
||||
int numjoy = SDL_NumJoysticks();
|
||||
|
||||
if (joyinfo)
|
||||
{
|
||||
delete [] joyinfo;
|
||||
joyinfo = new CONTROLLER_INFO [numjoy];
|
||||
}
|
||||
else
|
||||
{
|
||||
joyinfo = new CONTROLLER_INFO [numjoy];
|
||||
}
|
||||
|
||||
// Warn the user of no joysticks are detected
|
||||
if (numjoy == 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MessageBox(NULL, "No Joystick detected!", NULL, MB_ICONWARNING);
|
||||
#else
|
||||
printf("No Joystick detected!\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(pFile, "Scanning for devices\n");
|
||||
fprintf(pFile, "\n");
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < numjoy; i++ )
|
||||
{
|
||||
joyinfo[i].joy = SDL_JoystickOpen(i);
|
||||
joyinfo[i].ID = i;
|
||||
joyinfo[i].NumAxes = SDL_JoystickNumAxes(joyinfo[i].joy);
|
||||
joyinfo[i].NumButtons = SDL_JoystickNumButtons(joyinfo[i].joy);
|
||||
joyinfo[i].NumBalls = SDL_JoystickNumBalls(joyinfo[i].joy);
|
||||
joyinfo[i].NumHats = SDL_JoystickNumHats(joyinfo[i].joy);
|
||||
joyinfo[i].Name = SDL_JoystickName(i);
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(pFile, "ID: %d\n", i);
|
||||
fprintf(pFile, "Name: %s\n", joyinfo[i].Name);
|
||||
fprintf(pFile, "Buttons: %d\n", joyinfo[i].NumButtons);
|
||||
fprintf(pFile, "Axes: %d\n", joyinfo[i].NumAxes);
|
||||
fprintf(pFile, "Hats: %d\n", joyinfo[i].NumHats);
|
||||
fprintf(pFile, "Balls: %d\n\n", joyinfo[i].NumBalls);
|
||||
#endif
|
||||
|
||||
// Close if opened
|
||||
if (SDL_JoystickOpened(i))
|
||||
SDL_JoystickClose(joyinfo[i].joy);
|
||||
}
|
||||
|
||||
return numjoy;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
Reference in New Issue
Block a user