Files

329 lines
8.6 KiB
C

#include "lr_input.h"
#include "lr_input_crosshair.h"
#include "opera_lr_callbacks.h"
#include <libopera/opera_pbus.h>
#include <libretro.h>
#include <string.h>
static uint32_t ACTIVE_DEVICES = 0;
static unsigned PBUS_DEVICES[LR_INPUT_MAX_DEVICES] = {0};
static
uint8_t
poll_joypad(const int port_,
const int id_)
{
return retro_input_state_cb(port_,RETRO_DEVICE_JOYPAD,0,id_);
}
static
int16_t
poll_analog_lx(const int port_)
{
return retro_input_state_cb(port_,
RETRO_DEVICE_ANALOG,
RETRO_DEVICE_INDEX_ANALOG_LEFT,
RETRO_DEVICE_ID_ANALOG_X);
}
static
int16_t
poll_analog_ly(const int port_)
{
return retro_input_state_cb(port_,
RETRO_DEVICE_ANALOG,
RETRO_DEVICE_INDEX_ANALOG_LEFT,
RETRO_DEVICE_ID_ANALOG_Y);
}
static
int16_t
poll_analog_rx(const int port_)
{
return retro_input_state_cb(port_,
RETRO_DEVICE_ANALOG,
RETRO_DEVICE_INDEX_ANALOG_RIGHT,
RETRO_DEVICE_ID_ANALOG_X);
}
static
int16_t
poll_analog_ry(const int port_)
{
return retro_input_state_cb(port_,
RETRO_DEVICE_ANALOG,
RETRO_DEVICE_INDEX_ANALOG_RIGHT,
RETRO_DEVICE_ID_ANALOG_Y);
}
static
uint32_t
poll_mouse(const int port_,
const int id_)
{
return retro_input_state_cb(port_,RETRO_DEVICE_MOUSE,0,id_);
}
static
uint32_t
poll_lightgun(const int port_,
const int id_)
{
return retro_input_state_cb(port_,RETRO_DEVICE_LIGHTGUN,0,id_);
}
static
void
lr_input_poll_joypad(const int port_)
{
opera_pbus_joypad_t jp;
jp.u = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_UP);
jp.d = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_DOWN);
jp.l = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_LEFT);
jp.r = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_RIGHT);
jp.lt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L);
jp.rt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R);
jp.x = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT);
jp.p = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START) |
poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_X);
jp.a = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_Y);
jp.b = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_B);
jp.c = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_A);
opera_pbus_add_joypad(&jp);
}
static
void
lr_input_poll_flightstick(const int port_)
{
opera_pbus_flightstick_t fs;
fs.h_pos = poll_analog_lx(port_);
fs.v_pos = poll_analog_ly(port_);
fs.z_pos = poll_analog_ry(port_);
fs.fire = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R2);
fs.a = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_Y);
fs.b = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_B);
fs.c = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_A);
fs.u = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_UP);
fs.d = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_DOWN);
fs.l = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_LEFT);
fs.r = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_RIGHT);
fs.p = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START);
fs.x = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT);
fs.lt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L);
fs.rt = poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R);
opera_pbus_add_flightstick(&fs);
}
static
void
lr_input_poll_mouse(const int port_)
{
opera_pbus_mouse_t m;
m.x = poll_mouse(port_,RETRO_DEVICE_ID_MOUSE_X);
m.y = poll_mouse(port_,RETRO_DEVICE_ID_MOUSE_Y);
m.left = poll_mouse(port_,RETRO_DEVICE_ID_MOUSE_LEFT);
m.middle = poll_mouse(port_,RETRO_DEVICE_ID_MOUSE_MIDDLE);
m.right = poll_mouse(port_,RETRO_DEVICE_ID_MOUSE_RIGHT);
m.shift = poll_mouse(port_,RETRO_DEVICE_ID_MOUSE_BUTTON_4);
opera_pbus_add_mouse(&m);
}
static
void
lr_input_poll_lightgun(const int port_)
{
opera_pbus_lightgun_t lg;
lg.x = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
lg.y = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
lg.trigger = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_TRIGGER);
lg.option = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SELECT);
lg.reload = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
if(poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN))
{
lg.trigger = 0;
lg.reload = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_TRIGGER) || poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
}
lr_input_crosshair_set(port_,lg.x,lg.y);
opera_pbus_add_lightgun(&lg);
}
static
void
lr_input_poll_arcade_lightgun(const int port_)
{
opera_pbus_arcade_lightgun_t lg;
lg.x = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
lg.y = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
lg.trigger = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_TRIGGER);
lg.service = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_AUX_A);
lg.coins = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_SELECT);
lg.start = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_START);
lg.holster = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
if(poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN))
{
lg.trigger = 0;
lg.holster = poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_TRIGGER) || poll_lightgun(port_,RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
}
lr_input_crosshair_set(port_,lg.x,lg.y);
opera_pbus_add_arcade_lightgun(&lg);
}
static
void
lr_input_poll_orbatak_trackball(const int port_)
{
opera_pbus_orbatak_trackball_t tb;
tb.x = (poll_analog_lx(port_) / (32768 / 24));
tb.y = (poll_analog_ly(port_) / (32768 / 24));
if(tb.x == 0)
{
if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_LEFT))
tb.x = -24;
else if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_RIGHT))
tb.x = 24;
}
if(tb.y == 0)
{
if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_UP))
tb.y = -24;
else if(poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_DOWN))
tb.y = 24;
}
opera_pbus_add_orbatak_trackball(&tb);
}
static
void
lr_input_poll_orbatak_buttons(const int port_,
opera_pbus_orbatak_buttons_t *btn_)
{
btn_->start_p1 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_SELECT);
btn_->start_p2 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_START);
btn_->coin_p1 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_L);
btn_->coin_p2 |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R);
btn_->service |= poll_joypad(port_,RETRO_DEVICE_ID_JOYPAD_R2);
}
static
void
lr_input_poll(const int port_)
{
switch(PBUS_DEVICES[port_])
{
case RETRO_DEVICE_NONE:
break;
default:
case RETRO_DEVICE_JOYPAD:
lr_input_poll_joypad(port_);
return;
case RETRO_DEVICE_FLIGHTSTICK:
lr_input_poll_flightstick(port_);
break;
case RETRO_DEVICE_MOUSE:
lr_input_poll_mouse(port_);
break;
case RETRO_DEVICE_LIGHTGUN:
lr_input_poll_lightgun(port_);
break;
case RETRO_DEVICE_ARCADE_LIGHTGUN:
lr_input_poll_arcade_lightgun(port_);
break;
}
}
static
uint32_t
lr_input_get_active_devices(const uint32_t active_devices_)
{
unsigned frontend_devices;
uint32_t active_devices;
active_devices = active_devices_;
if(active_devices > LR_INPUT_MAX_DEVICES)
active_devices = LR_INPUT_MAX_DEVICES;
frontend_devices = 0;
if(retro_environment_cb(RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS,&frontend_devices) &&
(frontend_devices > 0) &&
(frontend_devices < active_devices))
active_devices = frontend_devices;
return active_devices;
}
void
lr_input_device_set(const uint32_t port_,
const uint32_t device_)
{
if(port_ >= LR_INPUT_MAX_DEVICES)
return;
PBUS_DEVICES[port_] = device_;
}
uint32_t
lr_input_device_get(const uint32_t port_)
{
if(port_ >= LR_INPUT_MAX_DEVICES)
return RETRO_DEVICE_NONE;
return PBUS_DEVICES[port_];
}
void
lr_input_update(const uint32_t active_devices_)
{
int i;
uint32_t active_devices;
int has_orbatak;
opera_pbus_orbatak_buttons_t orbatak_buttons;
has_orbatak = 0;
memset(&orbatak_buttons,0,sizeof(orbatak_buttons));
opera_pbus_reset();
retro_input_poll_cb();
active_devices = lr_input_get_active_devices(active_devices_);
for(i = 0; i < active_devices; i++)
{
if(PBUS_DEVICES[i] == RETRO_DEVICE_NONE)
continue;
if(PBUS_DEVICES[i] == RETRO_DEVICE_ORBATAK_TRACKBALL)
{
lr_input_poll_orbatak_trackball(i);
lr_input_poll_orbatak_buttons(i,&orbatak_buttons);
has_orbatak = 1;
}
else
lr_input_poll(i);
}
if(has_orbatak)
opera_pbus_add_orbatak_buttons(&orbatak_buttons);
}