root/wmdemo/wmdemo.c @ 805477a3e8c4bccbd90c78e829870267c783904b

Revision 805477a3e8c4bccbd90c78e829870267c783904b, 7.1 KB (checked in by dsmith <dsmith@…>, 6 years ago)

Merge libcwiid rename into trunk

git-svn-id: http://abstrakraft.org/cwiid/svn/trunk@83 918edb2d-ff29-0410-9de2-eb38e7f22bc7

  • Property mode set to 100644
Line 
1#include <stdarg.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5#include <cwiid.h>
6
7/* This is a sample program written to demonstrate basic CWiid libwiimote
8 * usage, until _actual_ documentation can be written.  It's quick and dirty
9 * has a horrible interface, but it's sparce enough to pick out the important
10 * parts easily.  For examples of read and write code, see wmgui.  Speaker
11 * support is "experimental" (read: bad) enough to be disabled.  The beginnings
12 * of a speaker output function are in libwiimote source. */
13/* Note: accelerometer (including nunchuk) and IR outputs produce a
14 * lot of data - the purpose of this program is demonstration, not good
15 * interface, and it shows. */
16
17cwiid_mesg_callback_t cwiid_callback;
18
19#define toggle_bit(bf,b)        \
20        (bf) = ((bf) & b)               \
21               ? ((bf) & ~(b))  \
22               : ((bf) | (b))
23
24void set_led_state(cwiid_wiimote_t *wiimote, unsigned char led_state);
25void set_rpt_mode(cwiid_wiimote_t *wiimote, unsigned char rpt_mode);
26
27cwiid_err_t err;
28void err(int id, const char *s, ...)
29{
30        va_list ap;
31
32        va_start(ap, s);
33        printf("%d:", id);
34        vprintf(s, ap);
35        printf("\n");
36        va_end(ap);
37}
38
39/* wiimote handle */
40cwiid_wiimote_t *wiimote;
41
42int main(int argc, char *argv[])
43{
44        bdaddr_t bdaddr;        /* bluetooth device address */
45        int cwiid_id;           /* wiimote id: useful for handling multiple wiimotes
46                               with a single callback */
47        unsigned char led_state = 0;
48        unsigned char rpt_mode = 0;
49        unsigned char rumble = 0;
50        int exit = 0;
51
52        cwiid_set_err(err);
53
54        /* Connect to any wiimote */
55        bdaddr = *BDADDR_ANY;
56        /* Connect to address in string CWIID_BDADDR */
57        /* str2ba(CWIID_BDADDR, &bdaddr); */
58
59        /* Connect to the wiimote */
60        printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
61        if (!(wiimote = cwiid_connect(&bdaddr, cwiid_callback, &cwiid_id))) {
62                fprintf(stderr, "Unable to connect to wiimote\n");
63                return -1;
64        }
65
66        /* Menu */
67        printf("1: toggle LED 1\n"
68               "2: toggle LED 2\n"
69               "3: toggle LED 3\n"
70               "4: toggle LED 4\n"
71               "a: toggle accelerometer output\n"
72               "b: toggle button output\n"
73               "e: toggle extension output\n"
74               "i: toggle ir output\n"
75               "r: toggle rumble\n"
76               "s: request status message (use t to turn on output)\n"
77               "t: toggle status output\n"
78               "x: exit\n");
79
80        while (!exit) {
81                switch (getchar()) {
82                case '1':
83                        toggle_bit(led_state, CWIID_LED1_ON);
84                        set_led_state(wiimote, led_state);
85                        break;
86                case '2':
87                        toggle_bit(led_state, CWIID_LED2_ON);
88                        set_led_state(wiimote, led_state);
89                        break;
90                case '3':
91                        toggle_bit(led_state, CWIID_LED3_ON);
92                        set_led_state(wiimote, led_state);
93                        break;
94                case '4':
95                        toggle_bit(led_state, CWIID_LED4_ON);
96                        set_led_state(wiimote, led_state);
97                        break;
98                case 'a':
99                        toggle_bit(rpt_mode, CWIID_RPT_ACC);
100                        set_rpt_mode(wiimote, rpt_mode);
101                        break;
102                case 'b':
103                        toggle_bit(rpt_mode, CWIID_RPT_BTN);
104                        set_rpt_mode(wiimote, rpt_mode);
105                        break;
106                case 'e':
107                        /* CWIID_RPT_EXT is actually
108                         * CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC */
109                        toggle_bit(rpt_mode, CWIID_RPT_EXT);
110                        set_rpt_mode(wiimote, rpt_mode);
111                        break;
112                case 'i':
113                        /* libwiimote picks the highest quality IR mode available with the
114                         * other options selected (not including as-yet-undeciphered
115                         * interleaved mode */
116                        toggle_bit(rpt_mode, CWIID_RPT_IR);
117                        set_rpt_mode(wiimote, rpt_mode);
118                        break;
119                case 'r':
120                        toggle_bit(rumble, 1);
121                        if (cwiid_command(wiimote, CWIID_CMD_RUMBLE, rumble)) {
122                                fprintf(stderr, "Error setting rumble\n");
123                        }
124                        break;
125                case 's':
126                        if (cwiid_command(wiimote, CWIID_CMD_STATUS, 0)) {
127                                fprintf(stderr, "Error requesting status message\n");
128                        }
129                        break;
130                case 't':
131                        toggle_bit(rpt_mode, CWIID_RPT_STATUS);
132                        set_rpt_mode(wiimote, rpt_mode);
133                        break;
134                case 'x':
135                        exit = -1;
136                        break;
137                case '\n':
138                        break;
139                default:
140                        fprintf(stderr, "invalid option\n");
141                }
142        }
143
144        if (cwiid_disconnect(wiimote)) {
145                fprintf(stderr, "Error on wiimote disconnect\n");
146                return -1;
147        }
148
149        return 0;
150}
151
152void set_led_state(cwiid_wiimote_t *wiimote, unsigned char led_state)
153{
154        if (cwiid_command(wiimote, CWIID_CMD_LED, led_state)) {
155                fprintf(stderr, "Error setting LEDs \n");
156        }
157}
158       
159void set_rpt_mode(cwiid_wiimote_t *wiimote, unsigned char rpt_mode)
160{
161        if (cwiid_command(wiimote, CWIID_CMD_RPT_MODE, rpt_mode)) {
162                fprintf(stderr, "Error setting report mode\n");
163        }
164}
165
166/* Prototype cwiid_callback with cwiid_callback_t, define it with the actual
167 * type - this will cause a compile error (rather than some undefined bizarre
168 * behavior) if cwiid_callback_t changes */
169/* cwiid_mesg_callback_t has undergone a few changes lately, hopefully this
170 * will be the last.  Some programs need to know which messages were received
171 * simultaneously (e.g. for correlating accelerometer and IR data), and the
172 * sequence number mechanism used previously proved cumbersome, so we just
173 * pass an array of messages, all of which were received at the same time.
174 * The id is to distinguish between multiple wiimotes using the same callback.
175 * */
176void cwiid_callback(int id, int mesg_count, union cwiid_mesg *mesg[])
177{
178        int i, j;
179        int valid_source;
180
181        for (i=0; i < mesg_count; i++)
182        {
183                switch (mesg[i]->type) {
184                case CWIID_MESG_STATUS:
185                        printf("Status Report: battery=%d extension=",
186                               mesg[i]->status_mesg.battery);
187                        switch (mesg[i]->status_mesg.extension) {
188                        case CWIID_EXT_NONE:
189                                printf("none");
190                                break;
191                        case CWIID_EXT_NUNCHUK:
192                                printf("Nunchuk");
193                                break;
194                        case CWIID_EXT_CLASSIC:
195                                printf("Classic Controller");
196                                break;
197                        default:
198                                printf("Unknown Extension");
199                                break;
200                        }
201                        printf("\n");
202                        break;
203                case CWIID_MESG_BTN:
204                        printf("Button Report: %.4X\n", mesg[i]->btn_mesg.buttons);
205                        break;
206                case CWIID_MESG_ACC:
207                        printf("Acc Report: x=%d, y=%d, z=%d\n", mesg[i]->acc_mesg.x,
208                                                                 mesg[i]->acc_mesg.y,
209                                                                 mesg[i]->acc_mesg.z);
210                        break;
211                case CWIID_MESG_IR:
212                        printf("IR Report: ");
213                        valid_source = 0;
214                        for (j = 0; j < CWIID_IR_SRC_COUNT; j++) {
215                                if (mesg[i]->ir_mesg.src[j].valid) {
216                                        valid_source = 1;
217                                        printf("(%d,%d) ", mesg[i]->ir_mesg.src[j].x,
218                                                           mesg[i]->ir_mesg.src[j].y);
219                                }
220                        }
221                        if (!valid_source) {
222                                printf("no sources detected");
223                        }
224                        printf("\n");
225                        break;
226                case CWIID_MESG_NUNCHUK:
227                        printf("Nunchuk Report: btns=%.2X stick=(%d,%d) acc.x=%d acc.y=%d "
228                               "acc.z=%d\n", mesg[i]->nunchuk_mesg.buttons,
229                               mesg[i]->nunchuk_mesg.stick_x,
230                               mesg[i]->nunchuk_mesg.stick_y, mesg[i]->nunchuk_mesg.acc_x,
231                               mesg[i]->nunchuk_mesg.acc_y, mesg[i]->nunchuk_mesg.acc_z);
232                        break;
233                case CWIID_MESG_CLASSIC:
234                        printf("Classic Report: btns=%.4X l_stick=(%d,%d) r_stick=(%d,%d) "
235                               "l=%d r=%d\n", mesg[i]->classic_mesg.buttons,
236                               mesg[i]->classic_mesg.l_stick_x,
237                               mesg[i]->classic_mesg.l_stick_y,
238                               mesg[i]->classic_mesg.r_stick_x,
239                               mesg[i]->classic_mesg.r_stick_y,
240                               mesg[i]->classic_mesg.l, mesg[i]->classic_mesg.r);
241                        break;
242                case CWIID_MESG_ERROR:
243                        if (cwiid_disconnect(wiimote)) {
244                                fprintf(stderr, "Error on wiimote disconnect\n");
245                                exit(-1);
246                        }
247                        exit(0);
248                        break;
249                default:
250                        printf("Unknown Report");
251                        break;
252                }
253        }
254}
255
Note: See TracBrowser for help on using the browser.