diff --git a/apple/common/hidpad/apple_wii_pad.c b/apple/common/hidpad/apple_wii_pad.c index 03326725cc..b87deae7f8 100644 --- a/apple/common/hidpad/apple_wii_pad.c +++ b/apple/common/hidpad/apple_wii_pad.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2013-2014 - Jason Fetters - * + * * 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. @@ -32,7 +32,7 @@ static void* hidpad_wii_connect(struct apple_pad_connection* connection, uint32_ device->exp.type = EXP_NONE; wiimote_handshake(device, -1, NULL, -1); - + return device; } @@ -43,20 +43,18 @@ static void hidpad_wii_disconnect(struct wiimote_t* device) static int16_t hidpad_wii_get_axis(struct wiimote_t* device, unsigned axis) { -/* TODO - if (device->.exp.type == EXP_CLASSIC) + if (device->exp.type == EXP_CLASSIC) { switch (axis) { - case 0: return device->wiimote.exp.classic.ljs.rx * 0x7FFF; - case 1: return device->wiimote.exp.classic.ljs.ry * 0x7FFF; - case 2: return device->wiimote.exp.classic.rjs.rx * 0x7FFF; - case 3: return device->wiimote.exp.classic.rjs.ry * 0x7FFF; + case 0: return device->exp.classic.ljs.x.value * 0x7FFF; + case 1: return device->exp.classic.ljs.y.value * 0x7FFF; + case 2: return device->exp.classic.rjs.x.value * 0x7FFF; + case 3: return device->exp.classic.rjs.y.value * 0x7FFF; default: return 0; } } -*/ - + return 0; } diff --git a/apple/common/hidpad/wiimote.c b/apple/common/hidpad/wiimote.c index b55f16079f..7fb6af8c73 100644 --- a/apple/common/hidpad/wiimote.c +++ b/apple/common/hidpad/wiimote.c @@ -442,171 +442,45 @@ int wiimote_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte /////////////////////// CLASSIC ///////////////// -static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now); -void calc_joystick_state(struct joystick_t* js, float x, float y); - -/** - * @brief Handle the handshake data from the classic controller. - * - * @param cc A pointer to a classic_ctrl_t structure. - * @param data The data read in from the device. - * @param len The length of the data block, in bytes. - * - * @return Returns 1 if handshake was successful, 0 if not. - */ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) { - int offset = 0; - - cc->btns = 0; - cc->r_shoulder = 0; - cc->l_shoulder = 0; - - /* decrypt data */ - /* - for (i = 0; i < len; ++i) - data[i] = (data[i] ^ 0x17) + 0x17; - */ - -#ifdef WIIMOTE_DBG - int x = 0; - printf("[DECRIPTED]"); - for (; x < len; x++) - printf("%.2x ", data[x]); - printf("\n"); -#endif - -/* - if (data[offset] == 0xFF) - { - return 0;//ERROR! - } -*/ - /* joystick stuff */ - if (data[offset] != 0xFF && data[offset] != 0x00) - { - cc->ljs.max.x = data[0 + offset] / 4; - cc->ljs.min.x = data[1 + offset] / 4; - cc->ljs.center.x = data[2 + offset] / 4; - cc->ljs.max.y = data[3 + offset] / 4; - cc->ljs.min.y = data[4 + offset] / 4; - cc->ljs.center.y = data[5 + offset] / 4; - - cc->rjs.max.x = data[6 + offset] / 8; - cc->rjs.min.x = data[7 + offset] / 8; - cc->rjs.center.x = data[8 + offset] / 8; - cc->rjs.max.y = data[9 + offset] / 8; - cc->rjs.min.y = data[10 + offset] / 8; - cc->rjs.center.y = data[11 + offset] / 8; - } - else - { - cc->ljs.max.x = 55; - cc->ljs.min.x = 5; - cc->ljs.center.x = 30; - cc->ljs.max.y = 55; - cc->ljs.min.y = 5; - cc->ljs.center.y = 30; - - cc->rjs.max.x = 30; - cc->rjs.min.x = 0; - cc->rjs.center.x = 15; - cc->rjs.max.y = 30; - cc->rjs.min.y = 0; - cc->rjs.center.y = 15; - } - - /* handshake done */ + memset(cc, 0, sizeof(*cc)); wm->exp.type = EXP_CLASSIC; - return 1; } -/** - * @brief Handle classic controller event. - * - * @param cc A pointer to a classic_ctrl_t structure. - * @param msg The message specified in the event packet. - */ -void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) { - int lx, ly, rx, ry; - byte l, r; - - /* decrypt data */ - /* - for (i = 0; i < 6; ++i) - msg[i] = (msg[i] ^ 0x17) + 0x17; - */ - - classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4))); - - /* left/right buttons */ - l = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5)); - r = (msg[3] & 0x1F); - - /* - * TODO - LR range hardcoded from 0x00 to 0x1F. - * This is probably in the calibration somewhere. - */ - cc->r_shoulder = ((float)r / 0x1F); - cc->l_shoulder = ((float)l / 0x1F); - - /* calculate joystick orientation */ - lx = (msg[0] & 0x3F); - ly = (msg[1] & 0x3F); - rx = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7); - ry = (msg[2] & 0x1F); - -#ifdef WIIMOTE_DBG - printf("lx ly rx ry %d %d %d %d\n",lx,ly,rx,ry); -#endif - -// calc_joystick_state(&cc->ljs, lx, ly); -// calc_joystick_state(&cc->rjs, rx, ry); - - /* - printf("classic L button pressed: %f\n", cc->l_shoulder); - printf("classic R button pressed: %f\n", cc->r_shoulder); - printf("classic left joystick angle: %f\n", cc->ljs.ang); - printf("classic left joystick magnitude: %f\n", cc->ljs.mag); - printf("classic right joystick angle: %f\n", cc->rjs.ang); - printf("classic right joystick magnitude: %f\n", cc->rjs.mag); - */ +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; + } -/** - * @brief Find what buttons are pressed. - * - * @param cc A pointer to a classic_ctrl_t structure. - * @param msg The message byte specified in the event packet. - */ -static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) { - /* message is inverted (0 is active, 1 is inactive) */ - now = ~now & CLASSIC_CTRL_BUTTON_ALL; + if (raw < axis->min) axis->min = raw; + if (raw > axis->max) axis->max = raw; + axis->raw_value = raw; - /* buttons pressed now */ - cc->btns = now; + 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; } -/** - * @brief Calculate the angle and magnitude of a joystick. - * - * @param js [out] Pointer to a joystick_t structure. - * @param x The raw x-axis value. - * @param y The raw y-axis value. - */ -void calc_joystick_state(struct joystick_t* js, float x, float y) { - js->rx = 0; - js->ry = 0; - - if (x > js->center.x) - js->rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x)); - else if (x < js->center.x) - js->rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f; - - if (y > js->center.y) - js->ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y)); - else if (js->ry < js->center.y) - js->ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f; +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)); } diff --git a/apple/common/hidpad/wiimote.h b/apple/common/hidpad/wiimote.h index 6e6ac1be56..96c44eb4f0 100644 --- a/apple/common/hidpad/wiimote.h +++ b/apple/common/hidpad/wiimote.h @@ -7,11 +7,11 @@ * * wiiuse * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > * - * Copyright 2006-2007 + * Copyright 2006-2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,218 +45,148 @@ extern "C" { #endif - typedef unsigned char byte; - typedef char sbyte; + typedef unsigned char byte; + typedef char sbyte; - //#define WIIMOTE_DBG 0 + /* Convert to big endian */ + #define BIG_ENDIAN_LONG(i) (htonl(i)) + #define BIG_ENDIAN_SHORT(i) (htons(i)) - /* Convert to big endian */ - #define BIG_ENDIAN_LONG(i) (htonl(i)) - #define BIG_ENDIAN_SHORT(i) (htons(i)) + #define absf(x) ((x >= 0) ? (x) : (x * -1.0f)) + #define diff_f(x, y) ((x >= y) ? (absf(x - y)) : (absf(y - x))) - #define absf(x) ((x >= 0) ? (x) : (x * -1.0f)) - #define diff_f(x, y) ((x >= y) ? (absf(x - y)) : (absf(y - x))) + /* wiimote state flags*/ + #define WIIMOTE_STATE_DEV_FOUND 0x0001 + #define WIIMOTE_STATE_HANDSHAKE 0x0002 /* actual connection exists but no handshake yet */ + #define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x0004 + #define WIIMOTE_STATE_CONNECTED 0x0008 + #define WIIMOTE_STATE_EXP 0x0040 - /* wiimote state flags*/ - #define WIIMOTE_STATE_DEV_FOUND 0x0001 - #define WIIMOTE_STATE_HANDSHAKE 0x0002 /* actual connection exists but no handshake yet */ - #define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x0004 - #define WIIMOTE_STATE_CONNECTED 0x0008 - #define WIIMOTE_STATE_EXP 0x0040 + /* Communication channels */ - /* Communication channels */ - #define WM_OUTPUT_CHANNEL 0x11 - #define WM_INPUT_CHANNEL 0x13 + #define WM_SET_REPORT 0x50 - #define WM_SET_REPORT 0x50 + /* commands */ + #define WM_CMD_LED 0x11 + #define WM_CMD_REPORT_TYPE 0x12 + #define WM_CMD_RUMBLE 0x13 + #define WM_CMD_IR 0x13 + #define WM_CMD_CTRL_STATUS 0x15 + #define WM_CMD_WRITE_DATA 0x16 + #define WM_CMD_READ_DATA 0x17 + #define WM_CMD_IR_2 0x1A - /* commands */ - #define WM_CMD_LED 0x11 - #define WM_CMD_REPORT_TYPE 0x12 - #define WM_CMD_RUMBLE 0x13 - #define WM_CMD_IR 0x13 - #define WM_CMD_CTRL_STATUS 0x15 - #define WM_CMD_WRITE_DATA 0x16 - #define WM_CMD_READ_DATA 0x17 - #define WM_CMD_IR_2 0x1A + /* input report ids */ + #define WM_RPT_CTRL_STATUS 0x20 + #define WM_RPT_READ 0x21 + #define WM_RPT_WRITE 0x22 + #define WM_RPT_BTN 0x30 + #define WM_RPT_BTN_ACC 0x31 + #define WM_RPT_BTN_ACC_IR 0x33 + #define WM_RPT_BTN_EXP 0x34 + #define WM_RPT_BTN_ACC_EXP 0x35 + #define WM_RPT_BTN_IR_EXP 0x36 + #define WM_RPT_BTN_ACC_IR_EXP 0x37 - /* input report ids */ - #define WM_RPT_CTRL_STATUS 0x20 - #define WM_RPT_READ 0x21 - #define WM_RPT_WRITE 0x22 - #define WM_RPT_BTN 0x30 - #define WM_RPT_BTN_ACC 0x31 - #define WM_RPT_BTN_ACC_IR 0x33 - #define WM_RPT_BTN_EXP 0x34 - #define WM_RPT_BTN_ACC_EXP 0x35 - #define WM_RPT_BTN_IR_EXP 0x36 - #define WM_RPT_BTN_ACC_IR_EXP 0x37 + #define WM_BT_INPUT 0x01 + #define WM_BT_OUTPUT 0x02 - #define WM_BT_INPUT 0x01 - #define WM_BT_OUTPUT 0x02 + /* controller status stuff */ + #define WM_MAX_BATTERY_CODE 0xC8 - /* controller status stuff */ - #define WM_MAX_BATTERY_CODE 0xC8 + #define EXP_ID_CODE_CLASSIC_CONTROLLER 0x9A1EFDFD - #define EXP_ID_CODE_CLASSIC_CONTROLLER 0x9A1EFDFD + /* offsets in wiimote memory */ + #define WM_MEM_OFFSET_CALIBRATION 0x16 + #define WM_EXP_MEM_BASE 0x04A40000 + #define WM_EXP_MEM_ENABLE 0x04A40040 + #define WM_EXP_MEM_CALIBR 0x04A40020 - /* offsets in wiimote memory */ - #define WM_MEM_OFFSET_CALIBRATION 0x16 - #define WM_EXP_MEM_BASE 0x04A40000 - #define WM_EXP_MEM_ENABLE 0x04A40040 - #define WM_EXP_MEM_CALIBR 0x04A40020 + #define EXP_HANDSHAKE_LEN 224 - #define EXP_HANDSHAKE_LEN 224 + /* controller status flags for the first message byte */ + /* bit 1 is unknown */ + #define WM_CTRL_STATUS_BYTE1_ATTACHMENT 0x02 + #define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED 0x04 + #define WM_CTRL_STATUS_BYTE1_IR_ENABLED 0x08 + #define WM_CTRL_STATUS_BYTE1_LED_1 0x10 + #define WM_CTRL_STATUS_BYTE1_LED_2 0x20 + #define WM_CTRL_STATUS_BYTE1_LED_3 0x40 + #define WM_CTRL_STATUS_BYTE1_LED_4 0x80 - /* controller status flags for the first message byte */ - /* bit 1 is unknown */ - #define WM_CTRL_STATUS_BYTE1_ATTACHMENT 0x02 - #define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED 0x04 - #define WM_CTRL_STATUS_BYTE1_IR_ENABLED 0x08 - #define WM_CTRL_STATUS_BYTE1_LED_1 0x10 - #define WM_CTRL_STATUS_BYTE1_LED_2 0x20 - #define WM_CTRL_STATUS_BYTE1_LED_3 0x40 - #define WM_CTRL_STATUS_BYTE1_LED_4 0x80 + /* led bit masks */ + #define WIIMOTE_LED_NONE 0x00 + #define WIIMOTE_LED_1 0x10 + #define WIIMOTE_LED_2 0x20 + #define WIIMOTE_LED_3 0x40 + #define WIIMOTE_LED_4 0x80 - /* led bit masks */ - #define WIIMOTE_LED_NONE 0x00 - #define WIIMOTE_LED_1 0x10 - #define WIIMOTE_LED_2 0x20 - #define WIIMOTE_LED_3 0x40 - #define WIIMOTE_LED_4 0x80 + /* button masks */ + #define WIIMOTE_BUTTON_ALL 0x1F9F + #define CLASSIC_CTRL_BUTTON_ALL 0xFEFF - /* button codes */ - #define WIIMOTE_BUTTON_TWO 0x0001 - #define WIIMOTE_BUTTON_ONE 0x0002 - #define WIIMOTE_BUTTON_B 0x0004 - #define WIIMOTE_BUTTON_A 0x0008 - #define WIIMOTE_BUTTON_MINUS 0x0010 - #define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020 - #define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040 - #define WIIMOTE_BUTTON_HOME 0x0080 - #define WIIMOTE_BUTTON_LEFT 0x0100 - #define WIIMOTE_BUTTON_RIGHT 0x0200 - #define WIIMOTE_BUTTON_DOWN 0x0400 - #define WIIMOTE_BUTTON_UP 0x0800 - #define WIIMOTE_BUTTON_PLUS 0x1000 - #define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000 - #define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000 - #define WIIMOTE_BUTTON_UNKNOWN 0x8000 - #define WIIMOTE_BUTTON_ALL 0x1F9F + /* expansion codes */ + #define EXP_NONE 0 + #define EXP_CLASSIC 2 - /* classic controller button codes */ - #define CLASSIC_CTRL_BUTTON_UP 0x0001 - #define CLASSIC_CTRL_BUTTON_LEFT 0x0002 - #define CLASSIC_CTRL_BUTTON_ZR 0x0004 - #define CLASSIC_CTRL_BUTTON_X 0x0008 - #define CLASSIC_CTRL_BUTTON_A 0x0010 - #define CLASSIC_CTRL_BUTTON_Y 0x0020 - #define CLASSIC_CTRL_BUTTON_B 0x0040 - #define CLASSIC_CTRL_BUTTON_ZL 0x0080 - #define CLASSIC_CTRL_BUTTON_FULL_R 0x0200 - #define CLASSIC_CTRL_BUTTON_PLUS 0x0400 - #define CLASSIC_CTRL_BUTTON_HOME 0x0800 - #define CLASSIC_CTRL_BUTTON_MINUS 0x1000 - #define CLASSIC_CTRL_BUTTON_FULL_L 0x2000 - #define CLASSIC_CTRL_BUTTON_DOWN 0x4000 - #define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 - #define CLASSIC_CTRL_BUTTON_ALL 0xFEFF + typedef struct axis_t { + bool has_center; - /* expansion codes */ - #define EXP_NONE 0 - #define EXP_CLASSIC 2 + byte min; + byte center; + byte max; + byte raw_value; + float value; + } axis_t; - /** - * @struct vec2b_t - * @brief Unsigned x,y byte vector. - */ - typedef struct vec2b_t { - byte x, y; - } vec2b_t; + typedef struct joystick_t { + axis_t x; + axis_t y; + } joystick_t; - /** - * @struct joystick_t - * @brief Joystick calibration structure. - * - * The angle \a ang is relative to the positive y-axis into quadrant I - * and ranges from 0 to 360 degrees. So if the joystick is held straight - * upwards then angle is 0 degrees. If it is held to the right it is 90, - * down is 180, and left is 270. - * - * The magnitude \a mag is the distance from the center to where the - * joystick is being held. The magnitude ranges from 0 to 1. - * If the joystick is only slightly tilted from the center the magnitude - * will be low, but if it is closer to the outter edge the value will - * be higher. - */ - typedef struct joystick_t { - struct vec2b_t max; /**< maximum joystick values */ - struct vec2b_t min; /**< minimum joystick values */ - struct vec2b_t center; /**< center joystick values */ + typedef struct classic_ctrl_t { + short btns; + struct joystick_t ljs; + struct joystick_t rjs; + } classic_ctrl_t; - float rx, ry; - } joystick_t; + /** + * @struct expansion_t + * @brief Generic expansion device plugged into wiimote. + */ + typedef struct expansion_t { + int type; /**< type of expansion attached */ - /** - * @struct classic_ctrl_t - * @brief Classic controller expansion device. - */ - typedef struct classic_ctrl_t { - short btns; /**< what buttons have just been pressed */ + union { + struct classic_ctrl_t classic; + }; + } expansion_t; - float r_shoulder; /**< right shoulder button (range 0-1) */ - float l_shoulder; /**< left shoulder button (range 0-1) */ - - struct joystick_t ljs; /**< left joystick calibration */ - struct joystick_t rjs; /**< right joystick calibration */ - } classic_ctrl_t; - - /** - * @struct expansion_t - * @brief Generic expansion device plugged into wiimote. - */ - typedef struct expansion_t { - int type; /**< type of expansion attached */ - - union { - struct classic_ctrl_t classic; - }; - } expansion_t; - - /** - * @struct wiimote_t - * @brief Wiimote structure. - */ - typedef struct wiimote_t { - int unid; /**< user specified id */ + /** + * @struct wiimote_t + * @brief Wiimote structure. + */ + typedef struct wiimote_t { + int unid; /**< user specified id */ struct apple_pad_connection* connection; - int state; /**< various state flags */ - byte leds; /**< currently lit leds */ - float battery_level; /**< battery level */ + int state; /**< various state flags */ + byte leds; /**< currently lit leds */ + float battery_level; /**< battery level */ - byte handshake_state; /**< the state of the connection handshake */ + byte handshake_state; /**< the state of the connection handshake */ - struct expansion_t exp; /**< wiimote expansion device */ + struct expansion_t exp; /**< wiimote expansion device */ - unsigned short btns; /**< what buttons have just been pressed */ - } wiimote; + unsigned short btns; /**< what buttons have just been pressed */ + } wiimote; - /** - * @brief Check if a button is pressed. - * @param dev Pointer to a wiimote_t or expansion structure. - * @param button The button you are interested in. - * @return 1 if the button is pressed, 0 if not. - */ - #define IS_PRESSED(dev, button) ((dev->btns & button) == button) - - /* macro to manage states */ - #define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) - #define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s)) - #define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s)) - #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)) + /* macro to manage states */ + #define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) + #define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s)) + #define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s)) + #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);