Update svn:eol-style=native ( r1442 ) for Source/*.cpp

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2384 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99
2009-02-23 06:15:48 +00:00
parent 472582022b
commit 578c402d2c
41 changed files with 13757 additions and 13757 deletions

View File

@ -1,252 +1,252 @@
//////////////////////////////////////////////////////////////////////////////////////////
// Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: Input Configuration and Calibration
// Description: Common SDL Input Functions
//
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003-2008 Dolphin Project.
//
//////////////////////////////////////////////////////////////////////////////////////////
//
// Licensetype: GNU General Public License (GPL)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
//
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
//
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#if defined HAVE_WX && HAVE_WX
#include <wx/wx.h>
#endif
#include "SDL.h" // Local
////////////////////////////////////
namespace InputCommon
{
//////////////////////////////////////////////////////////////////////////////////////////
// Degree to radian and back
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float Deg2Rad(float Deg)
{
return Deg * ((float)M_PI / 180.0f);
}
float Rad2Deg(float Rad)
{
return (Rad * 180.0f) / (float)M_PI;
}
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Check if the pad is within the dead zone, we assume the range is 0x8000
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float CoordinatesToRadius(int x, int y)
{
return sqrt(pow((float)x, 2) + pow((float)y, 2));
}
bool IsDeadZone(float DeadZone, int x, int y)
{
// Get the distance from the center
float Distance = CoordinatesToRadius(x, y) / 32767.0f;
//Console::Print("%f\n", Distance);
// Check if it's within the dead zone
if (Distance <= DeadZone)
return true;
else
return false;
}
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Scale down stick values from 0x8000 to 0x80
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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>
int Pad_Convert(int _val)
{
/* If the limits on PadState[].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 the range (-0x8000 to 0x7fff) to (0 to 0xffff)
_val = 0x8000 +_val;
// Convert the range (-32768 to 32767) to (-128 to 127)
_val = _val >> 8;
//Console::Print("0x%04x %06i\n\n", _val, _val);
return _val;
}
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/* Convert the stick raidus from a square or rounded box to a circular radius. 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%
PS2 Dual Shock 2 (Original) with Super Dual Box Pro: 90%
XBox 360 Wireless: 85%
GameCube Controller (Third Party) with EMS Trio Linker Plus II: 60%
*/
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Calculate the distance from the outer edges of the box to the outer edges of the circle inside the box
at any angle from 0<> to 360<36>. The returned value is 1 + Distance, for example at most sqrt(2) in the
corners and at least 1.0 at the horizontal and vertical angles. */
float Square2CircleDistance(float deg)
{
// See if we have to adjust the angle
deg = abs(deg);
if( (deg > 45 && deg < 135) ) deg = deg - 90;
// Calculate distance from center
float val = abs(cos(Deg2Rad(deg)));
float Distance = 1 / val;
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist));
return Distance;
}
// Produce a perfect circle from an original square or rounded box
std::vector<int> Square2Circle(int _x, int _y, int _pad, std::string SDiagonal, bool Circle2Square)
{
// Do we need this?
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
if(_x < -32768) _x = -32768; if(_y < -32768) _y = -32768; // lower limit
// ====================================
// Convert to circle
// -----------
// Get the manually configured diagonal distance
int Tmp = atoi (SDiagonal.substr(0, SDiagonal.length() - 1).c_str());
float Diagonal = Tmp / 100.0f;
// 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 deg = Rad2Deg(atan2((float)_y, (float)_x)); // Get current angle
/* Calculate the actual distance between the maxium diagonal values, and the outer edges of the
square. A diagonal of 85% means a maximum distance of 0.85 * sqrt(2) ~1.2 in the diagonals. */
float corner_circle_dist = ( Diagonal / sin(Deg2Rad(45)) );
float SquareDist = Square2CircleDistance(deg);
// The original-to-square distance adjustment
float adj_ratio1;
// The circle-to-square distance adjustment
float adj_ratio2 = SquareDist;
// The resulting distance
float result_dist;
// 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
if(Circle2Square)
result_dist = OrigDist * adj_ratio1;
else
result_dist = OrigDist * adj_ratio1 / adj_ratio2;
// Calculate x and y and return it
float x = result_dist * cos(Deg2Rad(deg));
float y = result_dist * sin(Deg2Rad(deg));
// Make integers
int int_x = (int)floor(x);
int int_y = (int)floor(y);
// Boundaries
if (int_x < -32768) int_x = -32768; if (int_x > 32767) int_x = 32767;
if (int_y < -32768) int_y = -32768; if (int_y > 32767) int_y = 32767;
// Return it
std::vector<int> vec;
vec.push_back(int_x);
vec.push_back(int_y);
// Debugging
//Console::Print("%f %f %i", corner_circle_dist, Diagonal, Tmp));
return vec;
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Windows Virtual Key Codes Names
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef _WIN32
std::string VKToString(int keycode)
{
#ifdef _WIN32
// Default value
char KeyStr[64] = {0};
GetKeyNameText(MapVirtualKey(keycode, MAPVK_VK_TO_VSC) << 16, KeyStr, 64);
std::string KeyString = KeyStr;
switch(keycode)
{
// Give it some help with a few keys
case VK_END: return "END";
case VK_INSERT: return "INS";
case VK_DELETE: return "DEL";
case VK_PRIOR: return "PGUP";
case VK_NEXT: return "PGDN";
case VK_UP: return "UP";
case VK_DOWN: return "DOWN";
case VK_LEFT: return "LEFT";
case VK_RIGHT: return "RIGHT";
case VK_LSHIFT: return "LEFT SHIFT";
case VK_LCONTROL: return "LEFT CTRL";
case VK_RCONTROL: return "RIGHT CTRL";
case VK_LMENU: return "LEFT ALT";
default: return KeyString;
}
#else
// An equivalent name translation can probably be used on other systems to?
return "";
#endif
}
#endif
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: Input Configuration and Calibration
// Description: Common SDL Input Functions
//
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003-2008 Dolphin Project.
//
//////////////////////////////////////////////////////////////////////////////////////////
//
// Licensetype: GNU General Public License (GPL)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
//
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
//
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#if defined HAVE_WX && HAVE_WX
#include <wx/wx.h>
#endif
#include "SDL.h" // Local
////////////////////////////////////
namespace InputCommon
{
//////////////////////////////////////////////////////////////////////////////////////////
// Degree to radian and back
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float Deg2Rad(float Deg)
{
return Deg * ((float)M_PI / 180.0f);
}
float Rad2Deg(float Rad)
{
return (Rad * 180.0f) / (float)M_PI;
}
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Check if the pad is within the dead zone, we assume the range is 0x8000
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float CoordinatesToRadius(int x, int y)
{
return sqrt(pow((float)x, 2) + pow((float)y, 2));
}
bool IsDeadZone(float DeadZone, int x, int y)
{
// Get the distance from the center
float Distance = CoordinatesToRadius(x, y) / 32767.0f;
//Console::Print("%f\n", Distance);
// Check if it's within the dead zone
if (Distance <= DeadZone)
return true;
else
return false;
}
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Scale down stick values from 0x8000 to 0x80
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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>
int Pad_Convert(int _val)
{
/* If the limits on PadState[].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 the range (-0x8000 to 0x7fff) to (0 to 0xffff)
_val = 0x8000 +_val;
// Convert the range (-32768 to 32767) to (-128 to 127)
_val = _val >> 8;
//Console::Print("0x%04x %06i\n\n", _val, _val);
return _val;
}
/////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/* Convert the stick raidus from a square or rounded box to a circular radius. 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%
PS2 Dual Shock 2 (Original) with Super Dual Box Pro: 90%
XBox 360 Wireless: 85%
GameCube Controller (Third Party) with EMS Trio Linker Plus II: 60%
*/
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Calculate the distance from the outer edges of the box to the outer edges of the circle inside the box
at any angle from 0<> to 360<36>. The returned value is 1 + Distance, for example at most sqrt(2) in the
corners and at least 1.0 at the horizontal and vertical angles. */
float Square2CircleDistance(float deg)
{
// See if we have to adjust the angle
deg = abs(deg);
if( (deg > 45 && deg < 135) ) deg = deg - 90;
// Calculate distance from center
float val = abs(cos(Deg2Rad(deg)));
float Distance = 1 / val;
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist));
return Distance;
}
// Produce a perfect circle from an original square or rounded box
std::vector<int> Square2Circle(int _x, int _y, int _pad, std::string SDiagonal, bool Circle2Square)
{
// Do we need this?
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
if(_x < -32768) _x = -32768; if(_y < -32768) _y = -32768; // lower limit
// ====================================
// Convert to circle
// -----------
// Get the manually configured diagonal distance
int Tmp = atoi (SDiagonal.substr(0, SDiagonal.length() - 1).c_str());
float Diagonal = Tmp / 100.0f;
// 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 deg = Rad2Deg(atan2((float)_y, (float)_x)); // Get current angle
/* Calculate the actual distance between the maxium diagonal values, and the outer edges of the
square. A diagonal of 85% means a maximum distance of 0.85 * sqrt(2) ~1.2 in the diagonals. */
float corner_circle_dist = ( Diagonal / sin(Deg2Rad(45)) );
float SquareDist = Square2CircleDistance(deg);
// The original-to-square distance adjustment
float adj_ratio1;
// The circle-to-square distance adjustment
float adj_ratio2 = SquareDist;
// The resulting distance
float result_dist;
// 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
if(Circle2Square)
result_dist = OrigDist * adj_ratio1;
else
result_dist = OrigDist * adj_ratio1 / adj_ratio2;
// Calculate x and y and return it
float x = result_dist * cos(Deg2Rad(deg));
float y = result_dist * sin(Deg2Rad(deg));
// Make integers
int int_x = (int)floor(x);
int int_y = (int)floor(y);
// Boundaries
if (int_x < -32768) int_x = -32768; if (int_x > 32767) int_x = 32767;
if (int_y < -32768) int_y = -32768; if (int_y > 32767) int_y = 32767;
// Return it
std::vector<int> vec;
vec.push_back(int_x);
vec.push_back(int_y);
// Debugging
//Console::Print("%f %f %i", corner_circle_dist, Diagonal, Tmp));
return vec;
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Windows Virtual Key Codes Names
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef _WIN32
std::string VKToString(int keycode)
{
#ifdef _WIN32
// Default value
char KeyStr[64] = {0};
GetKeyNameText(MapVirtualKey(keycode, MAPVK_VK_TO_VSC) << 16, KeyStr, 64);
std::string KeyString = KeyStr;
switch(keycode)
{
// Give it some help with a few keys
case VK_END: return "END";
case VK_INSERT: return "INS";
case VK_DELETE: return "DEL";
case VK_PRIOR: return "PGUP";
case VK_NEXT: return "PGDN";
case VK_UP: return "UP";
case VK_DOWN: return "DOWN";
case VK_LEFT: return "LEFT";
case VK_RIGHT: return "RIGHT";
case VK_LSHIFT: return "LEFT SHIFT";
case VK_LCONTROL: return "LEFT CTRL";
case VK_RCONTROL: return "RIGHT CTRL";
case VK_LMENU: return "LEFT ALT";
default: return KeyString;
}
#else
// An equivalent name translation can probably be used on other systems to?
return "";
#endif
}
#endif
/////////////////////////////////////////////////////////////////////
}

View File

@ -1,366 +1,366 @@
//////////////////////////////////////////////////////////////////////////////////////////
// Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: SDL Input
// Description: Common SDL Input Functions
//
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003-2008 Dolphin Project.
//
//////////////////////////////////////////////////////////////////////////////////////////
//
// Licensetype: GNU General Public License (GPL)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
//
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
//
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define _SDL_MAIN_ // Avoid certain declarations in SDL.h
#include "SDL.h" // Local
#include "XInput.h"
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int g_LastPad = 0;
////////////////////////////////////
namespace InputCommon
{
//////////////////////////////////////////////////////////////////////////////////////////
// Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// 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>
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{
/* SDL 1.3 use DirectInput instead of the old Microsoft Multimedia API, and with this we need
the SDL_INIT_VIDEO flag to */
if (!SDL_WasInit(0))
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
{
PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return false;
}
// Get device status
int numjoy = SDL_NumJoysticks();
for (int i = 0; i < numjoy; i++ )
{
CONTROLLER_INFO Tmp;
Tmp.joy = SDL_JoystickOpen(i);
Tmp.ID = i;
Tmp.NumAxes = SDL_JoystickNumAxes(Tmp.joy);
Tmp.NumButtons = SDL_JoystickNumButtons(Tmp.joy);
Tmp.NumBalls = SDL_JoystickNumBalls(Tmp.joy);
Tmp.NumHats = SDL_JoystickNumHats(Tmp.joy);
Tmp.Name = SDL_JoystickName(i);
// Check if the device is okay
if ( Tmp.NumAxes == 0
&& Tmp.NumBalls == 0
&& Tmp.NumButtons == 0
&& Tmp.NumHats == 0
)
{
Tmp.Good = false;
}
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);
}
_NumPads = (int)_joyinfo.size();
return true;
}
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Read current joystick status
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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) */
// Read buttons status. Called from GetJoyState().
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ReadButton(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int button, int NumButtons)
{
int ctl_button = _PadMapping.buttons[button];
if (ctl_button < NumButtons)
{
_PadState.buttons[button] = SDL_JoystickGetButton(_PadState.joy, ctl_button);
}
}
// Request joystick state.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Called from: PAD_GetStatus()
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)
{
// Update the gamepad status
SDL_JoystickUpdate();
// 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]);
_PadState.axis[CTL_MAIN_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_Y]);
_PadState.axis[CTL_SUB_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_X]);
_PadState.axis[CTL_SUB_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_Y]);
// Update the analog trigger axis values
#ifdef _WIN32
if (_PadMapping.triggertype == CTL_TRIGGER_SDL)
{
#endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
if(_PadMapping.buttons[CTL_L_SHOULDER] >= 1000) _PadState.axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_L_SHOULDER] - 1000); else _PadState.axis[CTL_L_SHOULDER] = 0;
if(_PadMapping.buttons[CTL_R_SHOULDER] >= 1000) _PadState.axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_R_SHOULDER] - 1000); else _PadState.axis[CTL_R_SHOULDER] = 0;
#ifdef _WIN32
}
else
{
_PadState.axis[CTL_L_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_L_SHOULDER] - 1000);
_PadState.axis[CTL_R_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_R_SHOULDER] - 1000);
}
#endif
// Update button states to on or off
ReadButton(_PadState, _PadMapping, CTL_L_SHOULDER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_R_SHOULDER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_A_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_B_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_X_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_Y_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_Z_TRIGGER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_START, NumButtons);
//
if (_PadMapping.halfpress < NumButtons)
_PadState.halfpress = SDL_JoystickGetButton(_PadState.joy, _PadMapping.halfpress);
// Check if we have an analog or digital joypad
if (_PadMapping.controllertype == CTL_DPAD_HAT)
{
_PadState.dpad = SDL_JoystickGetHat(_PadState.joy, _PadMapping.dpad);
}
else
{
/* Only do this if the assigned button is in range (to allow for the current way of saving keyboard
keys in the same array) */
if(_PadMapping.dpad2[CTL_D_PAD_UP] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_UP] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_UP]);
if(_PadMapping.dpad2[CTL_D_PAD_DOWN] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_DOWN] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_DOWN]);
if(_PadMapping.dpad2[CTL_D_PAD_LEFT] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_LEFT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_LEFT]);
if(_PadMapping.dpad2[CTL_D_PAD_RIGHT] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_RIGHT]);
}
#ifdef SHOW_PAD_STATUS
// Show the status of all connected pads
if ((g_LastPad == 0 && Controller == 0) || Controller < g_LastPad) Console::ClearScreen();
g_LastPad = Controller;
Console::Print(
"Pad | Number:%i Enabled:%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"
"Buttons | A:%i X:%i\n"
"D-Pad | Type:%s Hat:%i U:%i D:%i\n"
"======================================================\n",
Controller, _PadMapping.enabled, _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],
(_PadMapping.triggertype ? "CTL_TRIGGER_XINPUT" : "CTL_TRIGGER_SDL"),
_PadState.buttons[InputCommon::CTL_L_SHOULDER], _PadState.buttons[InputCommon::CTL_R_SHOULDER],
_PadState.axis[InputCommon::CTL_L_SHOULDER], _PadState.axis[InputCommon::CTL_R_SHOULDER],
_PadState.halfpress,
_PadState.buttons[InputCommon::CTL_A_BUTTON], _PadState.buttons[InputCommon::CTL_X_BUTTON],
(_PadMapping.controllertype ? "CTL_DPAD_CUSTOM" : "CTL_DPAD_HAT"),
_PadState.dpad,
_PadState.dpad2[InputCommon::CTL_D_PAD_UP], _PadState.dpad2[InputCommon::CTL_D_PAD_DOWN]
);
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Configure button mapping
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Avoid extreme axis values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the
unpressed state (and then go from -0x8000 to 0x8000 as they are fully pressed) */
bool AvoidValues(int value, bool NoTriggerFilter)
{
// Avoid detecting very small or very big (for triggers) values
if( (value > -0x2000 && value < 0x2000) // Small values
|| ((value < -0x6000 || value > 0x6000) && !NoTriggerFilter)) // Big values
return true; // Avoid
else
return false; // Keep
}
// Detect a pressed button
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int hats,
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;
// Update the internal status
SDL_JoystickUpdate();
// For the triggers we accept both a digital or an analog button
if(Axis)
{
for(int i = 0; i < axes; i++)
{
value = SDL_JoystickGetAxis(joy, i);
if(AvoidValues(value, NoTriggerFilter)) continue; // Avoid values
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = InputCommon::CTL_AXIS;
Succeed = true;
}
}
// Check for a hat
if(Hat)
{
for(int i = 0; i < hats; i++)
{
if(SDL_JoystickGetHat(joy, i))
{
pressed = i;
type = InputCommon::CTL_HAT;
Succeed = true;
}
}
}
// Check for a button
if(Button)
{
for(int i = 0; i < buttons; i++)
{
// Some kind of bug in SDL 1.3 would give button 9 and 10 (nonexistent) the value 48 on the 360 pad
if (SDL_JoystickGetButton(joy, i) > 1) continue;
if(SDL_JoystickGetButton(joy, i))
{
pressed = i;
type = InputCommon::CTL_BUTTON;
Succeed = true;
}
}
}
// Check for a XInput trigger
#ifdef _WIN32
if(XInput)
{
for(int i = 0; i <= InputCommon::XI_TRIGGER_R; i++)
{
if(XInput::GetXI(0, i))
{
pressed = i + 1000;
type = InputCommon::CTL_AXIS;
Succeed = true;
}
}
}
#endif
// Check for keyboard action
if (KeyboardKey)
{
if(Button)
{
// Todo: Add a separate keyboard vector to remove this restriction
if(KeyboardKey >= buttons)
{
pressed = KeyboardKey;
type = InputCommon::CTL_BUTTON;
Succeed = true;
KeyboardKey = 0;
if(pressed == WXK_ESCAPE) pressed = -1; // Check for the escape key
}
// Else show the error message
else
{
pressed = KeyboardKey;
KeyboardKey = -1;
Stop = true;
}
}
// Only accept the escape key
else if (KeyboardKey == WXK_ESCAPE)
{
Succeed = true;
KeyboardKey = 0;
pressed = -1;
}
}
}
/////////////////////////////////////////////////////////// Configure button mapping
//////////////////////////////////////////////////////////////////////////////////////////
// Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: SDL Input
// Description: Common SDL Input Functions
//
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003-2008 Dolphin Project.
//
//////////////////////////////////////////////////////////////////////////////////////////
//
// Licensetype: GNU General Public License (GPL)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
//
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
//
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define _SDL_MAIN_ // Avoid certain declarations in SDL.h
#include "SDL.h" // Local
#include "XInput.h"
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int g_LastPad = 0;
////////////////////////////////////
namespace InputCommon
{
//////////////////////////////////////////////////////////////////////////////////////////
// Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// 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>
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{
/* SDL 1.3 use DirectInput instead of the old Microsoft Multimedia API, and with this we need
the SDL_INIT_VIDEO flag to */
if (!SDL_WasInit(0))
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
{
PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return false;
}
// Get device status
int numjoy = SDL_NumJoysticks();
for (int i = 0; i < numjoy; i++ )
{
CONTROLLER_INFO Tmp;
Tmp.joy = SDL_JoystickOpen(i);
Tmp.ID = i;
Tmp.NumAxes = SDL_JoystickNumAxes(Tmp.joy);
Tmp.NumButtons = SDL_JoystickNumButtons(Tmp.joy);
Tmp.NumBalls = SDL_JoystickNumBalls(Tmp.joy);
Tmp.NumHats = SDL_JoystickNumHats(Tmp.joy);
Tmp.Name = SDL_JoystickName(i);
// Check if the device is okay
if ( Tmp.NumAxes == 0
&& Tmp.NumBalls == 0
&& Tmp.NumButtons == 0
&& Tmp.NumHats == 0
)
{
Tmp.Good = false;
}
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);
}
_NumPads = (int)_joyinfo.size();
return true;
}
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Read current joystick status
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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) */
// Read buttons status. Called from GetJoyState().
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ReadButton(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int button, int NumButtons)
{
int ctl_button = _PadMapping.buttons[button];
if (ctl_button < NumButtons)
{
_PadState.buttons[button] = SDL_JoystickGetButton(_PadState.joy, ctl_button);
}
}
// Request joystick state.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Called from: PAD_GetStatus()
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)
{
// Update the gamepad status
SDL_JoystickUpdate();
// 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]);
_PadState.axis[CTL_MAIN_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_Y]);
_PadState.axis[CTL_SUB_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_X]);
_PadState.axis[CTL_SUB_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_Y]);
// Update the analog trigger axis values
#ifdef _WIN32
if (_PadMapping.triggertype == CTL_TRIGGER_SDL)
{
#endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
if(_PadMapping.buttons[CTL_L_SHOULDER] >= 1000) _PadState.axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_L_SHOULDER] - 1000); else _PadState.axis[CTL_L_SHOULDER] = 0;
if(_PadMapping.buttons[CTL_R_SHOULDER] >= 1000) _PadState.axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_R_SHOULDER] - 1000); else _PadState.axis[CTL_R_SHOULDER] = 0;
#ifdef _WIN32
}
else
{
_PadState.axis[CTL_L_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_L_SHOULDER] - 1000);
_PadState.axis[CTL_R_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_R_SHOULDER] - 1000);
}
#endif
// Update button states to on or off
ReadButton(_PadState, _PadMapping, CTL_L_SHOULDER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_R_SHOULDER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_A_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_B_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_X_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_Y_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_Z_TRIGGER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_START, NumButtons);
//
if (_PadMapping.halfpress < NumButtons)
_PadState.halfpress = SDL_JoystickGetButton(_PadState.joy, _PadMapping.halfpress);
// Check if we have an analog or digital joypad
if (_PadMapping.controllertype == CTL_DPAD_HAT)
{
_PadState.dpad = SDL_JoystickGetHat(_PadState.joy, _PadMapping.dpad);
}
else
{
/* Only do this if the assigned button is in range (to allow for the current way of saving keyboard
keys in the same array) */
if(_PadMapping.dpad2[CTL_D_PAD_UP] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_UP] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_UP]);
if(_PadMapping.dpad2[CTL_D_PAD_DOWN] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_DOWN] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_DOWN]);
if(_PadMapping.dpad2[CTL_D_PAD_LEFT] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_LEFT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_LEFT]);
if(_PadMapping.dpad2[CTL_D_PAD_RIGHT] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_RIGHT]);
}
#ifdef SHOW_PAD_STATUS
// Show the status of all connected pads
if ((g_LastPad == 0 && Controller == 0) || Controller < g_LastPad) Console::ClearScreen();
g_LastPad = Controller;
Console::Print(
"Pad | Number:%i Enabled:%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"
"Buttons | A:%i X:%i\n"
"D-Pad | Type:%s Hat:%i U:%i D:%i\n"
"======================================================\n",
Controller, _PadMapping.enabled, _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],
(_PadMapping.triggertype ? "CTL_TRIGGER_XINPUT" : "CTL_TRIGGER_SDL"),
_PadState.buttons[InputCommon::CTL_L_SHOULDER], _PadState.buttons[InputCommon::CTL_R_SHOULDER],
_PadState.axis[InputCommon::CTL_L_SHOULDER], _PadState.axis[InputCommon::CTL_R_SHOULDER],
_PadState.halfpress,
_PadState.buttons[InputCommon::CTL_A_BUTTON], _PadState.buttons[InputCommon::CTL_X_BUTTON],
(_PadMapping.controllertype ? "CTL_DPAD_CUSTOM" : "CTL_DPAD_HAT"),
_PadState.dpad,
_PadState.dpad2[InputCommon::CTL_D_PAD_UP], _PadState.dpad2[InputCommon::CTL_D_PAD_DOWN]
);
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Configure button mapping
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Avoid extreme axis values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the
unpressed state (and then go from -0x8000 to 0x8000 as they are fully pressed) */
bool AvoidValues(int value, bool NoTriggerFilter)
{
// Avoid detecting very small or very big (for triggers) values
if( (value > -0x2000 && value < 0x2000) // Small values
|| ((value < -0x6000 || value > 0x6000) && !NoTriggerFilter)) // Big values
return true; // Avoid
else
return false; // Keep
}
// Detect a pressed button
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int hats,
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;
// Update the internal status
SDL_JoystickUpdate();
// For the triggers we accept both a digital or an analog button
if(Axis)
{
for(int i = 0; i < axes; i++)
{
value = SDL_JoystickGetAxis(joy, i);
if(AvoidValues(value, NoTriggerFilter)) continue; // Avoid values
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = InputCommon::CTL_AXIS;
Succeed = true;
}
}
// Check for a hat
if(Hat)
{
for(int i = 0; i < hats; i++)
{
if(SDL_JoystickGetHat(joy, i))
{
pressed = i;
type = InputCommon::CTL_HAT;
Succeed = true;
}
}
}
// Check for a button
if(Button)
{
for(int i = 0; i < buttons; i++)
{
// Some kind of bug in SDL 1.3 would give button 9 and 10 (nonexistent) the value 48 on the 360 pad
if (SDL_JoystickGetButton(joy, i) > 1) continue;
if(SDL_JoystickGetButton(joy, i))
{
pressed = i;
type = InputCommon::CTL_BUTTON;
Succeed = true;
}
}
}
// Check for a XInput trigger
#ifdef _WIN32
if(XInput)
{
for(int i = 0; i <= InputCommon::XI_TRIGGER_R; i++)
{
if(XInput::GetXI(0, i))
{
pressed = i + 1000;
type = InputCommon::CTL_AXIS;
Succeed = true;
}
}
}
#endif
// Check for keyboard action
if (KeyboardKey)
{
if(Button)
{
// Todo: Add a separate keyboard vector to remove this restriction
if(KeyboardKey >= buttons)
{
pressed = KeyboardKey;
type = InputCommon::CTL_BUTTON;
Succeed = true;
KeyboardKey = 0;
if(pressed == WXK_ESCAPE) pressed = -1; // Check for the escape key
}
// Else show the error message
else
{
pressed = KeyboardKey;
KeyboardKey = -1;
Stop = true;
}
}
// Only accept the escape key
else if (KeyboardKey == WXK_ESCAPE)
{
Succeed = true;
KeyboardKey = 0;
pressed = -1;
}
}
}
/////////////////////////////////////////////////////////// Configure button mapping
} // InputCommon

