View unanswered posts | View active topics It is currently Wed Nov 14, 2018 5:59 am



Reply to topic  [ 4 posts ] 
 Classic controllers returning invalid calibration data 
Author Message

Joined: Sat Mar 01, 2008 11:01 am
Posts: 64
It seems that most problems with 3rd party Classic Controllers in libogc/libwiiuse are caused by controllers that do not return valid calibration data during the initialization handshake.

The probleme is that there is actually no double-check in libwiiuse to see if acquired data is valid and the following code in dynamics.c can actually cause "Division by Zero" exception when the returned data is fixed to 0xFFF (which seems to be the case with those unsupported controllers):
Code:
   if (x == js->center.x)
rx = 0;
else if (x >= js->center.x)
rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x));
else
rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f;
if (y == js->center.y)
ry = 0;
else if (y >= js->center.y)
ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y));
else
ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f;


A quick solution would be to change the following code in classics.c :
Code:
   /* joystick stuff */
cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
cc->ljs.min.x = data[1 + offset] / 4;
cc->ljs.center.x = data[2 + offset] / 4 == 0 ? 32 : data[2 + offset] / 4;
cc->ljs.max.y = data[3 + offset] / 4 == 0 ? 64 : data[3 + offset] / 4;
cc->ljs.min.y = data[4 + offset] / 4;
cc->ljs.center.y = data[5 + offset] / 4 == 0 ? 32 : data[5 + offset] / 4;
cc->rjs.max.x = data[6 + offset] / 8 == 0 ? 32 : data[6 + offset] / 8;
cc->rjs.min.x = data[7 + offset] / 8;
cc->rjs.center.x = data[8 + offset] / 8 == 0 ? 16 : data[8 + offset] / 8;
cc->rjs.max.y = data[9 + offset] / 8 == 0 ? 32 : data[9 + offset] / 8;
cc->rjs.min.y = data[10 + offset] / 8;
cc->rjs.center.y = data[11 + offset] / 8 == 0 ? 16 : data[11 + offset] / 8;


to
Code:
   /* joystick stuff */
if (data[offset] = 0xFF)
{
        /* invalid calibration data : set sefault values */
        cc->ljs.max.x = cc->ljs.max.y =64;
        cc->ljs.min.x = cc->ljs.min.y =0;
        cc->ljs.center.x = cc->ljs.center.y =32;
        cc->rjs.max.x = cc->rjs.max.y = 32;
        cc->rjs.min.x = cc->rjs.min.y = 0;
        cc->rjs.center.x = cc->rjs.center.y = 16;
}
else
{
        cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
        cc->ljs.min.x = data[1 + offset] / 4;
        cc->ljs.center.x = data[2 + offset] / 4 == 0 ? 32 : data[2 + offset] / 4;
        cc->ljs.max.y = data[3 + offset] / 4 == 0 ? 64 : data[3 + offset] / 4;
        cc->ljs.min.y = data[4 + offset] / 4;
        cc->ljs.center.y = data[5 + offset] / 4 == 0 ? 32 : data[5 + offset] / 4;
        cc->rjs.max.x = data[6 + offset] / 8 == 0 ? 32 : data[6 + offset] / 8;
        cc->rjs.min.x = data[7 + offset] / 8;
        cc->rjs.center.x = data[8 + offset] / 8 == 0 ? 16 : data[8 + offset] / 8;
        cc->rjs.max.y = data[9 + offset] / 8 == 0 ? 32 : data[9 + offset] / 8;
        cc->rjs.min.y = data[10 + offset] / 8;
        cc->rjs.center.y = data[11 + offset] / 8 == 0 ? 16 : data[11 + offset] / 8;
}


Fri Jul 11, 2014 3:26 pm
Profile

Joined: Sat Mar 01, 2008 11:01 am
Posts: 64
Looking further at classic_ctrl_handshake function in classics.c, the following code :

Code:
   if (data[offset] == 0xFF) {
/*
* Sometimes the data returned here is not correct.
* This might happen because the wiimote is lagging
* behind our initialization sequence.
* To fix this just request the handshake again.
*
* Other times it's just the first 16 bytes are 0xFF,
* but since the next 16 bytes are the same, just use
* those.
*/
if (data[offset + 16] == 0xFF) {
/* get the calibration data again */
WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again.");
wiiuse_read_data(wm, data, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN, wiiuse_handshake_expansion);
} else
offset += 16;
}


seems to indicate the original developer assumed that if invalid data was returned, a second read would eventually acquire correct data and calibration settings would then correctly be set.

the problems with this solution is that:

1) there is no garantee that further reads would not return 0xFF as well, and no protection in the code against that

