Suporte a IR, talvez...
[Projeto-PCG.git] / controlewii.cpp
blobbd3afafd738aadf0c4d52771eaf574d34fe0bc1f
1 #include "controlewii.h"
2 #include "usereventtype.h"
3 #include <math.h>
6 ControleWii::ControleWii(Player &p) : Controle(p) {
7 initializeWiimote();
8 stickX = 0xffff;
9 stickY = 0xffff;
10 buttonsNunchuck = 0;
11 buttonsWii = 0;
12 for (int i = 0; i < 4; i++)
13 cyclesSinceSeen[i] = -1;
16 void ControleWii::handleOther() {
17 Uint8 *keystates = SDL_GetKeyState( NULL );
18 if (keystates[SDLK_DOWN]) {
19 jogador.onGround = false;
20 jogador.bypass = true;
22 if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) { //botao esquerdo do mouse pressionado
23 jogador.fire();
25 if (jogador.onGround &&
26 buttonsNunchuck & 2) { //pulo com botao C ou para cima
27 jogador.addSpeed( 0, -8);
28 jogador.onGround = false;
31 if (buttonsNunchuck & 1) {//descer com botao Z ou para baixo
32 jogador.onGround = false;
33 jogador.bypass = true;
36 if (buttonsWii & 4) { //R atira
37 jogador.fire();
42 void ControleWii::handleEvent(SDL_Event &e) {
43 switch( e.type ) {
44 case SDL_USEREVENT:
45 switch (e.user.code) {
46 case WIIMOTEEVENT:
47 cwiid_mesg_type* type = (cwiid_mesg_type*)e.user.data1;
48 union cwiid_mesg *mesg = (union cwiid_mesg*)e.user.data2;
49 switch (*type) {
50 case CWIID_MESG_IR: {
51 //printf("IR Report: ");
52 int sources = 0;
53 double x = 0.0;
54 double y = 0.0;
55 for (int j = 0; j < CWIID_IR_SRC_COUNT; j++) {
56 cyclesSinceSeen[j]++;
57 if (mesg->ir_mesg.src[j].valid) {
58 x += mesg->ir_mesg.src[j].pos[CWIID_X];
59 y += mesg->ir_mesg.src[j].pos[CWIID_Y];
60 sources++;
61 cyclesSinceSeen[j] = 0;
62 lastSeenAt[j].x = mesg->ir_mesg.src[j].pos[CWIID_X];
63 lastSeenAt[j].y = mesg->ir_mesg.src[j].pos[CWIID_Y];
64 //printf("(%d,%d) ", mesg->ir_mesg.src[j].pos[CWIID_X],
65 // mesg->ir_mesg.src[j].pos[CWIID_Y]);
67 //break;
70 if (sources > 0) {
71 y = y / sources;
72 double angle = (y / 738.0) * PI;
73 y = jogador.getY() + jogador.pescoco().y - jogador.game->camera.y - 100 * cos(angle);
74 x = jogador.getX() + jogador.pescoco().x - jogador.game->camera.x + 100 * sin(angle);
75 jogador.setAim(x,y);
76 //x = x / sources;
77 //y = y / sources;
78 //x = 1024.0 - (x / 1024.0) * jogador.game->config->screen["width"];
79 //y = (y / 738.0) * jogador.game->config->screen["height"];
80 //jogador.setAim(x,y);
81 //printf("%f %f\n",x,y);
84 break;
85 case CWIID_MESG_BTN: {
86 //printf("Button Report: %.4X\n", mesg->btn_mesg.buttons);
87 buttonsWii = mesg->btn_mesg.buttons;
88 if (mesg->btn_mesg.buttons & 4) { //R atira
89 jogador.fire();
92 break;
93 case CWIID_MESG_NUNCHUK: {
94 int newX = mesg->nunchuk_mesg.stick[CWIID_X] - 120;
95 int newY = mesg->nunchuk_mesg.stick[CWIID_Y] - 131;
97 printf("Nunchuk Report: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d "
98 "acc.z=%d\n", mesg->nunchuk_mesg.buttons,
99 newX,
100 newY,
101 mesg->nunchuk_mesg.acc[CWIID_X],
102 mesg->nunchuk_mesg.acc[CWIID_Y],
103 mesg->nunchuk_mesg.acc[CWIID_Z]);*/
105 if (stickX != 0xffff) { //para calibrar
106 //jogador.addSpeed(-3.0*stickX/128,0);
107 jogador.setSpeed(3.0*newX/128,jogador.getSpeedY());
109 stickX = newX;
110 stickY = newY;
111 buttonsNunchuck = mesg->nunchuk_mesg.buttons;
113 if (jogador.onGround &&
114 ((mesg->nunchuk_mesg.buttons & 2) ||
115 newY > 60)) { //pulo com botao C ou para cima
116 jogador.addSpeed( 0, -8);
117 jogador.onGround = false;
120 if (newY < -60 || (mesg->nunchuk_mesg.buttons & 1)) {//descer com botao Z ou para baixo
121 jogador.onGround = false;
122 jogador.bypass = true;
125 break;
128 free(e.user.data1);
129 free(e.user.data2);
130 break;
132 break;
133 case SDL_MOUSEMOTION: {
134 //jogador.setAim(e.motion.x,e.motion.y);
136 break;
137 case SDL_MOUSEBUTTONDOWN:
138 jogador.fire();
139 break;
140 case SDL_KEYUP:
141 switch (e.key.keysym.sym) {
142 case SDLK_LEFT:
143 jogador.addSpeed(3,0);
144 break;
145 case SDLK_RIGHT:
146 jogador.addSpeed(-3,0);
147 break;
148 default: break;
150 break;
151 case SDL_KEYDOWN:
152 switch (e.key.keysym.sym) {
153 case SDLK_DOWN:
154 jogador.onGround = false;
155 jogador.bypass = true;
156 break;
157 case SDLK_UP:
158 if (jogador.onGround) {
159 jogador.addSpeed( 0, -8);
160 jogador.onGround = false;
162 break;
163 case SDLK_LEFT:
164 jogador.addSpeed(-3, 0);
165 break;
166 case SDLK_RIGHT:
167 jogador.addSpeed( 3, 0);
168 break;
169 default: break;
171 break;
175 #define toggle_bit(bf,b) \
176 (bf) = ((bf) & b) \
177 ? ((bf) & ~(b)) \
178 : ((bf) | (b))
180 cwiid_err_t err;
181 void err(cwiid_wiimote_t *wiimote, const char *s, va_list ap)
183 if (wiimote) printf("%d:", cwiid_get_id(wiimote));
184 else printf("-1:");
185 vprintf(s, ap);
186 printf("\n");
189 void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count,
190 union cwiid_mesg mesg[], struct timespec *timestamp)
192 int i, j;
193 int valid_source;
197 for (i=0; i < mesg_count; i++)
199 SDL_Event event;
200 SDL_UserEvent userevent;
201 userevent.type = SDL_USEREVENT;
202 event.type = SDL_USEREVENT;
203 userevent.code = WIIMOTEEVENT;
204 cwiid_mesg_type *type = (cwiid_mesg_type*)malloc(sizeof(cwiid_mesg_type));
205 *type = mesg[i].type;
206 userevent.data1 = (void*)type;
207 union cwiid_mesg *m = (union cwiid_mesg *)malloc(sizeof(union cwiid_mesg));
208 *m = mesg[i];
209 userevent.data2 = m;
210 event.user = userevent;
211 SDL_PushEvent(&event);
212 /*switch (mesg[i].type) {
213 case CWIID_MESG_STATUS:
214 printf("Status Report: battery=%d extension=",
215 mesg[i].status_mesg.battery);
216 switch (mesg[i].status_mesg.ext_type) {
217 case CWIID_EXT_NONE:
218 printf("none");
219 break;
220 case CWIID_EXT_NUNCHUK:
221 printf("Nunchuk");
222 break;
223 case CWIID_EXT_CLASSIC:
224 printf("Classic Controller");
225 break;
226 default:
227 printf("Unknown Extension");
228 break;
230 printf("\n");
231 break;
232 case CWIID_MESG_BTN:
233 printf("Button Report: %.4X\n", mesg[i].btn_mesg.buttons);
234 break;
235 case CWIID_MESG_ACC:
236 printf("Acc Report: x=%d, y=%d, z=%d\n",
237 mesg[i].acc_mesg.acc[CWIID_X],
238 mesg[i].acc_mesg.acc[CWIID_Y],
239 mesg[i].acc_mesg.acc[CWIID_Z]);
240 break;
241 case CWIID_MESG_IR:
242 printf("IR Report: ");
243 valid_source = 0;
244 for (j = 0; j < CWIID_IR_SRC_COUNT; j++) {
245 if (mesg[i].ir_mesg.src[j].valid) {
246 valid_source = 1;
247 printf("(%d,%d) ", mesg[i].ir_mesg.src[j].pos[CWIID_X],
248 mesg[i].ir_mesg.src[j].pos[CWIID_Y]);
251 if (!valid_source) {
252 printf("no sources detected");
254 printf("\n");
255 break;
256 case CWIID_MESG_NUNCHUK: {
257 printf("Nunchuk Report: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d "
258 "acc.z=%d\n", mesg[i].nunchuk_mesg.buttons,
259 mesg[i].nunchuk_mesg.stick[CWIID_X],
260 mesg[i].nunchuk_mesg.stick[CWIID_Y],
261 mesg[i].nunchuk_mesg.acc[CWIID_X],
262 mesg[i].nunchuk_mesg.acc[CWIID_Y],
263 mesg[i].nunchuk_mesg.acc[CWIID_Z]);
264 break;
266 case CWIID_MESG_CLASSIC:
267 printf("Classic Report: btns=%.4X l_stick=(%d,%d) r_stick=(%d,%d) "
268 "l=%d r=%d\n", mesg[i].classic_mesg.buttons,
269 mesg[i].classic_mesg.l_stick[CWIID_X],
270 mesg[i].classic_mesg.l_stick[CWIID_Y],
271 mesg[i].classic_mesg.r_stick[CWIID_X],
272 mesg[i].classic_mesg.r_stick[CWIID_Y],
273 mesg[i].classic_mesg.l, mesg[i].classic_mesg.r);
274 break;
275 case CWIID_MESG_ERROR:
276 if (cwiid_close(wiimote)) {
277 fprintf(stderr, "Error on wiimote disconnect\n");
278 exit(-1);
280 exit(0);
281 break;
282 default:
283 printf("Unknown Report");
284 break;
289 void set_led_state(cwiid_wiimote_t *wiimote, unsigned char led_state)
291 if (cwiid_set_led(wiimote, led_state)) {
292 fprintf(stderr, "Error setting LEDs \n");
296 void set_rpt_mode(cwiid_wiimote_t *wiimote, unsigned char rpt_mode)
298 if (cwiid_set_rpt_mode(wiimote, rpt_mode)) {
299 fprintf(stderr, "Error setting report mode\n");
303 bool ControleWii::ControleWii::initializeWiimote() {
304 mesg = 0;
305 led_state = 0;
306 rpt_mode = 0;
307 rumble = 0;
309 cwiid_set_err(err);
311 bdaddr = *BDADDR_ANY;
313 /* Connect to the wiimote */
314 printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
315 if (!(wiimote = cwiid_open(&bdaddr, 0))) {
316 fprintf(stderr, "Unable to connect to wiimote\n");
317 return false;
319 if (cwiid_set_mesg_callback(wiimote, cwiid_callback)) {
320 fprintf(stderr, "Unable to set message callback\n");
321 return false;
324 toggle_bit(rpt_mode, CWIID_RPT_BTN); //abilita status report de botoes
325 //set_rpt_mode(wiimote, rpt_mode);
327 toggle_bit(rpt_mode, CWIID_RPT_NUNCHUK); //abilita status report de nunchuck
328 //set_rpt_mode(wiimote, rpt_mode);
330 toggle_bit(led_state, CWIID_LED1_ON); //liga primeiro LED por motivo nenhum
331 set_led_state(wiimote, led_state);
333 toggle_bit(rpt_mode, CWIID_RPT_IR); //abilita recebimento do infravermelho
334 set_rpt_mode(wiimote, rpt_mode);
336 if (cwiid_enable(wiimote, CWIID_FLAG_MESG_IFC)) {
337 fprintf(stderr, "Error enabling messages\n");
338 return false;