* new option SDL2_API
* drop GLSL_SHADER_DIR. Useless, shaders are embedded in .h file
* use some hardening flags (for the moment only basic one)
onepad:
* port the code to SDL2 (Note only SDL1 is supported for the moment)
* improve detection of button vs axis (long-standing issue)
* avoid potential overflow on mouse mouvement detection


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5756 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-11-01 21:05:59 +00:00
parent 2712bac5ee
commit 5df7af9bc5
9 changed files with 111 additions and 114 deletions

View File

@ -36,6 +36,9 @@ cmake_minimum_required(VERSION 2.8.5)
if(POLICY CMP0018)
cmake_policy(SET CMP0018 OLD)
endif()
if(POLICY CMP0022)
cmake_policy(SET CMP0022 OLD)
endif()
# Variable to check that people use the good file
set(TOP_CMAKE_WAS_SOURCED TRUE)

View File

@ -1,5 +1,5 @@
### TODO
# Hardcode GLSL_SHADER_DIR and GAMEINDEX_DIR. To check that default is fine for everybody
# Hardcode GAMEINDEX_DIR, if default is fine for everybody
### Select the build type
# Use Release/Devel/Debug : -DCMAKE_BUILD_TYPE=Release|Devel|Debug
@ -9,6 +9,7 @@
# Build the Replay Loaders : -DBUILD_REPLAY_LOADERS=TRUE|FALSE
# Use GLSL API(else NVIDIA_CG): -DGLSL_API=TRUE|FALSE
# Use EGL (vs GLX) : -DEGL_API=TRUE|FALSE
# Use SDL2 ; -DSDL2_API=TRUE|FALSE
### GCC optimization options
# control C flags : -DUSER_CMAKE_C_FLAGS="cflags"
@ -94,7 +95,8 @@ set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
# Set some default compiler flags
#-------------------------------------------------------------------------------
set(DEFAULT_WARNINGS "-Wno-write-strings -Wno-format -Wno-unused-parameter -Wno-unused-value -Wstrict-aliasing -Wno-unused-function -Wno-attributes -Wno-unused-result -Wno-missing-field-initializers -Wno-unused-local-typedefs -Wno-parentheses")
set(DEFAULT_GCC_FLAG "-m32 -msse -msse2 -march=i686 -pthread ${DEFAULT_WARNINGS}")
set (HARDEING_OPT "-D_FORTIFY_SOURCE=2 -Wformat -Wformat-security")
set(DEFAULT_GCC_FLAG "-m32 -msse -msse2 -march=i686 -pthread ${DEFAULT_WARNINGS} ${HARDEING_OPT}")
set(DEFAULT_CPP_FLAG "${DEFAULT_GCC_FLAG} -Wno-invalid-offsetof")
#-------------------------------------------------------------------------------
@ -153,13 +155,8 @@ if(PACKAGE_MODE)
set(GAMEINDEX_DIR "${CMAKE_INSTALL_PREFIX}/share/games/pcsx2")
endif(NOT DEFINED GAMEINDEX_DIR)
if(NOT DEFINED GLSL_SHADER_DIR)
set(GLSL_SHADER_DIR "${CMAKE_INSTALL_PREFIX}/share/games/pcsx2")
endif(NOT DEFINED GLSL_SHADER_DIR)
# Compile all source codes with these 3 defines
add_definitions(-DPLUGIN_DIR_COMPILATION=${PLUGIN_DIR} -DGAMEINDEX_DIR_COMPILATION=${GAMEINDEX_DIR})
add_definitions(-DGLSL_SHADER_DIR_COMPILATION=${GLSL_SHADER_DIR})
endif(PACKAGE_MODE)
#-------------------------------------------------------------------------------
@ -186,7 +183,16 @@ if(NOT DEFINED GLES_API)
endif()
#-------------------------------------------------------------------------------
# Use the precompiled shader file by default
# Select SDL1 by default (spu2x and onepad)
#-------------------------------------------------------------------------------
# FIXME do a proper detection
set(SDL2_LIBRARY "-lSDL2")
if(NOT DEFINED SDL2_API)
set(SDL2_API FALSE)
endif()
#-------------------------------------------------------------------------------
# Use the precompiled shader file by default (both zzogl&gsdx)
#-------------------------------------------------------------------------------
if(NOT DEFINED REBUILD_SHADER)
set(REBUILD_SHADER FALSE)