2) call to wiiuse_read_data is not blocking (reads are handled through a command fifo by another thread) so classic_ctrl_handshake function immediately returns with no errors to its caller (wiiuse_handshake_expansion) after having initialized min/max/center settings with invalid values

3) in wiiuse_handshake_expansion function, the following code:

Code:
   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:
if(!classic_ctrl_handshake(wm,&wm->exp.classic,data,len)) return;
break;
case EXP_ID_CODE_GUITAR:
if(!guitar_hero_3_handshake(wm,&wm->exp.gh3,data,len)) return;
break;
case EXP_ID_CODE_WIIBOARD:
if(!wii_board_handshake(wm,&wm->exp.wb,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;


shows that when the 2nd read attempt is acquired and wiiuse_handshake_expansion is called back, acquired data is ignored because expansion handshake is finished since classic_ctrl_handshake returned with no error on first attempt


I am not sure what the good solution would be but the easiest one would be to remove that second read attempt since it's useless anyway and ignore invalid calibration data acquired on first attempt


Fri Jul 11, 2014 4:13 pm
Profile

Joined: Thu Dec 10, 2009 9:26 am
Posts: 40
If this is ever going to be fixed I propose adding wii u pro controller support at the same time:
Code:
Index: gc/wiiuse/wiiuse.h
===================================================================
--- gc/wiiuse/wiiuse.h   (revision 4915)
+++ gc/wiiuse/wiiuse.h   (working copy)
@@ -245,7 +245,7 @@
    CMD_DONE
 } cmd_blk_s;
 
-struct cmd_blk_t
+struct cmd_blk_t
 {
    lwp_node node;
 
@@ -470,6 +470,7 @@
 
    struct joystick_t ljs;         /**< left joystick calibration            */
    struct joystick_t rjs;         /**< right joystick calibration            */
+   ubyte type;                  /**< original, pro, wiiu pro               */
 } classic_ctrl_t;
 
 
@@ -627,7 +628,7 @@
    WCONST ubyte expansion_state;         /**< the state of the expansion handshake   */
 
    WCONST struct data_req_t* data_req;      /**< list of data read requests            */
-   
+
    WCONST struct cmd_blk_t *cmd_head;
    WCONST struct cmd_blk_t *cmd_tail;
 
Index: wiiuse/classic.c
===================================================================
--- wiiuse/classic.c   (revision 4915)
+++ wiiuse/classic.c   (working copy)
@@ -71,40 +71,57 @@
    for (i = 0; i < len; ++i)
       data[i] = (data[i] ^ 0x17) + 0x17;
    */
-   if (data[offset] == 0xFF) {
-      /*
-       *   Sometimes the data returned here is not correct.
-       *   This might happen because the wiimote is lagging
-       *   behind our initialization sequence.
-       *   To fix this just request the handshake again.
-       *
-       *   Other times it's just the first 16 bytes are 0xFF,
-       *   but since the next 16 bytes are the same, just use
-       *   those.
-       */
-      if (data[offset + 16] == 0xFF) {
-         /* get the calibration data again */
-         WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again.");
-         wiiuse_read_data(wm, data, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN, wiiuse_handshake_expansion);
-      } else
-         offset += 16;
+
+   /* is this a wiiu pro? */
+   if (len > 223 && data[223] == 0x20) {
+      cc->ljs.max.x = cc->ljs.max.y = 0xFF;
+      cc->ljs.min.x = cc->ljs.min.y = 0;
+      cc->ljs.center.x = cc->ljs.center.y = 0x80;
+
+      cc->rjs = cc->ljs;
+
+      cc->type = 2;
    }
+   else {
+      if (data[offset] == 0xFF) {
+         /*
+          *   Sometimes the data returned here is not correct.
+          *   This might happen because the wiimote is lagging
+          *   behind our initialization sequence.
+          *   To fix this just request the handshake again.
+          *
+          *   Other times it's just the first 16 bytes are 0xFF,
+          *   but since the next 16 bytes are the same, just use
+          *   those.
+          */
+         if (data[offset + 16] == 0xFF) {
+            /* get the calibration data again */
+            WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again.");
+            wiiuse_read_data(wm, data, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN, wiiuse_handshake_expansion);
+         } else
+            offset += 16;
+      }
 
+      if (len > 218 && data[218])
+         cc->type = 1; /* classic controller pro (no analog triggers) */
+      else
+         cc->type = 0; /* original classic controller (analog triggers) */
 
-   /* joystick stuff */
-   cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
-   cc->ljs.min.x = data[1 + offset] / 4;
-   cc->ljs.center.x = data[2 + offset] / 4 == 0 ? 32 : data[2 + offset] / 4;
-   cc->ljs.max.y = data[3 + offset] / 4 == 0 ? 64 : data[3 + offset] / 4;
-   cc->ljs.min.y = data[4 + offset] / 4;
-   cc->ljs.center.y = data[5 + offset] / 4 == 0 ? 32 : data[5 + offset] / 4;
+      /* joystick stuff */
+      cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
+      cc->ljs.min.x = data[1 + offset] / 4;
+      cc->ljs.center.x = data[2 + offset] / 4 == 0 ? 32 : data[2 + offset] / 4;
+      cc->ljs.max.y = data[3 + offset] / 4 == 0 ? 64 : data[3 + offset] / 4;
+      cc->ljs.min.y = data[4 + offset] / 4;
+      cc->ljs.center.y = data[5 + offset] / 4 == 0 ? 32 : data[5 + offset] / 4;
 
-   cc->rjs.max.x = data[6 + offset] / 8 == 0 ? 32 : data[6 + offset] / 8;
-   cc->rjs.min.x = data[7 + offset] / 8;
-   cc->rjs.center.x = data[8 + offset] / 8 == 0 ? 16 : data[8 + offset] / 8;
-   cc->rjs.max.y = data[9 + offset] / 8 == 0 ? 32 : data[9 + offset] / 8;
-   cc->rjs.min.y = data[10 + offset] / 8;
-   cc->rjs.center.y = data[11 + offset] / 8 == 0 ? 16 : data[11 + offset] / 8;
+      cc->rjs.max.x = data[6 + offset] / 8 == 0 ? 32 : data[6 + offset] / 8;
+      cc->rjs.min.x = data[7 + offset] / 8;
+      cc->rjs.center.x = data[8 + offset] / 8 == 0 ? 16 : data[8 + offset] / 8;
+      cc->rjs.max.y = data[9 + offset] / 8 == 0 ? 32 : data[9 + offset] / 8;
+      cc->rjs.min.y = data[10 + offset] / 8;
+      cc->rjs.center.y = data[11 + offset] / 8 == 0 ? 16 : data[11 + offset] / 8;
+   }
 
    /* handshake done */
    wm->event = WIIUSE_CLASSIC_CTRL_INSERTED;
@@ -123,7 +140,7 @@
  *
  *   @param cc      A pointer to a classic_ctrl_t structure.
  */
-void classic_ctrl_disconnected(struct classic_ctrl_t* cc)
+void classic_ctrl_disconnected(struct classic_ctrl_t* cc)
 {
    memset(cc, 0, sizeof(struct classic_ctrl_t));
 }
@@ -144,25 +161,40 @@
    for (i = 0; i < 6; ++i)
       msg[i] = (msg[i] ^ 0x17) + 0x17;
    */
-   classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
+   if (cc->type==2) {
+      classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 8)));
 
