Changeset e1e47e116d4dcf9a1da4955a6d21d84baa73649e
- Timestamp:
- 04/25/07 02:41:13 (6 years ago)
- Children:
- c01a5a46907834f0636fddd3ab08d48f01e70449
- Parents:
- aeed7f70e058dad1d2a938bcf9a60652fd288552
- git-author:
- L. Donnie Smith <donnie.smith@…> (04/25/07 02:41:13)
- git-committer:
- dsmith <dsmith@…> (04/25/07 02:41:13)
- Files:
-
- 4 added
- 4 removed
- 15 modified
-
ChangeLog (modified) (1 diff)
-
NEWS (modified) (1 diff)
-
libcwiid/Makefile.in (modified) (1 diff)
-
libcwiid/bluetooth.c (modified) (6 diffs)
-
libcwiid/command.c (modified) (5 diffs)
-
libcwiid/connect.c (modified) (7 diffs)
-
libcwiid/cwiid.h (modified) (15 diffs)
-
libcwiid/cwiid_internal.h (modified) (6 diffs)
-
libcwiid/event.c (deleted)
-
libcwiid/interface.c (added)
-
libcwiid/process.c (added)
-
libcwiid/queue.c (deleted)
-
libcwiid/queue.h (deleted)
-
libcwiid/rw.c (deleted)
-
libcwiid/state.c (added)
-
libcwiid/thread.c (added)
-
libcwiid/util.c (modified) (9 diffs)
-
wmdemo/wmdemo.c (modified) (10 diffs)
-
wmgui/main.c (modified) (10 diffs)
-
wminput/main.c (modified) (14 diffs)
-
wminput/plugins/acc/acc.c (modified) (2 diffs)
-
wminput/plugins/ir_ptr/ir_ptr.c (modified) (11 diffs)
-
wminput/plugins/nunchuk_acc/nunchuk_acc.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ChangeLog
raeed7f7 re1e47e1 1 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 2 libcwiid 3 * rewrite (API overhaul) 4 5 wmdemo 6 * updated for API overhaul 7 8 wmgui 9 * updated for API overhaul 10 11 wminput 12 * updated for API overhaul 13 1 14 2007-04-15 <work.eric@gmail.com> 2 15 wminput -
NEWS
r03a856f re1e47e1 1 0.5.03 2 - Bugfixes, lswm utility, disconnect messages, wminput infinite wait 3 1 4 0.5.02 2 5 - Bugfixes, configure --disable-ldconfig -
libcwiid/Makefile.in
r805477a re1e47e1 6 6 MAJOR_VER = 0 7 7 MINOR_VER = 1 8 SOURCES = connect.c command.c event.c rw.c bluetooth.c util.c queue.c 8 SOURCES = bluetooth.c command.c connect.c interface.c process.c state.c \ 9 thread.c util.c 9 10 LDLIBS += -lbluetooth -lpthread -lrt 10 11 LIB_INST_DIR = @libdir@ -
libcwiid/bluetooth.c
r914629d re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith (cwiid@abstrakraft.org> 19 * * revised error messages 20 * 18 21 * 2007-04-12 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * streamlined wiimote filter … … 81 84 if ((dev_count = hci_inquiry(dev_id, timeout, max_inquiry, NULL, 82 85 &dev_list, IREQ_CACHE_FLUSH)) == -1) { 83 cwiid_err(NULL, " Error on bluetooth device inquiry");86 cwiid_err(NULL, "Bluetooth device inquiry error"); 84 87 err = 1; 85 88 goto CODA; … … 93 96 /* Open connection to Bluetooth Interface */ 94 97 if ((sock = hci_open_dev(dev_id)) == -1) { 95 cwiid_err(NULL, " Error opening Bluetooth interface");98 cwiid_err(NULL, "Bluetooth interface open error"); 96 99 err = 1; 97 100 goto CODA; … … 103 106 } 104 107 if ((*bdinfo = malloc(max_bdinfo * sizeof **bdinfo)) == NULL) { 105 cwiid_err(NULL, " Error mallocing bdinfo array");108 cwiid_err(NULL, "Memory allocation error (bdinfo array)"); 106 109 err = 1; 107 110 goto CODA; … … 122 125 if (hci_remote_name(sock, &dev_list[i].bdaddr, BT_NAME_LEN, 123 126 (*bdinfo)[bdinfo_count].name, 10000)) { 124 cwiid_err(NULL, " Error reading Bluetooth device name");127 cwiid_err(NULL, "Bluetooth name read error"); 125 128 err = 1; 126 129 goto CODA; … … 148 151 if ((*bdinfo = realloc(*bdinfo, bdinfo_count * sizeof **bdinfo)) 149 152 == NULL) { 150 cwiid_err(NULL, " Error reallocing bdinfo array");153 cwiid_err(NULL, "Memory reallocation error (bdinfo array)"); 151 154 err = 1; 152 155 goto CODA; -
libcwiid/command.c
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * rewrite for API overhaul 20 * * added rw and beep functions from rw.c 21 * 18 22 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 23 * * renamed wiimote to libcwiid, renamed structures accordingly 24 * 25 * 2007-04-04 L. Donnie Smith <cwiid@abstrakraft.org> 26 * * updated cwiid_read and cwiid_write to trigger and detect rw_error 20 27 * 21 28 * 2007-03-14 L. Donnie Smith <cwiid@abstrakraft.org> 22 29 * * audited error checking (coda and error handler sections) 23 30 * * updated comments 31 * * cwiid_read - changed to obey decode flag only for register read 24 32 * 25 33 * 2007-03-06 L. Donnie Smith <cwiid@abstrakraft.org> … … 32 40 33 41 #include <stdint.h> 42 #include <time.h> 43 #include <pthread.h> 34 44 #include <unistd.h> 35 45 #include "cwiid_internal.h" 36 46 37 /* IR Sensitivity Block */38 unsigned char ir_block1[] = CLIFF_IR_BLOCK_1;39 unsigned char ir_block2[] = CLIFF_IR_BLOCK_2;40 41 struct write_seq ir_enable10_seq[] = {42 {WRITE_SEQ_RPT, RPT_IR_ENABLE1, (const void *)"\x04", 1, 0},43 {WRITE_SEQ_RPT, RPT_IR_ENABLE2, (const void *)"\x04", 1, 0},44 {WRITE_SEQ_MEM, 0xB00030, (const void *)"\x08", 1, CWIID_RW_REG},45 {WRITE_SEQ_MEM, 0xB00000, ir_block1, sizeof(ir_block1)-1, CWIID_RW_REG},46 {WRITE_SEQ_MEM, 0xB0001A, ir_block2, sizeof(ir_block2)-1, CWIID_RW_REG},47 {WRITE_SEQ_MEM, 0xB00033, (const void *)"\x01", 1, CWIID_RW_REG}48 };49 50 struct write_seq ir_enable12_seq[] = {51 {WRITE_SEQ_RPT, RPT_IR_ENABLE1, (const void *)"\x04", 1, 0},52 {WRITE_SEQ_RPT, RPT_IR_ENABLE2, (const void *)"\x04", 1, 0},53 {WRITE_SEQ_MEM, 0xB00030, (const void *)"\x08", 1, CWIID_RW_REG},54 {WRITE_SEQ_MEM, 0xB00000, ir_block1, sizeof(ir_block1)-1, CWIID_RW_REG},55 {WRITE_SEQ_MEM, 0xB0001A, ir_block2, sizeof(ir_block2)-1, CWIID_RW_REG},56 {WRITE_SEQ_MEM, 0xB00033, (const void *)"\x03", 1, CWIID_RW_REG}57 };58 59 struct write_seq ir_disable_seq[] = {60 {WRITE_SEQ_RPT, RPT_IR_ENABLE1, (const void *)"\x00", 1, 0},61 {WRITE_SEQ_RPT, RPT_IR_ENABLE2, (const void *)"\x00", 1, 0}62 };63 64 47 #define CMD_BUF_LEN 21 65 48 int cwiid_command(struct wiimote *wiimote, enum cwiid_command command, 66 uint8_t flags) {49 int flags) { 67 50 int ret = 0; 68 51 unsigned char buf[CMD_BUF_LEN]; 69 52 53 /* TODO: assumption: char assignments are atomic, no mutex lock needed */ 70 54 switch (command) { 71 55 case CWIID_CMD_STATUS: 72 56 buf[0] = 0; 73 57 if (send_report(wiimote, 0, RPT_STATUS_REQ, 1, buf)) { 74 cwiid_err(wiimote, " Error requesting status");58 cwiid_err(wiimote, "Status request error"); 75 59 ret = -1; 76 60 } 77 61 break; 78 62 case CWIID_CMD_LED: 79 wiimote->led_rumble_state = ((flags & 0x0F)<<4) | 80 (wiimote->led_rumble_state & 0x01); 81 buf[0]=wiimote->led_rumble_state; 63 wiimote->state.led = flags & 0x0F; 64 buf[0] = wiimote->state.led<<4 | wiimote->state.rumble; 82 65 if (send_report(wiimote, SEND_RPT_NO_RUMBLE, RPT_LED_RUMBLE, 1, buf)) { 83 cwiid_err(wiimote, " Error setting LEDs");66 cwiid_err(wiimote, "Report send error (led)"); 84 67 ret = -1; 85 68 } 86 69 break; 87 70 case CWIID_CMD_RUMBLE: 88 wiimote->led_rumble_state = (wiimote->led_rumble_state & 0xFE) | 89 (flags ? 1 : 0); 90 buf[0]=wiimote->led_rumble_state; 71 wiimote->state.rumble = flags ? 1 : 0; 72 buf[0] = wiimote->state.led<<4 | wiimote->state.rumble; 91 73 if (send_report(wiimote, SEND_RPT_NO_RUMBLE, RPT_LED_RUMBLE, 1, buf)) { 92 cwiid_err(wiimote, " Error setting rumble");74 cwiid_err(wiimote, "Report send error (rumble)"); 93 75 ret = -1; 94 76 } … … 98 80 break; 99 81 default: 100 cwiid_err(wiimote, "Unknown command");101 82 ret = -1; 102 83 break; … … 106 87 } 107 88 108 #define RPT_MODE_BUF_LEN 2 109 int update_rpt_mode(struct wiimote *wiimote, int8_t flags) 89 #define RPT_READ_REQ_LEN 6 90 int cwiid_read(struct wiimote *wiimote, uint8_t flags, uint32_t offset, 91 uint16_t len, void *data) 110 92 { 111 unsigned char buf[RPT_MODE_BUF_LEN]; 112 uint8_t rpt_mode; 113 struct write_seq *ir_enable_seq; 114 int seq_len; 93 unsigned char buf[RPT_READ_REQ_LEN]; 94 struct rw_mesg mesg; 95 unsigned char *cursor; 115 96 int ret = 0; 116 117 /* Lock wiimote access */ 118 if (pthread_mutex_lock(&wiimote->wiimote_mutex)) { 119 cwiid_err(wiimote, "Error locking wiimote_mutex"); 97 int i; 98 99 /* Compose read request packet */ 100 buf[0]=flags & (CWIID_RW_EEPROM | CWIID_RW_REG); 101 buf[1]=(unsigned char)((offset>>16) & 0xFF); 102 buf[2]=(unsigned char)((offset>>8) & 0xFF); 103 buf[3]=(unsigned char)(offset & 0xFF); 104 buf[4]=(unsigned char)((len>>8) & 0xFF); 105 buf[5]=(unsigned char)(len & 0xFF); 106 107 /* Lock wiimote rw access */ 108 if (pthread_mutex_lock(&wiimote->rw_mutex)) { 109 cwiid_err(wiimote, "Mutex lock error (rw_mutex)"); 110 return -1; 111 } 112 113 /* Setup read info */ 114 wiimote->rw_status = RW_READ; 115 116 /* TODO: Document: user is responsible for ensuring that read/write 117 * operations are not in flight while disconnecting. Nothing serious, 118 * just accesses to freed memory */ 119 /* Send read request packet */ 120 if (send_report(wiimote, 0, RPT_READ_REQ, RPT_READ_REQ_LEN, buf)) { 121 cwiid_err(wiimote, "Report send error (read)"); 120 122 ret = -1; 121 123 goto CODA; 122 124 } 123 125 124 /* Use -1 to update the reporting mode without changing flags */ 125 if (flags == -1) { 126 flags = wiimote->rpt_mode_flags; 127 } 128 129 /* Pick a report mode based on report flags */ 130 if ((flags & CWIID_RPT_EXT) && 131 ((wiimote->extension == CWIID_EXT_NUNCHUK) || 132 (wiimote->extension == CWIID_EXT_CLASSIC))) { 133 if ((flags & CWIID_RPT_IR) && 134 (flags & CWIID_RPT_ACC)) { 135 rpt_mode = RPT_BTN_ACC_IR10_EXT6; 136 ir_enable_seq = ir_enable10_seq; 137 seq_len = SEQ_LEN(ir_enable10_seq); 138 } 139 else if (flags & CWIID_RPT_IR) { 140 rpt_mode = RPT_BTN_IR10_EXT9; 141 ir_enable_seq = ir_enable10_seq; 142 seq_len = SEQ_LEN(ir_enable10_seq); 143 } 144 else if (flags & CWIID_RPT_ACC) { 145 rpt_mode = RPT_BTN_ACC_EXT16; 146 } 147 else if (flags & CWIID_RPT_BTN) { 148 rpt_mode = RPT_BTN_EXT8; 149 } 150 else { 151 rpt_mode = RPT_EXT21; 152 } 153 } 154 else { 155 if (flags & CWIID_RPT_IR) { 156 rpt_mode = RPT_BTN_ACC_IR12; 157 ir_enable_seq = ir_enable12_seq; 158 seq_len = SEQ_LEN(ir_enable12_seq); 159 } 160 else if (flags & CWIID_RPT_ACC) { 161 rpt_mode = RPT_BTN_ACC; 162 } 163 else { 164 rpt_mode = RPT_BTN; 165 } 166 } 167 168 /* Enable IR */ 169 /* TODO: only do this when necessary (record old IR mode) */ 170 if ((flags & CWIID_RPT_IR)) { 171 if (exec_write_seq(wiimote, seq_len, ir_enable_seq)) { 172 cwiid_err(wiimote, "Error on IR enable"); 173 ret = -1; 174 goto CODA; 175 } 176 } 177 /* Disable IR */ 178 else if ((wiimote->rpt_mode_flags & CWIID_RPT_IR) & 179 !(flags & CWIID_RPT_IR)) { 180 if (exec_write_seq(wiimote, SEQ_LEN(ir_disable_seq), 181 ir_disable_seq)) { 182 cwiid_err(wiimote, "Error on IR enable"); 183 ret = -1; 184 goto CODA; 185 } 186 } 187 188 /* Send SET_REPORT */ 189 buf[0]=0; 190 buf[1]=rpt_mode; 191 if (send_report(wiimote, 0, RPT_RPT_MODE, RPT_MODE_BUF_LEN, buf)) { 192 cwiid_err(wiimote, "Error setting report state"); 193 ret = -1; 194 goto CODA; 195 } 196 197 wiimote->rpt_mode_flags = flags; 126 /* TODO:Better sanity checks (offset) */ 127 /* Read packets */ 128 for (cursor = data; cursor - (unsigned char *)data < len; 129 cursor += mesg.len) { 130 if (full_read(wiimote->rw_pipe[0], &mesg, sizeof mesg)) { 131 cwiid_err(wiimote, "Pipe read error (rw pipe)"); 132 ret = -1; 133 goto CODA; 134 } 135 136 if (mesg.type == RW_CANCEL) { 137 ret = -1; 138 goto CODA; 139 } 140 else if (mesg.type != RW_READ) { 141 cwiid_err(wiimote, "Unexpected write message"); 142 ret = -1; 143 goto CODA; 144 } 145 146 if (mesg.error) { 147 cwiid_err(wiimote, "Wiimote read error"); 148 ret = -1; 149 goto CODA; 150 } 151 152 memcpy(cursor, &mesg.data, mesg.len); 153 } 198 154 199 155 CODA: 200 /* Unlock cwiid_mutex */ 201 if (pthread_mutex_unlock(&wiimote->wiimote_mutex)) { 202 cwiid_err(wiimote, "Error unlocking wiimote_mutex: deadlock warning"); 156 /* Clear rw_status */ 157 wiimote->rw_status = RW_IDLE; 158 159 /* Unlock rw_mutex */ 160 if (pthread_mutex_unlock(&wiimote->rw_mutex)) { 161 cwiid_err(wiimote, "Mutex unlock error (rw_mutex) - deadlock warning"); 162 } 163 164 /* Decode (only for register reads) */ 165 if ((ret == 0) && (flags & CWIID_RW_DECODE) && (flags & CWIID_RW_REG)) { 166 for (i=0; i < len; i++) { 167 ((unsigned char *)data)[i] = DECODE(((unsigned char *)data)[i]); 168 } 203 169 } 204 170 … … 206 172 } 207 173 174 #define RPT_WRITE_LEN 21 175 int cwiid_write(struct wiimote *wiimote, uint8_t flags, uint32_t offset, 176 uint16_t len, const void *data) 177 { 178 unsigned char buf[RPT_WRITE_LEN]; 179 uint16_t sent=0; 180 struct rw_mesg mesg; 181 int ret = 0; 182 183 /* Compose write packet header */ 184 buf[0]=flags; 185 186 /* Lock wiimote rw access */ 187 if (pthread_mutex_lock(&wiimote->rw_mutex)) { 188 cwiid_err(wiimote, "Mutex lock error (rw mutex)"); 189 return -1; 190 } 191 192 /* Send packets */ 193 wiimote->rw_status = RW_WRITE; 194 while (sent<len) { 195 /* Compose write packet */ 196 buf[1]=(unsigned char)(((offset+sent)>>16) & 0xFF); 197 buf[2]=(unsigned char)(((offset+sent)>>8) & 0xFF); 198 buf[3]=(unsigned char)((offset+sent) & 0xFF); 199 if (len-sent >= 0x10) { 200 buf[4]=(unsigned char)0x10; 201 } 202 else { 203 buf[4]=(unsigned char)(len-sent); 204 } 205 memcpy(buf+5, data+sent, buf[4]); 206 207 if (send_report(wiimote, 0, RPT_WRITE, RPT_WRITE_LEN, buf)) { 208 cwiid_err(wiimote, "Report send error (write)"); 209 ret = -1; 210 goto CODA; 211 } 212 213 /* Read packets from pipe */ 214 if (read(wiimote->rw_pipe[0], &mesg, sizeof mesg) != sizeof mesg) { 215 cwiid_err(wiimote, "Pipe read error (rw pipe)"); 216 ret = -1; 217 goto CODA; 218 } 219 220 if (mesg.type == RW_CANCEL) { 221 ret = -1; 222 goto CODA; 223 } 224 else if (mesg.type != RW_WRITE) { 225 cwiid_err(wiimote, "Unexpected read message"); 226 ret = -1; 227 goto CODA; 228 } 229 230 if (mesg.error) { 231 cwiid_err(wiimote, "Wiimote write error"); 232 ret = -1; 233 goto CODA; 234 }; 235 236 sent+=buf[4]; 237 } 238 239 CODA: 240 /* Clear rw_status */ 241 wiimote->rw_status = RW_IDLE; 242 243 /* Unlock rw_mutex */ 244 if (pthread_mutex_unlock(&wiimote->rw_mutex)) { 245 cwiid_err(wiimote, "Mutex unlock error (rw_mutex) - deadlock warning"); 246 } 247 248 return ret; 249 } 250 251 252 struct write_seq speaker_enable_seq[] = { 253 {WRITE_SEQ_RPT, RPT_SPEAKER_ENABLE, (const void *)"\x04", 1, 0}, 254 {WRITE_SEQ_RPT, RPT_SPEAKER_MUTE, (const void *)"\x04", 1, 0}, 255 {WRITE_SEQ_MEM, 0xA20009, (const void *)"\x01", 1, CWIID_RW_REG}, 256 {WRITE_SEQ_MEM, 0xA20001, (const void *)"\x08", 1, CWIID_RW_REG}, 257 {WRITE_SEQ_MEM, 0xA20001, (const void *)"\x00\x00\x00\x0C\x40\x00\x00", 258 7, CWIID_RW_REG}, 259 {WRITE_SEQ_MEM, 0xA20008, (const void *)"\x01", 1, CWIID_RW_REG}, 260 {WRITE_SEQ_RPT, RPT_SPEAKER_MUTE, (const void *)"\x00", 1, 0} 261 }; 262 263 struct write_seq speaker_disable_seq[] = { 264 {WRITE_SEQ_RPT, RPT_SPEAKER_MUTE, (const void *)"\x04", 1, 0}, 265 {WRITE_SEQ_RPT, RPT_SPEAKER_ENABLE, (const void *)"\x00", 1, 0} 266 }; 267 268 #define SOUND_BUF_LEN 21 269 int cwiid_beep(cwiid_wiimote_t *wiimote) 270 { 271 /* unsigned char buf[SOUND_BUF_LEN] = { 0xA0, 0xCC, 0x33, 0xCC, 0x33, 272 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 273 0xCC, 0x33, 0xCC, 0x33}; */ 274 unsigned char buf[SOUND_BUF_LEN] = { 0xA0, 0xC3, 0xC3, 0xC3, 0xC3, 275 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 276 0xC3, 0xC3, 0xC3, 0xC3}; 277 int i; 278 int ret = 0; 279 pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER; 280 pthread_cond_t timer_cond = PTHREAD_COND_INITIALIZER; 281 struct timespec t; 282 283 if (exec_write_seq(wiimote, SEQ_LEN(speaker_enable_seq), 284 speaker_enable_seq)) { 285 cwiid_err(wiimote, "Speaker enable error"); 286 ret = -1; 287 } 288 289 pthread_mutex_lock(&timer_mutex); 290 291 for (i=0; i<100; i++) { 292 clock_gettime(CLOCK_REALTIME, &t); 293 t.tv_nsec += 10204081; 294 /* t.tv_nsec += 7000000; */ 295 if (send_report(wiimote, 0, RPT_SPEAKER_DATA, SOUND_BUF_LEN, buf)) { 296 printf("%d\n", i); 297 cwiid_err(wiimote, "Report send error (speaker data)"); 298 ret = -1; 299 break; 300 } 301 /* TODO: I should be shot for this, but hey, it works. 302 * longterm - find a better wait */ 303 pthread_cond_timedwait(&timer_cond, &timer_mutex, &t); 304 } 305 306 pthread_mutex_unlock(&timer_mutex); 307 308 if (exec_write_seq(wiimote, SEQ_LEN(speaker_disable_seq), 309 speaker_disable_seq)) { 310 cwiid_err(wiimote, "Speaker disable error"); 311 ret = -1; 312 } 313 314 return ret; 315 } -
libcwiid/connect.c
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * rewrite for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * renamed wiimote to libcwiid, renamed structures accordingly … … 38 41 */ 39 42 40 #include <pthread.h>41 43 #include <stdlib.h> 42 44 #include <string.h> 45 #include <fcntl.h> 46 #include <pthread.h> 43 47 #include <sys/types.h> 44 48 #include <sys/socket.h> … … 47 51 #include <bluetooth/l2cap.h> 48 52 #include "cwiid_internal.h" 49 #include "queue.h"50 53 51 54 pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; 52 55 static int wiimote_id = 0; 53 56 54 cwiid_wiimote_t *cwiid_connect(bdaddr_t *bdaddr, 55 cwiid_mesg_callback_t *mesg_callback, int *id) 57 cwiid_wiimote_t *cwiid_connect(bdaddr_t *bdaddr, int flags) 56 58 { 57 59 struct wiimote *wiimote = NULL; 58 struct sockaddr_l2 ctl_remote_addr, int_remote_addr; 60 struct sockaddr_l2 remote_addr; 61 char mesg_pipe_init = 0, status_pipe_init = 0, error_pipe_init = 0, 62 rw_pipe_init = 0, state_mutex_init = 0, rw_mutex_init = 0, 63 rpt_mutex_init = 0, router_thread_init = 0, status_thread_init = 0; 64 void *pthread_ret; 59 65 60 66 /* Allocate wiimote */ 61 67 if ((wiimote = malloc(sizeof *wiimote)) == NULL) { 62 cwiid_err(NULL, "Error allocating cwiid_wiimote"); 63 goto ERR_HND; 64 } 65 66 /* Set wiimote members for proper error detection */ 67 wiimote->ctl_socket = -1; 68 wiimote->int_socket = -1; 69 wiimote->dispatch_queue = NULL; 68 cwiid_err(NULL, "Memory allocation error (cwiid_wiimote_t)"); 69 goto ERR_HND; 70 } 71 72 /* set flags */ 73 wiimote->flags = flags; 74 75 /* For error detection */ 76 wiimote->ctl_socket = wiimote->int_socket = -1; 70 77 71 78 /* Global Lock, Store and Increment wiimote_id */ 72 79 if (pthread_mutex_lock(&global_mutex)) { 73 cwiid_err(NULL, " Error locking global lock");80 cwiid_err(NULL, "Mutex lock error (global mutex)"); 74 81 goto ERR_HND; 75 82 } 76 83 wiimote->id = wiimote_id++; 77 84 if (pthread_mutex_unlock(&global_mutex)) { 78 cwiid_err(wiimote, "Error unlocking global lock"); 79 goto ERR_HND; 80 } 81 /* Return the id in a pointer, if desired */ 82 if (id) { 83 *id = wiimote->id; 84 } 85 86 /* Store mesg callback */ 87 wiimote->mesg_callback = mesg_callback; 85 cwiid_err(wiimote, "Mutex unlock error (global mutex) - " 86 "deadlock warning"); 87 goto ERR_HND; 88 } 88 89 89 90 /* If BDADDR_ANY is given, find available wiimote */ … … 94 95 } 95 96 96 /* Clear address structs, fill address family, address, and ports */ 97 memset(&ctl_remote_addr, 0, sizeof(ctl_remote_addr)); 98 ctl_remote_addr.l2_family = AF_BLUETOOTH; 99 ctl_remote_addr.l2_bdaddr = *bdaddr; 100 ctl_remote_addr.l2_psm = htobs(CTL_PSM); 101 102 memset(&int_remote_addr, 0, sizeof(int_remote_addr)); 103 int_remote_addr.l2_family = AF_BLUETOOTH; 104 int_remote_addr.l2_bdaddr = *bdaddr; 105 int_remote_addr.l2_psm = htobs(INT_PSM); 106 107 /* Get Bluetooth Sockets */ 97 /* Connect to Wiimote */ 98 /* Control Channel */ 99 memset(&remote_addr, 0, sizeof remote_addr); 100 remote_addr.l2_family = AF_BLUETOOTH; 101 remote_addr.l2_bdaddr = *bdaddr; 102 remote_addr.l2_psm = htobs(CTL_PSM); 108 103 if ((wiimote->ctl_socket = 109 104 socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) { 110 cwiid_err(wiimote, "Error opening control socket"); 111 goto ERR_HND; 112 } 105 cwiid_err(wiimote, "Socket creation error (control socket)"); 106 goto ERR_HND; 107 } 108 if (connect(wiimote->ctl_socket, (struct sockaddr *)&remote_addr, 109 sizeof remote_addr)) { 110 cwiid_err(wiimote, "Socket connect error (control channel)"); 111 goto ERR_HND; 112 } 113 114 /* Interrupt Channel */ 115 remote_addr.l2_psm = htobs(INT_PSM); 113 116 if ((wiimote->int_socket = 114 117 socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1) { 115 cwiid_err(wiimote, "Error opening interrupt socket"); 116 goto ERR_HND; 117 } 118 119 /* Connect to Wiimote */ 120 if (connect(wiimote->ctl_socket, (struct sockaddr *)&ctl_remote_addr, 121 sizeof(ctl_remote_addr))) { 122 cwiid_err(wiimote, "Error opening control channel"); 123 goto ERR_HND; 124 } 125 if (connect(wiimote->int_socket, (struct sockaddr *)&int_remote_addr, 126 sizeof(int_remote_addr))) { 127 cwiid_err(wiimote, "Error opening interrupt channel"); 128 goto ERR_HND; 129 } 130 131 /* Create Dispatch Queue */ 132 if ((wiimote->dispatch_queue = queue_new()) == NULL) { 133 cwiid_err(wiimote, "Error creating dispatch queue"); 134 goto ERR_HND; 135 } 136 137 /* TODO: backout logic (pthread_*_destroy) */ 138 /* Mutex and cond init */ 139 if (pthread_mutex_init(&wiimote->wiimote_mutex, NULL) || 140 pthread_mutex_init(&wiimote->rw_mutex, NULL) || 141 pthread_cond_init(&wiimote->rw_cond, NULL) || 142 pthread_mutex_init(&wiimote->rw_cond_mutex, NULL)) { 143 cwiid_err(wiimote, "Error initializing synchronization variables"); 144 goto ERR_HND; 145 } 146 147 /* Set rw_status before interrupt thread */ 148 wiimote->rw_status = RW_NONE; 149 wiimote->rw_error = 0; 118 cwiid_err(wiimote, "Socket creation error (interrupt socket)"); 119 goto ERR_HND; 120 } 121 if (connect(wiimote->int_socket, (struct sockaddr *)&remote_addr, 122 sizeof remote_addr)) { 123 cwiid_err(wiimote, "Socket connect error (interrupt channel)"); 124 goto ERR_HND; 125 } 126 127 /* Create pipes */ 128 if (pipe(wiimote->mesg_pipe)) { 129 cwiid_err(wiimote, "Pipe creation error (mesg pipe)"); 130 goto ERR_HND; 131 } 132 mesg_pipe_init = 1; 133 if (pipe(wiimote->status_pipe)) { 134 cwiid_err(wiimote, "Pipe creation error (status pipe)"); 135 goto ERR_HND; 136 } 137 status_pipe_init = 1; 138 if (pipe(wiimote->error_pipe)) { 139 cwiid_err(wiimote, "Pipe creation error (error pipe)"); 140 goto ERR_HND; 141 } 142 error_pipe_init = 1; 143 if (pipe(wiimote->rw_pipe)) { 144 cwiid_err(wiimote, "Pipe creation error (rw pipe)"); 145 goto ERR_HND; 146 } 147 rw_pipe_init = 1; 148 149 /* Setup blocking */ 150 if (fcntl(wiimote->mesg_pipe[1], F_SETFL, O_NONBLOCK)) { 151 cwiid_err(wiimote, "File control error (mesg write pipe)"); 152 goto ERR_HND; 153 } 154 if (wiimote->flags & CWIID_FLAG_NONBLOCK) { 155 if (fcntl(wiimote->mesg_pipe[0], F_SETFL, O_NONBLOCK)) { 156 cwiid_err(wiimote, "File control error (mesg read pipe)"); 157 goto ERR_HND; 158 } 159 } 160 161 /* Init mutexes */ 162 if (pthread_mutex_init(&wiimote->state_mutex, NULL)) { 163 cwiid_err(wiimote, "Mutex initialization error (state mutex)"); 164 goto ERR_HND; 165 } 166 state_mutex_init = 1; 167 if (pthread_mutex_init(&wiimote->rw_mutex, NULL)) { 168 cwiid_err(wiimote, "Mutex initialization error (rw mutex)"); 169 goto ERR_HND; 170 } 171 rw_mutex_init = 1; 172 if (pthread_mutex_init(&wiimote->rpt_mutex, NULL)) { 173 cwiid_err(wiimote, "Mutex initialization error (rpt mutex)"); 174 goto ERR_HND; 175 } 176 rpt_mutex_init = 1; 177 178 /* Set rw_status before starting router thread */ 179 wiimote->rw_status = RW_IDLE; 150 180 151 181 /* Launch interrupt channel listener and dispatch threads */ 152 if (pthread_create(&wiimote-> int_listen_thread, NULL,153 (void *(*)(void *))& int_listen, wiimote)) {154 cwiid_err(wiimote, " Error creating interrupt channel listener thread");155 goto ERR_HND; 156 } 157 if (pthread_create(&wiimote->dispatch_thread, NULL,158 (void *(*)(void *))&dispatch, wiimote)) {159 pthread_cancel(wiimote->int_listen_thread);160 pthread_join(wiimote->int_listen_thread, NULL);161 cwiid_err(wiimote, "Error creating dispatch thread");162 goto ERR_HND;163 }182 if (pthread_create(&wiimote->router_thread, NULL, 183 (void *(*)(void *))&router_thread, wiimote)) { 184 cwiid_err(wiimote, "Thread creation error (router thread)"); 185 goto ERR_HND; 186 } 187 router_thread_init = 1; 188 if (pthread_create(&wiimote->status_thread, NULL, 189 (void *(*)(void *))&status_thread, wiimote)) { 190 cwiid_err(wiimote, "Thread creation error (status thread)"); 191 goto ERR_HND; 192 } 193 status_thread_init = 1; 164 194 165 195 /* Success! Update state */ 166 wiimote->buttons = 0; 167 wiimote->rpt_mode_flags = 0; 168 wiimote->extension = CWIID_EXT_NONE; 169 wiimote->led_rumble_state = 0; 196 memset(&wiimote->state, 0, sizeof wiimote->state); 197 wiimote->mesg_callback = NULL; 170 198 cwiid_command(wiimote, CWIID_CMD_LED, 0); 171 199 cwiid_command(wiimote, CWIID_CMD_STATUS, 0); … … 175 203 ERR_HND: 176 204 if (wiimote) { 177 if (wiimote->dispatch_queue) { 178 queue_free(wiimote->dispatch_queue, 179 (free_func_t *)free_mesg_array); 180 } 205 /* Close threads */ 206 if (router_thread_init) { 207 pthread_cancel(wiimote->router_thread); 208 if (pthread_join(wiimote->router_thread, &pthread_ret)) { 209 cwiid_err(wiimote, "Thread join error (router thread)"); 210 } 211 else if (!((pthread_ret == PTHREAD_CANCELED) && 212 (pthread_ret == NULL))) { 213 cwiid_err(wiimote, "Bad return value from router thread"); 214 } 215 } 216 217 if (status_thread_init) { 218 pthread_cancel(wiimote->status_thread); 219 if (pthread_join(wiimote->status_thread, &pthread_ret)) { 220 cwiid_err(wiimote, "Thread join error (status thread)"); 221 } 222 else if (!((pthread_ret == PTHREAD_CANCELED) && (pthread_ret == NULL))) { 223 cwiid_err(wiimote, "Bad return value from status thread"); 224 } 225 } 226 227 /* Close Sockets */ 181 228 if (wiimote->int_socket != -1) { 182 229 if (close(wiimote->int_socket)) { 183 cwiid_err(wiimote, " Error closing interrupt channel");230 cwiid_err(wiimote, "Socket close error (interrupt channel)"); 184 231 } 185 232 } 186 233 if (wiimote->ctl_socket != -1) { 187 234 if (close(wiimote->ctl_socket)) { 188 cwiid_err(wiimote, "Error closing control channel"); 235 cwiid_err(wiimote, "Socket close error (control channel)"); 236 } 237 } 238 /* Close Pipes */ 239 if (mesg_pipe_init) { 240 if (close(wiimote->mesg_pipe[0]) || close(wiimote->mesg_pipe[1])) { 241 cwiid_err(wiimote, "Pipe close error (mesg pipe)"); 242 } 243 } 244 if (status_pipe_init) { 245 if (close(wiimote->status_pipe[0]) || 246 close(wiimote->status_pipe[1])) { 247 cwiid_err(wiimote, "Pipe close error (status pipe)"); 248 } 249 } 250 if (error_pipe_init) { 251 if (close(wiimote->error_pipe[0]) || 252 close(wiimote->error_pipe[1])) { 253 cwiid_err(wiimote, "Pipe close error (error pipe)"); 254 } 255 } 256 if (rw_pipe_init) { 257 if (close(wiimote->rw_pipe[0]) || close(wiimote->rw_pipe[1])) { 258 cwiid_err(wiimote, "Pipe close error (rw pipe)"); 259 } 260 } 261 /* Destroy Mutexes */ 262 if (state_mutex_init) { 263 if (pthread_mutex_destroy(&wiimote->state_mutex)) { 264 cwiid_err(wiimote, "Mutex destroy error (state mutex)"); 265 } 266 } 267 if (rw_mutex_init) { 268 if (pthread_mutex_destroy(&wiimote->rw_mutex)) { 269 cwiid_err(wiimote, "Mutex destroy error (rw mutex)"); 270 } 271 } 272 if (rpt_mutex_init) { 273 if (pthread_mutex_destroy(&wiimote->rpt_mutex)) { 274 cwiid_err(wiimote, "Mutex destroy error (rpt mutex)"); 189 275 } 190 276 } … … 198 284 void *pthread_ret; 199 285 200 /* Cancel and join int_thread */ 201 if (pthread_cancel(wiimote->int_listen_thread)) { 202 /* int could exit on it's own, so we don't care */ 203 /* cwiid_err(wiimote, "Error canceling int_listen_thread"); */ 204 } 205 else { 206 if (pthread_join(wiimote->int_listen_thread, &pthread_ret)) { 207 cwiid_err(wiimote, "Error joining int_listen_thread"); 208 } 209 else if (pthread_ret != PTHREAD_CANCELED) { 210 cwiid_err(wiimote, "Invalid return value from int_listen_thread"); 211 } 212 } 213 214 /* Cancel any RW operations in progress */ 215 wiimote->rw_error = 1; 216 if (pthread_mutex_lock(&wiimote->rw_cond_mutex)) { 217 cwiid_err(wiimote, "Error locking rw_cond_mutex: deadlock warning"); 218 } 219 else { 220 if (pthread_cond_signal(&wiimote->rw_cond)) { 221 cwiid_err(wiimote, "Error signaling rw_cond: deadlock warning"); 222 } 223 if (pthread_mutex_unlock( 224 &wiimote->rw_cond_mutex)) { 225 cwiid_err(wiimote, "Error unlocking rw_cond_mutex"); 226 } 227 } 228 229 /* Cancel and detach dispatch_thread */ 230 /* We detach to decouple dispatch (which runs the callback) from callback 231 * code - specifically, a race condition exists for gtk apps */ 232 if (pthread_cancel(wiimote->dispatch_thread)) { 233 cwiid_err(wiimote, "Error canceling dispatch_thread"); 234 } 235 if (pthread_detach(wiimote->dispatch_thread)) { 236 cwiid_err(wiimote, "Error detaching dispatch_thread"); 286 /* Cancel and join router_thread and status_thread */ 287 if (pthread_cancel(wiimote->router_thread)) { 288 /* if thread quit abnormally, would have printed it's own error */ 289 } 290 if (pthread_join(wiimote->router_thread, &pthread_ret)) { 291 cwiid_err(wiimote, "Thread join error (router thread)"); 292 } 293 else if (!((pthread_ret == PTHREAD_CANCELED) || (pthread_ret == NULL))) { 294 cwiid_err(wiimote, "Bad return value from router thread"); 295 } 296 297 if (pthread_cancel(wiimote->status_thread)) { 298 /* if thread quit abnormally, would have printed it's own error */ 299 } 300 if (pthread_join(wiimote->status_thread, &pthread_ret)) { 301 cwiid_err(wiimote, "Thread join error (status thread)"); 302 } 303 else if (!((pthread_ret == PTHREAD_CANCELED) || (pthread_ret == NULL))) { 304 cwiid_err(wiimote, "Bad return value from status thread"); 305 } 306 307 if (wiimote->mesg_callback) { 308 if (cancel_mesg_callback(wiimote)) { 309 /* prints it's own errors */ 310 } 311 } 312 313 if (cancel_rw(wiimote)) { 314 /* prints it's own errors */ 237 315 } 238 316 239 317 /* Close sockets */ 240 318 if (close(wiimote->int_socket)) { 241 cwiid_err(wiimote, " Error closing interrupt channel");319 cwiid_err(wiimote, "Socket close error (interrupt channel)"); 242 320 } 243 321 if (close(wiimote->ctl_socket)) { 244 cwiid_err(wiimote, "Error closing control channel"); 245 } 246 247 /* TODO: We have no way of telling if all in flight rw operations 248 * have exited yet, so for now, user must verify that all have returned 249 * before calling disconnect */ 250 251 /* Destroy sync variables */ 252 if (pthread_mutex_destroy(&wiimote->wiimote_mutex)) { 253 cwiid_err(wiimote, "Error destroying cwiid_mutex"); 322 cwiid_err(wiimote, "Socket close error (control channel)"); 323 } 324 /* Close Pipes */ 325 if (close(wiimote->mesg_pipe[0]) || close(wiimote->mesg_pipe[1])) { 326 cwiid_err(wiimote, "Pipe close error (mesg pipe)"); 327 } 328 if (close(wiimote->status_pipe[0]) || close(wiimote->status_pipe[1])) { 329 cwiid_err(wiimote, "Pipe close error (status pipe)"); 330 } 331 if (close(wiimote->error_pipe[0]) || close(wiimote->error_pipe[1])) { 332 cwiid_err(wiimote, "Pipe close error (error pipe)"); 333 } 334 if (close(wiimote->rw_pipe[0]) || close(wiimote->rw_pipe[1])) { 335 cwiid_err(wiimote, "Pipe close error (rw pipe)"); 336 } 337 /* Destroy mutexes */ 338 if (pthread_mutex_destroy(&wiimote->state_mutex)) { 339 cwiid_err(wiimote, "Mutex destroy error (state)"); 254 340 } 255 341 if (pthread_mutex_destroy(&wiimote->rw_mutex)) { 256 cwiid_err(wiimote, "Error destroying rw_mutex"); 257 } 258 if (pthread_cond_destroy(&wiimote->rw_cond)) { 259 cwiid_err(wiimote, "Error destroying rw_cond"); 260 } 261 if (pthread_mutex_destroy(&wiimote->rw_cond_mutex)) { 262 cwiid_err(wiimote, "Error destroying rw_cond_mutex"); 342 cwiid_err(wiimote, "Mutex destroy error (rw)"); 343 } 344 if (pthread_mutex_destroy(&wiimote->rpt_mutex)) { 345 cwiid_err(wiimote, "Mutex destroy error (rpt)"); 263 346 } 264 347 … … 267 350 return 0; 268 351 } 269 -
libcwiid/cwiid.h
r422e116 re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * rewrite for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * renamed wiimote to libcwiid, renamed structures accordingly … … 43 46 #define CWIID_H 44 47 48 #include <stdarg.h> 45 49 #include <stdint.h> 46 50 #include <bluetooth/bluetooth.h> /* bdaddr_t */ 51 52 /* Flags */ 53 #define CWIID_FLAG_MESG_IFC 0x01 54 #define CWIID_FLAG_CONTINUOUS 0x02 55 #define CWIID_FLAG_REPEAT_BTN 0x04 56 #define CWIID_FLAG_NONBLOCK 0x08 47 57 48 58 /* Report Mode Flags */ … … 56 66 57 67 /* LED flags */ 58 #define CWIID_LED1_ON 0x0159 #define CWIID_LED2_ON 0x0260 #define CWIID_LED3_ON 0x0461 #define CWIID_LED4_ON 0x0868 #define CWIID_LED1_ON 0x01 69 #define CWIID_LED2_ON 0x02 70 #define CWIID_LED3_ON 0x04 71 #define CWIID_LED4_ON 0x08 62 72 63 73 /* Button flags */ … … 71 81 #define CWIID_BTN_RIGHT 0x0200 72 82 #define CWIID_BTN_DOWN 0x0400 73 #define CWIID_BTN_UP 0x080083 #define CWIID_BTN_UP 0x0800 74 84 #define CWIID_BTN_PLUS 0x1000 75 85 … … 77 87 #define CWIID_NUNCHUK_BTN_C 0x02 78 88 79 #define CWIID_CLASSIC_BTN_UP 0x000189 #define CWIID_CLASSIC_BTN_UP 0x0001 80 90 #define CWIID_CLASSIC_BTN_LEFT 0x0002 81 #define CWIID_CLASSIC_BTN_ZR 0x000491 #define CWIID_CLASSIC_BTN_ZR 0x0004 82 92 #define CWIID_CLASSIC_BTN_X 0x0008 83 93 #define CWIID_CLASSIC_BTN_A 0x0010 84 94 #define CWIID_CLASSIC_BTN_Y 0x0020 85 95 #define CWIID_CLASSIC_BTN_B 0x0040 86 #define CWIID_CLASSIC_BTN_ZL 0x008096 #define CWIID_CLASSIC_BTN_ZL 0x0080 87 97 #define CWIID_CLASSIC_BTN_R 0x0200 88 98 #define CWIID_CLASSIC_BTN_PLUS 0x0400 … … 95 105 /* Data Read/Write flags */ 96 106 #define CWIID_RW_EEPROM 0x00 97 #define CWIID_RW_REG 0x04107 #define CWIID_RW_REG 0x04 98 108 #define CWIID_RW_DECODE 0x01 99 109 100 110 /* Maximum Data Read Length */ 101 111 #define CWIID_MAX_READ_LEN 0xFFFF 112 113 /* Array Index Defs */ 114 #define CWIID_X 0 115 #define CWIID_Y 1 116 #define CWIID_Z 2 117 118 /* Acc Defs */ 119 #define CWIID_ACC_MAX 0xFF 102 120 103 121 /* IR Defs */ … … 120 138 #define CWIID_MAX_MESG_COUNT 5 121 139 140 /* Enumerations */ 122 141 enum cwiid_command { 123 142 CWIID_CMD_STATUS, … … 146 165 147 166 enum cwiid_error { 167 CWIID_ERROR_NONE, 148 168 CWIID_ERROR_DISCONNECT, 149 CWIID_ERROR_COMM, 150 }; 151 169 CWIID_ERROR_COMM 170 }; 171 172 /* Message Structs */ 152 173 struct cwiid_status_mesg { 153 174 enum cwiid_mesg_type type; 154 175 uint8_t battery; 155 enum cwiid_ext_type ext ension;176 enum cwiid_ext_type ext_type; 156 177 }; 157 178 … … 163 184 struct cwiid_acc_mesg { 164 185 enum cwiid_mesg_type type; 165 uint8_t x; 166 uint8_t y; 167 uint8_t z; 186 uint8_t acc[3]; 168 187 }; 169 188 170 189 struct cwiid_ir_src { 171 int valid; 172 uint16_t x; 173 uint16_t y; 190 char valid; 191 uint16_t pos[2]; 174 192 int8_t size; 175 193 }; … … 182 200 struct cwiid_nunchuk_mesg { 183 201 enum cwiid_mesg_type type; 184 uint8_t stick_x; 185 uint8_t stick_y; 186 uint8_t acc_x; 187 uint8_t acc_y; 188 uint8_t acc_z; 202 uint8_t stick[2]; 203 uint8_t acc[3]; 189 204 uint8_t buttons; 190 205 }; … … 192 207 struct cwiid_classic_mesg { 193 208 enum cwiid_mesg_type type; 194 uint8_t l_stick_x; 195 uint8_t l_stick_y; 196 uint8_t r_stick_x; 197 uint8_t r_stick_y; 209 uint8_t l_stick[2]; 210 uint8_t r_stick[2]; 198 211 uint8_t l; 199 212 uint8_t r; … … 217 230 }; 218 231 232 /* State Structs */ 233 struct nunchuk_state { 234 uint8_t stick[2]; 235 uint8_t acc[3]; 236 uint8_t buttons; 237 }; 238 239 struct classic_state { 240 uint8_t l_stick[2]; 241 uint8_t r_stick[2]; 242 uint8_t l; 243 uint8_t r; 244 uint16_t buttons; 245 }; 246 247 union ext_state { 248 struct nunchuk_state nunchuk; 249 struct classic_state classic; 250 }; 251 252 struct cwiid_state { 253 uint8_t rpt_mode; 254 uint8_t led; 255 uint8_t rumble; 256 uint8_t battery; 257 uint16_t buttons; 258 uint8_t acc[3]; 259 struct cwiid_ir_src ir_src[CWIID_IR_SRC_COUNT]; 260 enum cwiid_ext_type ext_type; 261 union ext_state ext; 262 enum cwiid_error error; 263 }; 264 265 /* Typedefs */ 219 266 typedef struct wiimote cwiid_wiimote_t; 220 267 221 typedef void cwiid_mesg_callback_t(int, int, union cwiid_mesg* []); 222 typedef void cwiid_err_t(int, const char *, ...); 223 224 /* getinfo flags */ 268 typedef void cwiid_mesg_callback_t(cwiid_wiimote_t *, int, 269 union cwiid_mesg []); 270 typedef void cwiid_err_t(cwiid_wiimote_t *, const char *, va_list ap); 271 272 /* get_bdinfo */ 225 273 #define BT_NO_WIIMOTE_FILTER 0x01 226 274 #define BT_NAME_LEN 32 … … 236 284 #endif 237 285 286 /* Error reporting (library wide) */ 238 287 int cwiid_set_err(cwiid_err_t *err); 239 cwiid_wiimote_t *cwiid_connect(bdaddr_t *bdaddr, 240 cwiid_mesg_callback_t *mesg_callback, 241 int *id);288 289 /* Connection */ 290 cwiid_wiimote_t *cwiid_connect(bdaddr_t *bdaddr, int flags); 242 291 int cwiid_disconnect(cwiid_wiimote_t *wiimote); 292 293 int cwiid_get_id(cwiid_wiimote_t *wiimote); 294 int cwiid_set_data(cwiid_wiimote_t *wiimote, const void *data); 295 const void *cwiid_get_data(cwiid_wiimote_t *wiimote); 296 int cwiid_enable(cwiid_wiimote_t *wiimote, int flags); 297 int cwiid_disable(cwiid_wiimote_t *wiimote, int flags); 298 299 /* Interfaces */ 300 int cwiid_set_mesg_callback(cwiid_wiimote_t *wiimote, 301 cwiid_mesg_callback_t *callback); 302 int cwiid_get_mesg(cwiid_wiimote_t *wiimote, int *mesg_count, 303 union cwiid_mesg *mesg[]); 304 int cwiid_get_state(cwiid_wiimote_t *wiimote, struct cwiid_state *state); 305 306 /* Operations */ 243 307 int cwiid_command(cwiid_wiimote_t *wiimote, enum cwiid_command command, 244 uint8_t flags);308 int flags); 245 309 int cwiid_read(cwiid_wiimote_t *wiimote, uint8_t flags, uint32_t offset, 246 310 uint16_t len, void *data); … … 248 312 uint16_t len, const void *data); 249 313 /* int cwiid_beep(cwiid_wiimote_t *wiimote); */ 314 315 /* HCI functions */ 250 316 int cwiid_get_bdinfo_array(int dev_id, unsigned int timeout, int max_bdinfo, 251 317 struct cwiid_bdinfo **bdinfo, uint8_t flags); … … 257 323 258 324 #endif 259 -
libcwiid/cwiid_internal.h
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * rewrite for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * renamed wiimote to libcwiid, renamed structures accordingly … … 38 41 #include <stdint.h> 39 42 #include <pthread.h> 43 #include <sys/types.h> /* ssize_t */ 40 44 #include "cwiid.h" 41 45 … … 117 121 #define DECODE(a) (((a ^ 0x17)+0x17)&0xFF) 118 122 123 /* Write Sequences */ 119 124 enum write_seq_type { 120 125 WRITE_SEQ_RPT, … … 123 128 124 129 /* send_report flags */ 125 #define SEND_RPT_NO_RUMBLE 0x01130 #define SEND_RPT_NO_RUMBLE 0x01 126 131 127 132 struct write_seq { … … 135 140 #define SEQ_LEN(seq) (sizeof(seq)/sizeof(struct write_seq)) 136 141 142 /* Message arrays */ 143 struct mesg_array { 144 uint8_t count; 145 union cwiid_mesg array[CWIID_MAX_MESG_COUNT]; 146 }; 147 148 /* RW State/Mesg */ 137 149 enum rw_status { 138 RW_NONE, 139 RW_PENDING, 140 RW_READY 141 }; 142 143 struct mesg_array { 144 int count; 145 union cwiid_mesg *mesg[CWIID_MAX_MESG_COUNT]; 146 }; 147 150 RW_IDLE, 151 RW_READ, 152 RW_WRITE, 153 RW_CANCEL 154 }; 155 156 struct rw_mesg { 157 enum rw_status type; 158 uint8_t error; 159 uint32_t offset; 160 uint8_t len; 161 char data[16]; 162 }; 163 164 /* Wiimote struct */ 148 165 struct wiimote { 149 int id;166 int flags; 150 167 int ctl_socket; 151 168 int int_socket; 152 uint8_t led_rumble_state; 153 uint8_t rpt_mode_flags; 154 uint16_t buttons; 155 enum cwiid_ext_type extension; 169 pthread_t router_thread; 170 pthread_t status_thread; 171 pthread_t mesg_callback_thread; 172 int mesg_pipe[2]; 173 int status_pipe[2]; 174 int error_pipe[2]; 175 int rw_pipe[2]; 176 struct cwiid_state state; 177 enum rw_status rw_status; 156 178 cwiid_mesg_callback_t *mesg_callback; 157 pthread_t int_listen_thread; 158 pthread_t dispatch_thread; 159 struct queue *dispatch_queue; 160 pthread_mutex_t wiimote_mutex; 179 pthread_mutex_t state_mutex; 161 180 pthread_mutex_t rw_mutex; 162 pthread_cond_t rw_cond; 163 pthread_mutex_t rw_cond_mutex; 164 enum rw_status rw_status; 165 char rw_error; 166 void *read_buf; 167 uint16_t read_len; 168 uint16_t read_received; 181 pthread_mutex_t rpt_mutex; 182 int id; 183 const void *data; 169 184 }; 170 185 171 186 /* prototypes */ 172 void *int_listen(struct wiimote *wiimote); 173 void *dispatch(struct wiimote *wiimote); 174 175 int update_rpt_mode(struct wiimote *wiimote, int8_t flags); 176 187 /* thread.c */ 188 void *router_thread(struct wiimote *wiimote); 189 void *status_thread(struct wiimote *wiimote); 190 void *mesg_callback_thread(struct wiimote *wiimote); 191 192 /* util.c */ 177 193 void cwiid_err(struct wiimote *wiimote, const char *str, ...); 178 194 int verify_handshake(struct wiimote *wiimote); … … 181 197 int exec_write_seq(struct wiimote *wiimote, unsigned int len, 182 198 struct write_seq *seq); 183 void free_mesg_array(struct mesg_array *array); 199 int full_read(int fd, void *buf, size_t len); 200 int write_mesg_array(struct wiimote *wiimote, struct mesg_array *ma); 201 int read_mesg_array(int fd, struct mesg_array *ma); 202 int cancel_rw(struct wiimote *wiimote); 203 int cancel_mesg_callback(struct wiimote *wiimote); 204 205 /* process.c */ 206 int process_error(struct wiimote *, ssize_t); 207 int process_status(struct wiimote *, const unsigned char *, 208 struct mesg_array *); 209 int process_btn(struct wiimote *, const unsigned char *, struct mesg_array *); 210 int process_acc(struct wiimote *, const unsigned char *, struct mesg_array *); 211 int process_ir10(struct wiimote *, const unsigned char *, struct mesg_array *); 212 int process_ir12(struct wiimote *, const unsigned char *, struct mesg_array *); 213 int process_ext(struct wiimote *, unsigned char *, unsigned char, 214 struct mesg_array *); 215 int process_read(struct wiimote *, unsigned char *); 216 int process_write(struct wiimote *, unsigned char *); 217 218 /* state.c */ 219 int update_state(struct wiimote *wiimote, struct mesg_array *ma); 220 int update_rpt_mode(struct wiimote *wiimote, int8_t rpt_mode); 184 221 185 222 #endif 186 -
libcwiid/util.c
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * rewrite for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * renamed wiimote to libcwiid, renamed structures accordingly … … 42 45 */ 43 46 47 #include <errno.h> 44 48 #include <stdarg.h> 45 49 #include <stdint.h> … … 47 51 #include <stdlib.h> 48 52 #include <string.h> 53 #include <fcntl.h> 49 54 #include <unistd.h> 50 55 #include "cwiid_internal.h" … … 63 68 } 64 69 65 static void cwiid_err_default(int id, const char *str, ...) 66 { 67 va_list ap; 68 69 va_start(ap, str); 70 static void cwiid_err_default(struct wiimote *wiimote, const char *str, 71 va_list ap) 72 { 70 73 vfprintf(stderr, str, ap); 71 74 fprintf(stderr, "\n"); 72 va_end(ap);73 75 } 74 76 … … 80 82 va_start(ap, str); 81 83 if (wiimote) { 82 (*cwiid_err_func)(wiimote ->id, str, ap);84 (*cwiid_err_func)(wiimote, str, ap); 83 85 } 84 86 else { 85 (*cwiid_err_func)( -1, str, ap);87 (*cwiid_err_func)(NULL, str, ap); 86 88 } 87 89 va_end(ap); … … 93 95 unsigned char handshake; 94 96 if (read(wiimote->ctl_socket, &handshake, 1) != 1) { 95 cwiid_err(wiimote, " Error on read handshake");97 cwiid_err(wiimote, "Socket read error (handshake)"); 96 98 return -1; 97 99 } … … 122 124 memcpy(buf+2, data, len); 123 125 if (!(flags & SEND_RPT_NO_RUMBLE)) { 124 buf[2] |= wiimote-> led_rumble_state & 0x01;126 buf[2] |= wiimote->state.rumble; 125 127 } 126 128 … … 150 152 case WRITE_SEQ_MEM: 151 153 if (cwiid_write(wiimote, seq[i].flags, seq[i].report_offset, 152 seq[i].len, seq[i].data)) {154 seq[i].len, seq[i].data)) { 153 155 return -1; 154 156 } … … 160 162 } 161 163 162 void free_mesg_array(struct mesg_array *array) 163 { 164 int i; 165 166 for (i=0; i < array->count; i++) { 167 free(array->mesg[i]); 168 } 169 free(array); 170 } 171 164 int full_read(int fd, void *buf, size_t len) 165 { 166 ssize_t last_len = 0; 167 168 do { 169 if ((last_len = read(fd, buf, len)) == -1) { 170 return -1; 171 } 172 len -= last_len; 173 buf += last_len; 174 } while (len > 0); 175 176 return 0; 177 } 178 179 int write_mesg_array(struct wiimote *wiimote, struct mesg_array *ma) 180 { 181 ssize_t len = (void *)&ma->array[ma->count] - (void *)ma; 182 int ret = 0; 183 184 /* This must remain a single write operation to ensure atomicity, 185 * which is required to avoid mutexes and cancellation issues */ 186 if (write(wiimote->mesg_pipe[1], ma, len) != len) { 187 if (errno == EAGAIN) { 188 cwiid_err(wiimote, "Mesg pipe overflow"); 189 if (fcntl(wiimote->mesg_pipe[1], F_SETFL, 0)) { 190 cwiid_err(wiimote, "File control error (mesg pipe)"); 191 ret = -1; 192 } 193 else { 194 if (write(wiimote->mesg_pipe[1], ma, len) != len) { 195 cwiid_err(wiimote, "Pipe write error (mesg pipe)"); 196 ret = -1; 197 } 198 if (fcntl(wiimote->mesg_pipe[1], F_SETFL, O_NONBLOCK)) { 199 cwiid_err(wiimote, "File control error (mesg pipe"); 200 } 201 } 202 } 203 else { 204 cwiid_err(wiimote, "Pipe write error (mesg pipe)"); 205 ret = -1; 206 } 207 } 208 209 return ret; 210 } 211 212 int read_mesg_array(int fd, struct mesg_array *ma) 213 { 214 ssize_t len; 215 216 /* there may be padding after ma->count */ 217 len = (void *)&ma->array[0] - (void *)ma; 218 if (full_read(fd, ma, len)) { 219 return -1; 220 } 221 222 len = ma->count * sizeof ma->array[0]; 223 if (full_read(fd, &ma->array[0], len)) { 224 return -1; 225 } 226 227 return 0; 228 } 229 230 int cancel_rw(struct wiimote *wiimote) 231 { 232 struct rw_mesg rw_mesg; 233 234 rw_mesg.type = RW_CANCEL; 235 236 if (write(wiimote->rw_pipe[1], &rw_mesg, sizeof rw_mesg) != 237 sizeof rw_mesg) { 238 cwiid_err(wiimote, "Pipe write error (rw)"); 239 return -1; 240 } 241 242 return 0; 243 } 244 245 int cancel_mesg_callback(struct wiimote *wiimote) 246 { 247 int ret = 0; 248 249 if (pthread_cancel(wiimote->mesg_callback_thread)) { 250 cwiid_err(wiimote, "Thread cancel error (callback thread)"); 251 ret = -1; 252 } 253 254 if (pthread_detach(wiimote->mesg_callback_thread)) { 255 cwiid_err(wiimote, "Thread detach error (callback thread)"); 256 ret = -1; 257 } 258 259 return ret; 260 } -
wmdemo/wmdemo.c
rb800125 re1e47e1 22 22 : ((bf) | (b)) 23 23 24 #define MENU \ 25 "1: toggle LED 1\n" \ 26 "2: toggle LED 2\n" \ 27 "3: toggle LED 3\n" \ 28 "4: toggle LED 4\n" \ 29 "5: toggle rumble\n" \ 30 "a: toggle accelerometer reporting\n" \ 31 "b: toggle button reporting\n" \ 32 "e: toggle extension reporting\n" \ 33 "i: toggle ir reporting\n" \ 34 "m: toggle messages\n" \ 35 "p: print this menu\n" \ 36 "r: request status message ((t) enables callback output)\n" \ 37 "s: print current state\n" \ 38 "t: toggle status reporting\n" \ 39 "x: exit\n" 40 24 41 void set_led_state(cwiid_wiimote_t *wiimote, unsigned char led_state); 25 42 void set_rpt_mode(cwiid_wiimote_t *wiimote, unsigned char rpt_mode); 43 void print_state(struct cwiid_state *state); 26 44 27 45 cwiid_err_t err; 28 void err(int id, const char *s, ...) 29 { 30 va_list ap; 31 32 va_start(ap, s); 33 printf("%d:", id); 46 void err(cwiid_wiimote_t *wiimote, const char *s, va_list ap) 47 { 48 if (wiimote) printf("%d:", cwiid_get_id(wiimote)); 49 else printf("-1:"); 34 50 vprintf(s, ap); 35 51 printf("\n"); 36 va_end(ap); 37 } 38 39 /* wiimote handle */ 40 cwiid_wiimote_t *wiimote; 52 } 41 53 42 54 int main(int argc, char *argv[]) 43 55 { 56 cwiid_wiimote_t *wiimote; /* wiimote handle */ 57 struct cwiid_state state; /* wiimote state */ 44 58 bdaddr_t bdaddr; /* bluetooth device address */ 45 int cwiid_id; /* wiimote id: useful for handling multiple wiimotes 46 with a single callback */ 59 unsigned char mesg = 0; 47 60 unsigned char led_state = 0; 48 61 unsigned char rpt_mode = 0; 49 62 unsigned char rumble = 0; 50 63 int exit = 0; 51 char *str_addr;52 int c;53 64 54 65 cwiid_set_err(err); 55 66 56 57 67 /* Connect to address given on command-line, if present */ 58 68 if (argc > 1) { … … 65 75 /* Connect to the wiimote */ 66 76 printf("Put Wiimote in discoverable mode now (press 1+2)...\n"); 67 if (!(wiimote = cwiid_connect(&bdaddr, cwiid_callback, &cwiid_id))) {77 if (!(wiimote = cwiid_connect(&bdaddr, 0))) { 68 78 fprintf(stderr, "Unable to connect to wiimote\n"); 69 79 return -1; 70 80 } 81 if (cwiid_set_mesg_callback(wiimote, cwiid_callback)) { 82 fprintf(stderr, "Unable to set message callback\n"); 83 } 84 85 printf("Note: To demonstrate the new API interfaces, wmdemo no longer " 86 "enables messages by default.\n" 87 "Output can be gathered through the new state-based interface (s), " 88 "or by enabling the messages interface (c).\n"); 71 89 72 90 /* Menu */ 73 printf("1: toggle LED 1\n" 74 "2: toggle LED 2\n" 75 "3: toggle LED 3\n" 76 "4: toggle LED 4\n" 77 "a: toggle accelerometer output\n" 78 "b: toggle button output\n" 79 "e: toggle extension output\n" 80 "i: toggle ir output\n" 81 "r: toggle rumble\n" 82 "s: request status message (use t to turn on output)\n" 83 "t: toggle status output\n" 84 "x: exit\n"); 91 printf("%s", MENU); 85 92 86 93 while (!exit) { … … 102 109 set_led_state(wiimote, led_state); 103 110 break; 111 case '5': 112 toggle_bit(rumble, 1); 113 if (cwiid_command(wiimote, CWIID_CMD_RUMBLE, rumble)) { 114 fprintf(stderr, "Error setting rumble\n"); 115 } 116 break; 104 117 case 'a': 105 118 toggle_bit(rpt_mode, CWIID_RPT_ACC); … … 123 136 set_rpt_mode(wiimote, rpt_mode); 124 137 break; 138 case 'm': 139 if (!mesg) { 140 if (cwiid_enable(wiimote, CWIID_FLAG_MESG_IFC)) { 141 fprintf(stderr, "Error enabling messages\n"); 142 } 143 else { 144 mesg = 1; 145 } 146 } 147 else { 148 if (cwiid_disable(wiimote, CWIID_FLAG_MESG_IFC)) { 149 fprintf(stderr, "Error disabling message\n"); 150 } 151 else { 152 mesg = 0; 153 } 154 } 155 break; 156 case 'p': 157 printf("%s", MENU); 158 break; 125 159 case 'r': 126 toggle_bit(rumble, 1);127 if (cwiid_command(wiimote, CWIID_CMD_RUMBLE, rumble)) {128 fprintf(stderr, "Error setting rumble\n");129 }130 break;131 case 's':132 160 if (cwiid_command(wiimote, CWIID_CMD_STATUS, 0)) { 133 161 fprintf(stderr, "Error requesting status message\n"); 134 162 } 163 break; 164 case 's': 165 if (cwiid_get_state(wiimote, &state)) { 166 fprintf(stderr, "Error getting state\n"); 167 } 168 print_state(&state); 135 169 break; 136 170 case 't': … … 167 201 if (cwiid_command(wiimote, CWIID_CMD_RPT_MODE, rpt_mode)) { 168 202 fprintf(stderr, "Error setting report mode\n"); 203 } 204 } 205 206 void print_state(struct cwiid_state *state) 207 { 208 int i; 209 int valid_source = 0; 210 211 printf("Report Mode:"); 212 if (state->rpt_mode & CWIID_RPT_STATUS) printf(" STATUS"); 213 if (state->rpt_mode & CWIID_RPT_BTN) printf(" BTN"); 214 if (state->rpt_mode & CWIID_RPT_ACC) printf(" ACC"); 215 if (state->rpt_mode & CWIID_RPT_IR) printf(" IR"); 216 if (state->rpt_mode & CWIID_RPT_NUNCHUK) printf(" NUNCHUK"); 217 if (state->rpt_mode & CWIID_RPT_CLASSIC) printf(" CLASSIC"); 218 printf("\n"); 219 220 printf("Active LEDs:"); 221 if (state->led & CWIID_LED1_ON) printf(" 1"); 222 if (state->led & CWIID_LED2_ON) printf(" 2"); 223 if (state->led & CWIID_LED3_ON) printf(" 3"); 224 if (state->led & CWIID_LED4_ON) printf(" 4"); 225 printf("\n"); 226 227 printf("Rumble: %s\n", state->rumble ? "On" : "Off"); 228 229 printf("Battery: %d%%\n", 230 (int)(100.0 * state->battery / CWIID_BATTERY_MAX)); 231 232 printf("Buttons: %X\n", state->buttons); 233 234 printf("Acc: x=%d y=%d z=%d\n", state->acc[CWIID_X], state->acc[CWIID_Y], 235 state->acc[CWIID_Z]); 236 237 printf("IR: "); 238 for (i = 0; i < CWIID_IR_SRC_COUNT; i++) { 239 if (state->ir_src[i].valid) { 240 valid_source = 1; 241 printf("(%d,%d) ", state->ir_src[i].pos[CWIID_X], 242 state->ir_src[i].pos[CWIID_Y]); 243 } 244 } 245 if (!valid_source) { 246 printf("no sources detected"); 247 } 248 printf("\n"); 249 250 switch (state->ext_type) { 251 case CWIID_EXT_NONE: 252 printf("No extension\n"); 253 break; 254 case CWIID_EXT_UNKNOWN: 255 printf("Unknown extension attached\n"); 256 break; 257 case CWIID_EXT_NUNCHUK: 258 printf("Nunchuk: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d " 259 "acc.z=%d\n", state->ext.nunchuk.buttons, 260 state->ext.nunchuk.stick[CWIID_X], 261 state->ext.nunchuk.stick[CWIID_Y], 262 state->ext.nunchuk.acc[CWIID_X], 263 state->ext.nunchuk.acc[CWIID_Y], 264 state->ext.nunchuk.acc[CWIID_Z]); 265 break; 266 case CWIID_EXT_CLASSIC: 267 printf("Classic: btns=%.4X l_stick=(%d,%d) r_stick=(%d,%d) " 268 "l=%d r=%d\n", state->ext.classic.buttons, 269 state->ext.classic.l_stick[CWIID_X], 270 state->ext.classic.l_stick[CWIID_Y], 271 state->ext.classic.r_stick[CWIID_X], 272 state->ext.classic.r_stick[CWIID_Y], 273 state->ext.classic.l, state->ext.classic.r); 274 break; 169 275 } 170 276 } … … 180 286 * The id is to distinguish between multiple wiimotes using the same callback. 181 287 * */ 182 void cwiid_callback(int id, int mesg_count, union cwiid_mesg *mesg[]) 288 void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, 289 union cwiid_mesg mesg[]) 183 290 { 184 291 int i, j; … … 187 294 for (i=0; i < mesg_count; i++) 188 295 { 189 switch (mesg[i] ->type) {296 switch (mesg[i].type) { 190 297 case CWIID_MESG_STATUS: 191 298 printf("Status Report: battery=%d extension=", 192 mesg[i] ->status_mesg.battery);193 switch (mesg[i] ->status_mesg.extension) {299 mesg[i].status_mesg.battery); 300 switch (mesg[i].status_mesg.ext_type) { 194 301 case CWIID_EXT_NONE: 195 302 printf("none"); … … 208 315 break; 209 316 case CWIID_MESG_BTN: 210 printf("Button Report: %.4X\n", mesg[i] ->btn_mesg.buttons);317 printf("Button Report: %.4X\n", mesg[i].btn_mesg.buttons); 211 318 break; 212 319 case CWIID_MESG_ACC: 213 printf("Acc Report: x=%d, y=%d, z=%d\n", mesg[i]->acc_mesg.x, 214 mesg[i]->acc_mesg.y, 215 mesg[i]->acc_mesg.z); 320 printf("Acc Report: x=%d, y=%d, z=%d\n", 321 mesg[i].acc_mesg.acc[CWIID_X], 322 mesg[i].acc_mesg.acc[CWIID_Y], 323 mesg[i].acc_mesg.acc[CWIID_Z]); 216 324 break; 217 325 case CWIID_MESG_IR: … … 219 327 valid_source = 0; 220 328 for (j = 0; j < CWIID_IR_SRC_COUNT; j++) { 221 if (mesg[i] ->ir_mesg.src[j].valid) {329 if (mesg[i].ir_mesg.src[j].valid) { 222 330 valid_source = 1; 223 printf("(%d,%d) ", mesg[i] ->ir_mesg.src[j].x,224 mesg[i] ->ir_mesg.src[j].y);331 printf("(%d,%d) ", mesg[i].ir_mesg.src[j].pos[CWIID_X], 332 mesg[i].ir_mesg.src[j].pos[CWIID_Y]); 225 333 } 226 334 } … … 232 340 case CWIID_MESG_NUNCHUK: 233 341 printf("Nunchuk Report: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d " 234 "acc.z=%d\n", mesg[i]->nunchuk_mesg.buttons, 235 mesg[i]->nunchuk_mesg.stick_x, 236 mesg[i]->nunchuk_mesg.stick_y, mesg[i]->nunchuk_mesg.acc_x, 237 mesg[i]->nunchuk_mesg.acc_y, mesg[i]->nunchuk_mesg.acc_z); 342 "acc.z=%d\n", mesg[i].nunchuk_mesg.buttons, 343 mesg[i].nunchuk_mesg.stick[CWIID_X], 344 mesg[i].nunchuk_mesg.stick[CWIID_Y], 345 mesg[i].nunchuk_mesg.acc[CWIID_X], 346 mesg[i].nunchuk_mesg.acc[CWIID_Y], 347 mesg[i].nunchuk_mesg.acc[CWIID_Z]); 238 348 break; 239 349 case CWIID_MESG_CLASSIC: 240 350 printf("Classic Report: btns=%.4X l_stick=(%d,%d) r_stick=(%d,%d) " 241 "l=%d r=%d\n", mesg[i] ->classic_mesg.buttons,242 mesg[i] ->classic_mesg.l_stick_x,243 mesg[i] ->classic_mesg.l_stick_y,244 mesg[i] ->classic_mesg.r_stick_x,245 mesg[i] ->classic_mesg.r_stick_y,246 mesg[i] ->classic_mesg.l, mesg[i]->classic_mesg.r);351 "l=%d r=%d\n", mesg[i].classic_mesg.buttons, 352 mesg[i].classic_mesg.l_stick[CWIID_X], 353 mesg[i].classic_mesg.l_stick[CWIID_Y], 354 mesg[i].classic_mesg.r_stick[CWIID_X], 355 mesg[i].classic_mesg.r_stick[CWIID_Y], 356 mesg[i].classic_mesg.l, mesg[i].classic_mesg.r); 247 357 break; 248 358 case CWIID_MESG_ERROR: -
wmgui/main.c
r422e116 re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * updated for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * updated for libcwiid rename … … 577 580 578 581 for (i=0; i < CWIID_IR_SRC_COUNT; i++) { 579 ir_data.src[i]. x= -1;580 ir_data.src[i]. y= -1;582 ir_data.src[i].pos[CWIID_X] = -1; 583 ir_data.src[i].pos[CWIID_Y] = -1; 581 584 ir_data.src[i].size = -1; 582 585 } … … 636 639 "Put Wiimote in discoverable mode (press 1+2) and press OK", 637 640 GTK_WINDOW(winMain)); 638 if ((wiimote = cwiid_connect(&bdaddr, &cwiid_callback, NULL)) == NULL) {641 if ((wiimote = cwiid_connect(&bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) { 639 642 message(GTK_MESSAGE_ERROR, "Unable to connect", GTK_WINDOW(winMain)); 643 status("No connection"); 644 } 645 else if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) { 646 message(GTK_MESSAGE_ERROR, "Error setting callback", 647 GTK_WINDOW(winMain)); 648 if (cwiid_disconnect(wiimote)) { 649 message(GTK_MESSAGE_ERROR, "Error on disconnect", 650 GTK_WINDOW(winMain)); 651 } 652 wiimote = NULL; 640 653 status("No connection"); 641 654 } … … 783 796 drawIR->style->fg_gc[GTK_WIDGET_STATE(drawIR)], 784 797 TRUE, 785 ir_data.src[i].x*width/CWIID_IR_X_MAX, 786 height - ir_data.src[i].y*height/CWIID_IR_Y_MAX, 798 ir_data.src[i].pos[CWIID_X] * width / CWIID_IR_X_MAX, 799 height - ir_data.src[i].pos[CWIID_Y] * height / 800 CWIID_IR_Y_MAX, 787 801 size, size, 788 802 0, 64 * 360); … … 1002 1016 1003 1017 #define BATTERY_STR_LEN 14 /* "Battery: 100%" + '\0' */ 1004 void cwiid_callback(int id, int mesg_count, union cwiid_mesg *mesg_array[]) 1018 void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, 1019 union cwiid_mesg mesg_array[]) 1005 1020 { 1006 1021 int i; … … 1012 1027 gdk_threads_enter(); 1013 1028 for (i=0; i < mesg_count; i++) { 1014 switch (mesg_array[i] ->type) {1029 switch (mesg_array[i].type) { 1015 1030 case CWIID_MESG_STATUS: 1016 1031 snprintf(battery, BATTERY_STR_LEN,"Battery:%d%%", 1017 (int) (100.0 * mesg_array[i] ->status_mesg.battery /1032 (int) (100.0 * mesg_array[i].status_mesg.battery / 1018 1033 CWIID_BATTERY_MAX)); 1019 1034 gtk_statusbar_push(GTK_STATUSBAR(statBattery), 0, battery); 1020 switch (mesg_array[i] ->status_mesg.extension) {1035 switch (mesg_array[i].status_mesg.ext_type) { 1021 1036 case CWIID_EXT_NONE: 1022 1037 ext_str = "No extension"; … … 1051 1066 clear_nunchuk_widgets(); 1052 1067 clear_classic_widgets(); 1053 ext_type = mesg_array[i] ->status_mesg.extension;1068 ext_type = mesg_array[i].status_mesg.ext_type; 1054 1069 break; 1055 1070 case CWIID_MESG_BTN: 1056 cwiid_btn(&mesg_array[i] ->btn_mesg);1071 cwiid_btn(&mesg_array[i].btn_mesg); 1057 1072 break; 1058 1073 case CWIID_MESG_ACC: 1059 cwiid_acc(&mesg_array[i] ->acc_mesg);1074 cwiid_acc(&mesg_array[i].acc_mesg); 1060 1075 break; 1061 1076 case CWIID_MESG_IR: 1062 cwiid_ir(&mesg_array[i] ->ir_mesg);1077 cwiid_ir(&mesg_array[i].ir_mesg); 1063 1078 break; 1064 1079 case CWIID_MESG_NUNCHUK: 1065 cwiid_nunchuk(&mesg_array[i] ->nunchuk_mesg);1080 cwiid_nunchuk(&mesg_array[i].nunchuk_mesg); 1066 1081 break; 1067 1082 case CWIID_MESG_CLASSIC: 1068 cwiid_classic(&mesg_array[i] ->classic_mesg);1083 cwiid_classic(&mesg_array[i].classic_mesg); 1069 1084 break; 1070 1085 case CWIID_MESG_ERROR: … … 1113 1128 1114 1129 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkAcc))) { 1115 g_snprintf(str, LBLVAL_LEN, "%X", mesg-> x);1130 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc[CWIID_X]); 1116 1131 gtk_label_set_text(GTK_LABEL(lblAccXVal), str); 1117 1132 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccX), 1118 (double)mesg-> x/0xFF);1119 g_snprintf(str, LBLVAL_LEN, "%X", mesg-> y);1133 (double)mesg->acc[CWIID_X]/0xFF); 1134 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc[CWIID_Y]); 1120 1135 gtk_label_set_text(GTK_LABEL(lblAccYVal), str); 1121 1136 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccY), 1122 (double)mesg-> y/0xFF);1123 g_snprintf(str, LBLVAL_LEN, "%X", mesg-> z);1137 (double)mesg->acc[CWIID_Y]/0xFF); 1138 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc[CWIID_Z]); 1124 1139 gtk_label_set_text(GTK_LABEL(lblAccZVal), str); 1125 1140 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccZ), 1126 (double)mesg-> z/0xFF);1127 1128 a_x = ((double)mesg-> x- acc_zero.x) /1141 (double)mesg->acc[CWIID_Z]/0xFF); 1142 1143 a_x = ((double)mesg->acc[CWIID_X] - acc_zero.x) / 1129 1144 (acc_one.x - acc_zero.x); 1130 a_y = ((double)mesg-> y- acc_zero.y) /1145 a_y = ((double)mesg->acc[CWIID_Y] - acc_zero.y) / 1131 1146 (acc_one.y - acc_zero.y); 1132 a_z = ((double)mesg-> z- acc_zero.z) /1147 a_z = ((double)mesg->acc[CWIID_Z] - acc_zero.z) / 1133 1148 (acc_one.z - acc_zero.z); 1134 1149 a = sqrt(pow(a_x,2)+pow(a_y,2)+pow(a_z,2)); … … 1173 1188 1174 1189 nc_stick.valid = 1; 1175 nc_stick.x = mesg->stick _x;1176 nc_stick.y = mesg->stick _y;1190 nc_stick.x = mesg->stick[CWIID_X]; 1191 nc_stick.y = mesg->stick[CWIID_Y]; 1177 1192 gtk_widget_queue_draw(drawNCStick); 1178 1193 1179 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc _x);1194 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc[CWIID_X]); 1180 1195 gtk_label_set_text(GTK_LABEL(lblNCAccXVal), str); 1181 1196 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccX), 1182 (double)mesg->acc _x/0xFF);1183 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc _y);1197 (double)mesg->acc[CWIID_X]/0xFF); 1198 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc[CWIID_Y]); 1184 1199 gtk_label_set_text(GTK_LABEL(lblNCAccYVal), str); 1185 1200 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccY), 1186 (double)mesg->acc _y/0xFF);1187 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc _z);1201 (double)mesg->acc[CWIID_Y]/0xFF); 1202 g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc[CWIID_Z]); 1188 1203 gtk_label_set_text(GTK_LABEL(lblNCAccZVal), str); 1189 1204 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccZ), 1190 (double)mesg->acc _z/0xFF);1205 (double)mesg->acc[CWIID_Z]/0xFF); 1191 1206 1192 1207 /* TODO: get nunchuk calibration */ 1193 a_x = ((double)mesg->acc _x- nc_acc_zero.x) /1208 a_x = ((double)mesg->acc[CWIID_X] - nc_acc_zero.x) / 1194 1209 (nc_acc_one.x - nc_acc_zero.x); 1195 a_y = ((double)mesg->acc _y- nc_acc_zero.y) /1210 a_y = ((double)mesg->acc[CWIID_Y] - nc_acc_zero.y) / 1196 1211 (nc_acc_one.y - nc_acc_zero.y); 1197 a_z = ((double)mesg->acc _z- nc_acc_zero.z) /1212 a_z = ((double)mesg->acc[CWIID_Z] - nc_acc_zero.z) / 1198 1213 (nc_acc_one.z - nc_acc_zero.z); 1199 1214 a = sqrt(pow(a_x,2)+pow(a_y,2)+pow(a_z,2)); … … 1248 1263 1249 1264 cc_l_stick.valid = 1; 1250 cc_l_stick.x = mesg->l_stick _x;1251 cc_l_stick.y = mesg->l_stick _y;1265 cc_l_stick.x = mesg->l_stick[CWIID_X]; 1266 cc_l_stick.y = mesg->l_stick[CWIID_Y]; 1252 1267 gtk_widget_queue_draw(drawCCLStick); 1253 1268 1254 1269 cc_r_stick.valid = 1; 1255 cc_r_stick.x = mesg->r_stick _x;1256 cc_r_stick.y = mesg->r_stick _y;1270 cc_r_stick.x = mesg->r_stick[CWIID_X]; 1271 cc_r_stick.y = mesg->r_stick[CWIID_Y]; 1257 1272 gtk_widget_queue_draw(drawCCRStick); 1258 1273 -
wminput/main.c
r422e116 re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * update for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * updated for libcwiid rename … … 55 58 void process_nunchuk_mesg(struct cwiid_nunchuk_mesg *mesg); 56 59 void process_classic_mesg(struct cwiid_classic_mesg *mesg); 57 void process_plugin(struct plugin *, int, union cwiid_mesg *[]);60 void process_plugin(struct plugin *, int, union cwiid_mesg []); 58 61 59 62 /* Globals */ … … 159 162 } 160 163 } 161 if ((wiimote = cwiid_connect(&bdaddr, cwiid_callback, NULL)) == NULL) {164 if ((wiimote = cwiid_connect(&bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) { 162 165 wminput_err("unable to connect"); 166 conf_unload(&conf); 167 return -1; 168 } 169 if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) { 170 wminput_err("error setting callback"); 163 171 conf_unload(&conf); 164 172 return -1; … … 258 266 } 259 267 260 void cwiid_callback(int id, int mesg_count, union cwiid_mesg *mesg[]) 268 void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, 269 union cwiid_mesg mesg[]) 261 270 { 262 271 int i; 263 272 264 273 for (i=0; i < mesg_count; i++) { 265 switch (mesg[i] ->type) {274 switch (mesg[i].type) { 266 275 case CWIID_MESG_BTN: 267 process_btn_mesg((struct cwiid_btn_mesg *) mesg[i]);276 process_btn_mesg((struct cwiid_btn_mesg *) &mesg[i]); 268 277 break; 269 278 case CWIID_MESG_NUNCHUK: 270 process_nunchuk_mesg((struct cwiid_nunchuk_mesg *) mesg[i]);279 process_nunchuk_mesg((struct cwiid_nunchuk_mesg *) &mesg[i]); 271 280 break; 272 281 case CWIID_MESG_CLASSIC: 273 process_classic_mesg((struct cwiid_classic_mesg *) mesg[i]);282 process_classic_mesg((struct cwiid_classic_mesg *) &mesg[i]); 274 283 break; 275 284 case CWIID_MESG_ERROR: … … 367 376 /* Nunchuk.Stick.X */ 368 377 if (conf.amap[CONF_NC_AXIS_STICK_X].active) { 369 axis_value = mesg->stick _x;378 axis_value = mesg->stick[CWIID_X]; 370 379 if (conf.amap[CONF_NC_AXIS_STICK_X].flags & CONF_INVERT) { 371 380 axis_value = 0xFF - axis_value; … … 377 386 /* Nunchuk.Stick.Y */ 378 387 if (conf.amap[CONF_NC_AXIS_STICK_Y].active) { 379 axis_value = mesg->stick _y;388 axis_value = mesg->stick[CWIID_Y]; 380 389 if (conf.amap[CONF_NC_AXIS_STICK_Y].flags & CONF_INVERT) { 381 390 axis_value = 0xFF - axis_value; … … 442 451 /* Classic.LStick.X */ 443 452 if (conf.amap[CONF_CC_AXIS_L_STICK_X].active) { 444 axis_value = mesg->l_stick _x;453 axis_value = mesg->l_stick[CWIID_X]; 445 454 if (conf.amap[CONF_CC_AXIS_L_STICK_X].flags & CONF_INVERT) { 446 455 axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value; … … 452 461 /* Classic.LStick.Y */ 453 462 if (conf.amap[CONF_CC_AXIS_L_STICK_Y].active) { 454 axis_value = mesg->l_stick _y;463 axis_value = mesg->l_stick[CWIID_Y]; 455 464 if (conf.amap[CONF_CC_AXIS_L_STICK_Y].flags & CONF_INVERT) { 456 465 axis_value = CWIID_CLASSIC_L_STICK_MAX - axis_value; … … 462 471 /* Classic.RStick.X */ 463 472 if (conf.amap[CONF_CC_AXIS_R_STICK_X].active) { 464 axis_value = mesg->r_stick _x;473 axis_value = mesg->r_stick[CWIID_X]; 465 474 if (conf.amap[CONF_CC_AXIS_R_STICK_X].flags & CONF_INVERT) { 466 475 axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value; … … 472 481 /* Classic.RStick.Y */ 473 482 if (conf.amap[CONF_CC_AXIS_R_STICK_Y].active) { 474 axis_value = mesg->r_stick _y;483 axis_value = mesg->r_stick[CWIID_Y]; 475 484 if (conf.amap[CONF_CC_AXIS_R_STICK_Y].flags & CONF_INVERT) { 476 485 axis_value = CWIID_CLASSIC_R_STICK_MAX - axis_value; … … 502 511 503 512 void process_plugin(struct plugin *plugin, int mesg_count, 504 union cwiid_mesg *mesg[])513 union cwiid_mesg mesg[]) 505 514 { 506 515 union cwiid_mesg *plugin_mesg[CWIID_MAX_MESG_COUNT]; … … 513 522 514 523 for (i=0; i < mesg_count; i++) { 515 switch (mesg[i] ->type) {524 switch (mesg[i].type) { 516 525 case CWIID_MESG_STATUS: 517 526 flag = CWIID_RPT_STATUS; … … 536 545 } 537 546 if (plugin->rpt_mode_flags & flag) { 538 plugin_mesg[plugin_mesg_count++] = mesg[i];547 plugin_mesg[plugin_mesg_count++] = &mesg[i]; 539 548 } 540 549 } … … 574 583 } 575 584 } 576 -
wminput/plugins/acc/acc.c
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * updated for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * updated for libcwiid rename … … 160 163 double roll, pitch; 161 164 162 a_x = (((double)mesg-> x- acc_zero.x) /165 a_x = (((double)mesg->acc[CWIID_X] - acc_zero.x) / 163 166 (acc_one.x - acc_zero.x))*NEW_AMOUNT + a_x*OLD_AMOUNT; 164 a_y = (((double)mesg-> y- acc_zero.y) /167 a_y = (((double)mesg->acc[CWIID_Y] - acc_zero.y) / 165 168 (acc_one.y - acc_zero.y))*NEW_AMOUNT + a_y*OLD_AMOUNT; 166 a_z = (((double)mesg-> z- acc_zero.z) /169 a_z = (((double)mesg->acc[CWIID_Z] - acc_zero.z) / 167 170 (acc_one.z - acc_zero.z))*NEW_AMOUNT + a_z*OLD_AMOUNT; 168 171 -
wminput/plugins/ir_ptr/ir_ptr.c
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * updated for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * updated for libcwiid rename … … 39 42 struct cursor { 40 43 unsigned char valid; 41 uint16_t x; 42 uint16_t y; 44 uint16_t pos[2]; 43 45 }; 44 46 int a_debounce, b_debounce; … … 161 163 else { 162 164 a = ir_mesg->src[a_index]; 163 a. x = CWIID_IR_X_MAX - a.x;165 a.pos[CWIID_X] = CWIID_IR_X_MAX - a.pos[CWIID_X]; 164 166 a_debounce = 0; 165 167 } … … 175 177 else { 176 178 b = ir_mesg->src[b_index]; 177 b. x = CWIID_IR_X_MAX - b.x;179 b.pos[CWIID_X] = CWIID_IR_X_MAX - b.pos[CWIID_X]; 178 180 b_debounce = 0; 179 181 } … … 182 184 if (a.valid && b.valid) { 183 185 c.valid = 1; 184 c.x = (a.x + b.x)/2; 185 c.y = (a.y + b.y)/2; 186 for (i=0; i < 2; i++) { 187 c.pos[i] = (a.pos[i] + b.pos[i])/2; 188 } 186 189 } 187 190 /* if either source is valid, use best guess */ … … 191 194 if (prev_a.valid && prev_c.valid) { 192 195 c.valid = 1; 193 c.x = a.x + (prev_c.x - prev_a.x); 194 c.y = a.y + (prev_c.y - prev_a.y); 196 for (i=0; i < 2; i++) { 197 c.pos[i] = a.pos[i] + (prev_c.pos[i] - prev_a.pos[i]); 198 } 195 199 } 196 200 /* if a is new or we don't have a previous center, … … 198 202 else { 199 203 c.valid = 1; 200 c.x = a.x; 201 c.y = a.y; 204 for (i=0; i < 2; i++) { 205 c.pos[i] = a.pos[i]; 206 } 202 207 } 203 208 } … … 207 212 if (prev_b.valid && prev_c.valid) { 208 213 c.valid = 1; 209 c.x = b.x + (prev_c.x - prev_b.x); 210 c.y = b.y + (prev_c.y - prev_b.y); 214 for (i=0; i < 2; i++) { 215 c.pos[i] = b.pos[i] + (prev_c.pos[i] - prev_b.pos[i]); 216 } 211 217 } 212 218 /* if b is new or we don't have a previous center, … … 214 220 else { 215 221 c.valid = 1; 216 c.x = b.x; 217 c.y = b.y; 222 for (i=0; i < 2; i++) { 223 c.pos[i] = b.pos[i]; 224 } 218 225 } 219 226 } … … 238 245 } 239 246 if (flags != old_flags) { 240 /* TODO: if this message is sent every time, we get a battery meter of241 * blinking lights - why? */242 247 cwiid_command(wiimote, CWIID_CMD_LED, flags); 243 248 } … … 249 254 #define OLD_AMOUNT (1.0-NEW_AMOUNT) 250 255 251 data.axes[0].value = c.x*NEW_AMOUNT + data.axes[0].value*OLD_AMOUNT; 252 data.axes[1].value = c.y*NEW_AMOUNT + data.axes[1].value*OLD_AMOUNT; 256 data.axes[0].value = c.pos[CWIID_X]*NEW_AMOUNT + 257 data.axes[0].value*OLD_AMOUNT; 258 data.axes[1].value = c.pos[CWIID_Y]*NEW_AMOUNT + 259 data.axes[1].value*OLD_AMOUNT; 253 260 254 261 return &data; 255 262 } 256 -
wminput/plugins/nunchuk_acc/nunchuk_acc.c
r805477a re1e47e1 16 16 * 17 17 * ChangeLog: 18 * 2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org> 19 * * updated for API overhaul 20 * 18 21 * 2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org> 19 22 * * updated for libcwiid rename … … 123 126 { 124 127 int i; 125 enum cwiid_ext_type ext ension= CWIID_EXT_NONE;128 enum cwiid_ext_type ext_type = CWIID_EXT_NONE; 126 129 unsigned char buf[7]; 127 130 struct wmplugin_data *ret = NULL; … … 130 133 switch (mesg[i]->type) { 131 134 case CWIID_MESG_STATUS: 132 if ((mesg[i]->status_mesg.ext ension== CWIID_EXT_NUNCHUK) &&133 (ext ension!= CWIID_EXT_NUNCHUK)) {135 if ((mesg[i]->status_mesg.ext_type == CWIID_EXT_NUNCHUK) && 136 (ext_type != CWIID_EXT_NUNCHUK)) { 134 137 if (cwiid_read(wiimote, CWIID_RW_REG | CWIID_RW_DECODE, 135 138 0xA40020, 7, buf)) { … … 143 146 acc_one.z = buf[6]; 144 147 } 145 ext ension = mesg[i]->status_mesg.extension;148 ext_type = mesg[i]->status_mesg.ext_type; 146 149 break; 147 150 case CWIID_MESG_NUNCHUK: … … 166 169 double roll, pitch; 167 170 168 a_x = (((double)mesg->acc _x- acc_zero.x) /171 a_x = (((double)mesg->acc[CWIID_X] - acc_zero.x) / 169 172 (acc_one.x - acc_zero.x))*NEW_AMOUNT + a_x*OLD_AMOUNT; 170 a_y = (((double)mesg->acc _y- acc_zero.y) /173 a_y = (((double)mesg->acc[CWIID_Y] - acc_zero.y) / 171 174 (acc_one.y - acc_zero.y))*NEW_AMOUNT + a_y*OLD_AMOUNT; 172 a_z = (((double)mesg->acc _z- acc_zero.z) /175 a_z = (((double)mesg->acc[CWIID_Z] - acc_zero.z) / 173 176 (acc_one.z - acc_zero.z))*NEW_AMOUNT + a_z*OLD_AMOUNT; 174 177
