diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 172 |
1 files changed, 172 insertions, 0 deletions
@@ -0,0 +1,172 @@ | |||
1 | #include <stdarg.h> | ||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <signal.h> | ||
5 | #include <time.h> | ||
6 | |||
7 | #include <cwiid.h> | ||
8 | #include "gm.h" | ||
9 | #include "display.h" | ||
10 | |||
11 | /* Our wii's bluetooth and wii handles */ | ||
12 | static bdaddr_t g_bdaddr[4]; | ||
13 | static cwiid_wiimote_t *g_wiimotes[4]; | ||
14 | static int g_num_controls = 0; | ||
15 | static int g_samples_received = 0; | ||
16 | static uint32_t g_starttime; | ||
17 | |||
18 | static volatile int g_redraw_lock = 0; | ||
19 | |||
20 | static const int g_width = 400, g_height = 300; | ||
21 | |||
22 | cwiid_mesg_callback_t cwiid_callback; | ||
23 | cwiid_err_t err; | ||
24 | void err(cwiid_wiimote_t *wiimote, const char *s, va_list ap) | ||
25 | { | ||
26 | if (wiimote) printf("%d:", cwiid_get_id(wiimote)); else printf("-1:"); | ||
27 | vprintf(s, ap); | ||
28 | printf("\n"); | ||
29 | } | ||
30 | |||
31 | int main( int argc, char **argv ) { | ||
32 | int LEDs[4] = { CWIID_LED1_ON, CWIID_LED1_ON | CWIID_LED2_ON, | ||
33 | CWIID_LED1_ON | CWIID_LED2_ON | CWIID_LED3_ON, | ||
34 | CWIID_LED1_ON | CWIID_LED2_ON | CWIID_LED3_ON | CWIID_LED4_ON }; | ||
35 | int i; | ||
36 | struct timeval now; | ||
37 | |||
38 | signal( SIGINT, exit ); | ||
39 | display_init( g_width, g_height); | ||
40 | |||
41 | cwiid_set_err(err); | ||
42 | |||
43 | /* If no bdaddrs given on command line, just connect to | ||
44 | first visible wii */ | ||
45 | if( argc <= 1 ) { | ||
46 | char bt_out[64]; | ||
47 | g_bdaddr[0] = *BDADDR_ANY; | ||
48 | |||
49 | while( !(g_wiimotes[g_num_controls] = cwiid_open( &g_bdaddr[0], 0 ))) | ||
50 | fprintf( stderr, "Unable to connect to wiimote\n" ); | ||
51 | |||
52 | ba2str( &g_bdaddr[0], bt_out ); | ||
53 | fprintf( stderr, "Connected to wiimote %i (BT-Addr: %s)\n", i, bt_out ); | ||
54 | g_num_controls++; | ||
55 | } | ||
56 | |||
57 | /* ... else try to reach every single wii */ | ||
58 | for( i=0; i<argc-1; ++i ) { | ||
59 | str2ba(argv[i+1], &g_bdaddr[i]); | ||
60 | |||
61 | while( !(g_wiimotes[g_num_controls] = cwiid_open( &g_bdaddr[i], 0 ))) | ||
62 | fprintf( stderr, "Unable to connect to wiimote %i (BT-Addr: %s)\n", i, argv[i+1] ); | ||
63 | |||
64 | g_num_controls++; | ||
65 | fprintf( stderr, "Connected to wiimote %i (BT-Addr: %s)\n", i, argv[i+1] ); | ||
66 | } | ||
67 | |||
68 | for( i=0; i<g_num_controls; ++i ) { | ||
69 | if (cwiid_set_mesg_callback(g_wiimotes[i], cwiid_callback)) { | ||
70 | fprintf(stderr, "Unable to set message callback\n"); | ||
71 | return -1; | ||
72 | } | ||
73 | |||
74 | /* Set report mode to IR */ | ||
75 | cwiid_set_rpt_mode(g_wiimotes[i], CWIID_RPT_IR); | ||
76 | |||
77 | /* Enable call back */ | ||
78 | cwiid_enable(g_wiimotes[i], CWIID_FLAG_MESG_IFC); | ||
79 | |||
80 | /* Reflect number in leds */ | ||
81 | cwiid_set_led(g_wiimotes[i], LEDs[i]); | ||
82 | } | ||
83 | |||
84 | gettimeofday(&now, (struct timezone *)NULL); | ||
85 | g_starttime = now.tv_sec * 1000 + now.tv_usec / 1000; /* in ms */ | ||
86 | |||
87 | /* Spin and let call back do all the work */ | ||
88 | while( 1 ) { | ||
89 | if( ! (++i & 0xffff ) ) { | ||
90 | int wii_id, led; | ||
91 | while( g_redraw_lock ); | ||
92 | |||
93 | for( wii_id=0; wii_id<4; ++wii_id ) | ||
94 | for( led = 0; led<4; ++led ) | ||
95 | display_rectangle( wii_id, led * g_width / 16, 0, g_width / 16, vubars_getinfo(wii_id, led)/2 ); | ||
96 | |||
97 | display_redraw(); | ||
98 | usleep( 1000 ); | ||
99 | vubars_reduce(); | ||
100 | display_rectangle( 2, g_width/2-10, 0, 20, -vubars_getweather()/2 ); | ||
101 | display_rectangle( 2, g_width/2-15, -128, 30, 1 ); | ||
102 | display_rectangle( 2, g_width/2-15, -64, 30, 1 ); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, | ||
110 | union cwiid_mesg mesg[], struct timespec *timestamp) | ||
111 | { | ||
112 | int i, j, k, wii_id, ledmask; | ||
113 | int valid_sources; | ||
114 | struct timeval now; | ||
115 | uint32_t runtime; | ||
116 | wii_pt coords[4]; | ||
117 | |||
118 | gettimeofday(&now, (struct timezone *)NULL); | ||
119 | runtime = now.tv_sec * 1000 + now.tv_usec / 1000 - g_starttime; /* in ms */ | ||
120 | |||
121 | for( i=0; i<g_num_controls; ++i ) { | ||
122 | if( wiimote == g_wiimotes[i] ) | ||
123 | wii_id = i; | ||
124 | } | ||
125 | g_redraw_lock = 1; | ||
126 | display_clear(); | ||
127 | g_samples_received++; | ||
128 | for (i=0; i < mesg_count; i++) { | ||
129 | switch (mesg[i].type) { | ||
130 | |||
131 | case CWIID_MESG_IR: | ||
132 | // printf("IR Report (%i): ", wii_id ); | ||
133 | // printf("(%ld Hz) ", ( g_samples_received * 1000 ) / runtime ); | ||
134 | |||
135 | valid_sources = 0; | ||
136 | for (j = 0; j < CWIID_IR_SRC_COUNT; j++) { | ||
137 | if (mesg[i].ir_mesg.src[j].valid) { | ||
138 | coords[valid_sources].x = (double)mesg[i].ir_mesg.src[j].pos[CWIID_X]; | ||
139 | coords[valid_sources].y = (double)mesg[i].ir_mesg.src[j].pos[CWIID_Y]; | ||
140 | |||
141 | display_circle( wii_id, coords[valid_sources].x / 5.0, coords[valid_sources].y / 5.0, 6 ); | ||
142 | valid_sources++; | ||
143 | // printf("(%d,%d) ", mesg[i].ir_mesg.src[j].pos[CWIID_X], | ||
144 | // mesg[i].ir_mesg.src[j].pos[CWIID_Y]); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if (!valid_sources) { | ||
149 | // printf("no sources detected"); | ||
150 | } | ||
151 | |||
152 | if( valid_sources == 4 ) { | ||
153 | wii_calibrate( wii_id, coords ); | ||
154 | } | ||
155 | |||
156 | ledmask = 0; | ||
157 | for( j=0; j<valid_sources; ++j ) { | ||
158 | int led = wii_point_to_led( wii_id, coords+j ); | ||
159 | ledmask |= 1<<led; | ||
160 | } | ||
161 | for( j=0; j<4; ++j ) { | ||
162 | vubars_peak( wii_id, j, ( ledmask >> j ) & 1 ); | ||
163 | } | ||
164 | |||
165 | break; | ||
166 | default: | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | g_redraw_lock = 0; | ||
171 | } | ||
172 | |||