mirror of
https://github.com/libretro/RetroArch
synced 2024-12-29 12:31:05 +00:00
165 lines
4.6 KiB
C
165 lines
4.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "definitions.h"
|
|
#include "wiiuse_internal.h"
|
|
#include "nunchuk.h"
|
|
#include "classic.h"
|
|
#include "motion_plus.h"
|
|
#include "io.h"
|
|
|
|
void wiiuse_handshake(struct wiimote_t *wm,ubyte *data,uword len)
|
|
{
|
|
ubyte *buf = NULL;
|
|
struct accel_t *accel = &wm->accel_calib;
|
|
|
|
//printf("wiiuse_handshake(%d,%p,%d)\n",wm->handshake_state,data,len);
|
|
|
|
switch(wm->handshake_state) {
|
|
case 0:
|
|
wm->handshake_state++;
|
|
|
|
wiiuse_set_leds(wm,WIIMOTE_LED_NONE,NULL);
|
|
wiiuse_status(wm,wiiuse_handshake);
|
|
return;
|
|
|
|
case 1:
|
|
wm->handshake_state++;
|
|
buf = __lwp_wkspace_allocate(sizeof(ubyte)*8);
|
|
|
|
if (len > 2 && data[2]&WM_CTRL_STATUS_BYTE1_ATTACHMENT) {
|
|
wiiuse_read_data(wm,buf,WM_EXP_ID,6,wiiuse_handshake);
|
|
return;
|
|
|
|
case 2:
|
|
if (BIG_ENDIAN_LONG(*(int*)(&data[2])) == EXP_ID_CODE_CLASSIC_WIIU_PRO) {
|
|
memset(data, 0, 8);
|
|
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_WIIU_PRO);
|
|
break;
|
|
}
|
|
buf = data;
|
|
}
|
|
|
|
wm->handshake_state++;
|
|
wiiuse_read_data(wm,buf,WM_MEM_OFFSET_CALIBRATION,7,wiiuse_handshake);
|
|
return;
|
|
}
|
|
|
|
accel->cal_zero.x = ((data[0]<<2)|((data[3]>>4)&3));
|
|
accel->cal_zero.y = ((data[1]<<2)|((data[3]>>2)&3));
|
|
accel->cal_zero.z = ((data[2]<<2)|(data[3]&3));
|
|
|
|
accel->cal_g.x = (((data[4]<<2)|((data[7]>>4)&3)) - accel->cal_zero.x);
|
|
accel->cal_g.y = (((data[5]<<2)|((data[7]>>2)&3)) - accel->cal_zero.y);
|
|
accel->cal_g.z = (((data[6]<<2)|(data[7]&3)) - accel->cal_zero.z);
|
|
__lwp_wkspace_free(data);
|
|
|
|
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
|
|
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
|
|
|
|
wm->event = WIIUSE_CONNECT;
|
|
wiiuse_status(wm,NULL);
|
|
}
|
|
|
|
void wiiuse_handshake_expansion_start(struct wiimote_t *wm)
|
|
{
|
|
if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP) || WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_FAILED) || WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE))
|
|
return;
|
|
|
|
wm->expansion_state = 0;
|
|
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
|
|
wiiuse_handshake_expansion(wm, NULL, 0);
|
|
}
|
|
|
|
void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len)
|
|
{
|
|
int id;
|
|
ubyte val;
|
|
ubyte *buf = NULL;
|
|
|
|
switch(wm->expansion_state) {
|
|
/* These two initialization writes disable the encryption */
|
|
case 0:
|
|
wm->expansion_state = 1;
|
|
val = 0x55;
|
|
wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_handshake_expansion);
|
|
break;
|
|
case 1:
|
|
wm->expansion_state = 2;
|
|
val = 0x00;
|
|
wiiuse_write_data(wm,WM_EXP_MEM_ENABLE2,&val,1,wiiuse_handshake_expansion);
|
|
break;
|
|
case 2:
|
|
wm->expansion_state = 3;
|
|
buf = __lwp_wkspace_allocate(sizeof(ubyte)*EXP_HANDSHAKE_LEN);
|
|
wiiuse_read_data(wm,buf,WM_EXP_MEM_CALIBR,EXP_HANDSHAKE_LEN,wiiuse_handshake_expansion);
|
|
break;
|
|
case 3:
|
|
if(!data || !len) return;
|
|
id = BIG_ENDIAN_LONG(*(int*)(&data[220]));
|
|
|
|
switch(id) {
|
|
case EXP_ID_CODE_NUNCHUK:
|
|
if(!nunchuk_handshake(wm,&wm->exp.nunchuk,data,len)) return;
|
|
break;
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING2:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING3:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC2:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC3:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC4:
|
|
case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC5:
|
|
case EXP_ID_CODE_CLASSIC_WIIU_PRO:
|
|
if(!classic_ctrl_handshake(wm,&wm->exp.classic,data,len)) return;
|
|
break;
|
|
default:
|
|
if(!classic_ctrl_handshake(wm,&wm->exp.classic,data,len)) return;
|
|
/*WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_HANDSHAKE);
|
|
WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP_FAILED);
|
|
__lwp_wkspace_free(data);
|
|
wiiuse_status(wm,NULL);
|
|
return;*/
|
|
}
|
|
__lwp_wkspace_free(data);
|
|
|
|
WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_HANDSHAKE);
|
|
WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP);
|
|
wiiuse_set_ir_mode(wm);
|
|
wiiuse_status(wm,NULL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void wiiuse_disable_expansion(struct wiimote_t *wm)
|
|
{
|
|
if(!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) return;
|
|
|
|
/* tell the associated module the expansion was removed */
|
|
switch(wm->exp.type) {
|
|
case EXP_NUNCHUK:
|
|
nunchuk_disconnected(&wm->exp.nunchuk);
|
|
wm->event = WIIUSE_NUNCHUK_REMOVED;
|
|
break;
|
|
case EXP_CLASSIC:
|
|
classic_ctrl_disconnected(&wm->exp.classic);
|
|
wm->event = WIIUSE_CLASSIC_CTRL_REMOVED;
|
|
break;
|
|
case EXP_MOTION_PLUS:
|
|
motion_plus_disconnected(&wm->exp.mp);
|
|
wm->event = WIIUSE_MOTION_PLUS_REMOVED;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
|
|
wm->exp.type = EXP_NONE;
|
|
|
|
wiiuse_set_ir_mode(wm);
|
|
wiiuse_status(wm,NULL);
|
|
}
|