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 | |||
