#define MAX_X CWIID_IR_X_MAX
#define MAX_Y CWIID_IR_Y_MAX
-#define CALIB_OFF 50
-
struct coord
{
double x;
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
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,
&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;
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;
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]);
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",
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. */
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");
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],