uae-wii/src/jd-sdl/joystick.c

272 lines
6.5 KiB
C

/*
* UAE - The Un*x Amiga Emulator
*
* SDL Joystick code
*
* Copyright 1997 Bernd Schmidt
* Copyright 1998 Krister Walfridsson
* Copyright 2003-2005 Richard Drummond
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include "options.h"
#include "inputdevice.h"
#include <SDL.h>
#if defined(GEKKO)
# include <ogc/system.h>
# include <wiiuse/wpad.h>
#endif
extern int gui_is_active;
unsigned int nr_joysticks;
static int initialized;
struct joyinfo {
SDL_Joystick *joy;
unsigned int axles;
unsigned int buttons;
};
struct joyinfo joys[MAX_INPUT_DEVICES];
//Wiimote Rumble
#ifdef GEKKO
void Rumble(unsigned int nr, unsigned int i, int bs)
{
static Uint32 last_ticks[2];
Uint32 cur_ticks;
static bool rumble_on[2];
static bool fire_pressed[2];
static int joystickbutton_fire[2]={-1,-1};
int kc;
if (nr>1) return;
cur_ticks = SDL_GetTicks();
kc = currprefs.joystick_settings[1][nr].eventid[i][0];
if (bs && (kc == INPUTEVENT_JOY2_FIRE_BUTTON || kc == INPUTEVENT_JOY1_FIRE_BUTTON) && !rumble_on[nr] && !fire_pressed[nr])
{
WPAD_Rumble(nr, true);
last_ticks[nr]= cur_ticks;
rumble_on[nr]=true;
fire_pressed[nr]=true;
joystickbutton_fire[nr]=i;
}
if (joystickbutton_fire[nr] == i)
{
if (!bs && (kc == INPUTEVENT_JOY2_FIRE_BUTTON || kc == INPUTEVENT_JOY1_FIRE_BUTTON) && rumble_on[nr] && fire_pressed[nr])
{
rumble_on[nr]=true;
fire_pressed[nr]=false;
}
if (((cur_ticks - last_ticks[nr] > 120) && rumble_on[nr] && !fire_pressed[nr]) \
||(!bs && (kc == INPUTEVENT_JOY2_FIRE_BUTTON || kc == INPUTEVENT_JOY1_FIRE_BUTTON) && !rumble_on[nr] && fire_pressed[nr]))
{
WPAD_Rumble(nr, false);
rumble_on[nr]=false;
fire_pressed[nr]=false;
joystickbutton_fire[nr]=-1;
}
if ((cur_ticks - last_ticks[nr] > 120) && rumble_on[nr] && fire_pressed[nr])
{
WPAD_Rumble(nr, false);
rumble_on[nr]=false;
fire_pressed[nr]=true;
}
}
}
#endif
static void read_joy (unsigned int nr)
{
unsigned int num, i, axes, axis, hats;
SDL_Joystick *joy;
if (currprefs.input_selected_setting == 0) {
if (jsem_isjoy (0, &currprefs) != (int)nr && jsem_isjoy (1, &currprefs) != (int)nr)
return;
}
joy = joys[nr].joy;
axes = SDL_JoystickNumAxes (joy);
for (i = 0; i < axes; i++) {
axis = SDL_JoystickGetAxis (joy, i);
setjoystickstate (nr, i, axis, 32767);
}
/* Handle hat - used e.g., for the Wii */
hats = SDL_JoystickNumHats (joy);
for (i = 0; i < hats; i++) {
Uint8 v = SDL_JoystickGetHat (joy, i);
int x = 0, y = 0;
if (v & SDL_HAT_UP)
y = -1;
if (v & SDL_HAT_DOWN)
y = 1;
if (v & SDL_HAT_LEFT)
x = -1;
if (v & SDL_HAT_RIGHT)
x = 1;
setjoystickstate (nr, axes + i * 2, x, 1);
setjoystickstate (nr, axes + i * 2 + 1, y, 1);
}
num = SDL_JoystickNumButtons (joy);
for (i = 0; i < num; i++) {
int bs = SDL_JoystickGetButton (joy, i) ? 1 : 0;
setjoybuttonstate (nr, i, bs);
#ifdef GEKKO
if ((nr==0) && (currprefs.rumble[0])) Rumble (0,i, bs);
if ((nr==1) && (currprefs.rumble[1])) Rumble (1,i, bs);
#endif
}
}
static unsigned int get_joystick_num (void)
{
return nr_joysticks;
}
static unsigned int get_joystick_widget_num (unsigned int joy)
{
return joys[joy].axles + joys[joy].buttons;
}
static int get_joystick_widget_type (unsigned int joy, unsigned int num, char *name, uae_u32 *code)
{
if (num >= joys[joy].axles && num < joys[joy].axles + joys[joy].buttons) {
if (name)
sprintf (name, "Button %d", num + 1 - joys[joy].axles);
return IDEV_WIDGET_BUTTON;
} else if (num < joys[joy].axles) {
if (name)
sprintf (name, "Axis %d", num + 1);
return IDEV_WIDGET_AXIS;
}
return IDEV_WIDGET_NONE;
}
static int get_joystick_widget_first (unsigned int joy, int type)
{
switch (type) {
case IDEV_WIDGET_BUTTON:
return joys[joy].axles;
case IDEV_WIDGET_AXIS:
return 0;
}
return -1;
}
static const char *get_joystick_name (unsigned int joy)
{
return SDL_JoystickName (joy);
}
static void read_joysticks (void)
{
if (get_joystick_num ()) {
unsigned int i;
//IR wiimote fix
#ifndef GEKKO
SDL_JoystickUpdate ();
#endif
for (i = 0; i < get_joystick_num (); i++)
read_joy (i);
}
}
static int init_joysticks (void)
{
int success = 0;
if (!initialized) {
if (SDL_InitSubSystem (SDL_INIT_JOYSTICK) == 0) {
unsigned int i;
nr_joysticks = SDL_NumJoysticks ();
write_log ("Found %d joystick(s)\n", nr_joysticks);
if (nr_joysticks > MAX_INPUT_DEVICES)
nr_joysticks = MAX_INPUT_DEVICES;
for (i = 0; i < get_joystick_num (); i++) {
joys[i].joy = SDL_JoystickOpen (i);
joys[i].axles = SDL_JoystickNumAxes (joys[i].joy);
joys[i].buttons = SDL_JoystickNumButtons (joys[i].joy);
}
//IR wiimote fix
#ifdef GEKKO
SDL_JoystickEventState(SDL_ENABLE);
#endif
success = initialized = 1;
} else
write_log ("Failed to initialize joysticks\n");
}
return success;
}
static void close_joysticks (void)
{
unsigned int i;
for (i = 0; i < nr_joysticks; i++) {
SDL_JoystickClose (joys[i].joy);
joys[i].joy = 0;
}
nr_joysticks = 0;
if (initialized) {
SDL_QuitSubSystem (SDL_INIT_JOYSTICK);
initialized = 0;
}
}
static int acquire_joy (unsigned int num, int flags)
{
return num < get_joystick_num ();
}
static void unacquire_joy (unsigned int num)
{
}
struct inputdevice_functions inputdevicefunc_joystick = {
init_joysticks,
close_joysticks,
acquire_joy,
unacquire_joy,
read_joysticks,
get_joystick_num,
get_joystick_name,
get_joystick_widget_num,
get_joystick_widget_type,
get_joystick_widget_first
};
/*
* Set default inputdevice config for SDL joysticks
*/
void input_get_default_joystick (struct uae_input_device *uid)
{
unsigned int i, port;
for (i = 0; i < nr_joysticks; i++) {
port = i & 1;
uid[i].eventid[ID_AXIS_OFFSET + 0][0] = port ? INPUTEVENT_JOY2_HORIZ : INPUTEVENT_JOY1_HORIZ;
uid[i].eventid[ID_AXIS_OFFSET + 1][0] = port ? INPUTEVENT_JOY2_VERT : INPUTEVENT_JOY1_VERT;
uid[i].eventid[ID_BUTTON_OFFSET + 0][0] = port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON;
uid[i].eventid[ID_BUTTON_OFFSET + 1][0] = port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON;
uid[i].eventid[ID_BUTTON_OFFSET + 2][0] = port ? INPUTEVENT_JOY2_3RD_BUTTON : INPUTEVENT_JOY1_3RD_BUTTON;
}
uid[0].enabled = 1;
}