int wiiuse_write_data(struct wiimote_t *wm,uint addr,ubyte *data,ubyte len,cmd_blk_cb cb) { struct op_t *op; struct cmd_blk_t *cmd; if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0; if(!data || !len) return 0; cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq); if(!cmd) return 0; cmd->cb = cb; cmd->len = 22; op = (struct op_t*)cmd->data; op->cmd = WM_CMD_WRITE_DATA; op->buffer = NULL; op->wait = 0; op->writedata.addr = BIG_ENDIAN_LONG(addr); op->writedata.size = (len&0x0f); memcpy(op->writedata.data,data,len); memset(op->writedata.data+len,0,(16 - len)); __wiiuse_push_command(wm,cmd); return 1; }
void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len) { int id; ubyte val; ubyte *buf = NULL; switch(wm->expansion_state) { /* These two initialization writes disable the encryption */ case 0: wm->expansion_state = 1; val = 0x55; wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_handshake_expansion); break; case 1: wm->expansion_state = 2; val = 0x00; wiiuse_write_data(wm,WM_EXP_MEM_ENABLE2,&val,1,wiiuse_handshake_expansion); break; case 2: wm->expansion_state = 3; buf = __lwp_wkspace_allocate(sizeof(ubyte)*EXP_HANDSHAKE_LEN); wiiuse_read_data(wm,buf,WM_EXP_MEM_CALIBR,EXP_HANDSHAKE_LEN,wiiuse_handshake_expansion); break; 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: 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: 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; } }
void wiiuse_handshake(struct wiimote_t *wm,ubyte *data,uword len) { ubyte *buf = NULL; struct accel_t *accel = &wm->accel_calib; //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; case 1: wm->handshake_state++; buf = __lwp_wkspace_allocate(sizeof(ubyte)*8); if (len > 2 && data[2]&WM_CTRL_STATUS_BYTE1_ATTACHMENT) { wiiuse_read_data(wm,buf,WM_EXP_ID,6,wiiuse_handshake); return; 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->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); }
int wiiuse_read_data(struct wiimote_t *wm,ubyte *buffer,uint addr,uword len,cmd_blk_cb cb) { struct op_t *op; struct cmd_blk_t *cmd; if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0; if(!buffer || !len) return 0; cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq); if(!cmd) return 0; cmd->cb = cb; cmd->len = 7; op = (struct op_t*)cmd->data; op->cmd = WM_CMD_READ_DATA; op->buffer = buffer; op->wait = len; op->readdata.addr = BIG_ENDIAN_LONG(addr); op->readdata.size = BIG_ENDIAN_SHORT(len); __wiiuse_push_command(wm,cmd); return 1; }