View File

@ -1,136 +1,136 @@
//////////////////////////////////////////////////////////////////////////////////////////
//
// Licensetype: GNU General Public License (GPL)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
//
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
//
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// File description
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Function: This file will get the status of the analog triggers of any connected XInput device.
This code was made with the help of SimpleController.cpp in the June 2008 Microsoft DirectX SDK
Samples.
///////////////////////////////////////////////////// */
#ifdef _WIN32
//////////////////////////////////////////////////////////////////////////////////////////
// Includes
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <windows.h>
#include <XInput.h> // XInput API
#include "SDL.h" // Local
///////////////////////////////////////////////
namespace XInput
{
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MAX_CONTROLLERS 4 // XInput handles up to 4 controllers
struct CONTROLER_STATE
{
XINPUT_STATE state;
bool bConnected;
};
CONTROLER_STATE g_Controllers[MAX_CONTROLLERS];
///////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Init
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Function: Calculate the number of connected XInput devices
Todo: Implement this to figure out if there are multiple XInput controllers connected,
we currently only try to connect to XInput device 0 */
void Init()
{
// Init state
//ZeroMemory( g_Controllers, sizeof( CONTROLER_STATE ) * MAX_CONTROLLERS );
// Declaration
DWORD dwResult;
// Calculate the number of connected XInput devices
for( DWORD i = 0; i < MAX_CONTROLLERS; i++ )
{
// Simply get the state of the controller from XInput.
dwResult = XInputGetState( i, &g_Controllers[i].state );
if( dwResult == ERROR_SUCCESS )
g_Controllers[i].bConnected = true;
else
g_Controllers[i].bConnected = false;
}
}
///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Get the trigger status
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int GetXI(int Controller, int Button)
{
// Update the internal status
DWORD dwResult;
dwResult = XInputGetState( Controller, &g_Controllers[Controller].state );
if( dwResult != ERROR_SUCCESS ) return -1;
switch(Button)
{
case InputCommon::XI_TRIGGER_L:
return g_Controllers[0].state.Gamepad.bLeftTrigger;
case InputCommon::XI_TRIGGER_R:
return g_Controllers[0].state.Gamepad.bRightTrigger;
default:
return 0;
}
}
///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Check if a certain controller is connected
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool IsConnected(int Controller)
{
DWORD dwResult = XInputGetState( Controller, &g_Controllers[Controller].state );
// Update the connected status
if( dwResult == ERROR_SUCCESS )
return true;
else
return false;
}
///////////////////////////////////////////
} // XInput
//////////////////////////////////////////////////////////////////////////////////////////
//
// Licensetype: GNU General Public License (GPL)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
//
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
//
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// File description
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Function: This file will get the status of the analog triggers of any connected XInput device.
This code was made with the help of SimpleController.cpp in the June 2008 Microsoft DirectX SDK
Samples.
///////////////////////////////////////////////////// */
#ifdef _WIN32
//////////////////////////////////////////////////////////////////////////////////////////
// Includes
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <windows.h>
#include <XInput.h> // XInput API
#include "SDL.h" // Local
///////////////////////////////////////////////
namespace XInput
{
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MAX_CONTROLLERS 4 // XInput handles up to 4 controllers
struct CONTROLER_STATE
{
XINPUT_STATE state;
bool bConnected;
};
CONTROLER_STATE g_Controllers[MAX_CONTROLLERS];
///////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Init
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Function: Calculate the number of connected XInput devices
Todo: Implement this to figure out if there are multiple XInput controllers connected,
we currently only try to connect to XInput device 0 */
void Init()
{
// Init state
//ZeroMemory( g_Controllers, sizeof( CONTROLER_STATE ) * MAX_CONTROLLERS );
// Declaration
DWORD dwResult;
// Calculate the number of connected XInput devices
for( DWORD i = 0; i < MAX_CONTROLLERS; i++ )
{
// Simply get the state of the controller from XInput.
dwResult = XInputGetState( i, &g_Controllers[i].state );
if( dwResult == ERROR_SUCCESS )
g_Controllers[i].bConnected = true;
else
g_Controllers[i].bConnected = false;
}
}
///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Get the trigger status
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int GetXI(int Controller, int Button)
{
// Update the internal status
DWORD dwResult;
dwResult = XInputGetState( Controller, &g_Controllers[Controller].state );
if( dwResult != ERROR_SUCCESS ) return -1;
switch(Button)
{
case InputCommon::XI_TRIGGER_L:
return g_Controllers[0].state.Gamepad.bLeftTrigger;
case InputCommon::XI_TRIGGER_R:
return g_Controllers[0].state.Gamepad.bRightTrigger;
default:
return 0;
}
}
///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Check if a certain controller is connected
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool IsConnected(int Controller)
{
DWORD dwResult = XInputGetState( Controller, &g_Controllers[Controller].state );
// Update the connected status
if( dwResult == ERROR_SUCCESS )
return true;
else
return false;
}
///////////////////////////////////////////
} // XInput
#endif