From: Rusty Russell Date: Thu, 24 Jan 2008 08:06:48 +0000 (+1100) Subject: Mouse support, and fix calibration to outer edges. X-Git-Url: https://git.ozlabs.org/?a=commitdiff_plain;h=d1dd6d7b08f5ac95e6e0806abe93e51701044e23;p=ponghero.git Mouse support, and fix calibration to outer edges. --- diff --git a/prpong.c b/prpong.c index b814c43..7799f63 100644 --- a/prpong.c +++ b/prpong.c @@ -17,8 +17,6 @@ #define MAX_X CWIID_IR_X_MAX #define MAX_Y CWIID_IR_Y_MAX -#define CALIB_OFF 50 - struct coord { double x; @@ -651,41 +649,42 @@ static void clear_ignore(struct list_head *lines) i->ignore = false; } -static void make_cross(unsigned x, unsigned y, - struct line_segment *seg1, - struct line_segment *seg2) +static uint16_t *find_valid_point(struct cwiid_state *state) { - seg1->start.x = x-5; - seg1->start.y = y-5; - seg1->end.x = x+5; - seg1->end.y = y+5; - seg2->start.x = x-5; - seg2->start.y = y+5; - seg2->end.x = x+5; - seg2->end.y = y-5; + unsigned int i; + + for (i = 0; i < CWIID_IR_SRC_COUNT; i++) { + if (state->ir_src[i].valid) + return state->ir_src[i].pos; + } + return NULL; } static void calibrate(SDL_Surface *screen, cwiid_wiimote_t *wiimote, struct coord *calib, unsigned x, unsigned y) { - struct line_segment seg1, seg2; + uint16_t *pos; struct cwiid_state state; - unsigned int i; - - make_cross(x, y, &seg1, &seg2); - thick_line(screen, &seg1, 0); - thick_line(screen, &seg2, 0); + unsigned int last_x = MAX_X, last_y = MAX_Y, count = 0; - do { + /* Must see it for a full half second. */ + while (count < 20) { SDL_Event event; + if (cwiid_get_state(wiimote, &state)) errx(1, "No wii state"); - for (i = 0; i < CWIID_IR_SRC_COUNT; i++) { - if (state.ir_src[i].valid) - break; + pos = find_valid_point(&state); + if (!pos || pos[0] != last_x || pos[1] != last_y) + count = 0; + + if (pos) { + last_x = pos[0]; + last_y = pos[1]; + count++; } + SDL_Delay(25); if (SDL_PollEvent(&event) && (event.type == SDL_QUIT @@ -694,20 +693,11 @@ static void calibrate(SDL_Surface *screen, SDL_Quit(); exit(0); } - } while (i == CWIID_IR_SRC_COUNT); - - thick_line(screen, &seg1, 0xFFFFFFFF); - thick_line(screen, &seg2, 0xFFFFFFFF); - - calib->x = state.ir_src[i].pos[0]; - calib->y = state.ir_src[i].pos[1]; - printf("Calibration point: %u,%u\n", - state.ir_src[i].pos[0], - state.ir_src[i].pos[1]); - make_cross(calib->x, calib->y, &seg1, &seg2); + } - thick_line(screen, &seg1, 0xFFFF0000); - thick_line(screen, &seg2, 0xFFFF0000); + calib->x = last_x; + calib->y = last_y; + printf("Calibration point: %u,%u\n", last_x, last_y); } static bool map_coord(unsigned int x, unsigned int y, @@ -740,7 +730,7 @@ static bool map_coord(unsigned int x, unsigned int y, &intersect)) return false; d2 = dist(&pos, &intersect); - res->x = d1 / (d1 + d2) * (MAX_X - 2*CALIB_OFF) + CALIB_OFF; + res->x = d1 / (d1 + d2) * MAX_X; line_start.y = 0; line_end.y = MAX_Y-1; @@ -788,9 +778,10 @@ int main(int argc, char *argv[]) struct cwiid_state state; struct coord calib[4]; bdaddr_t addr = *BDADDR_ANY; - bool needs_calibration = true; + bool mouse = false, needs_calibration = true, drawing = false; LIST_HEAD(lines); struct cwiid_ir_src *ir, last_ir = { .valid = 0 }; + struct line_segment *n; videoflags = SDL_SWSURFACE; @@ -812,8 +803,22 @@ int main(int argc, char *argv[]) argv++; } + if (argv[1] && streq(argv[1], "--mouse")) { + mouse = true; + needs_calibration = false; + calib[0].x = calib[0].y = 0; + calib[1].x = MAX_X - 1; + calib[1].y = 0; + calib[2].x = MAX_X - 1; + calib[2].y = MAX_Y - 1; + calib[3].x = 0; + calib[3].y = MAX_Y - 1; + argc--; + argv++; + } + if (argc != 5) - errx(1, "Usage: %s [--fullscreen] [--calib=x,y,x,y,x,y,x,y] ballx bally ballangle ballspeed\n" + errx(1, "Usage: %s [--fullscreen] [--calib=x,y,x,y,x,y,x,y] [--mouse] ballx bally ballangle ballspeed\n" " Where ballangle is 0 for north, 90 for east, etc\n", argv[0]); @@ -824,20 +829,22 @@ int main(int argc, char *argv[]) printf("ball move = %f,%f\n", ball.move.x, ball.move.y); /* Initialize SDL */ - if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); return(1); } video_bpp = 0; - printf("Put Wiimote in discoverable mode (press 1+2)\n"); - wiimote = cwiid_open(&addr, 0); - if (!wiimote) - errx(1, "Can't find the Wiimote"); + if (!mouse) { + printf("Put Wiimote in discoverable mode (press 1+2)\n"); + wiimote = cwiid_open(&addr, 0); + if (!wiimote) + errx(1, "Can't find the Wiimote"); - if (cwiid_set_rpt_mode(wiimote, CWIID_RPT_IR)) - errx(1, "Can't set IR repeat mode"); + if (cwiid_set_rpt_mode(wiimote, CWIID_RPT_IR)) + errx(1, "Can't set IR repeat mode"); + } if ( (screen=SDL_SetVideoMode(MAX_X,MAX_Y,video_bpp,videoflags)) == NULL ) { errx(1, "Couldn't set %dx%dx%d video mode: %s", @@ -857,16 +864,10 @@ int main(int argc, char *argv[]) if (needs_calibration) { /* Calibration */ - calibrate(screen, wiimote, &calib[0], CALIB_OFF, 6); - sleep(1); - calibrate(screen, wiimote, &calib[1], - MAX_X - 1 - CALIB_OFF, 6); - sleep(1); - calibrate(screen, wiimote, &calib[2], - MAX_X - 1 - CALIB_OFF, MAX_Y - 7); - sleep(1); - calibrate(screen, wiimote, &calib[3], - CALIB_OFF, MAX_Y - 7); + calibrate(screen, wiimote, &calib[0], 0, 0); + calibrate(screen, wiimote, &calib[1], MAX_X - 1, 0); + calibrate(screen, wiimote, &calib[2], MAX_X - 1, MAX_Y - 1); + calibrate(screen, wiimote, &calib[3], 0, MAX_Y - 1); } /* Draw borders, put them in list. */ @@ -966,14 +967,46 @@ int main(int argc, char *argv[]) ball.pos = new; SDL_Delay(25); - if (SDL_PollEvent(&event) - && (event.type == SDL_QUIT - || (event.type == SDL_KEYDOWN - && event.key.keysym.sym == SDLK_ESCAPE))) { - SDL_Quit(); - return 0; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT + || (event.type == SDL_KEYDOWN + && event.key.keysym.sym == SDLK_ESCAPE)) { + SDL_Quit(); + return 0; + } + if (mouse) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + drawing = true; + break; + case SDL_MOUSEBUTTONUP: + drawing = false; + break; + case SDL_MOUSEMOTION: + if (!drawing) + break; + + n = new_line(event.motion.x, + event.motion.y, + event.motion.x + + event.motion.xrel, + event.motion.y + + event.motion.yrel, + calib); + + if (n) { + timeradd(&now, &line_life, + &n->expires); + list_add_tail(&lines, &n->list); + thick_line(screen, n, 0); + } + } + } } + if (mouse) + continue; + if (cwiid_get_state(wiimote, &state)) errx(1, "No wii state"); @@ -989,8 +1022,6 @@ int main(int argc, char *argv[]) if (ir->valid) { /* Give it some slack for missing one or two... */ if (time_since_last_ir <= 5) { - struct line_segment *n; - n = new_line(last_ir.pos[0], last_ir.pos[1], ir->pos[0],