Merged PadSimple with nJoy

(Linux build could be broken, X360Pad support could be broken)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4924 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx
2010-01-22 23:19:16 +00:00
parent c09ec17bb2
commit 68a4eacb62
38 changed files with 3302 additions and 9319 deletions

View File

@ -27,10 +27,6 @@
// http://code.google.com/p/dolphin-emu/
//
// Include
// -------------------
#if defined HAVE_WX && HAVE_WX
@ -45,12 +41,9 @@
#include "SDL.h" // Local
namespace InputCommon
{
// Degree to radian and back
// -------------
float Deg2Rad(float Deg)
@ -83,9 +76,6 @@ bool IsDeadZone(float DeadZone, int x, int y)
return false;
}
// Scale down stick values from 0x8000 to 0x80
/* ----------------
The value returned by SDL_JoystickGetAxis is a signed integer s16
@ -112,33 +102,19 @@ int Pad_Convert(int _val)
return _val;
}
// Adjust the radius
// ----------------
void RadiusAdjustment(int &_x, int &_y, int _pad, std::string SRadius)
void RadiusAdjustment(s8 &_x, s8 &_y, int _Radius)
{
// Get the radius setting
int Tmp = atoi (SRadius.substr(0, SRadius.length() - 1).c_str());
float RadiusSetting = Tmp / 100.0f;
// Get current angle
float Deg = Rad2Deg(atan2((float)_y, (float)_x));
// Get the current radius
float Radius = sqrt((float)(_x*_x + _y*_y));
// Adjust radius
Radius = Radius * RadiusSetting;
// Produce new coordinates
float x = Radius * cos(Deg2Rad(Deg));
float y = Radius * sin(Deg2Rad(Deg));
float RadiusSetting = (float)_Radius / 100.0f;
float x = (float)_x * RadiusSetting;
float y = (float)_y * RadiusSetting;
// Update values
_x = (int)x, _y = (int)y;
_x = (s8)x;
_y = (s8)y;
}
/* 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
@ -173,8 +149,9 @@ float Square2CircleDistance(float deg)
return Distance;
}
// Produce a perfect circle from an original square or rounded box
void Square2Circle(int &_x, int &_y, int _pad, std::string SDiagonal, bool Circle2Square)
void Square2Circle(int &_x, int &_y, int _Diagonal, bool Circle2Square)
{
// Do we need to do this check?
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
@ -184,8 +161,7 @@ void Square2Circle(int &_x, int &_y, int _pad, std::string SDiagonal, bool Circl
// 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;
float Diagonal = (float)_Diagonal / 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
@ -226,9 +202,6 @@ void Square2Circle(int &_x, int &_y, int _pad, std::string SDiagonal, bool Circl
//Console::Print("%f %f %i", corner_circle_dist, Diagonal, Tmp));
}
// Windows Virtual Key Codes Names
// ---------------------
#ifdef _WIN32

View File

@ -28,34 +28,14 @@
//
// Include
// -------------------
#define _SDL_MAIN_ // Avoid certain declarations in SDL.h
#include "SDL.h" // Local
#include "XInput.h"
// Definitions
// -------------------
int g_LastPad = 0;
namespace InputCommon
{
// Definitions
// -------------------
// Search attached devices. Populate joyinfo for all attached physical devices.
// -----------------------
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
@ -112,140 +92,6 @@ bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_
}
// Supporting functions
// ----------------
// Read current joystick status
/* ----------------
The value PadMapping[].buttons[] is the number of the assigned joypad button,
PadState[].buttons[] is the status of the button, it becomes 0 (no pressed) or 1 (pressed) */
// Read buttons status. Called from GetJoyState().
// ----------------------
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.
// ----------------------
/* 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
{
// XInput triggers for Xbox360 pads
_PadState.axis[CTL_L_SHOULDER] = XInput::GetXI(Controller, _PadMapping.buttons[CTL_L_SHOULDER] - 1000);
_PadState.axis[CTL_R_SHOULDER] = XInput::GetXI(Controller, _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);
// Update Halfpress state, this one is not in the standard _PadState.buttons array
if (_PadMapping.halfpress < NumButtons && _PadMapping.halfpress >= 0)
_PadState.halfpress = SDL_JoystickGetButton(_PadState.joy, _PadMapping.halfpress);
else
_PadState.halfpress = 0;
// 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
//ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
//if ((g_LastPad == 0 && Controller == 0) || Controller < g_LastPad) Console->ClearScreen();
g_LastPad = Controller;
NOTICE_LOG(CONSOLE,
"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
// ----------
// Avoid extreme axis values
// ---------------------
/* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the
@ -367,8 +213,6 @@ void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int h
}
}
}
/////////////////////////////////////////////////////////// Configure button mapping
} // InputCommon

View File

@ -1,39 +1,24 @@
// Project description
// -------------------
// Name: SDL Input
// Description: Common SDL Input Functions
//
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003 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/
//
#ifndef _SDL_h
#define _SDL_h
// Include
// -------------------
#include <iostream> // System
#include <vector>
#include <cmath>
@ -55,52 +40,27 @@
#include "Common.h" // Common
namespace InputCommon
{
// Settings
// ----------
// Show a status window with the detected axes, buttons and so on
//#define SHOW_PAD_STATUS
// Structures
/* -------------------
CONTROLLER_STATE buttons (PadState) = 0 or 1
CONTROLLER_MAPPING buttons (joystick) = 0 or 1, 2, 3, 4, a certain joypad button
Please remember: The axis limit is hardcoded here, if you allow more axises (for
example for analog A and B buttons) you must first incrase the size of the axis array
size here
*/
struct CONTROLLER_STATE // GC PAD INFO/STATE
enum EButtonType
{
int buttons[8]; // Amount of buttons (A B X Y Z, L-Trigger R-Trigger Start) might need to change the triggers buttons
int dpad; // Automatic SDL D-Pad (8 directions + neutral)
int dpad2[4]; // D-pad using buttons
int axis[6]; // 2 x 2 Axes (Main & Sub)
int halfpress; // Halfpress... you know, like not fully pressed ;)...
SDL_Joystick *joy; // SDL joystick device
CTL_AXIS = 0,
CTL_HAT,
CTL_BUTTON,
CTL_KEY,
};
struct CONTROLLER_MAPPING // GC PAD MAPPING
enum ETriggerType
{
bool enable;
int buttons[8]; // (See above)
int dpad; // (See above)
int dpad2[4]; // (See above)
int axis[6]; // (See above)
int halfpress; // (See above)
int deadzone; // Deadzone... what else?
int ID; // SDL joystick device ID
int controllertype; // Hat: Hat or custom buttons
int triggertype; // Triggers range
std::string SRadius, SDiagonal, SRadiusC, SDiagonalC;
bool bRadiusOnOff, bSquareToCircle, bRadiusOnOffC, bSquareToCircleC;
bool rumble;
int eventnum; // Linux Event Number, Can't be found dynamically yet
CTL_TRIGGER_SDL = 0,
CTL_TRIGGER_XINPUT,
};
enum EXInputTrigger
{
XI_TRIGGER_L = 0,
XI_TRIGGER_R,
};
struct CONTROLLER_INFO // CONNECTED WINDOWS DEVICES INFO
@ -114,66 +74,10 @@ struct CONTROLLER_INFO // CONNECTED WINDOWS DEVICES INFO
bool Good; // Pad is good (it has at least one button or axis)
SDL_Joystick *joy; // SDL joystick device
};
enum
{
// CTL_L_SHOULDER and CTL_R_SHOULDER = 0 and 1
CTL_MAIN_X = 2,
CTL_MAIN_Y,
CTL_SUB_X,
CTL_SUB_Y
};
enum
{
CTL_L_SHOULDER = 0,
CTL_R_SHOULDER,
CTL_A_BUTTON,
CTL_B_BUTTON,
CTL_X_BUTTON,
CTL_Y_BUTTON,
CTL_Z_TRIGGER,
CTL_START
};
// DPad Type
enum
{
CTL_DPAD_HAT = 0, // Automatically use the first hat that SDL finds
CTL_DPAD_CUSTOM // Custom directional pad settings
};
// Trigger Type
enum
{
CTL_TRIGGER_SDL = 0, //
CTL_TRIGGER_XINPUT // The XBox 360 pad
};
enum
{
CTL_D_PAD_UP = 0,
CTL_D_PAD_DOWN,
CTL_D_PAD_LEFT,
CTL_D_PAD_RIGHT
};
// Button type for the configuration
enum
{
CTL_AXIS = 0,
CTL_HAT,
CTL_BUTTON,
CTL_KEY
};
// XInput buttons
enum
{
XI_TRIGGER_L = 0,
XI_TRIGGER_R
};
// Declarations
// ---------
// General functions
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &NumPads, int &NumGoodPads);
void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int controller, int NumButtons);
void GetButton(SDL_Joystick*, int,int,int,int, int&,int&,int&,int&,bool&,bool&, bool,bool,bool,bool,bool,bool);
// Value conversion
@ -182,17 +86,11 @@ float Rad2Deg(float Rad);
int Pad_Convert(int _val);
float SquareDistance(float deg);
bool IsDeadZone(float DeadZone, int x, int y);
void Square2Circle(int &_x, int &_y, int _pad, std::string SDiagonal, bool Circle2Square = false);
void RadiusAdjustment(int &_x, int &_y, int _pad, std::string SRadius);
void Square2Circle(int &_x, int &_y, int _Diagonal, bool Circle2Square = false);
void RadiusAdjustment(s8 &_x, s8 &_y, int _Radius);
// Input configuration
std::string VKToString(int keycode);
#ifndef _SDL_MAIN_
extern int g_LastPad;
#endif
} // InputCommon