mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-28 18:50:29 +00:00
916 lines
23 KiB
C
916 lines
23 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
|
* Copyright (C) 2020 Google
|
|
*
|
|
* RetroArch 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 Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch 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 for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <boolean.h>
|
|
#include <libretro.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "../../config.h"
|
|
#endif
|
|
|
|
#include <defines/ps3_defines.h>
|
|
|
|
#include "../input_driver.h"
|
|
|
|
#include <retro_inline.h>
|
|
|
|
#include "../../config.def.h"
|
|
|
|
#include "../../tasks/tasks_internal.h"
|
|
|
|
#ifdef HAVE_LIGHTGUN
|
|
#include <sys/spu.h>
|
|
#include <io/camera.h>
|
|
#include <io/move.h>
|
|
#include <vectormath/c/vectormath_aos.h>
|
|
#define SPURS_PREFIX_NAME "gemsample"
|
|
#endif
|
|
|
|
#ifdef HAVE_MOUSE
|
|
#define MAX_MICE 7
|
|
#endif
|
|
|
|
/* TODO/FIXME -
|
|
* fix game focus toggle */
|
|
|
|
typedef struct
|
|
{
|
|
float x;
|
|
float y;
|
|
float z;
|
|
} sensor_t;
|
|
|
|
typedef struct ps3_input
|
|
{
|
|
int connected[MAX_KB_PORT_NUM];
|
|
#ifdef HAVE_MOUSE
|
|
unsigned mice_connected;
|
|
#endif
|
|
KbInfo kbinfo;
|
|
KbData kbdata[MAX_KB_PORT_NUM];
|
|
#ifdef HAVE_LIGHTGUN
|
|
unsigned gem_connected, gem_init;
|
|
cameraType type;
|
|
cameraReadInfo camread;
|
|
cameraInfoEx camInf;
|
|
sys_mem_container_t container;
|
|
u8 *cam_buf;
|
|
gemAttribute gem_attr;
|
|
gemInfo gem_info;
|
|
gemVideoConvertAttribute gem_video_convert;
|
|
gemState gem_state;
|
|
gemInertialState gem_inertial_state;
|
|
Spurs *spurs ATTRIBUTE_PRXPTR;
|
|
sys_spu_thread_t *threads;
|
|
void *gem_memory ATTRIBUTE_PRXPTR;
|
|
void *buffer_mem ATTRIBUTE_PRXPTR;
|
|
void *video_out ATTRIBUTE_PRXPTR;
|
|
u8 video_frame[640*480*4];
|
|
u16 pos_x;
|
|
u16 pos_y;
|
|
float adj_x;
|
|
float adj_y;
|
|
u16 oldGemPad;
|
|
u16 newGemPad;
|
|
u16 newGemAnalogT;
|
|
int t_pressed;
|
|
int start_pressed;
|
|
int select_pressed;
|
|
int m_pressed;
|
|
int square_pressed;
|
|
int circle_pressed;
|
|
int cross_pressed;
|
|
int triangle_pressed;
|
|
#endif
|
|
} ps3_input_t;
|
|
|
|
static int mod_table[] = {
|
|
RETROK_RSUPER,
|
|
RETROK_RALT,
|
|
RETROK_RSHIFT,
|
|
RETROK_RCTRL,
|
|
RETROK_LSUPER,
|
|
RETROK_LALT,
|
|
RETROK_LSHIFT,
|
|
RETROK_LCTRL
|
|
};
|
|
|
|
static void ps3_connect_keyboard(ps3_input_t *ps3, int port)
|
|
{
|
|
ioKbSetCodeType(port, KB_CODETYPE_RAW);
|
|
ioKbSetReadMode(port, KB_RMODE_INPUTCHAR);
|
|
ps3->connected[port] = 1;
|
|
}
|
|
|
|
#ifdef HAVE_LIGHTGUN
|
|
void endCamera(ps3_input_t *ps3)
|
|
{
|
|
cameraStop(0);
|
|
cameraClose(0);
|
|
cameraEnd();
|
|
sysMemContainerDestroy(ps3->container);
|
|
}
|
|
|
|
int setupCamera(ps3_input_t *ps3)
|
|
{
|
|
int error = 0;
|
|
|
|
cameraGetType(0, &ps3->type);
|
|
if (ps3->type == CAM_TYPE_PLAYSTATION_EYE)
|
|
{
|
|
ps3->camInf.format = CAM_FORM_RAW8;
|
|
ps3->camInf.framerate = 60;
|
|
ps3->camInf.resolution = CAM_RESO_VGA;
|
|
ps3->camInf.info_ver = 0x0101;
|
|
ps3->camInf.container = ps3->container;
|
|
|
|
switch (cameraOpenEx(0, &ps3->camInf))
|
|
{
|
|
case CAMERA_ERRO_DOUBLE_OPEN:
|
|
cameraClose(0);
|
|
error = 1;
|
|
break;
|
|
case CAMERA_ERRO_NO_DEVICE_FOUND:
|
|
error = 1;
|
|
break;
|
|
case 0:
|
|
ps3->camread.buffer = ps3->camInf.buffer;
|
|
ps3->camread.version = 0x0100;
|
|
ps3->cam_buf = (u8 *)(u64)ps3->camread.buffer;
|
|
break;
|
|
default:
|
|
error = 1;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
error = 1;
|
|
return error;
|
|
}
|
|
|
|
int initCamera(ps3_input_t *ps3)
|
|
{
|
|
int ret = sysMemContainerCreate(&ps3->container, 0x200000);
|
|
ret = cameraInit();
|
|
if (ret == 0)
|
|
return setupCamera(ps3);
|
|
return ret;
|
|
|
|
}
|
|
|
|
int readCamera(ps3_input_t *ps3)
|
|
{
|
|
int ret = cameraReadEx(0, &ps3->camread);
|
|
switch (ret)
|
|
{
|
|
case CAMERA_ERRO_NEED_START:
|
|
cameraReset(0);
|
|
ret = gemPrepareCamera(128, 0.5);
|
|
ret = cameraStart(0);
|
|
break;
|
|
case 0:
|
|
break;
|
|
default:
|
|
ret = 1;
|
|
break;
|
|
}
|
|
if (ret == 0 && ps3->camread.readcount != 0)
|
|
return ps3->camread.readcount;
|
|
return 0;
|
|
}
|
|
|
|
int proccessGem(ps3_input_t *ps3, int t)
|
|
{
|
|
switch (t)
|
|
{
|
|
case 0:
|
|
return gemUpdateStart(ps3->camread.buffer, ps3->camread.timestamp);
|
|
case 1:
|
|
return gemConvertVideoStart(ps3->camread.buffer);
|
|
case 2:
|
|
return gemUpdateFinish();
|
|
case 3:
|
|
return gemConvertVideoFinish();
|
|
default:
|
|
break;
|
|
}
|
|
return -1;
|
|
|
|
}
|
|
|
|
int processMove(ps3_input_t *ps3)
|
|
{
|
|
const unsigned int hues[] = { 4 << 24, 4 << 24, 4 << 24, 4 << 24 };
|
|
int ret = -1;
|
|
|
|
if (readCamera(ps3) > 0)
|
|
{
|
|
ret = gemUpdateStart(ps3->camread.buffer, ps3->camread.timestamp);
|
|
if (ret == 0)
|
|
{
|
|
ret = gemUpdateFinish();
|
|
if (ret == 0)
|
|
{
|
|
ret = gemGetState(0, STATE_LATEST_IMAGE_TIME, 0, &ps3->gem_state);
|
|
switch (ret)
|
|
{
|
|
case 2:
|
|
gemForceRGB(0, 0.5, 0.5, 0.5);
|
|
break;
|
|
case 5:
|
|
gemTrackHues(hues, NULL);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int initSpurs(ps3_input_t *ps3)
|
|
{
|
|
int i;
|
|
int ppu_prio;
|
|
sys_ppu_thread_t ppu_thread_id;
|
|
unsigned int nthread;
|
|
int ret = sysSpuInitialize(6, 0);
|
|
ret = sysThreadGetId(&ppu_thread_id);
|
|
ret = sysThreadGetPriority(ppu_thread_id, &ppu_prio);
|
|
|
|
/* initialize spurs */
|
|
ps3->spurs = (Spurs *)memalign(SPURS_ALIGN, sizeof(Spurs));
|
|
SpursAttribute attributeSpurs;
|
|
|
|
if ((ret = spursAttributeInitialize(&attributeSpurs, 5, 250, ppu_prio - 1, true)))
|
|
return (ret);
|
|
|
|
if ((ret = spursAttributeSetNamePrefix(&attributeSpurs, SPURS_PREFIX_NAME, strlen(SPURS_PREFIX_NAME))))
|
|
return (ret);
|
|
|
|
if ((ret = spursInitializeWithAttribute(ps3->spurs, &attributeSpurs)))
|
|
return (ret);
|
|
|
|
if ((ret = spursGetNumSpuThread(ps3->spurs, &nthread)))
|
|
return (ret);
|
|
|
|
ps3->threads = (sys_spu_thread_t *)malloc(sizeof(sys_spu_thread_t) * nthread);
|
|
|
|
if ((ret = spursGetSpuThreadId(ps3->spurs, ps3->threads, &nthread)))
|
|
return (ret);
|
|
|
|
SpursInfo info;
|
|
ret = spursGetInfo(ps3->spurs, &info);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int endSpurs(ps3_input_t *ps3)
|
|
{
|
|
spursFinalize(ps3->spurs);
|
|
free(ps3->spurs);
|
|
free(ps3->threads);
|
|
return 0;
|
|
}
|
|
|
|
int endGem(ps3_input_t *ps3)
|
|
{
|
|
endSpurs(ps3);
|
|
gemEnd();
|
|
free(ps3->gem_memory);
|
|
return 0;
|
|
}
|
|
|
|
static inline void initAttributeGem(gemAttribute * attribute,
|
|
u32 max_connect, void *memory_ptr,
|
|
Spurs *spurs, const u8 spu_priorities[8])
|
|
{
|
|
int i;
|
|
|
|
attribute->version = 2;
|
|
attribute->max = max_connect;
|
|
attribute->spurs = spurs;
|
|
attribute->memory = memory_ptr;
|
|
for (i = 0; i < 8; ++i)
|
|
attribute->spu_priorities[i] = spu_priorities[i];
|
|
}
|
|
|
|
int initGemVideoConvert(ps3_input_t *ps3)
|
|
{
|
|
ps3->gem_video_convert.version = 2;
|
|
ps3->gem_video_convert.format = 2; /* GEM_RGBA_640x480; */
|
|
ps3->gem_video_convert.conversion = GEM_AUTO_WHITE_BALANCE
|
|
| GEM_COMBINE_PREVIOUS_INPUT_FRAME
|
|
| GEM_FILTER_OUTLIER_PIXELS
|
|
| GEM_GAMMA_BOOST;
|
|
ps3->gem_video_convert.gain = 1.0f;
|
|
ps3->gem_video_convert.red_gain = 1.0f;
|
|
ps3->gem_video_convert.green_gain = 1.0f;
|
|
ps3->gem_video_convert.blue_gain = 1.0f;
|
|
ps3->buffer_mem = (void *)memalign(128, 640*480);
|
|
ps3->video_out = (void *)ps3->video_frame;
|
|
ps3->gem_video_convert.buffer_memory = ps3->buffer_mem;
|
|
ps3->gem_video_convert.video_data_out = ps3->video_out;
|
|
ps3->gem_video_convert.alpha = 255;
|
|
|
|
return gemPrepareVideoConvert(&ps3->gem_video_convert);
|
|
}
|
|
|
|
int initGem(ps3_input_t *ps3)
|
|
{
|
|
int i;
|
|
gemAttribute gem_attr;
|
|
u8 gem_spu_priorities[8] = { 1, 1, 1, 1, 1, 0, 0, 0 }; /* execute */
|
|
/* libgem jobs */
|
|
/* on 5 SPUs */
|
|
if (initSpurs(ps3))
|
|
return -1;
|
|
|
|
if (!(ps3->gem_memory = (void *)malloc(gemGetMemorySize(1))))
|
|
return -1;
|
|
|
|
initAttributeGem(&gem_attr, 1, ps3->gem_memory,
|
|
ps3->spurs, gem_spu_priorities);
|
|
|
|
gemInit (&gem_attr);
|
|
initGemVideoConvert(ps3);
|
|
gemPrepareCamera (128, 0.5);
|
|
gemReset(0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void readGemPad(ps3_input_t *ps3, int num_gem)
|
|
{
|
|
unsigned int hues[] = { 4 << 24, 4 << 24, 4 << 24, 4 << 24 };
|
|
int ret = gemGetState(0, 0, -22000, &ps3->gem_state);
|
|
|
|
ps3->newGemPad = ps3->gem_state.paddata.buttons & (~ps3->oldGemPad);
|
|
ps3->newGemAnalogT = ps3->gem_state.paddata.ANA_T;
|
|
ps3->oldGemPad = ps3->gem_state.paddata.buttons;
|
|
|
|
switch (ret)
|
|
{
|
|
case 2:
|
|
gemForceRGB (num_gem, 0.5, 0.5, 0.5);
|
|
break;
|
|
case 5:
|
|
gemTrackHues (hues, NULL);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void readGemAccPosition(int num_gem)
|
|
{
|
|
vec_float4 position;
|
|
VmathVector4 v;
|
|
gemGetAccelerometerPositionInDevice(num_gem, &position);
|
|
|
|
v.vec128 = position;
|
|
}
|
|
|
|
void readGemInertial(ps3_input_t *ps3, int num_gem)
|
|
{
|
|
VmathVector4 v;
|
|
int ret = gemGetInertialState(num_gem, 0, -22000, &ps3->gem_inertial_state);
|
|
v.vec128 = ps3->gem_inertial_state.accelerometer;
|
|
v.vec128 = ps3->gem_inertial_state.accelerometer_bias;
|
|
v.vec128 = ps3->gem_inertial_state.gyro;
|
|
v.vec128 = ps3->gem_inertial_state.gyro_bias;
|
|
}
|
|
|
|
void readGem(ps3_input_t *ps3)
|
|
{
|
|
VmathVector4 v;
|
|
|
|
proccessGem(ps3, 0);
|
|
proccessGem(ps3, 1);
|
|
proccessGem(ps3, 2);
|
|
proccessGem(ps3, 3);
|
|
readGemPad(ps3, 0); /* This will read buttons from Move */
|
|
v.vec128 = ps3->gem_state.pos;
|
|
switch (ps3->newGemPad)
|
|
{
|
|
case 1:
|
|
ps3->select_pressed++;
|
|
break;
|
|
case 2:
|
|
ps3->t_pressed++;
|
|
break;
|
|
case 4:
|
|
ps3->m_pressed++;
|
|
gemCalibrate(0);
|
|
ps3->adj_x = v.vec128[0];
|
|
ps3->adj_y = v.vec128[1];
|
|
break;
|
|
case 8:
|
|
ps3->start_pressed++;
|
|
break;
|
|
case 16:
|
|
ps3->triangle_pressed++;
|
|
break;
|
|
case 32:
|
|
ps3->circle_pressed++;
|
|
break;
|
|
case 64:
|
|
ps3->cross_pressed++;
|
|
#if 0
|
|
readGemAccPosition(0);
|
|
#endif
|
|
break;
|
|
case 128:
|
|
ps3->square_pressed++;
|
|
#if 0
|
|
readGemInertial(ps3, 0);
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#endif /* HAVE_LIGHTGUN */
|
|
|
|
static void ps3_input_poll(void *data)
|
|
{
|
|
unsigned i, j;
|
|
ps3_input_t *ps3 = (ps3_input_t*)data;
|
|
KbData last_kbdata[MAX_KB_PORT_NUM];
|
|
|
|
ioKbGetInfo(&ps3->kbinfo);
|
|
|
|
for (i = 0; i < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
if (ps3->kbinfo.status[i] && !ps3->connected[i])
|
|
ps3_connect_keyboard(ps3, i);
|
|
#if 0
|
|
if (!ps3->kbinfo.status[i] && ps3->connected[i])
|
|
ps3->connected[i] = 0;
|
|
#endif
|
|
}
|
|
|
|
memcpy(last_kbdata, ps3->kbdata, sizeof(last_kbdata));
|
|
for (i = 0; i < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
if (ps3->kbinfo.status[i])
|
|
ioKbRead(i, &ps3->kbdata[i]);
|
|
}
|
|
|
|
for (i = 0; i < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
/* Set keyboard modifier based on shift,ctrl and alt state */
|
|
uint16_t mod = 0;
|
|
|
|
if ( ps3->kbdata[i].mkey._KbMkeyU._KbMkeyS.l_alt
|
|
|| ps3->kbdata[i].mkey._KbMkeyU._KbMkeyS.r_alt)
|
|
mod |= RETROKMOD_ALT;
|
|
if ( ps3->kbdata[i].mkey._KbMkeyU._KbMkeyS.l_ctrl
|
|
|| ps3->kbdata[i].mkey._KbMkeyU._KbMkeyS.r_ctrl)
|
|
mod |= RETROKMOD_CTRL;
|
|
if ( ps3->kbdata[i].mkey._KbMkeyU._KbMkeyS.l_shift
|
|
|| ps3->kbdata[i].mkey._KbMkeyU._KbMkeyS.r_shift)
|
|
mod |= RETROKMOD_SHIFT;
|
|
|
|
/* TODO: windows keys. */
|
|
|
|
for (j = 0; j < last_kbdata[i].nb_keycode; j++)
|
|
{
|
|
unsigned k;
|
|
int code = last_kbdata[i].keycode[j];
|
|
int newly_depressed = 1;
|
|
|
|
for (k = 0; k < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
if (ps3->kbdata[i].keycode[k] == code)
|
|
{
|
|
newly_depressed = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (newly_depressed)
|
|
{
|
|
unsigned keyboardcode = input_keymaps_translate_keysym_to_rk(code);
|
|
input_keyboard_event(false, keyboardcode, keyboardcode, mod, RETRO_DEVICE_KEYBOARD);
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < ps3->kbdata[i].nb_keycode; j++)
|
|
{
|
|
unsigned k;
|
|
int code = ps3->kbdata[i].keycode[j];
|
|
int newly_pressed = 1;
|
|
|
|
for (k = 0; k < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
if (last_kbdata[i].keycode[k] == code)
|
|
{
|
|
newly_pressed = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (newly_pressed)
|
|
{
|
|
unsigned keyboardcode = input_keymaps_translate_keysym_to_rk(code);
|
|
input_keyboard_event(true, keyboardcode, keyboardcode, mod, RETRO_DEVICE_KEYBOARD);
|
|
}
|
|
}
|
|
}
|
|
#ifdef HAVE_MOUSE
|
|
mouseInfo mouse_info;
|
|
ioMouseGetInfo(&mouse_info);
|
|
ps3->mice_connected = mouse_info.connected;
|
|
#endif
|
|
#ifdef HAVE_LIGHTGUN
|
|
gemInfo gem_info;
|
|
gemGetInfo(&gem_info);
|
|
ps3->gem_connected = gem_info.connected;
|
|
#endif
|
|
}
|
|
|
|
static bool psl1ght_keyboard_port_input_pressed(
|
|
ps3_input_t *ps3, unsigned id)
|
|
{
|
|
int code;
|
|
unsigned i, j;
|
|
|
|
if (id >= RETROK_LAST || id == 0)
|
|
return false;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if (id == mod_table[i])
|
|
{
|
|
for (j = 0; j < MAX_KB_PORT_NUM; j++)
|
|
{
|
|
if (ps3->kbinfo.status[j]
|
|
&& (ps3->kbdata[j].mkey._KbMkeyU.mkeys & (1 << i)))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
code = rarch_keysym_lut[id];
|
|
if (code != 0)
|
|
{
|
|
for (i = 0; i < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
if (ps3->kbinfo.status[i])
|
|
{
|
|
for (j = 0; j < ps3->kbdata[i].nb_keycode; j++)
|
|
{
|
|
if (ps3->kbdata[i].keycode[j] == code)
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#ifdef HAVE_MOUSE
|
|
static int16_t ps3_mouse_device_state(ps3_input_t *ps3,
|
|
unsigned user, unsigned id)
|
|
{
|
|
if (ps3->mice_connected)
|
|
{
|
|
mouseData mouse_state;
|
|
ioMouseGetData(id, &mouse_state);
|
|
|
|
switch (id)
|
|
{
|
|
/* TODO: mouse wheel up/down */
|
|
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
|
return (mouse_state.buttons & CELL_MOUSE_BUTTON_1);
|
|
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
|
return (mouse_state.buttons & CELL_MOUSE_BUTTON_2);
|
|
case RETRO_DEVICE_ID_MOUSE_X:
|
|
return (mouse_state.x_axis);
|
|
case RETRO_DEVICE_ID_MOUSE_Y:
|
|
return (mouse_state.y_axis);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAVE_LIGHTGUN
|
|
static int16_t ps3_lightgun_device_state(ps3_input_t *ps3,
|
|
unsigned user, unsigned id)
|
|
{
|
|
float center_x;
|
|
float center_y;
|
|
float pointer_x;
|
|
float pointer_y;
|
|
videoState state;
|
|
videoConfiguration vconfig;
|
|
videoResolution res;
|
|
VmathVector4 ray_start, ray_dir;
|
|
struct video_viewport vp;
|
|
const int edge_detect = 32700;
|
|
bool inside = false;
|
|
int16_t res_x = 0;
|
|
int16_t res_y = 0;
|
|
int16_t res_screen_x = 0;
|
|
int16_t res_screen_y = 0;
|
|
float sensitivity = 1.0f;
|
|
if (!ps3->gem_connected || !ps3->gem_init)
|
|
return 0;
|
|
|
|
readCamera(ps3);
|
|
readGem(ps3);
|
|
|
|
videoGetState(0, 0, &state);
|
|
videoGetResolution(state.displayMode.resolution, &res);
|
|
|
|
if (res.height == 720)
|
|
{
|
|
/* 720p offset adjustments */
|
|
center_x = 645.0f;
|
|
center_y = 375.0f;
|
|
}
|
|
else if (res.height == 1080)
|
|
{
|
|
/* 1080p offset adjustments */
|
|
center_x = 960.0f;
|
|
center_y = 565.0f;
|
|
}
|
|
|
|
vp.x = 0;
|
|
vp.y = 0;
|
|
vp.width = 0;
|
|
vp.height = 0;
|
|
vp.full_width = 0;
|
|
vp.full_height = 0;
|
|
|
|
/* tracking mode 1: laser pointer mode (this is closest
|
|
to actual lightgun behavior) */
|
|
ray_start.vec128 = ps3->gem_state.pos;
|
|
VmathVector4 ray_tmp = {.vec128 = {0.0f,0.0f,-1.0f,0.0f}};
|
|
const VmathQuat *quat = &ps3->gem_state.quat;
|
|
vmathQRotate(&ray_dir, quat, &ray_tmp);
|
|
float t = -ray_start.vec128[2] / ray_dir.vec128[2];
|
|
pointer_x = ray_start.vec128[0] + ray_dir.vec128[0]*t;
|
|
pointer_y = ray_start.vec128[1] + ray_dir.vec128[1]*t;
|
|
|
|
#if 0
|
|
/* tracking mode 2: 3D coordinate system (move pointer position by moving the
|
|
* whole controller) */
|
|
VmathVector4 v;
|
|
v.vec128 = ps3->gem_state.pos;
|
|
pointer_x = v.vec128[0];
|
|
pointer_y = v.vec128[1];
|
|
#endif
|
|
|
|
if (video_driver_translate_coord_viewport_wrap(&vp,
|
|
center_x + ((pointer_x - ps3->adj_x)*sensitivity), center_y + ((pointer_y - ps3->adj_y)*sensitivity),
|
|
&res_x, &res_y, &res_screen_x, &res_screen_y))
|
|
{
|
|
|
|
inside = (res_x >= -edge_detect)
|
|
&& (res_y >= -edge_detect)
|
|
&& (res_x <= edge_detect)
|
|
&& (res_y <= edge_detect);
|
|
|
|
switch (id)
|
|
{
|
|
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
|
|
#if 0
|
|
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
|
|
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: /* deprecated */
|
|
#endif
|
|
if (ps3->t_pressed > 0)
|
|
{
|
|
ps3->t_pressed = 0;
|
|
return 1;
|
|
}
|
|
break;
|
|
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
|
if (ps3->start_pressed > 0)
|
|
{
|
|
ps3->start_pressed = 0;
|
|
return 1;
|
|
}
|
|
break;
|
|
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
|
|
if (ps3->select_pressed > 0)
|
|
{
|
|
ps3->select_pressed = 0;
|
|
return 1;
|
|
}
|
|
break;
|
|
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
|
|
if (ps3->triangle_pressed > 0)
|
|
{
|
|
ps3->triangle_pressed = 0;
|
|
return 1;
|
|
}
|
|
break;
|
|
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
|
if (inside)
|
|
return res_x;
|
|
break;
|
|
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
|
if (inside)
|
|
return ~res_y;
|
|
break;
|
|
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
|
return !inside;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static int16_t ps3_input_state(
|
|
void *data,
|
|
const input_device_driver_t *joypad,
|
|
const input_device_driver_t *sec_joypad,
|
|
rarch_joypad_info_t *joypad_info,
|
|
const retro_keybind_set *binds,
|
|
bool keyboard_mapping_blocked,
|
|
unsigned port,
|
|
unsigned device,
|
|
unsigned idx,
|
|
unsigned id)
|
|
{
|
|
ps3_input_t *ps3 = (ps3_input_t*)data;
|
|
|
|
if (ps3)
|
|
{
|
|
switch (device)
|
|
{
|
|
case RETRO_DEVICE_JOYPAD:
|
|
if (id == RETRO_DEVICE_ID_JOYPAD_MASK)
|
|
{
|
|
int i;
|
|
int16_t ret = 0;
|
|
|
|
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
|
|
{
|
|
if (binds[port][i].valid)
|
|
{
|
|
if (psl1ght_keyboard_port_input_pressed(
|
|
ps3, binds[port][i].key))
|
|
ret |= (1 << i);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
if (binds[port][id].valid)
|
|
{
|
|
if (psl1ght_keyboard_port_input_pressed(
|
|
ps3, binds[port][id].key))
|
|
return 1;
|
|
}
|
|
break;
|
|
case RETRO_DEVICE_ANALOG:
|
|
break;
|
|
case RETRO_DEVICE_KEYBOARD:
|
|
return psl1ght_keyboard_port_input_pressed(ps3, id);
|
|
#ifdef HAVE_MOUSE
|
|
case RETRO_DEVICE_MOUSE:
|
|
return ps3_mouse_device_state(ps3, port, id);
|
|
#endif
|
|
#ifdef HAVE_LIGHTGUN
|
|
case RETRO_DEVICE_LIGHTGUN:
|
|
return ps3_lightgun_device_state(ps3, port, id);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void ps3_input_free_input(void *data)
|
|
{
|
|
ioPadEnd();
|
|
ioKbEnd();
|
|
#ifdef HAVE_MOUSE
|
|
ioMouseEnd();
|
|
#endif
|
|
#ifdef HAVE_LIGHTGUN
|
|
endGem((ps3_input_t *)data);
|
|
endCamera((ps3_input_t *)data);
|
|
#endif
|
|
}
|
|
|
|
static void* ps3_input_init(const char *joypad_driver)
|
|
{
|
|
int i;
|
|
#ifdef HAVE_LIGHTGUN
|
|
gemInfo gem_info;
|
|
#endif
|
|
ps3_input_t *ps3 = (ps3_input_t*)calloc(1, sizeof(*ps3));
|
|
if (!ps3)
|
|
return NULL;
|
|
|
|
/* Keyboard */
|
|
|
|
input_keymaps_init_keyboard_lut(rarch_key_map_psl1ght);
|
|
|
|
ioKbInit(MAX_KB_PORT_NUM);
|
|
ioKbGetInfo(&ps3->kbinfo);
|
|
|
|
for (i = 0; i < MAX_KB_PORT_NUM; i++)
|
|
{
|
|
if (ps3->kbinfo.status[i])
|
|
ps3_connect_keyboard(ps3, i);
|
|
}
|
|
|
|
#ifdef HAVE_MOUSE
|
|
ioMouseInit(MAX_MICE);
|
|
#endif
|
|
#ifdef HAVE_LIGHTGUN
|
|
ps3->gem_init = 0;
|
|
gemGetInfo(&gem_info);
|
|
ps3->gem_connected = gem_info.connected;
|
|
if (ps3->gem_connected)
|
|
{
|
|
if (!cameraInit())
|
|
{
|
|
cameraGetType(0, &ps3->type);
|
|
if (ps3->type == CAM_TYPE_PLAYSTATION_EYE)
|
|
{
|
|
if (!sysMemContainerCreate(&ps3->container, 0x200000))
|
|
{
|
|
if (!setupCamera(ps3));
|
|
{
|
|
if (!initGem(ps3))
|
|
ps3->gem_init = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return ps3;
|
|
}
|
|
|
|
static uint64_t ps3_input_get_capabilities(void *data)
|
|
{
|
|
return
|
|
#ifdef HAVE_MOUSE
|
|
(1 << RETRO_DEVICE_MOUSE) |
|
|
#endif
|
|
#ifdef HAVE_LIGHTGUN
|
|
(1 << RETRO_DEVICE_LIGHTGUN) |
|
|
#endif
|
|
(1 << RETRO_DEVICE_KEYBOARD)
|
|
| (1 << RETRO_DEVICE_JOYPAD)
|
|
| (1 << RETRO_DEVICE_ANALOG);
|
|
}
|
|
|
|
static bool ps3_input_set_sensor_state(void *data, unsigned port,
|
|
enum retro_sensor_action action, unsigned event_rate) { return false; }
|
|
|
|
input_driver_t input_ps3 = {
|
|
ps3_input_init,
|
|
ps3_input_poll,
|
|
ps3_input_state,
|
|
ps3_input_free_input,
|
|
ps3_input_set_sensor_state,
|
|
NULL,
|
|
ps3_input_get_capabilities,
|
|
"ps3",
|
|
|
|
NULL, /* grab_mouse */
|
|
NULL,
|
|
NULL
|
|
};
|