mirror of https://github.com/libsdl-org/SDL
Initial PS2_Joystick implementation
This commit is contained in:
parent
84d69da4e1
commit
7fd46ec581
|
@ -2539,7 +2539,7 @@ elseif(PSP)
|
|||
endif(NOT SDL2_DISABLE_SDL2MAIN)
|
||||
|
||||
elseif(PS2)
|
||||
list(APPEND EXTRA_CFLAGS "-DPS2" "-D__PS2__" "-I${PS2SDK}/ports/include")
|
||||
list(APPEND EXTRA_CFLAGS "-DPS2" "-D__PS2__" "-I$ENV{PS2SDK}/ports/include")
|
||||
|
||||
file(GLOB PS2_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/ps2/*.c)
|
||||
set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${PS2_MAIN_SOURCES})
|
||||
|
@ -2550,6 +2550,12 @@ elseif(PS2)
|
|||
list(APPEND SOURCE_FILES ${PS2_FILESYSTEM_SOURCES})
|
||||
set(HAVE_SDL_FILESYSTEM TRUE)
|
||||
endif()
|
||||
if(SDL_JOYSTICK)
|
||||
set(SDL_JOYSTICK_PS2 1)
|
||||
file(GLOB PS2_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/ps2/*.c)
|
||||
list(APPEND SOURCE_FILES ${PS2_JOYSTICK_SOURCES})
|
||||
set(HAVE_SDL_JOYSTICK TRUE)
|
||||
endif()
|
||||
if(SDL_THREADS)
|
||||
set(SDL_THREAD_PS2 1)
|
||||
file(GLOB PS2_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_sysmutex.c ${SDL2_SOURCE_DIR}/src/thread/ps2/*.c)
|
||||
|
|
|
@ -348,6 +348,7 @@
|
|||
#cmakedefine SDL_JOYSTICK_VIRTUAL @SDL_JOYSTICK_VIRTUAL@
|
||||
#cmakedefine SDL_JOYSTICK_VITA @SDL_JOYSTICK_VITA@
|
||||
#cmakedefine SDL_JOYSTICK_PSP @SDL_JOYSTICK_PSP@
|
||||
#cmakedefine SDL_JOYSTICK_PS2 @SDL_JOYSTICK_PS2@
|
||||
#cmakedefine SDL_HAPTIC_DUMMY @SDL_HAPTIC_DUMMY@
|
||||
#cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@
|
||||
#cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@
|
||||
|
|
|
@ -913,6 +913,9 @@ static const char *s_ControllerMappings [] =
|
|||
#endif
|
||||
#if defined(SDL_JOYSTICK_PSP)
|
||||
"505350206275696c74696e206a6f7970,PSP builtin joypad,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_PS2)
|
||||
"50533220436f6e74726f6c6c65720000,PS2 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,leftstick:b1,rightstick:b2,",
|
||||
#endif
|
||||
"hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
|
||||
NULL
|
||||
|
|
|
@ -89,6 +89,9 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
|
|||
#ifdef SDL_JOYSTICK_OS2
|
||||
&SDL_OS2_JoystickDriver,
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_PS2
|
||||
&SDL_PS2_JoystickDriver,
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_PSP
|
||||
&SDL_PSP_JoystickDriver,
|
||||
#endif
|
||||
|
|
|
@ -155,7 +155,7 @@ typedef struct _SDL_JoystickDriver
|
|||
/* Function to get the player index of a joystick */
|
||||
int (*GetDevicePlayerIndex)(int device_index);
|
||||
|
||||
/* Function to get the player index of a joystick */
|
||||
/* Function to set the player index of a joystick */
|
||||
void (*SetDevicePlayerIndex)(int device_index, int player_index);
|
||||
|
||||
/* Function to return the stable GUID for a plugged in device */
|
||||
|
@ -226,6 +226,7 @@ extern SDL_JoystickDriver SDL_WGI_JoystickDriver;
|
|||
extern SDL_JoystickDriver SDL_WINDOWS_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_WINMM_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_OS2_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_PS2_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_PSP_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_VITA_JoystickDriver;
|
||||
|
||||
|
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_JOYSTICK_PS2
|
||||
|
||||
/* This is the PS2 implementation of the SDL joystick API */
|
||||
#include <libmtap.h>
|
||||
#include <libpad.h>
|
||||
#include <ps2_joystick_driver.h>
|
||||
|
||||
#include <stdio.h> /* For the definition of NULL */
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_error.h"
|
||||
|
||||
#define PS2_MAX_PORT 2 /* each ps2 has 2 ports */
|
||||
#define PS2_MAX_SLOT 4 /* maximum - 4 slots in one multitap */
|
||||
#define MAX_CONTROLLERS (PS2_MAX_PORT * PS2_MAX_SLOT)
|
||||
#define PS2_ANALOG_STICKS 2
|
||||
#define PS2_ANALOG_AXIS 2
|
||||
#define PS2_BUTTONS 16
|
||||
#define PS2_TOTAL_AXIS (PS2_ANALOG_STICKS * PS2_ANALOG_AXIS)
|
||||
|
||||
struct JoyInfo {
|
||||
uint8_t padBuf[256];
|
||||
uint16_t btns;
|
||||
uint8_t analog_state[PS2_TOTAL_AXIS];
|
||||
uint8_t port;
|
||||
uint8_t slot;
|
||||
int8_t rumble_ready;
|
||||
} __attribute__ ((aligned (64)));
|
||||
|
||||
static uint8_t enabled_pads = 0;
|
||||
static struct JoyInfo joyInfo[MAX_CONTROLLERS];
|
||||
|
||||
static inline int16_t convert_u8_to_s16(uint8_t val)
|
||||
{
|
||||
if (val == 0)
|
||||
return -0x7fff;
|
||||
return val * 0x0101 - 0x8000;
|
||||
}
|
||||
|
||||
static inline uint8_t rumble_status(uint8_t index)
|
||||
{
|
||||
char actAlign[6];
|
||||
int res;
|
||||
struct JoyInfo *info = &joyInfo[index];
|
||||
|
||||
if (info->rumble_ready == 0) {
|
||||
actAlign[0] = 0;
|
||||
actAlign[1] = 1;
|
||||
actAlign[2] = 0xff;
|
||||
actAlign[3] = 0xff;
|
||||
actAlign[4] = 0xff;
|
||||
actAlign[5] = 0xff;
|
||||
|
||||
res = padSetActAlign(info->port, info->slot, actAlign);
|
||||
info->rumble_ready = res <= 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
return info->rumble_ready == 1;
|
||||
}
|
||||
|
||||
/* Function to scan the system for joysticks.
|
||||
* Joystick 0 should be the system default joystick.
|
||||
* This function should return 0, or -1 on an unrecoverable error.
|
||||
*/
|
||||
static int PS2_JoystickInit(void)
|
||||
{
|
||||
uint32_t port = 0;
|
||||
uint32_t slot = 0;
|
||||
|
||||
if(init_joystick_driver(true) < 0)
|
||||
return -1;
|
||||
|
||||
for (port = 0; port < PS2_MAX_PORT; port++)
|
||||
mtapPortOpen(port);
|
||||
/* it can fail - we dont care, we will check it more strictly when padPortOpen */
|
||||
|
||||
for (slot = 0; slot < PS2_MAX_SLOT; slot++) {
|
||||
for (port = 0; port < PS2_MAX_PORT; port++) {
|
||||
/* 2 main controller ports acts the same with and without multitap
|
||||
Port 0,0 -> Connector 1 - the same as Port 0
|
||||
Port 1,0 -> Connector 2 - the same as Port 1
|
||||
Port 0,1 -> Connector 3
|
||||
Port 1,1 -> Connector 4
|
||||
Port 0,2 -> Connector 5
|
||||
Port 1,2 -> Connector 6
|
||||
Port 0,3 -> Connector 7
|
||||
Port 1,3 -> Connector 8
|
||||
*/
|
||||
|
||||
struct JoyInfo *info = &joyInfo[enabled_pads];
|
||||
if(padPortOpen(port, slot, (void *)info->padBuf) > 0) {
|
||||
info->port = (uint8_t)port;
|
||||
info->slot = (uint8_t)slot;
|
||||
enabled_pads++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enabled_pads > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Function to return the number of joystick devices plugged in right now */
|
||||
static int PS2_JoystickGetCount()
|
||||
{
|
||||
return (int)enabled_pads;
|
||||
}
|
||||
|
||||
/* Function to cause any queued joystick insertions to be processed */
|
||||
static void PS2_JoystickDetect()
|
||||
{
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *PS2_JoystickGetDeviceName(int index)
|
||||
{
|
||||
if (index >= 0 && index < enabled_pads)
|
||||
return "PS2 Controller";
|
||||
|
||||
SDL_SetError("No joystick available with that index");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent path of a joystick */
|
||||
static const char *PS2_JoystickGetDevicePath(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Function to get the player index of a joystick */
|
||||
static int PS2_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Function to set the player index of a joystick */
|
||||
static void PS2_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
{
|
||||
}
|
||||
|
||||
/* Function to return the stable GUID for a plugged in device */
|
||||
static SDL_JoystickGUID PS2_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
const char *name = PS2_JoystickGetDeviceName(device_index);
|
||||
SDL_zero(guid);
|
||||
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
|
||||
return guid;
|
||||
}
|
||||
|
||||
/* Function to get the current instance id of the joystick located at device_index */
|
||||
static SDL_JoystickID PS2_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
return device_index;
|
||||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
static int PS2_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
{
|
||||
joystick->nbuttons = PS2_BUTTONS;
|
||||
joystick->naxes = PS2_TOTAL_AXIS;
|
||||
joystick->nhats = 0;
|
||||
joystick->instance_id = device_index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Rumble functionality */
|
||||
static int PS2_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
char actAlign[6];
|
||||
int res;
|
||||
int index = joystick->instance_id;
|
||||
struct JoyInfo *info = &joyInfo[index];
|
||||
|
||||
if (!rumble_status(index)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initial value
|
||||
actAlign[0] = low_frequency_rumble >> 8; // Enable small engine
|
||||
actAlign[1] = high_frequency_rumble >> 8; // Enable big engine
|
||||
actAlign[2] = 0xff;
|
||||
actAlign[3] = 0xff;
|
||||
actAlign[4] = 0xff;
|
||||
actAlign[5] = 0xff;
|
||||
|
||||
res = padSetActDirect(info->port, info->slot, actAlign);
|
||||
return res == 1 ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Rumble functionality */
|
||||
static int PS2_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Capability detection */
|
||||
static Uint32 PS2_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
/* LED functionality */
|
||||
static int PS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* General effects */
|
||||
static int PS2_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Sensor functionality */
|
||||
static int PS2_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Function to update the state of a joystick - called as a device poll.
|
||||
* This function shouldn't update the joystick structure directly,
|
||||
* but instead should call SDL_PrivateJoystick*() to deliver events
|
||||
* and update joystick device state.
|
||||
*/
|
||||
static void PS2_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t previous_axis, current_axis;
|
||||
uint16_t mask, previous, current;
|
||||
struct padButtonStatus buttons;
|
||||
uint8_t all_axis[PS2_TOTAL_AXIS];
|
||||
int index = joystick->instance_id;
|
||||
struct JoyInfo *info = &joyInfo[index];
|
||||
int state = padGetState(info->port, info->slot);
|
||||
|
||||
if (state != PAD_STATE_DISCONN || state != PAD_STATE_EXECCMD || state != PAD_STATE_ERROR) {
|
||||
int ret = padRead(info->port, info->slot, &buttons); /* port, slot, buttons */
|
||||
if (ret != 0) {
|
||||
/* Buttons */
|
||||
int32_t pressed_buttons = 0xffff ^ buttons.btns;;
|
||||
if (info->btns != pressed_buttons) {
|
||||
for (i = 0; i < PS2_BUTTONS; i++) {
|
||||
mask = (1 << i);
|
||||
previous = info->btns & mask;
|
||||
current = pressed_buttons & mask;
|
||||
if (previous != current)
|
||||
SDL_PrivateJoystickButton(joystick, i, current ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
}
|
||||
info->btns = pressed_buttons;
|
||||
|
||||
/* Analog */
|
||||
all_axis[0] = buttons.ljoy_h;
|
||||
all_axis[1] = buttons.ljoy_v;
|
||||
all_axis[2] = buttons.rjoy_h;
|
||||
all_axis[3] = buttons.rjoy_v;
|
||||
|
||||
for (i = 0; i < PS2_TOTAL_AXIS; i++) {
|
||||
previous_axis = info->analog_state[i];
|
||||
current_axis = all_axis[i];
|
||||
if (previous_axis != current_axis)
|
||||
SDL_PrivateJoystickAxis(joystick, i, convert_u8_to_s16(current_axis));
|
||||
|
||||
info->analog_state[i] = current_axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
static void PS2_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
int index = joystick->instance_id;
|
||||
struct JoyInfo *info = &joyInfo[index];
|
||||
padPortClose(info->port, info->slot);
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
static void PS2_JoystickQuit(void)
|
||||
{
|
||||
deinit_joystick_driver(true);
|
||||
}
|
||||
|
||||
static SDL_bool PS2_GetGamepadMapping(int device_index, SDL_GamepadMapping * out)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_PS2_JoystickDriver =
|
||||
{
|
||||
PS2_JoystickInit,
|
||||
PS2_JoystickGetCount,
|
||||
PS2_JoystickDetect,
|
||||
PS2_JoystickGetDeviceName,
|
||||
PS2_JoystickGetDevicePath,
|
||||
PS2_JoystickGetDevicePlayerIndex,
|
||||
PS2_JoystickSetDevicePlayerIndex,
|
||||
PS2_JoystickGetDeviceGUID,
|
||||
PS2_JoystickGetDeviceInstanceID,
|
||||
PS2_JoystickOpen,
|
||||
PS2_JoystickRumble,
|
||||
PS2_JoystickRumbleTriggers,
|
||||
PS2_JoystickGetCapabilities,
|
||||
PS2_JoystickSetLED,
|
||||
PS2_JoystickSendEffect,
|
||||
PS2_JoystickSetSensorsEnabled,
|
||||
PS2_JoystickUpdate,
|
||||
PS2_JoystickClose,
|
||||
PS2_JoystickQuit,
|
||||
PS2_GetGamepadMapping,
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_PS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
Loading…
Reference in New Issue