Ticket #24: cwiid-savemesg.diff
| File cwiid-savemesg.diff, 13.5 KB (added by amp, 6 years ago) |
|---|
-
Makefile.in
12 12 13 13 install uninstall distclean: $(DOC_DIRS) 14 14 15 all clean distclean: wmdemo 15 all clean distclean: wmdemo wmdemo_savedmesg 16 16 17 17 ifneq ($(MAKECMDGOALS),clean) 18 18 ifneq ($(MAKECMDGOALS),distclean) … … 24 24 $(BIN_DIRS) $(LIB_DIRS): $(CWIID_CONFIG_DIR) $(CWIID_PLUGINS_DIR) 25 25 endif 26 26 27 $(LIB_DIRS) $(BIN_DIRS) $(DOC_DIRS) wmdemo :27 $(LIB_DIRS) $(BIN_DIRS) $(DOC_DIRS) wmdemo wmdemo_savedmesg: 28 28 $(MAKE) $(TARGET) -C $@ 29 29 30 30 $(CWIID_CONFIG_DIR): … … 44 44 rm -rf $(CWIID_CONFIG_DIR) 45 45 46 46 .PHONY: all install clean distclean uninstall uninstall_config $(LIB_DIRS) \ 47 $(BIN_DIRS) $(DOC_DIRS) wmdemo 47 $(BIN_DIRS) $(DOC_DIRS) wmdemo wmdemo_savedmesg 48 48 49 49 .NOTPARALLEL: -
configure.ac
1 1 # ChangeLog: 2 # 04/06/2007 Arthur Peters <amp@singingwizard.org> 3 # * added wmdemo_savedmesg/Makefile 4 # 2 5 # 04/01/2007 L. Donnie Smith <cwiid@abstrakraft.org> 3 6 # * added lswm/Makefile 4 7 # * moved defs.mak … … 94 97 [man/Makefile] 95 98 [wiimote/Makefile] 96 99 [wmdemo/Makefile] 100 [wmdemo_savedmesg/Makefile] 97 101 [wmgui/Makefile] 98 102 [wminput/Makefile] 99 103 [wminput/plugins/Makefile] -
wmdemo_savedmesg/Makefile.in
1 #Copyright (C) 2007 L. Donnie Smith 2 3 include @top_builddir@/defs.mak 4 5 APP_NAME = wmdemo_savedmesg 6 7 SOURCES = wmdemo_savedmesg.c 8 9 CFLAGS += -I@top_builddir@/wiimote 10 LDFLAGS += -L@top_builddir@/wiimote 11 LDLIBS += -lwiimote 12 INST_DIR = @bindir@ 13 14 include $(COMMON)/include/app.mak 15 16 distclean: clean 17 rm Makefile 18 19 .PHONY: distclean -
wmdemo_savedmesg/wmdemo_savedmesg.c
1 #include <stdarg.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <fcntl.h> 6 7 #include <wiimote.h> 8 9 /* This is a sample program written to demonstrate basic CWiid libwiimote 10 * usage, until _actual_ documentation can be written. It's quick and dirty 11 * has a horrible interface, but it's sparce enough to pick out the important 12 * parts easily. For examples of read and write code, see wmgui. Speaker 13 * support is "experimental" (read: bad) enough to be disabled. The beginnings 14 * of a speaker output function are in libwiimote source. */ 15 /* Note: accelerometer (including nunchuk) and IR outputs produce a 16 * lot of data - the purpose of this program is demonstration, not good 17 * interface, and it shows. */ 18 19 #define toggle_bit(bf,b) \ 20 (bf) = ((bf) & b) \ 21 ? ((bf) & ~(b)) \ 22 : ((bf) | (b)) 23 24 void set_led_state(wiimote_t *wiimote, unsigned char led_state); 25 void set_rpt_mode(wiimote_t *wiimote, unsigned char rpt_mode); 26 27 int set_nonblock_flag (int desc, int value); 28 29 wiimote_err_t err; 30 void err(int id, const char *s, ...) 31 { 32 va_list ap; 33 34 va_start(ap, s); 35 printf("%d:", id); 36 vprintf(s, ap); 37 printf("\n"); 38 va_end(ap); 39 } 40 41 /* wiimote handle */ 42 wiimote_t *wiimote; 43 44 int main(int argc, char *argv[]) 45 { 46 if( set_nonblock_flag( 0, 1 ) != 0 ) 47 perror( "set_nonblock_flag failed" ); 48 49 bdaddr_t bdaddr; /* bluetooth device address */ 50 int wiimote_id; /* wiimote id: useful for handling multiple wiimotes 51 with a single callback */ 52 unsigned char led_state = 0; 53 unsigned char rpt_mode = 0; 54 unsigned char rumble = 0; 55 int exit = 0; 56 57 wiimote_set_err(err); 58 59 /* Connect to any wiimote */ 60 bdaddr = *BDADDR_ANY; 61 /* Connect to address in string WIIMOTE_BDADDR */ 62 /* str2ba(WIIMOTE_BDADDR, &bdaddr); */ 63 64 /* Connect to the wiimote */ 65 printf("Put Wiimote in discoverable mode now (press 1+2)...\n"); 66 if (!(wiimote = wiimote_connect(&bdaddr, wiimote_save_messages, &wiimote_id))) { 67 fprintf(stderr, "Unable to connect to wiimote\n"); 68 return -1; 69 } 70 71 /* Menu */ 72 printf("1: toggle LED 1\n" 73 "2: toggle LED 2\n" 74 "3: toggle LED 3\n" 75 "4: toggle LED 4\n" 76 "a: toggle accelerometer output\n" 77 "b: toggle button output\n" 78 "e: toggle extension output\n" 79 "i: toggle ir output\n" 80 "r: toggle rumble\n" 81 "s: request status message (use t to turn on output)\n" 82 "t: toggle status output\n" 83 "x: exit\n"); 84 85 while (!exit) { 86 switch (getchar()) { 87 case '1': 88 toggle_bit(led_state, WIIMOTE_LED1_ON); 89 set_led_state(wiimote, led_state); 90 break; 91 case '2': 92 toggle_bit(led_state, WIIMOTE_LED2_ON); 93 set_led_state(wiimote, led_state); 94 break; 95 case '3': 96 toggle_bit(led_state, WIIMOTE_LED3_ON); 97 set_led_state(wiimote, led_state); 98 break; 99 case '4': 100 toggle_bit(led_state, WIIMOTE_LED4_ON); 101 set_led_state(wiimote, led_state); 102 break; 103 case 'a': 104 toggle_bit(rpt_mode, WIIMOTE_RPT_ACC); 105 set_rpt_mode(wiimote, rpt_mode); 106 break; 107 case 'b': 108 toggle_bit(rpt_mode, WIIMOTE_RPT_BTN); 109 set_rpt_mode(wiimote, rpt_mode); 110 break; 111 case 'e': 112 /* WIIMOTE_RPT_EXT is actually 113 * WIIMOTE_RPT_NUNCHUK | WIIMOTE_RPT_CLASSIC */ 114 toggle_bit(rpt_mode, WIIMOTE_RPT_EXT); 115 set_rpt_mode(wiimote, rpt_mode); 116 break; 117 case 'i': 118 /* libwiimote picks the highest quality IR mode available with the 119 * other options selected (not including as-yet-undeciphered 120 * interleaved mode */ 121 toggle_bit(rpt_mode, WIIMOTE_RPT_IR); 122 set_rpt_mode(wiimote, rpt_mode); 123 break; 124 case 'r': 125 toggle_bit(rumble, 1); 126 if (wiimote_command(wiimote, WIIMOTE_CMD_RUMBLE, rumble)) { 127 fprintf(stderr, "Error setting rumble\n"); 128 } 129 break; 130 case 's': 131 if (wiimote_command(wiimote, WIIMOTE_CMD_STATUS, 0)) { 132 fprintf(stderr, "Error requesting status message\n"); 133 } 134 break; 135 case 't': 136 toggle_bit(rpt_mode, WIIMOTE_RPT_STATUS); 137 set_rpt_mode(wiimote, rpt_mode); 138 break; 139 case 'x': 140 exit = -1; 141 break; 142 case '\n': 143 break; 144 case EOF: 145 break; 146 default: 147 fprintf(stderr, "invalid option\n"); 148 } 149 150 printf("Acc: x=%d, y=%d, z=%d\t", wiimote_saved_messages[wiimote_id].acc_mesg.x, 151 wiimote_saved_messages[wiimote_id].acc_mesg.y, 152 wiimote_saved_messages[wiimote_id].acc_mesg.z); 153 printf("Buttons: %.4X\t", wiimote_saved_messages[wiimote_id].btn_mesg.buttons); 154 printf("Status: battery=%d extension=", wiimote_saved_messages[wiimote_id].status_mesg.battery); 155 switch (wiimote_saved_messages[wiimote_id].status_mesg.extension) { 156 case WIIMOTE_EXT_NONE: 157 printf("none"); 158 break; 159 case WIIMOTE_EXT_NUNCHUK: 160 printf("Nunchuk"); 161 break; 162 case WIIMOTE_EXT_CLASSIC: 163 printf("Classic Controller"); 164 break; 165 default: 166 printf("Unknown Extension"); 167 break; 168 } 169 printf("\n"); 170 171 usleep( 100*1000 ); 172 } 173 174 if (wiimote_disconnect(wiimote)) { 175 fprintf(stderr, "Error on wiimote disconnect\n"); 176 return -1; 177 } 178 179 return 0; 180 } 181 182 void set_led_state(wiimote_t *wiimote, unsigned char led_state) 183 { 184 if (wiimote_command(wiimote, WIIMOTE_CMD_LED, led_state)) { 185 fprintf(stderr, "Error setting LEDs \n"); 186 } 187 } 188 189 void set_rpt_mode(wiimote_t *wiimote, unsigned char rpt_mode) 190 { 191 if (wiimote_command(wiimote, WIIMOTE_CMD_RPT_MODE, rpt_mode)) { 192 fprintf(stderr, "Error setting report mode\n"); 193 } 194 } 195 196 /* Set the O_NONBLOCK flag of desc if value is nonzero, 197 or clear the flag if value is 0. 198 Return 0 on success, or -1 on error with errno set. */ 199 200 int 201 set_nonblock_flag (int desc, int value) 202 { 203 int oldflags = fcntl (desc, F_GETFL, 0); 204 /* If reading the flags failed, return error indication now. */ 205 if (oldflags < 0) 206 return oldflags; 207 /* Set just the flag we want to set. */ 208 if (value != 0) 209 oldflags |= O_NONBLOCK; 210 else 211 oldflags &= ~O_NONBLOCK; 212 /* Store modified flag word in the descriptor. */ 213 return fcntl (desc, F_SETFL, oldflags); 214 } 215 -
wiimote/Makefile.in
5 5 LIB_NAME = wiimote 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 = connect.c command.c event.c rw.c bluetooth.c util.c queue.c savemesg.c 9 9 LDLIBS += -lbluetooth -lpthread -lrt 10 10 LIB_INST_DIR = @libdir@ 11 11 INC_INST_DIR = @includedir@ -
wiimote/wiimote.h
210 210 struct wiimote_error_mesg error_mesg; 211 211 }; 212 212 213 /// One of each of all the message types. This can be used to store the state of the Wiimote as it has been most recently reported. 214 struct wiimote_mesg_set { 215 struct wiimote_status_mesg status_mesg; 216 struct wiimote_btn_mesg btn_mesg; 217 struct wiimote_acc_mesg acc_mesg; 218 struct wiimote_ir_mesg ir_mesg; 219 struct wiimote_nunchuk_mesg nunchuk_mesg; 220 struct wiimote_classic_mesg classic_mesg; 221 struct wiimote_error_mesg error_mesg; 222 }; 223 213 224 typedef struct wiimote wiimote_t; 214 225 215 226 typedef void wiimote_mesg_callback_t(int, int, union wiimote_mesg* []); … … 245 256 struct wiimote_info **wm, uint8_t flags); 246 257 int wiimote_find_wiimote(bdaddr_t *bdaddr, int timeout); 247 258 259 /** 260 A callback that saves the most recent message of each type. It is very useful for program that 261 only need the current state (not the changes in state) and don't want to deal with threading. 262 263 There is a race condition in the message copies into wiimote_saved_messages[]. A reader could read 264 the message while it is being updated resulting in reading half old and half new data. I don't think 265 this will be a big issue. The new and old values will likely be very close to each other and there 266 is no temporary values written to wiimote_saved_messages[]. However if this is a problem maybe a lock 267 should be added or people who need accuracy should use the event API. 268 */ 269 void wiimote_save_messages(int, int, union wiimote_mesg* []); 270 271 /** 272 The values saved by wiimote_save_messages(). The data for a given wiimote is in "wiimote_saved_messages[id]". 273 */ 274 extern struct wiimote_mesg_set wiimote_saved_messages[]; 275 248 276 #ifdef __cplusplus 249 277 } 250 278 #endif -
wiimote/savemesg.c
1 /* Copyright (C) 2007 Arthur Peters <amp@singingwizard.org> 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 * 17 */ 18 19 #include "wiimote_internal.h" 20 21 #define MAX_WIIMOTES 16 22 23 struct wiimote_mesg_set wiimote_saved_messages[MAX_WIIMOTES]; 24 25 /* 26 A callback that saves the most recent message of each type. It is very useful for program that 27 only need the current state (not the changes in state) and don't want to deal with threading. 28 29 There is a race condition in the message copies into wiimote_saved_messages[]. A reader could read 30 the message while it is being updated resulting in reading half old and half new data. I don't think 31 this will be a big issue. The new and old values will likely be very close to each other and there 32 is no temporary values written to wiimote_saved_messages[]. However if this is a problem maybe a lock 33 should be added or people who need accuracy should use the event API. 34 */ 35 void wiimote_save_messages(int id, int mesg_count, union wiimote_mesg *mesgs[]) 36 { 37 int i; 38 39 if( id >= MAX_WIIMOTES ) { 40 wiimote_err(NULL, "Too many wiimotes in wiimote_save_messages(...)"); 41 return; 42 } 43 44 for( i=0; i < mesg_count; i++ ) { 45 union wiimote_mesg* mesg = mesgs[i]; 46 47 switch( mesg->type ) { 48 case WIIMOTE_MESG_STATUS: 49 wiimote_saved_messages[id].status_mesg = mesg->status_mesg; 50 break; 51 case WIIMOTE_MESG_BTN: 52 wiimote_saved_messages[id].btn_mesg = mesg->btn_mesg; 53 break; 54 case WIIMOTE_MESG_ACC: 55 wiimote_saved_messages[id].acc_mesg = mesg->acc_mesg; 56 break; 57 case WIIMOTE_MESG_IR: 58 wiimote_saved_messages[id].ir_mesg = mesg->ir_mesg; 59 break; 60 case WIIMOTE_MESG_NUNCHUK: 61 wiimote_saved_messages[id].nunchuk_mesg = mesg->nunchuk_mesg; 62 break; 63 case WIIMOTE_MESG_CLASSIC: 64 wiimote_saved_messages[id].classic_mesg = mesg->classic_mesg; 65 break; 66 case WIIMOTE_MESG_ERROR: 67 wiimote_saved_messages[id].error_mesg = mesg->error_mesg; 68 break; 69 //case WIIMOTE_MESG_UNKNOWN: 70 default: 71 wiimote_err(NULL, "Unknown message type in wiimote_save_messages(...)"); 72 break; 73 } 74 } 75 } 76 77
