/* Program to test the svgalib joystick functions. */ /* Written by M. Weller */ #include #include #include #include #include #include #include #include #include #include #include #include extern char *optarg; extern int optind, opterr, optopt; #define PENCILSIZE 5 struct { int wx; /* xoffset to add to scaled joystick position to get cx */ int cx, cy; /* onscreen coords of pencil */ int jx, jy; /* current joystick status */ int tx; /* onscreen xcoord of text for joypos */ char bitmap[PENCILSIZE * PENCILSIZE * 4]; /* big enough in any screen mode */ int ox, oy; /* location of saved patch, ox < 0 for no data saved */ int color; /* drawing color */ int drawing; /* we are drawing (actually shadows button 1 state) */ int newpos; /* cx/cy changed, draw new pencil position */ } joypanel[2]; int wy, sx, sy, ty; /* wy, ty y coords of wx, tx. sx/sy are scale values: * (jx * sx + 128) / 256 is pencil coords (add wx for screen * coords). Same for y. */ int newcolor(void) { if (BYTESPERPIXEL == 1) return random() % 15 + 1; return gl_rgbcolor(random() & 255, random() & 255, random() & 255); } void draw_pencil(int i) { char msg[100]; if (!joypanel[i].newpos) return; sprintf(msg, "x = %4d, y = %4d", joypanel[i].jx, joypanel[i].jy); gl_write(joypanel[i].tx, ty, msg); if (joypanel[i].ox >= 0) gl_putbox(joypanel[i].ox, joypanel[i].oy, PENCILSIZE, PENCILSIZE, joypanel[i].bitmap); /* If not drawing, save destination area */ if (!joypanel[i].drawing) gl_getbox(joypanel[i].ox = joypanel[i].cx, joypanel[i].oy = joypanel[i].cy, PENCILSIZE, PENCILSIZE, joypanel[i].bitmap); else joypanel[i].ox = -1; gl_fillbox(joypanel[i].cx, joypanel[i].cy, PENCILSIZE, PENCILSIZE, joypanel[i].color); joypanel[i].newpos = 0; } void init_screen(void) { int white; gl_clearscreen(0); white = vga_white(); gl_line(0, 0, WIDTH - 2, 0, white); gl_line(0, 0, 0, HEIGHT - 1, white); gl_line(WIDTH/2, 0, WIDTH/2, HEIGHT - 1, white); gl_line(WIDTH - 2, 0, WIDTH - 2 , HEIGHT - 1, white); gl_line(0, 11, WIDTH - 2, 11, white); gl_line(0, HEIGHT - 1, WIDTH - 2, HEIGHT - 1, white); ty = 2; sx = WIDTH / 2 - 3 - PENCILSIZE; sy = HEIGHT - 6 - PENCILSIZE - 9; wy = 2 + 8 + 3 + (((sy << 7) + 128) >> 8); joypanel[0].color = white; joypanel[0].drawing = 0; joypanel[0].newpos = 1; joypanel[0].ox = -1; joypanel[0].tx = 2; joypanel[0].jx = 0; joypanel[0].jy = 0; joypanel[0].wx = 2 + (((sx << 7) + 128) >> 8); joypanel[0].cx = joypanel[0].wx; joypanel[0].cy = wy; draw_pencil(0); joypanel[1].color = white; joypanel[1].drawing = 0; joypanel[1].newpos = 1; joypanel[1].ox = -1; joypanel[1].tx = WIDTH / 2 + 2; joypanel[1].jx = 0; joypanel[1].jy = 0; joypanel[1].wx = joypanel[0].wx + joypanel[1].tx; joypanel[1].cx = joypanel[0].cx + joypanel[1].tx; joypanel[1].cy = wy; draw_pencil(1); } void myhandler(int event, int number, char value, int joydev) { #if 0 printf("%d: %d %d %d\n", joydev, event, number, (int)value); #endif switch(event) { case JOY_EVENTBUTTONUP: if (!number) joypanel[joydev].drawing = 0; else { joypanel[joydev].color = newcolor(); joypanel[joydev].newpos = 1; } break; case JOY_EVENTBUTTONDOWN: if (!number) joypanel[joydev].drawing = 1; break; case JOY_EVENTAXIS: switch(number) { case 0: /* x */ joypanel[joydev].jx = value; joypanel[joydev].cx = joypanel[joydev].wx + ((((int)value) * sx + 128) / 256); joypanel[joydev].newpos = 1; break; case 1: joypanel[joydev].jy = value; joypanel[joydev].cy = wy + ((((int)value) * sy + 128) / 256); joypanel[joydev].newpos = 1; break; } } /* Note that any reserved events are ignored */ } void usage(void) { puts("Usage: mjoytest [-j ] [svgalib mode]\n" "\ttest multiple joystick support and joystick sharing."); exit(1); } void mycalout(const char *msg) { gl_printf(-1, -1, msg); } int main(int argc, char *argv[]) { int vgamode = -1; int which, joymask = 3; struct timeval timeout; while(EOF != (which = getopt(argc, argv, "j:m:"))) { switch(which) { case 'j': if (!strcmp(optarg, "0")) joymask = 1; else if (!strcmp(optarg, "1")) joymask = 1; else usage(); break; case 'm': vgamode = vga_getmodenumber(optarg); if (vgamode < 0) usage(); break; default: usage(); } } if (optind < argc) { if (optind != 1 + argc) usage(); if (vgamode >= 0) usage(); vgamode = vga_getmodenumber(argv[optind]); if (vgamode < 0) usage(); } vga_init(); if (vgamode < 0) vgamode = vga_getdefaultmode(); if (vgamode < 0) vgamode = G320x200x256; if (!vga_hasmode(vgamode)) { printf("Mode not available.\n"); exit(-1); } puts("In the demo, press\n" "<1> to calibrate joystick 1.\n" "<2> to calibrate joystick 2.\n" " to clear the screen (<1> & <2> do this too).\n" " to exit (-C should work too.\n" "Joystick button 1 enables drawing while pressed.\n" "Joystick button 2 selects next color.\n" "\nNow hit to start the demo."); getchar(); fflush(stdin); for (which = 0; which < 2; which++) { if (!(joymask & (1 << which))) continue; errno = 0; if (joystick_init(which, JOY_CALIB_STDOUT) < 0) { if (errno) printf("Unable to initialize joystick %d: %s.\n", which, strerror(errno)); else printf("Unable to initialize joystick %d.\n", which); } } joystick_sethandler(-1, myhandler); vga_setmode(vgamode); gl_setcontextvga(vgamode); gl_setwritemode(FONT_COMPRESSED | WRITEMODE_OVERWRITE); gl_setfontcolors(0, vga_white()); gl_setfont(8, 8, gl_font8x8); init_screen(); for(;;) { timeout.tv_sec = 0; timeout.tv_usec = 10000; which = vga_waitevent(VGA_KEYEVENT, NULL, NULL, NULL, &timeout); if (which & VGA_KEYEVENT) { switch(vga_getch()) { case '1': gl_printf(2, 2, ""); if (1 & joymask) { vga_lockvc(); joystick_init(0, mycalout); /* IMPORTANT, reenable ownhandler! */ joystick_sethandler(0, myhandler); vga_unlockvc(); } init_screen(); break; case '2': gl_printf(2, 2, ""); if (2 & joymask) { vga_lockvc(); joystick_init(1, mycalout); /* IMPORTANT, reenable ownhandler! */ joystick_sethandler(1, myhandler); vga_unlockvc(); } init_screen(); break; case 'c': case 'C': init_screen(); break; case 'q': case 'Q': goto leave_loop; default: putchar('\a'); fflush(stdout); break; } } which = joystick_update(); if (which & 1); draw_pencil(0); /* It makes only sense to check for the newpos flag * if something happened with the joystick at all */ if (which & 2); draw_pencil(1); } leave_loop: printf("Shutting down.\n"); vga_setmode(TEXT); exit(0); }