-   /* left/right buttons */
-   cc->ls_raw = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5));
-   cc->rs_raw = (msg[3] & 0x1F);
+      /* 12-bit little endian values adjusted to 8-bit */
+      cc->ljs.pos.x = (msg[0] >> 4) | (msg[1] << 4);
+      cc->rjs.pos.x = (msg[2] >> 4) | (msg[3] << 4);
+      cc->ljs.pos.y = (msg[4] >> 4) | (msg[5] << 4);
+      cc->rjs.pos.y = (msg[6] >> 4) | (msg[7] << 4);
 
-   /*
-    *   TODO - LR range hardcoded from 0x00 to 0x1F.
-    *   This is probably in the calibration somewhere.
-    */
+      cc->ls_raw = cc->btns & CLASSIC_CTRL_BUTTON_FULL_L ? 0x1F : 0;
+      cc->rs_raw = cc->btns & CLASSIC_CTRL_BUTTON_FULL_R ? 0x1F : 0;
+   }
+   else {
+      classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
+
+      /* left/right buttons */
+      cc->ls_raw = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5));
+      cc->rs_raw = (msg[3] & 0x1F);
+
+      /*
+       *   TODO - LR range hardcoded from 0x00 to 0x1F.
+       *   This is probably in the calibration somewhere.
+       */
 #ifndef GEKKO
-   cc->r_shoulder = ((float)r / 0x1F);
-   cc->l_shoulder = ((float)l / 0x1F);
+      cc->r_shoulder = ((float)r / 0x1F);
+      cc->l_shoulder = ((float)l / 0x1F);
 #endif
