Fixed smbClose() for older dkppc versions
[libogc.git] / wiiuse / nunchuk.c
blobc79b994df73f483bb3e8888b89457adb568590e0
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
6 #include "dynamics.h"
7 #include "definitions.h"
8 #include "wiiuse_internal.h"
9 #include "nunchuk.h"
10 #include "io.h"
12 /**
13 * @brief Find what buttons are pressed.
15 * @param nc Pointer to a nunchuk_t structure.
16 * @param msg The message byte specified in the event packet.
18 static void nunchuk_pressed_buttons(struct nunchuk_t* nc, ubyte now) {
19 /* message is inverted (0 is active, 1 is inactive) */
20 now = ~now & NUNCHUK_BUTTON_ALL;
22 /* preserve old btns pressed */
23 nc->btns_last = nc->btns;
25 /* pressed now & were pressed, then held */
26 nc->btns_held = (now & nc->btns);
28 /* were pressed or were held & not pressed now, then released */
29 nc->btns_released = ((nc->btns | nc->btns_held) & ~now);
31 /* buttons pressed now */
32 nc->btns = now;
35 int nunchuk_handshake(struct wiimote_t *wm,struct nunchuk_t *nc,ubyte *data,uword len)
37 //int i;
38 int offset = 0;
40 nc->btns = 0;
41 nc->btns_held = 0;
42 nc->btns_released = 0;
43 nc->flags = &wm->flags;
44 nc->accel_calib = wm->accel_calib;
46 //for(i=0;i<len;i++) data[i] = (data[i]^0x17)+0x17;
47 if(data[offset]==0xff) {
48 if(data[offset+16]==0xff) {
49 wiiuse_read_data(wm,data,WM_EXP_MEM_CALIBR,EXP_HANDSHAKE_LEN,wiiuse_handshake_expansion);
50 return 0;
52 offset += 16;
55 nc->accel_calib.cal_zero.x = (data[offset + 0]<<2)|((data[offset + 3]>>4)&3);
56 nc->accel_calib.cal_zero.y = (data[offset + 1]<<2)|((data[offset + 3]>>2)&3);
57 nc->accel_calib.cal_zero.z = (data[offset + 2]<<2)|(data[offset + 3]&3);
58 nc->accel_calib.cal_g.x = (data[offset + 4]<<2)|((data[offset + 7]>>4)&3);
59 nc->accel_calib.cal_g.y = (data[offset + 5]<<2)|((data[offset + 7]>>2)&3);
60 nc->accel_calib.cal_g.z = (data[offset + 6]<<2)|(data[offset + 7]&3);
61 nc->js.max.x = data[offset + 8];
62 nc->js.min.x = data[offset + 9];
63 nc->js.center.x = data[offset + 10];
64 nc->js.max.y = data[offset + 11];
65 nc->js.min.y = data[offset + 12];
66 nc->js.center.y = data[offset + 13];
68 wm->event = WIIUSE_NUNCHUK_INSERTED;
69 wm->exp.type = EXP_NUNCHUK;
71 /* if min and max are reported as 0, initialize them to usable values based on center, and fine tune in nunchuck_event() */
72 if (nc->js.center.x) {
73 if (nc->js.min.x == 0) nc->js.min.x = nc->js.center.x - 80;
74 if (nc->js.max.x == 0) nc->js.max.x = nc->js.center.x + 80;
76 if (nc->js.center.y) {
77 if (nc->js.min.y == 0) nc->js.min.y = nc->js.center.y - 80;
78 if (nc->js.max.y == 0) nc->js.max.y = nc->js.center.y + 80;
81 return 1;
84 /**
85 * @brief The nunchuk disconnected.
87 * @param nc A pointer to a nunchuk_t structure.
89 void nunchuk_disconnected(struct nunchuk_t* nc)
91 //printf("nunchuk_disconnected()\n");
92 memset(nc, 0, sizeof(struct nunchuk_t));
95 /**
96 * @brief Handle nunchuk event.
98 * @param nc A pointer to a nunchuk_t structure.
99 * @param msg The message specified in the event packet.
101 void nunchuk_event(struct nunchuk_t* nc, ubyte* msg) {
102 //int i;
104 /* decrypt data */
106 for (i = 0; i < 6; ++i)
107 msg[i] = (msg[i] ^ 0x17) + 0x17;
109 /* get button states */
110 nunchuk_pressed_buttons(nc, msg[5]);
112 nc->js.pos.x = msg[0];
113 nc->js.pos.y = msg[1];
115 /* extend min and max values to physical range of motion */
116 if (nc->js.center.x) {
117 if (nc->js.min.x > nc->js.pos.x) nc->js.min.x = nc->js.pos.x;
118 if (nc->js.max.x < nc->js.pos.x) nc->js.max.x = nc->js.pos.x;
120 if (nc->js.center.y) {
121 if (nc->js.min.y > nc->js.pos.y) nc->js.min.y = nc->js.pos.y;
122 if (nc->js.max.y < nc->js.pos.y) nc->js.max.y = nc->js.pos.y;
125 #ifndef GEKKO
126 /* calculate joystick state */
127 calc_joystick_state(&nc->js, nc->js.pos.x, nc->js.pos.y);
128 #endif
129 /* calculate orientation */
130 nc->accel.x = (msg[2]<<2) + ((msg[5]>>2)&3);
131 nc->accel.y = (msg[3]<<2) + ((msg[5]>>4)&3);
132 nc->accel.z = (msg[4]<<2) + ((msg[5]>>6)&3);
133 #ifndef GEKKO
134 calculate_orientation(&nc->accel_calib, &nc->accel, &nc->orient, NUNCHUK_IS_FLAG_SET(nc, WIIUSE_SMOOTHING));
135 calculate_gforce(&nc->accel_calib, &nc->accel, &nc->gforce);
136 #endif