// GC, classic controller, nunchuk and guitar support by gannon // remapping tweaks by Dr. Clipper #include #include #include #include #include #include "sys.h" #include "wpad.h" #include "subsystem.h" #include "cfg.h" #include "menu.h" /* Constants */ #define MAX_WIIMOTES 4 #define MIN_X -20 #define MAX_X 650 #define MIN_Y -20 #define MAX_Y 480 extern u8 shutdown; float coord[2] = {320,240}; bool padMoved = false; const char *button_names[MAX_BUTTONS] = { "UP", "RIGHT", "DOWN", "LEFT", "-", "+", "A", "B", "HOME", "1", "2", "X", "Y", "Z", "C", "L", "R" }; void Do_Shutdown() { Services_Close(); Subsystem_Close(); Sys_Shutdown(); } void Wpad_Stick(int n, float mm, float *am, float *aa, int *ax, int *ay) { float m = 0.0; float a = 0.0; float x = 0.0; float y = 0.0; WPADData *data = WPAD_Data(n); if (data->exp.type == WPAD_EXP_NUNCHUK) { m = data->exp.nunchuk.js.mag; a = data->exp.nunchuk.js.ang; } else if (data->exp.type == WPAD_EXP_CLASSIC) { m = data->exp.classic.ljs.mag; a = data->exp.classic.ljs.ang; } else if (data->exp.type == WPAD_EXP_GUITARHERO3) { m = data->exp.gh3.js.mag; a = data->exp.gh3.js.ang; } // no movement zone if ((m > 0 && m < mm) || (m < 0 && m > -mm)) m = 0; if (m > 1.0) m = 1.0; else if (m < -1.0) m = -1.0; if (am) *am = m; if (aa) *aa = a; // sometimes a is NaN if (a >= -360.0 && a <= 360.0 && m >= -1 && m <= 1 ) { x = m * sin((M_PI * a)/180.0f); y = m * cos((M_PI * a)/180.0f); } else { //dbg_printf("wtf: %f\n", a); // NaN } if (ax) *ax = x * 128; if (ay) *ay = y * 128; } bool Wpad_set_pos(struct ir_t *ir, float x, float y) { bool ret = padMoved; if (ir) { if (ir->smooth_valid) return ret; coord[0] = x; coord[1] = y; if (coord[0] < MIN_X) coord[0] = MIN_X; if (coord[0] > MAX_X) coord[0] = MAX_X; if (coord[1] < MIN_Y) coord[1] = MIN_Y; if (coord[1] > MAX_Y) coord[1] = MAX_Y; ir->sx = coord[0]; ir->sy = coord[1]; ir->angle = 0.0; ir->raw_valid = 1; ir->smooth_valid = 1; ir->valid = 1; padMoved = true; } else { padMoved = false; } return ret; } void Wpad_getIRx(int n, struct ir_t *ir) { int i; WPAD_ScanPads(); PAD_ScanPads(); // handle shutdown if (shutdown) Do_Shutdown(); if (n == WPAD_CHAN_ALL) { n = WPAD_CHAN_0; for (i=0; i < WPAD_MAX_IR_DOTS; i++) { WPAD_IR(WPAD_CHAN_0 + i, ir); if (ir->smooth_valid) break; } } else { WPAD_IR(n, ir); } ir->sx -= 160; ir->sy -= 220; if (ir->smooth_valid == 0) { s8 padX = PAD_StickX(n); s8 padY = PAD_StickY(n); // GC Controller deadzone if(padX > -16 && padX < 16) padX = 0; if(padY > -16 && padY < 16) padY = 0; int wpadX; int wpadY; float pm, pa; Wpad_Stick(n, 0.08, &pm, &pa, &wpadX, &wpadY); // Wii Classic Controller deadzone if(wpadX > -16 && wpadX < 16) wpadX = 0; if(wpadY > -16 && wpadY < 16) wpadY = 0; float mX = (float)(padX+wpadX) / 8; float mY = (float)(padY+wpadY) / 8; //dbg_printf("%d,%d %d,%d %.2f,%.2f %d %.2f,%.2f %.2f,%.2f\n", // padX, padY, wpadX, wpadY, mX, mY, padMoved, pm, pa, coord[0], coord[1]); if (mX > 1 || mY > 1 || mX < -1 || mY < -1) { padMoved = true; } if (padMoved) { Wpad_set_pos(ir, coord[0] + mX, coord[1] - mY); } } else { coord[0] = 320; coord[1] = 240; padMoved = false; } return; } void Wpad_getIR(struct ir_t *ir) { Wpad_getIRx(WPAD_CHAN_ALL, ir); } u32 readPad(int n, bool held) { int i; u32 pad, wii, type; u32 buttons = 0; pad = (held == 1) ? PAD_ButtonsHeld(n) : PAD_ButtonsDown(n); for (i=0; i wait) { if (buttons_held & WPAD_BUTTON_UP) { buttons |= WPAD_BUTTON_UP; held = 2; } else if (buttons_held & WPAD_BUTTON_DOWN) { buttons |= WPAD_BUTTON_DOWN; held = 2; } else if (buttons_held & WPAD_BUTTON_LEFT) { buttons |= WPAD_BUTTON_LEFT; held = 3; } else if (buttons_held & WPAD_BUTTON_RIGHT) { buttons |= WPAD_BUTTON_RIGHT; held = 3; } t_start = t_now; } } else { held = 0; } } VIDEO_WaitVSync(); } return buttons; } u32 Wpad_WaitButtonsTimeout(int ms) { u32 buttons = 0; long long t = gettime(); for (;;) { buttons = Wpad_GetButtons(); if (buttons) break; if (diff_msec(t, gettime()) >= ms) break; VIDEO_WaitVSync(); } return buttons; }