View File

@ -12,6 +12,7 @@ set(Output onepad-1.1.0)
set(CommonFlags
-fvisibility=hidden
-Wall
-std=c++0x
)
set(OptimizationFlags
@ -19,24 +20,22 @@ set(OptimizationFlags
-DNDEBUG
)
# Debug - Build
if(CMAKE_BUILD_TYPE STREQUAL Debug)
# add defines
add_definitions(${CommonFlags} -g)
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
# Devel - Build
if(CMAKE_BUILD_TYPE STREQUAL Devel)
# add defines
add_definitions(${CommonFlags} ${OptimizationFlags})
endif(CMAKE_BUILD_TYPE STREQUAL Devel)
# Release - Build
if(CMAKE_BUILD_TYPE STREQUAL Release)
# add defines
add_definitions(${CommonFlags} ${OptimizationFlags})
endif(CMAKE_BUILD_TYPE STREQUAL Release)
if (SDL2_API)
add_definitions(-DONEPAD_SDL2)
endif()
# onepad sources
set(onepadSources
controller.cpp
@ -82,8 +81,11 @@ add_library(${Output} SHARED
${onepadLinuxSources}
${onepadLinuxHeaders})
# link target with SDL
target_link_libraries(${Output} ${SDL_LIBRARY})
if (SDL2_API)
target_link_libraries(${Output} ${SDL2_LIBRARY})
else()
target_link_libraries(${Output} ${SDL_LIBRARY})
endif()
if(Linux)
# link target with gtk2

View File

@ -304,9 +304,8 @@ void config_key(int pad, int key)
bool captured = false;
u32 key_pressed = 0;
// save the joystick states
UpdateJoysticks();
// I don't have any guarantee that not-yet-pressed state is egual to released state
JoystickInfo::UpdateReleaseState();
while (!captured)
{
vector<JoystickInfo*>::iterator itjoy;

View File

@ -26,7 +26,6 @@
#include <string.h>
#include <gtk/gtk.h>
#include "linux.h"
#include <gdk/gdkx.h>
Display *GSdsp;
Window GSwin;

View File

@ -28,7 +28,7 @@
vector<JoystickInfo*> s_vjoysticks;
static u32 s_bSDLInit = false;
void UpdateJoysticks()
void JoystickInfo::UpdateReleaseState()
{
vector<JoystickInfo*>::iterator itjoy = s_vjoysticks.begin();
@ -42,25 +42,6 @@ void UpdateJoysticks()
}
}
const char *HatName(int value)
{
switch(value)
{
case SDL_HAT_CENTERED: return "SDL_HAT_CENTERED";
case SDL_HAT_UP: return "SDL_HAT_UP";
case SDL_HAT_RIGHT: return "SDL_HAT_RIGHT";
case SDL_HAT_DOWN: return "SDL_HAT_DOWN";
case SDL_HAT_LEFT: return "SDL_HAT_LEFT";
case SDL_HAT_RIGHTUP: return "SDL_HAT_RIGHTUP";
case SDL_HAT_RIGHTDOWN: return "SDL_HAT_RIGHTDOWN";
case SDL_HAT_LEFTUP: return "SDL_HAT_LEFTUP";
case SDL_HAT_LEFTDOWN: return "SDL_HAT_LEFTDOWN";
default: return "Unknown";
}
return "Unknown";
}
bool JoystickIdWithinBounds(int joyid)
{
return ((joyid >= 0) && (joyid < (int)s_vjoysticks.size()));
@ -72,11 +53,13 @@ void JoystickInfo::EnumerateJoysticks(vector<JoystickInfo*>& vjoysticks)
if (!s_bSDLInit)
{
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
// Tell SDL to catch event even if the windows isn't focussed
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
// SDL in 3rdparty wrap X11 call. In order to get x11 symbols loaded
// video must be loaded too.
// Example of X11 symbol are XAutoRepeatOn/XAutoRepeatOff
if (SDL_Init(SDL_INIT_JOYSTICK|SDL_INIT_VIDEO|SDL_INIT_HAPTIC) < 0) return;
if (SDL_Init(SDL_INIT_JOYSTICK|SDL_INIT_VIDEO|SDL_INIT_HAPTIC|SDL_INIT_GAMECONTROLLER|SDL_INIT_EVENTS) < 0) return;
#else
if (SDL_Init(SDL_INIT_JOYSTICK) < 0) return;
#endif
@ -104,7 +87,7 @@ void JoystickInfo::EnumerateJoysticks(vector<JoystickInfo*>& vjoysticks)
void JoystickInfo::InitHapticEffect()
{
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
if (haptic == NULL) return;
#if 0
@ -119,51 +102,39 @@ void JoystickInfo::InitHapticEffect()
#endif
/*******************************************************************/
/* Effect small */
/* Effect big & small */
/*******************************************************************/
haptic_effect_data[0].type = SDL_HAPTIC_SQUARE;
for (int new_effect = 0; new_effect < 2 ; new_effect++) {
// Direction of the effect SDL_HapticDirection
haptic_effect_data[0].periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
haptic_effect_data[0].periodic.direction.dir[0] = 18000; // Force comes from south
haptic_effect_data[new_effect].periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
haptic_effect_data[new_effect].periodic.direction.dir[0] = 18000; // Force comes from south
// periodic parameter
haptic_effect_data[0].periodic.period = 200; // 200 ms
haptic_effect_data[0].periodic.magnitude = 2000; // 2000/32767 strength
haptic_effect_data[new_effect].periodic.period = 20; // 20 ms
haptic_effect_data[new_effect].periodic.magnitude = 2000; // 2000/32767 strength
// Replay
haptic_effect_data[0].periodic.length = 1000; // 1 seconds long
haptic_effect_data[0].periodic.delay = 0; // start 0 second after the upload
haptic_effect_data[new_effect].periodic.length = 60; // 60 ms long
haptic_effect_data[new_effect].periodic.delay = 0; // start 0 second after the upload
// enveloppe
haptic_effect_data[0].periodic.attack_length = 100;// Takes 0.1 second to get max strength
haptic_effect_data[0].periodic.attack_level = 0; // start at 0
haptic_effect_data[0].periodic.fade_length = 100; // Takes 0.1 second to fade away
haptic_effect_data[0].periodic.fade_level = 0; // finish at 0
haptic_effect_data[new_effect].periodic.attack_length = 5;// Takes 5 ms to get max strength
haptic_effect_data[new_effect].periodic.attack_level = 0; // start at 0
haptic_effect_data[new_effect].periodic.fade_length = 5; // Takes 5 ms to fade away
haptic_effect_data[new_effect].periodic.fade_level = 0; // finish at 0
}
/*******************************************************************/
/* Effect small */
/*******************************************************************/
haptic_effect_data[0].type = SDL_HAPTIC_LEFTRIGHT;
/*******************************************************************/
/* Effect big */
/*******************************************************************/
haptic_effect_data[1].type = SDL_HAPTIC_TRIANGLE;
// Direction of the effect SDL_HapticDirection
haptic_effect_data[1].periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
haptic_effect_data[1].periodic.direction.dir[0] = 18000; // Force comes from south
// periodic parameter
haptic_effect_data[1].periodic.period = 200; // 200 ms
haptic_effect_data[1].periodic.magnitude = 2000; // 2000/32767 strength
// Replay
haptic_effect_data[1].periodic.length = 1000; // 1 seconds long
haptic_effect_data[1].periodic.delay = 0; // start 0 second after the upload
// enveloppe
haptic_effect_data[1].periodic.attack_length = 100;// Takes 0.1 second to get max strength
haptic_effect_data[1].periodic.attack_level = 0; // start at 0
haptic_effect_data[1].periodic.fade_length = 100; // Takes 0.1 second to fade away
haptic_effect_data[1].periodic.fade_level = 0; // finish at 0
/*******************************************************************/
/* Upload effect to the device */
/*******************************************************************/
@ -177,7 +148,7 @@ void JoystickInfo::DoHapticEffect(int type, int pad, int force)
if (type > 1) return;
if ( !(conf->options & (PADOPTION_FORCEFEEDBACK << 16 * pad)) ) return;
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
int joyid = conf->get_joyid(pad);
if (!JoystickIdWithinBounds(joyid)) return;
JoystickInfo* pjoy = s_vjoysticks[joyid];
@ -199,7 +170,7 @@ void JoystickInfo::Destroy()
{
if (joy != NULL)
{
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
// Haptic must be closed before the joystick
if (haptic != NULL) {
SDL_HapticClose(haptic);
@ -207,7 +178,11 @@ void JoystickInfo::Destroy()
}
#endif
#if SDL_MAJOR_VERSION >= 2
if (joy) SDL_JoystickClose(joy);
#else
if (SDL_JoystickOpened(_id)) SDL_JoystickClose(joy);
#endif
joy = NULL;
}
}
@ -227,7 +202,11 @@ bool JoystickInfo::Init(int id)
numaxes = SDL_JoystickNumAxes(joy);
numbuttons = SDL_JoystickNumButtons(joy);
numhats = SDL_JoystickNumHats(joy);
#if SDL_MAJOR_VERSION >= 2
devname = SDL_JoystickName(joy);
#else
devname = SDL_JoystickName(id);
#endif
vaxisstate.resize(numaxes);
vbuttonstate.resize(numbuttons);
@ -245,7 +224,7 @@ bool JoystickInfo::Init(int id)
numbuttons += 4;
}
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
if ( haptic == NULL ) {
if (!SDL_JoystickIsHaptic(joy)) {
PAD_LOG("Haptic devices not supported!\n");
@ -281,19 +260,17 @@ bool JoystickInfo::PollButtons(u32 &pkey)
for (int i = 0; i < GetNumButtons(); ++i)
{
int but = SDL_JoystickGetButton(GetJoy(), i);
if (but != GetButtonState(i))
{
if (!but) // released, we don't really want this
{
continue;
// Pressure sensitive button are detected as both button (digital) and axes (analog). So better
// drop the button to emulate the pressure sensiblity of the ds2 :)
// Trick: detect the release of the button. It avoid all races condition between axes and buttons :)
// If the button support pressure it will be detected as an axis when it is pressed.
if (but) {
SetButtonState(i, but);
return false;
}
// Pressure sensitive button are detected as both button (digital) and axes (analog). So better
// drop the button to emulate the pressure sensiblity of the ds2 :) -- Gregory
u32 pkey_dummy;
if (PollAxes(pkey_dummy))
return false;
pkey = button_to_key(i);
return true;
@ -322,10 +299,13 @@ bool JoystickInfo::PollAxes(u32 &pkey)
s32 value = SDL_JoystickGetAxis(GetJoy(), i);
s32 old_value = GetAxisState(i);
if (abs(value - old_value) < 0x1000)
continue;
if (value != old_value)
{
PAD_LOG("Change in joystick %d: %d.\n", i, value);
// There is several kinds of axes
// There are several kinds of axes
// Half+: 0 (release) -> 32768
// Half-: 0 (release) -> -32768
// Full (like dualshock 3): -32768 (release) ->32768
@ -351,6 +331,7 @@ bool JoystickInfo::PollAxes(u32 &pkey)
}
}
}
return false;
}

View File

@ -22,11 +22,14 @@
#ifndef __JOYSTICK_H__
#define __JOYSTICK_H__
#include "SDL.h"
#if SDL_VERSION_ATLEAST(1,3,0)
#include "SDL_haptic.h"
#ifdef ONEPAD_SDL2
#include "SDL2/SDL.h"
#include "SDL2/SDL_haptic.h"
#else
#include "SDL/SDL.h"
#endif
#include "onepad.h"
#include "controller.h"
@ -34,12 +37,12 @@
class JoystickInfo
{
public:
JoystickInfo() : devname(""), _id(-1), numbuttons(0), numaxes(0), numhats(0), axisrange(0x7fff),
JoystickInfo() : devname(""), _id(-1), numbuttons(0), numaxes(0), numhats(0),
deadzone(1500), pad(-1), joy(NULL) {
vbuttonstate.clear();
vaxisstate.clear();
vhatstate.clear();
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
haptic = NULL;
for (int i = 0 ; i < 2 ; i++)
haptic_effect_id[i] = -1;
@ -140,17 +143,19 @@ class JoystickInfo
int GetAxisFromKey(int pad, int index);
static void UpdateReleaseState();
private:
string devname; // pretty device name
int _id;
int numbuttons, numaxes, numhats;
int axisrange, deadzone;
int deadzone;
int pad;
vector<int> vbuttonstate, vaxisstate, vhatstate;
SDL_Joystick* joy;
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_MAJOR_VERSION >= 2
SDL_Haptic* haptic;
SDL_HapticEffect haptic_effect_data[2];
int haptic_effect_id[2];
@ -160,7 +165,5 @@ class JoystickInfo
extern int s_selectedpad;
extern vector<JoystickInfo*> s_vjoysticks;
extern void UpdateJoysticks();
extern const char *HatName(int value);
extern bool JoystickIdWithinBounds(int joyid);
#endif

View File

@ -155,7 +155,8 @@ void AnalyzeKeyEvent(int pad, keyEvent &evt)
}
unsigned x = evt.key & 0xFFFF;
unsigned int value = abs(s_previous_mouse_x - x) * conf->sensibility;
unsigned int value = (s_previous_mouse_x > x) ? s_previous_mouse_x - x : x - s_previous_mouse_x;
value *= conf->sensibility;
if (x == 0)
key_status->press(pad, pad_x, -MAX_ANALOG_VALUE);
@ -170,7 +171,8 @@ void AnalyzeKeyEvent(int pad, keyEvent &evt)
unsigned y = evt.key >> 16;
value = abs(s_previous_mouse_y - y) * conf->sensibility;
value = (s_previous_mouse_y > y) ? s_previous_mouse_y - y : y - s_previous_mouse_y;
value *= conf->sensibility;
if (y == 0)
key_status->press(pad, pad_y, -MAX_ANALOG_VALUE);
@ -231,12 +233,7 @@ bool PollX11KeyboardMouseEvent(u32 &pkey)
if (ev != NULL)
{
if (ev->type == GDK_KEY_PRESS) {
if (ev->key.keyval == GDK_Escape)
pkey = 0;
else
pkey = ev->key.keyval;
pkey = ev->key.keyval != GDK_Escape ? ev->key.keyval : 0;
return true;
} else if(ev->type == GDK_BUTTON_PRESS) {
pkey = ev->button.button;

View File

@ -111,11 +111,14 @@ include_directories(. Linux)
# endif()
if(SDL_FOUND)
add_definitions(-DSPU2X_SDL)
list(APPEND spu2xSources SndOut_SDL.cpp)
if(SDL2_API)
add_definitions(-DSPU2X_SDL)
else()
add_definitions(-DSPU2X_SDL2)
endif()
#elseif(SDL2_FOUND)
# add_definitions(-DSPU2X_SDL2)
# list(APPEND spu2xSources SndOut_SDL.cpp)
endif()
# add library
@ -131,7 +134,11 @@ target_link_libraries(${Output} Utilities)
# link target with various backend
target_link_libraries(${Output} ${ALSA_LIBRARIES})
target_link_libraries(${Output} ${PORTAUDIO_LIBRARIES})
target_link_libraries(${Output} ${SDL_LIBRARY})
if (SDL2_API)
target_link_libraries(${Output} ${SDL2_LIBRARY})
else()
target_link_libraries(${Output} ${SDL_LIBRARY})
endif()
# link target with SoundTouch
target_link_libraries(${Output} ${SOUNDTOUCH_LIBRARIES})