mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-07 10:50:35 +00:00
158 lines
4.4 KiB
C
158 lines
4.4 KiB
C
/* This source as presented is a modified version of original wiiuse for use
|
|
* with RetroArch, and must not be confused with the original software. */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#include "dynamics.h"
|
|
#include "definitions.h"
|
|
#include "wiiuse_internal.h"
|
|
#include "nunchuk.h"
|
|
#include "io.h"
|
|
|
|
/**
|
|
* @brief Find what buttons are pressed.
|
|
*
|
|
* @param nc Pointer to a nunchuk_t structure.
|
|
* @param msg The message byte specified in the event packet.
|
|
*/
|
|
static void nunchuk_pressed_buttons(struct nunchuk_t* nc, ubyte now) {
|
|
/* message is inverted (0 is active, 1 is inactive) */
|
|
now = ~now & NUNCHUK_BUTTON_ALL;
|
|
|
|
/* preserve old btns pressed */
|
|
nc->btns_last = nc->btns;
|
|
|
|
/* pressed now & were pressed, then held */
|
|
nc->btns_held = (now & nc->btns);
|
|
|
|
/* were pressed or were held & not pressed now, then released */
|
|
nc->btns_released = ((nc->btns | nc->btns_held) & ~now);
|
|
|
|
/* buttons pressed now */
|
|
nc->btns = now;
|
|
}
|
|
|
|
int nunchuk_handshake(struct wiimote_t *wm,struct nunchuk_t *nc,ubyte *data,uword len)
|
|
{
|
|
//int i;
|
|
int offset = 0;
|
|
|
|
nc->btns = 0;
|
|
nc->btns_held = 0;
|
|
nc->btns_released = 0;
|
|
nc->flags = &wm->flags;
|
|
nc->accel_calib = wm->accel_calib;
|
|
|
|
//for(i=0;i<len;i++) data[i] = (data[i]^0x17)+0x17;
|
|
if(data[offset]==0xff) {
|
|
if(data[offset+16]==0xff) {
|
|
// try to read the calibration data again
|
|
wiiuse_read_data(wm,data,WM_EXP_MEM_CALIBR,EXP_HANDSHAKE_LEN,wiiuse_handshake_expansion);
|
|
} else
|
|
offset += 16;
|
|
}
|
|
|
|
nc->accel_calib.cal_zero.x = (data[offset + 0]<<2)|((data[offset + 3]>>4)&3);
|
|
nc->accel_calib.cal_zero.y = (data[offset + 1]<<2)|((data[offset + 3]>>2)&3);
|
|
nc->accel_calib.cal_zero.z = (data[offset + 2]<<2)|(data[offset + 3]&3);
|
|
nc->accel_calib.cal_g.x = (data[offset + 4]<<2)|((data[offset + 7]>>4)&3);
|
|
nc->accel_calib.cal_g.y = (data[offset + 5]<<2)|((data[offset + 7]>>2)&3);
|
|
nc->accel_calib.cal_g.z = (data[offset + 6]<<2)|(data[offset + 7]&3);
|
|
nc->js.max.x = data[offset + 8];
|
|
nc->js.min.x = data[offset + 9];
|
|
nc->js.center.x = data[offset + 10];
|
|
nc->js.max.y = data[offset + 11];
|
|
nc->js.min.y = data[offset + 12];
|
|
nc->js.center.y = data[offset + 13];
|
|
|
|
// set to defaults (averages from 5 nunchuks) if calibration data is invalid
|
|
if(nc->accel_calib.cal_zero.x == 0)
|
|
nc->accel_calib.cal_zero.x = 499;
|
|
if(nc->accel_calib.cal_zero.y == 0)
|
|
nc->accel_calib.cal_zero.y = 509;
|
|
if(nc->accel_calib.cal_zero.z == 0)
|
|
nc->accel_calib.cal_zero.z = 507;
|
|
if(nc->accel_calib.cal_g.x == 0)
|
|
nc->accel_calib.cal_g.x = 703;
|
|
if(nc->accel_calib.cal_g.y == 0)
|
|
nc->accel_calib.cal_g.y = 709;
|
|
if(nc->accel_calib.cal_g.z == 0)
|
|
nc->accel_calib.cal_g.z = 709;
|
|
if(nc->js.max.x == 0)
|
|
nc->js.max.x = 223;
|
|
if(nc->js.min.x == 0)
|
|
nc->js.min.x = 27;
|
|
if(nc->js.center.x == 0)
|
|
nc->js.center.x = 126;
|
|
if(nc->js.max.y == 0)
|
|
nc->js.max.y = 222;
|
|
if(nc->js.min.y == 0)
|
|
nc->js.min.y = 30;
|
|
if(nc->js.center.y == 0)
|
|
nc->js.center.y = 131;
|
|
|
|
wm->event = WIIUSE_NUNCHUK_INSERTED;
|
|
wm->exp.type = EXP_NUNCHUK;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @brief The nunchuk disconnected.
|
|
*
|
|
* @param nc A pointer to a nunchuk_t structure.
|
|
*/
|
|
void nunchuk_disconnected(struct nunchuk_t* nc)
|
|
{
|
|
//printf("nunchuk_disconnected()\n");
|
|
memset(nc, 0, sizeof(struct nunchuk_t));
|
|
}
|
|
|
|
/**
|
|
* @brief Handle nunchuk event.
|
|
*
|
|
* @param nc A pointer to a nunchuk_t structure.
|
|
* @param msg The message specified in the event packet.
|
|
*/
|
|
void nunchuk_event(struct nunchuk_t* nc, ubyte* msg) {
|
|
//int i;
|
|
|
|
/* decrypt data */
|
|
/*
|
|
for (i = 0; i < 6; ++i)
|
|
msg[i] = (msg[i] ^ 0x17) + 0x17;
|
|
*/
|
|
/* get button states */
|
|
nunchuk_pressed_buttons(nc, msg[5]);
|
|
|
|
nc->js.pos.x = msg[0];
|
|
nc->js.pos.y = msg[1];
|
|
|
|
/* extend min and max values to physical range of motion */
|
|
if (nc->js.center.x) {
|
|
if (nc->js.min.x > nc->js.pos.x) nc->js.min.x = nc->js.pos.x;
|
|
if (nc->js.max.x < nc->js.pos.x) nc->js.max.x = nc->js.pos.x;
|
|
}
|
|
if (nc->js.center.y) {
|
|
if (nc->js.min.y > nc->js.pos.y) nc->js.min.y = nc->js.pos.y;
|
|
if (nc->js.max.y < nc->js.pos.y) nc->js.max.y = nc->js.pos.y;
|
|
}
|
|
|
|
#ifndef GEKKO
|
|
/* calculate joystick state */
|
|
calc_joystick_state(&nc->js, nc->js.pos.x, nc->js.pos.y);
|
|
#endif
|
|
/* calculate orientation */
|
|
nc->accel.x = (msg[2]<<2) + ((msg[5]>>2)&3);
|
|
nc->accel.y = (msg[3]<<2) + ((msg[5]>>4)&3);
|
|
nc->accel.z = (msg[4]<<2) + ((msg[5]>>6)&3);
|
|
#ifndef GEKKO
|
|
calculate_orientation(&nc->accel_calib, &nc->accel, &nc->orient, NUNCHUK_IS_FLAG_SET(nc, WIIUSE_SMOOTHING));
|
|
calculate_gforce(&nc->accel_calib, &nc->accel, &nc->gforce);
|
|
#endif
|
|
}
|
|
|