-   /* calculate joystick orientation */
-   cc->ljs.pos.x = (msg[0] & 0x3F);
-   cc->ljs.pos.y = (msg[1] & 0x3F);
-   cc->rjs.pos.x = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7);
-   cc->rjs.pos.y = (msg[2] & 0x1F);
+      /* calculate joystick orientation */
+      cc->ljs.pos.x = (msg[0] & 0x3F);
+      cc->ljs.pos.y = (msg[1] & 0x3F);
+      cc->rjs.pos.x = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7);
+      cc->rjs.pos.y = (msg[2] & 0x1F);
+   }
+
 #ifndef GEKKO
    calc_joystick_state(&cc->ljs, cc->ljs.pos.x, cc->ljs.pos.y);
    calc_joystick_state(&cc->rjs, cc->rjs.pos.x, cc->rjs.pos.y);
Index: wiiuse/io.c
===================================================================
--- wiiuse/io.c   (revision 4915)
+++ wiiuse/io.c   (working copy)
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "definitions.h"
 #include "wiiuse_internal.h"
@@ -16,39 +17,52 @@
    ubyte *buf = NULL;
    struct accel_t *accel = &wm->accel_calib;
 
-   //printf("wiiuse_handshake(%d,%p,%d)\n",wm->handshake_state,data,len);
+//   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;
 
-         buf = __lwp_wkspace_allocate(sizeof(ubyte)*8);
-         wiiuse_read_data(wm,buf,WM_MEM_OFFSET_CALIBRATION,7,wiiuse_handshake);
-         break;
       case 1:
          wm->handshake_state++;
+         buf = __lwp_wkspace_allocate(sizeof(ubyte)*8);
 
-         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));
+         if (len > 2 && data[2]&WM_CTRL_STATUS_BYTE1_ATTACHMENT) {
+            wiiuse_read_data(wm,buf,WM_EXP_ID,6,wiiuse_handshake);
+            return;
 
-         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);
+      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->event = WIIUSE_CONNECT;
-         wiiuse_status(wm,NULL);
-         break;
-      default:
-         break;
+         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)
@@ -101,6 +115,7 @@
             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;
             case EXP_ID_CODE_GUITAR:
Index: wiiuse/ir.c
===================================================================
--- wiiuse/ir.c   (revision 4915)
+++ wiiuse/ir.c   (working copy)
@@ -190,7 +190,7 @@
 
    if (status) {
       /* if already enabled then stop */
-      if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
+      if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR) || WIIMOTE_IS_SET(wm, WIIMOTE_STATE_WIIU_PRO)) {
          wiiuse_status(wm,NULL);
          return;
       }
@@ -579,7 +579,7 @@
                hadj = SB_DOT_HEIGHT_RATIO * difference.x;
                wadj = SB_DOT_WIDTH_RATIO * difference.x;
                rotate_dots(&dots[i], &tdot, 1, cand.angle);
-               if( ((cand.rot_dots[0].x + wadj) < tdot.x) &&
+               if( ((cand.rot_dots[0].x + wadj) < tdot.x) &&
                   ((cand.rot_dots[1].x - wadj) > tdot.x) &&
                   ((cand.rot_dots[0].y + hadj) > tdot.y) &&
                   ((cand.rot_dots[0].y - hadj) < tdot.y))
Index: wiiuse/wiiuse_internal.h
===================================================================
--- wiiuse/wiiuse_internal.h   (revision 4915)
+++ wiiuse/wiiuse_internal.h   (working copy)
@@ -173,6 +173,7 @@
 #define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC3      0xa0a1a000
 #define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC4      0x8d8d8e00
 #define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC5      0x93949400
+#define EXP_ID_CODE_CLASSIC_WIIU_PRO            0xa4200120
 #define EXP_ID_CODE_GUITAR                     0xa4200103
 #define EXP_ID_CODE_WIIBOARD                  0xa4200402
 #define EXP_ID_CODE_MOTION_PLUS                  0xa4200405
@@ -205,6 +206,7 @@
 #define WIIMOTE_STATE_IR_SENS_LVL5            0x10000
 #define WIIMOTE_STATE_IR_INIT               0x20000
 #define WIIMOTE_STATE_SPEAKER_INIT            0x40000
+#define WIIMOTE_STATE_WIIU_PRO               0x80000
 
 #define WIIMOTE_INIT_STATES               (WIIMOTE_STATE_IR_SENS_LVL3)
 


Wed Sep 17, 2014 1:46 am
Profile

Joined: Mon Jul 04, 2011 1:03 pm
Posts: 34
As far as I understand from the code, the Wii U pro controller is "seen" as a classic controller expansion of the Wiimote.

As such the status of the Wii U pro controller can be checked with the same functions, parameters and data structure used for the Classic controller (normal and pro).

It is possible to check which type of Classic controller is connected, using the WPAD_Expansion(int chan, struct expansion_t *exp) function where a new variable named "type" has been added to the structure expansion_t.

Is all correct?

Thanks


Thu Jan 05, 2017 8:01 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.
Get devkitPro at SourceForge.net. Fast, secure and Free Open Source software downloads