mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
(Apple) More Wiimote integration
This commit is contained in:
parent
59b3f96e5f
commit
c90c2c5829
@ -22,6 +22,34 @@
|
||||
#include "joypad_connection.h"
|
||||
|
||||
#ifndef NO_BAKED_IN_WIIMOTE
|
||||
/*
|
||||
* Send a packet to the wiimote.
|
||||
*
|
||||
* This function should replace any write()s directly to the wiimote device.
|
||||
*/
|
||||
|
||||
static int wiimote_send(struct wiimote_t* wm,
|
||||
byte report_type, byte* msg, int len)
|
||||
{
|
||||
byte buf[32];
|
||||
|
||||
buf[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
||||
buf[1] = report_type;
|
||||
|
||||
memcpy(buf+2, msg, len);
|
||||
|
||||
#ifdef WIIMOTE_DBG
|
||||
int x = 2;
|
||||
printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]);
|
||||
for (; x < len+2; ++x)
|
||||
printf("%.2x ", buf[x]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
pad_connection_send_control(wm->connection, buf, len + 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Request the wiimote controller status.
|
||||
*
|
||||
@ -93,6 +121,55 @@ static void wiimote_pressed_buttons(struct wiimote_t* wm, byte* msg)
|
||||
wm->btns = now;
|
||||
}
|
||||
|
||||
static int classic_ctrl_handshake(struct wiimote_t* wm,
|
||||
struct classic_ctrl_t* cc, byte* data, unsigned short len)
|
||||
{
|
||||
memset(cc, 0, sizeof(*cc));
|
||||
wm->exp.type = EXP_CLASSIC;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static float normalize_and_interpolate(float min, float max, float t)
|
||||
{
|
||||
return (min == max) ? 0.0f : (t - min) / (max - min);
|
||||
}
|
||||
|
||||
static void process_axis(struct axis_t* axis, byte raw)
|
||||
{
|
||||
if (!axis->has_center)
|
||||
{
|
||||
axis->has_center = true;
|
||||
axis->min = raw - 2;
|
||||
axis->center = raw;
|
||||
axis->max = raw + 2;
|
||||
}
|
||||
|
||||
if (raw < axis->min)
|
||||
axis->min = raw;
|
||||
if (raw > axis->max)
|
||||
axis->max = raw;
|
||||
axis->raw_value = raw;
|
||||
|
||||
if (raw < axis->center)
|
||||
axis->value = -normalize_and_interpolate(
|
||||
axis->center, axis->min, raw);
|
||||
else if (raw > axis->center)
|
||||
axis->value = normalize_and_interpolate(
|
||||
axis->center, axis->max, raw);
|
||||
else
|
||||
axis->value = 0;
|
||||
}
|
||||
|
||||
static void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg)
|
||||
{
|
||||
cc->btns = ~BIG_ENDIAN_SHORT(*(short*)(msg + 4)) & CLASSIC_CTRL_BUTTON_ALL;
|
||||
process_axis(&cc->ljs.x, (msg[0] & 0x3F));
|
||||
process_axis(&cc->ljs.y, (msg[1] & 0x3F));
|
||||
process_axis(&cc->rjs.x, ((msg[0] & 0xC0) >> 3) |
|
||||
((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7));
|
||||
process_axis(&cc->rjs.y, (msg[2] & 0x1F));
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle data from the expansion.
|
||||
*/
|
||||
@ -109,6 +186,77 @@ static void wiimote_handle_expansion(struct wiimote_t* wm, byte* msg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to the wiimote.
|
||||
*/
|
||||
static int wiimote_write_data(struct wiimote_t* wm,
|
||||
unsigned int addr, byte* data, byte len)
|
||||
{
|
||||
byte buf[21] = {0}; /* the payload is always 23 */
|
||||
|
||||
if (!wm || !WIIMOTE_IS_CONNECTED(wm))
|
||||
return 0;
|
||||
if (!data || !len)
|
||||
return 0;
|
||||
|
||||
#ifdef WIIMOTE_DBG
|
||||
printf("Writing %i bytes to memory location 0x%x...\n", len, addr);
|
||||
|
||||
int i = 0;
|
||||
printf("Write data is: ");
|
||||
for (; i < len; ++i)
|
||||
printf("%x ", data[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* the offset is in big endian */
|
||||
*(int*)(buf) = BIG_ENDIAN_LONG(addr);
|
||||
|
||||
/* length */
|
||||
*(byte*)(buf + 4) = len;
|
||||
|
||||
/* data */
|
||||
memcpy(buf + 5, data, len);
|
||||
|
||||
wiimote_send(wm, WM_CMD_WRITE_DATA, buf, 21);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from the wiimote (event version).
|
||||
*
|
||||
* The library can only handle one data read request at a time
|
||||
* because it must keep track of the buffer and other
|
||||
* events that are specific to that request. So if a request
|
||||
* has already been made, subsequent requests will be added
|
||||
* to a pending list and be sent out when the previous
|
||||
* finishes.
|
||||
*/
|
||||
|
||||
static int wiimote_read_data(struct wiimote_t* wm, unsigned int addr,
|
||||
unsigned short len)
|
||||
{
|
||||
byte buf[6];
|
||||
|
||||
/* No puden ser mas de 16 lo leido o vendra en trozos! */
|
||||
|
||||
if (!wm || !WIIMOTE_IS_CONNECTED(wm) || !len)
|
||||
return 0;
|
||||
|
||||
/* the offset is in big endian */
|
||||
*(int*)(buf) = BIG_ENDIAN_LONG(addr);
|
||||
|
||||
/* the length is in big endian */
|
||||
*(short*)(buf + 4) = BIG_ENDIAN_SHORT(len);
|
||||
|
||||
#ifdef WIIMOTE_DBG
|
||||
printf("Request read at address: 0x%x length: %i", addr, len);
|
||||
#endif
|
||||
wiimote_send(wm, WM_CMD_READ_DATA, buf, 6);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get initialization data from the Wiimote.
|
||||
*
|
||||
@ -304,153 +452,8 @@ static int wiimote_handshake(struct wiimote_t* wm, byte event, byte* data,
|
||||
} while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a packet to the wiimote.
|
||||
*
|
||||
* This function should replace any write()s directly to the wiimote device.
|
||||
*/
|
||||
|
||||
static int wiimote_send(struct wiimote_t* wm,
|
||||
byte report_type, byte* msg, int len)
|
||||
{
|
||||
byte buf[32];
|
||||
|
||||
buf[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
||||
buf[1] = report_type;
|
||||
|
||||
memcpy(buf+2, msg, len);
|
||||
|
||||
#ifdef WIIMOTE_DBG
|
||||
int x = 2;
|
||||
printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]);
|
||||
for (; x < len+2; ++x)
|
||||
printf("%.2x ", buf[x]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
pad_connection_send_control(wm->connection, buf, len + 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from the wiimote (event version).
|
||||
*
|
||||
* The library can only handle one data read request at a time
|
||||
* because it must keep track of the buffer and other
|
||||
* events that are specific to that request. So if a request
|
||||
* has already been made, subsequent requests will be added
|
||||
* to a pending list and be sent out when the previous
|
||||
* finishes.
|
||||
*/
|
||||
|
||||
static int wiimote_read_data(struct wiimote_t* wm, unsigned int addr,
|
||||
unsigned short len)
|
||||
{
|
||||
byte buf[6];
|
||||
|
||||
/* No puden ser mas de 16 lo leido o vendra en trozos! */
|
||||
|
||||
if (!wm || !WIIMOTE_IS_CONNECTED(wm) || !len)
|
||||
return 0;
|
||||
|
||||
/* the offset is in big endian */
|
||||
*(int*)(buf) = BIG_ENDIAN_LONG(addr);
|
||||
|
||||
/* the length is in big endian */
|
||||
*(short*)(buf + 4) = BIG_ENDIAN_SHORT(len);
|
||||
|
||||
#ifdef WIIMOTE_DBG
|
||||
printf("Request read at address: 0x%x length: %i", addr, len);
|
||||
#endif
|
||||
wiimote_send(wm, WM_CMD_READ_DATA, buf, 6);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to the wiimote.
|
||||
*/
|
||||
static int wiimote_write_data(struct wiimote_t* wm,
|
||||
unsigned int addr, byte* data, byte len)
|
||||
{
|
||||
byte buf[21] = {0}; /* the payload is always 23 */
|
||||
|
||||
if (!wm || !WIIMOTE_IS_CONNECTED(wm))
|
||||
return 0;
|
||||
if (!data || !len)
|
||||
return 0;
|
||||
|
||||
#ifdef WIIMOTE_DBG
|
||||
printf("Writing %i bytes to memory location 0x%x...\n", len, addr);
|
||||
|
||||
int i = 0;
|
||||
printf("Write data is: ");
|
||||
for (; i < len; ++i)
|
||||
printf("%x ", data[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* the offset is in big endian */
|
||||
*(int*)(buf) = BIG_ENDIAN_LONG(addr);
|
||||
|
||||
/* length */
|
||||
*(byte*)(buf + 4) = len;
|
||||
|
||||
/* data */
|
||||
memcpy(buf + 5, data, len);
|
||||
|
||||
wiimote_send(wm, WM_CMD_WRITE_DATA, buf, 21);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int classic_ctrl_handshake(struct wiimote_t* wm,
|
||||
struct classic_ctrl_t* cc, byte* data, unsigned short len)
|
||||
{
|
||||
memset(cc, 0, sizeof(*cc));
|
||||
wm->exp.type = EXP_CLASSIC;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static float normalize_and_interpolate(float min, float max, float t)
|
||||
{
|
||||
return (min == max) ? 0.0f : (t - min) / (max - min);
|
||||
}
|
||||
|
||||
static void process_axis(struct axis_t* axis, byte raw)
|
||||
{
|
||||
if (!axis->has_center)
|
||||
{
|
||||
axis->has_center = true;
|
||||
axis->min = raw - 2;
|
||||
axis->center = raw;
|
||||
axis->max = raw + 2;
|
||||
}
|
||||
|
||||
if (raw < axis->min)
|
||||
axis->min = raw;
|
||||
if (raw > axis->max)
|
||||
axis->max = raw;
|
||||
axis->raw_value = raw;
|
||||
|
||||
if (raw < axis->center)
|
||||
axis->value = -normalize_and_interpolate(
|
||||
axis->center, axis->min, raw);
|
||||
else if (raw > axis->center)
|
||||
axis->value = normalize_and_interpolate(
|
||||
axis->center, axis->max, raw);
|
||||
else
|
||||
axis->value = 0;
|
||||
}
|
||||
|
||||
static void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg)
|
||||
{
|
||||
cc->btns = ~BIG_ENDIAN_SHORT(*(short*)(msg + 4)) & CLASSIC_CTRL_BUTTON_ALL;
|
||||
process_axis(&cc->ljs.x, (msg[0] & 0x3F));
|
||||
process_axis(&cc->ljs.y, (msg[1] & 0x3F));
|
||||
process_axis(&cc->rjs.x, ((msg[0] & 0xC0) >> 3) |
|
||||
((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7));
|
||||
process_axis(&cc->rjs.y, (msg[2] & 0x1F));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -195,17 +195,6 @@ typedef struct wiimote_t
|
||||
#define WIIMOTE_TOGGLE_STATE(wm, s) ((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s))
|
||||
#define WIIMOTE_IS_CONNECTED(wm) (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED))
|
||||
|
||||
int wiimote_handshake(struct wiimote_t* wm,
|
||||
byte event, byte* data, unsigned short len);
|
||||
|
||||
void wiimote_status(struct wiimote_t* wm);
|
||||
|
||||
void wiimote_data_report(struct wiimote_t* wm, byte type);
|
||||
|
||||
void wiimote_pressed_buttons(struct wiimote_t* wm, byte* msg);
|
||||
|
||||
void wiimote_handle_expansion(struct wiimote_t* wm, byte* msg);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user