Ticket #24: cwiid-savemesg.diff

File cwiid-savemesg.diff, 13.5 KB (added by amp, 6 years ago)

Patch to add this feature

  • Makefile.in

     
    1212 
    1313install uninstall distclean: $(DOC_DIRS) 
    1414 
    15 all clean distclean: wmdemo 
     15all clean distclean: wmdemo wmdemo_savedmesg 
    1616 
    1717ifneq ($(MAKECMDGOALS),clean) 
    1818ifneq ($(MAKECMDGOALS),distclean) 
     
    2424$(BIN_DIRS) $(LIB_DIRS): $(CWIID_CONFIG_DIR) $(CWIID_PLUGINS_DIR) 
    2525endif 
    2626 
    27 $(LIB_DIRS) $(BIN_DIRS) $(DOC_DIRS) wmdemo: 
     27$(LIB_DIRS) $(BIN_DIRS) $(DOC_DIRS) wmdemo wmdemo_savedmesg: 
    2828        $(MAKE) $(TARGET) -C $@ 
    2929 
    3030$(CWIID_CONFIG_DIR): 
     
    4444        rm -rf $(CWIID_CONFIG_DIR) 
    4545 
    4646.PHONY: all install clean distclean uninstall uninstall_config $(LIB_DIRS) \ 
    47         $(BIN_DIRS) $(DOC_DIRS) wmdemo 
     47        $(BIN_DIRS) $(DOC_DIRS) wmdemo  wmdemo_savedmesg 
    4848 
    4949.NOTPARALLEL: 
  • configure.ac

     
    11# ChangeLog: 
     2# 04/06/2007 Arthur Peters <amp@singingwizard.org> 
     3# * added wmdemo_savedmesg/Makefile 
     4# 
    25# 04/01/2007 L. Donnie Smith <cwiid@abstrakraft.org> 
    36# * added lswm/Makefile 
    47# * moved defs.mak 
     
    9497        [man/Makefile] 
    9598        [wiimote/Makefile] 
    9699        [wmdemo/Makefile] 
     100        [wmdemo_savedmesg/Makefile] 
    97101        [wmgui/Makefile] 
    98102        [wminput/Makefile] 
    99103        [wminput/plugins/Makefile] 
  • wmdemo_savedmesg/Makefile.in

     
     1#Copyright (C) 2007 L. Donnie Smith 
     2 
     3include @top_builddir@/defs.mak 
     4 
     5APP_NAME = wmdemo_savedmesg 
     6 
     7SOURCES = wmdemo_savedmesg.c 
     8 
     9CFLAGS += -I@top_builddir@/wiimote 
     10LDFLAGS += -L@top_builddir@/wiimote 
     11LDLIBS += -lwiimote 
     12INST_DIR = @bindir@ 
     13 
     14include $(COMMON)/include/app.mak 
     15 
     16distclean: 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 
     24void set_led_state(wiimote_t *wiimote, unsigned char led_state); 
     25void set_rpt_mode(wiimote_t *wiimote, unsigned char rpt_mode); 
     26 
     27int set_nonblock_flag (int desc, int value); 
     28 
     29wiimote_err_t err; 
     30void 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 */ 
     42wiimote_t *wiimote; 
     43 
     44int 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 
     182void 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         
     189void 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 
     200int 
     201set_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

     
    55LIB_NAME = wiimote 
    66MAJOR_VER = 0 
    77MINOR_VER = 1 
    8 SOURCES = connect.c command.c event.c rw.c bluetooth.c util.c queue.c 
     8SOURCES = connect.c command.c event.c rw.c bluetooth.c util.c queue.c savemesg.c 
    99LDLIBS += -lbluetooth -lpthread -lrt 
    1010LIB_INST_DIR = @libdir@ 
    1111INC_INST_DIR = @includedir@ 
  • wiimote/wiimote.h

     
    210210        struct wiimote_error_mesg error_mesg; 
    211211}; 
    212212 
     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. 
     214struct 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 
    213224typedef struct wiimote wiimote_t; 
    214225 
    215226typedef void wiimote_mesg_callback_t(int, int, union wiimote_mesg* []); 
     
    245256                           struct wiimote_info **wm, uint8_t flags); 
    246257int wiimote_find_wiimote(bdaddr_t *bdaddr, int timeout); 
    247258 
     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*/ 
     269void 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*/ 
     274extern struct wiimote_mesg_set wiimote_saved_messages[]; 
     275 
    248276#ifdef __cplusplus 
    249277} 
    250278#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 
     23struct 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*/ 
     35void 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