void *status_thread(struct wiimote *wiimote) { struct mesg_array ma; struct cwiid_status_mesg *status_mesg; unsigned char buf[2]; unsigned char data[2]; ma.count = 1; status_mesg = &ma.array[0].status_mesg; while (1) { if (full_read(wiimote->status_pipe[0], status_mesg, sizeof *status_mesg)) { cwiid_err(wiimote, "Pipe read error (status)"); /* Quit! */ break; } if (status_mesg->type != CWIID_MESG_STATUS) { cwiid_err(wiimote, "Bad message on status pipe"); continue; } if (status_mesg->ext_type == CWIID_EXT_UNKNOWN) { /* Read extension ID */ if (cwiid_read(wiimote, CWIID_RW_REG, 0xA400FE, 2, &buf)) { cwiid_err(wiimote, "Read error (extension error)"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } /* If we have just disabled passthrough override passthrough with just plain motionplus */ /*if ((!wiimote->passthrough_activate_flag && ((buf[0] << 8) | buf[1]) == EXT_NUNCHUK_MOTIONPLUS) || (!wiimote->passthrough_activate_flag && ((buf[0] << 8) | buf[1]) == EXT_CLASSIC_MOTIONPLUS)) { fprintf(stderr, "status_thread: reverting to motionplus\n"); buf[0] = EXT_MOTIONPLUS; }*/ /* If the extension didn't change, or if the extension is a * MotionPlus, no init necessary */ switch ((buf[0] << 8) | buf[1]) { case EXT_NONE: status_mesg->ext_type = CWIID_EXT_NONE; break; case EXT_NUNCHUK: if (wiimote->ext == MOTIONPLUS_PRESENT && wiimote->passthrough_activate_flag){ data[0] = 0x05; cwiid_write(wiimote, CWIID_RW_REG, 0xA600FE, 1, &data[0]); cwiid_read(wiimote, CWIID_RW_REG, 0xA400FE, 1, &data[1]); if (data[1] == 0x05) { status_mesg->ext_type = CWIID_EXT_NUNCHUK_MPLUS_PASSTHROUGH; wiimote->ext = NUNCHUK_MOTIONPLUS_PRESENT; break; } }else{ status_mesg->ext_type = CWIID_EXT_NUNCHUK; wiimote->ext = EXT_PRESENT_NOT_MOTIONPLUS; break; } case EXT_NUNCHUK_MOTIONPLUS: status_mesg->ext_type = CWIID_EXT_NUNCHUK_MPLUS_PASSTHROUGH; wiimote->ext = NUNCHUK_MOTIONPLUS_PRESENT; break; case EXT_CLASSIC: if (wiimote->ext == MOTIONPLUS_PRESENT && wiimote->passthrough_activate_flag){ data[0] = 0x07; cwiid_write(wiimote, CWIID_RW_REG, 0xA600FE, 1, &data[0]); cwiid_read(wiimote, CWIID_RW_REG, 0xA400FE, 1, &data[1]); if (data[1] == 0x07) { status_mesg->ext_type = CWIID_EXT_CLASSIC_MPLUS_PASSTHROUGH; wiimote->ext = CLASSIC_MOTIONPLUS_PRESENT; break; } }else{ status_mesg->ext_type = CWIID_EXT_CLASSIC; wiimote->ext = EXT_PRESENT_NOT_MOTIONPLUS; break; } case EXT_CLASSIC_MOTIONPLUS: status_mesg->ext_type = CWIID_EXT_CLASSIC_MPLUS_PASSTHROUGH; wiimote->ext = CLASSIC_MOTIONPLUS_PRESENT; break; case EXT_BALANCE: status_mesg->ext_type = CWIID_EXT_BALANCE; wiimote->ext = EXT_PRESENT_NOT_MOTIONPLUS; break; case EXT_MOTIONPLUS: status_mesg->ext_type = CWIID_EXT_MOTIONPLUS; wiimote->ext = MOTIONPLUS_PRESENT; break; case EXT_PARTIAL: /* Everything (but MotionPlus) shows up as partial until initialized */ buf[0] = 0x55; buf[1] = 0x00; /* Initialize extension register space */ if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &buf[0])) { cwiid_err(wiimote, "Extension initialization error"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } else if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, &buf[1])) { cwiid_err(wiimote, "Extension initialization error"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } /* Read extension ID */ else if (cwiid_read(wiimote, CWIID_RW_REG, 0xA400FE, 2, &buf)) { cwiid_err(wiimote, "Read error (extension error)"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } else { switch ((buf[0] << 8) | buf[1]) { case EXT_NONE: case EXT_PARTIAL: status_mesg->ext_type = CWIID_EXT_NONE; break; case EXT_NUNCHUK: status_mesg->ext_type = CWIID_EXT_NUNCHUK; break; case EXT_CLASSIC: status_mesg->ext_type = CWIID_EXT_CLASSIC; break; case EXT_BALANCE: status_mesg->ext_type = CWIID_EXT_BALANCE; break; case EXT_NUNCHUK_MOTIONPLUS: status_mesg->ext_type = CWIID_EXT_NUNCHUK_MPLUS_PASSTHROUGH; break; case EXT_CLASSIC_MOTIONPLUS: status_mesg->ext_type = CWIID_EXT_CLASSIC_MPLUS_PASSTHROUGH; break; default: status_mesg->ext_type = CWIID_EXT_UNKNOWN; break; } } break; } } else { //fprintf(stderr,"ext_type=%d ext=%d\n", status_mesg->ext_type, wiimote->ext); if (!(wiimote->passthrough_activate_flag && wiimote->ext == MOTIONPLUS_PRESENT) || !wiimote->passthrough_activate_flag) { //fprintf(stderr,"NO EXTENSION\n"); wiimote->ext = NO_EXTENSION; } pthread_cond_signal(&wiimote->condition_var); } if (update_state(wiimote, &ma)) { cwiid_err(wiimote, "State update error"); } if (update_rpt_mode(wiimote, -1)) { cwiid_err(wiimote, "Error reseting report mode"); } if ((wiimote->state.rpt_mode & CWIID_RPT_STATUS) && (wiimote->flags & CWIID_FLAG_MESG_IFC)) { if (write_mesg_array(wiimote, &ma)) { /* prints its own errors */ } } } return NULL; }
void *status_thread(struct wiimote *wiimote) { struct mesg_array ma; struct cwiid_status_mesg *status_mesg; unsigned char buf[2]; ma.count = 1; status_mesg = &ma.array[0].status_mesg; while (1) { if (full_read(wiimote->status_pipe[0], status_mesg, sizeof *status_mesg)) { cwiid_err(wiimote, "Pipe read error (status)"); /* Quit! */ break; } if (status_mesg->type != CWIID_MESG_STATUS) { cwiid_err(wiimote, "Bad message on status pipe"); continue; } if (status_mesg->ext_type == CWIID_EXT_UNKNOWN) { /* Read extension ID */ if (cwiid_read(wiimote, CWIID_RW_REG, 0xA400FE, 1, &buf[0])) { cwiid_err(wiimote, "Read error (extension error)"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } /* If the extension didn't change, or if the extension is a * MotionPlus, no init necessary */ switch (buf[0]) { case EXT_NONE: status_mesg->ext_type = CWIID_EXT_NONE; break; case EXT_NUNCHUK: status_mesg->ext_type = CWIID_EXT_NUNCHUK; break; case EXT_CLASSIC: status_mesg->ext_type = CWIID_EXT_CLASSIC; break; case EXT_BALANCE: status_mesg->ext_type = CWIID_EXT_BALANCE; break; case EXT_MOTIONPLUS: status_mesg->ext_type = CWIID_EXT_MOTIONPLUS; break; case EXT_PARTIAL: /* Everything (but MotionPlus) shows up as partial until initialized */ buf[0] = 0x55; buf[1] = 0x00; /* Initialize extension register space */ if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &buf[0])) { cwiid_err(wiimote, "Extension initialization error"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } else if (cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, &buf[1])) { cwiid_err(wiimote, "Extension initialization error"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } /* Read extension ID */ else if (cwiid_read(wiimote, CWIID_RW_REG, 0xA400FE, 1, &buf[0])) { cwiid_err(wiimote, "Read error (extension error)"); status_mesg->ext_type = CWIID_EXT_UNKNOWN; } else { switch (buf[0]) { case EXT_NONE: case EXT_PARTIAL: status_mesg->ext_type = CWIID_EXT_NONE; break; case EXT_NUNCHUK: status_mesg->ext_type = CWIID_EXT_NUNCHUK; break; case EXT_CLASSIC: status_mesg->ext_type = CWIID_EXT_CLASSIC; break; case EXT_BALANCE: status_mesg->ext_type = CWIID_EXT_BALANCE; break; default: status_mesg->ext_type = CWIID_EXT_UNKNOWN; break; } } break; } } if (update_state(wiimote, &ma)) { cwiid_err(wiimote, "State update error"); } if (update_rpt_mode(wiimote, -1)) { cwiid_err(wiimote, "Error reseting report mode"); } if ((wiimote->state.rpt_mode & CWIID_RPT_STATUS) && (wiimote->flags & CWIID_FLAG_MESG_IFC)) { if (write_mesg_array(wiimote, &ma)) { /* prints its own errors */ } } } return NULL; }
int cwiid_set_rpt_mode(cwiid_wiimote_t *wiimote, uint8_t rpt_mode) { return update_rpt_mode(wiimote, rpt_mode); }