From: John Tsiombikas Date: Fri, 6 Nov 2020 08:49:57 +0000 (-0500) Subject: done I think, time to test X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=sball;a=commitdiff_plain;h=9c67b30c9aacfdd2bf783ed25848a152d73ea8b3 done I think, time to test --- diff --git a/NOTES b/NOTES index 3ce0f23..1e148f4 100644 --- a/NOTES +++ b/NOTES @@ -1,8 +1,14 @@ -id strings -========== - -Spaceballs ----------- +axis mapping +------------ +spaceball: + - T: +X right / +Y up / +Z fwd + - R: +X CCW / +Y CCW / +Z CW +magellan: + - T: +X right / +Y up / +Z back + - R: +X CCW / +Y CCW / +Z CCW + +Spaceball id strings +-------------------- Spaceball 1003 (buttons: 8) Firmware version 2.02 created on 11-Jun-1991. @@ -22,13 +28,12 @@ Spaceball 4000 FLX/5000 FLX-A (buttons: 12) Firmware version 2.43 created on 13-Oct-2000 Firmware version 2.45 created on 06-May-2003 (5000 FLX-A) - -Magellan --------- SpaceMouse classic (buttons: 9) MAGELLAN Version 5.49 by LOGITECH INC. 10/22/96 MAGELLAN Version 5.79 by LOGITECH INC. 10/10/97 +Magellan id strings +------------------- SpaceMouse plus (buttons: 9) MAGELLAN Version 6.50 by LogiCad3D GmbH 05/11/00 MAGELLAN Version 6.60 3Dconnexion GmbH 05/11/01 diff --git a/src/main.c b/src/main.c index c39e0ff..3c41acf 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,8 @@ int main(int argc, char **argv) } fd = sball_fd(sb); + printf("Monitoring device, ctrl-c to quit\n"); + while(!quit) { FD_ZERO(&rdset); FD_SET(fd, &rdset); @@ -33,7 +35,9 @@ int main(int argc, char **argv) sball_read(sb); } } + } + putchar('\n'); sball_close(sb); return 0; diff --git a/src/sball.c b/src/sball.c index 627fc1b..4b03040 100644 --- a/src/sball.c +++ b/src/sball.c @@ -26,6 +26,9 @@ struct sball { char buf[INP_BUF_SZ]; int len; + short mot[6]; + unsigned int keystate; + int (*parse)(struct sball*, int, char*, int); }; @@ -42,6 +45,9 @@ static int guess_num_buttons(const char *verstr); static void make_printable(char *buf, int len); static int read_timeout(int fd, char *buf, int bufsz, long tm_usec); +static void print_state(struct sball *sb); + + struct sball *sball_open(const char *dev) { int fd, sz; @@ -88,7 +94,7 @@ struct sball *sball_open(const char *dev) if((sz = read_timeout(fd, buf, sizeof buf - 1, 250000)) > 0 && buf[0] == 'v') { make_printable(buf, sz); - printf("Magellan SpaceMouse detected: %s\n", buf); + printf("Magellan SpaceMouse detected:\n%s\n", buf); sb->nbuttons = guess_num_buttons(buf); printf("%d buttons\n", sb->nbuttons); @@ -137,6 +143,21 @@ int sball_read(struct sball *sb) return 0; } +int sball_axis(struct sball *sb, int axis) +{ + return sb->mot[axis]; +} + +unsigned int sball_buttons(struct sball *sb) +{ + return sb->keystate; +} + +int sball_num_buttons(struct sball *sb) +{ + return sb->nbuttons; +} + /* Labtec spaceball: 9600 8n1 XON/XOFF */ static int stty_sball(int fd) { @@ -222,23 +243,9 @@ static int proc_input(struct sball *sb) return 0; } -static void print_keystate(unsigned int keystate) -{ - int i; - - printf("keystate: "); - for(i=0; i<12; i++) { - int b = 11 - i; - int hex = b < 10 ? b + '0' : b - 10 + 'a'; - putchar(keystate & (1 << b) ? hex : '-'); - } - putchar('\n'); -} - static int mag_parsepkt(struct sball *sb, int id, char *data, int len) { - int i, mot[6]; - unsigned int keystate; + int i; /*printf("magellan packet: %c - %s (%d bytes)\n", (char)id, data, len);*/ @@ -249,11 +256,16 @@ static int mag_parsepkt(struct sball *sb, int id, char *data, int len) return -1; } for(i=0; i<6; i++) { - mot[i] = ((((int)data[0] & 0xf) << 12) | (((int)data[1] & 0xf) << 8) | +#ifdef SBALL_BIG_ENDIAN + sb->mot[i] = ((((int)data[3] & 0xf) << 12) | (((int)data[2] & 0xf) << 8) | + (((int)data[1] & 0xf) << 4) | (data[0] & 0xf)) - 0x8000; +#else + sb->mot[i] = ((((int)data[0] & 0xf) << 12) | (((int)data[1] & 0xf) << 8) | (((int)data[2] & 0xf) << 4) | (data[3] & 0xf)) - 0x8000; +#endif data += 4; } - printf("motion: T %+4d %+4d %+4d R %+4d %+4d %+4d\n", mot[0], mot[1], mot[2], mot[3], mot[4], mot[5]); + print_state(sb); break; case 'k': @@ -261,8 +273,8 @@ static int mag_parsepkt(struct sball *sb, int id, char *data, int len) fprintf(stderr, "magellan: invalid keyboard pakcet, expected 3 bytes, got: %d\n", len); return -1; } - keystate = (data[0] & 0xf) | ((data[1] & 0xf) << 4) | (((unsigned int)data[2] & 0xf) << 8); - print_keystate(keystate); + sb->keystate = (data[0] & 0xf) | ((data[1] & 0xf) << 4) | (((unsigned int)data[2] & 0xf) << 8); + print_state(sb); break; case 'e': @@ -284,9 +296,7 @@ static int mag_parsepkt(struct sball *sb, int id, char *data, int len) static int sball_parsepkt(struct sball *sb, int id, char *data, int len) { int i; - unsigned int keystate; char c, *rd, *wr; - short *mot; /* decode data packet, replacing escaped values with the correct ones */ rd = wr = data; @@ -304,6 +314,7 @@ static int sball_parsepkt(struct sball *sb, int id, char *data, int len) break; case '^': *wr++ = '^'; + break; default: fprintf(stderr, "sball decode: ignoring invalid escape code: %xh\n", (unsigned int)c); } @@ -320,8 +331,18 @@ static int sball_parsepkt(struct sball *sb, int id, char *data, int len) return -1; } - mot = (short*)(data + 2); /* skip the period */ - printf("motion: T %+6d %+6d %+6d R %+6d %+6d %+6d\n", mot[0], mot[1], mot[2], mot[3], mot[4], mot[5]); +#ifndef SBALL_BIG_ENDIAN + for(i=0; i<6; i++) { + data += 2; + c = data[0]; + data[0] = data[1]; + data[1] = c; + sb->mot[i] = *(short*)data; + } +#else + memcpy(sb->mot, data + 2, 12); +#endif + print_state(sb); break; case 'K': @@ -336,9 +357,9 @@ static int sball_parsepkt(struct sball *sb, int id, char *data, int len) * data[0] bits 0-2 -> buttons 4,5,6 * data[0] bit 4 is (2003 pick) -> button 7 */ - keystate = (data[1] & 0xf) | ((data[1] >> 4) & 3) | ((data[0] & 7) << 4) | + sb->keystate = (data[1] & 0xf) | ((data[1] >> 4) & 3) | ((data[0] & 7) << 4) | ((data[0] & 0x10) >> 1); - print_keystate(keystate); + print_state(sb); break; case '.': @@ -348,19 +369,21 @@ static int sball_parsepkt(struct sball *sb, int id, char *data, int len) } /* spaceball 4000 key packet */ sb->flags |= SB4000; - /* update orientation flag */ + /* update orientation flag (actually don't bother) */ + /* if(data[0] & 0x20) { sb->flags |= FLIPXY; } else { sb->flags &= ~FLIPXY; } + */ /* data[1] bits 0-5 -> buttons 0,1,2,3,4,5 * data[1] bit 7 -> button 6 * data[0] bits 0-4 -> buttons 7,8,9,10,11 */ - keystate = (data[1] & 0x3f) | ((data[1] & 0x80) >> 1) | ((data[0] & 0x1f) << 7); - print_keystate(keystate); + sb->keystate = (data[1] & 0x3f) | ((data[1] & 0x80) >> 1) | ((data[0] & 0x1f) << 7); + print_state(sb); break; case 'E': @@ -374,6 +397,9 @@ static int sball_parsepkt(struct sball *sb, int id, char *data, int len) } break; + case 'M': /* ignore MSS responses */ + break; + default: /* DEBUG */ fprintf(stderr, "sball: got '%c' packet:", (char)id); @@ -427,15 +453,15 @@ static int guess_num_buttons(const char *verstr) } } - if(strstr(verstr, "MAGELLAN Version")) { + if(strstr(verstr, "MAGELLAN")) { return 9; /* magellan spacemouse */ } - if(strstr(verstr, "SPACEBALL Version")) { + if(strstr(verstr, "SPACEBALL")) { return 12; /* spaceball 5000 */ } - if(strstr(verstr, "CadMan Version")) { + if(strstr(verstr, "CadMan")) { return 2; } @@ -495,3 +521,28 @@ static int read_timeout(int fd, char *buf, int bufsz, long tm_usec) return sz > 0 ? sz : -1; } +static void print_motion(short *mot) +{ + printf(" T[%+6d %+6d %+6d] R[%+6d %+6d %+6d]", mot[0], mot[1], + mot[2], mot[3], mot[4], mot[5]); +} + +static void print_keystate(unsigned int keystate) +{ + int i; + + for(i=0; i<12; i++) { + int b = 11 - i; + int hex = b < 10 ? b + '0' : b - 10 + 'a'; + putchar(keystate & (1 << b) ? hex : '-'); + } +} + +static void print_state(struct sball *sb) +{ + print_motion(sb->mot); + printf(" B["); + print_keystate(sb->keystate); + printf("]\r"); + fflush(stdout); +} diff --git a/src/sball.h b/src/sball.h index 797e132..507a056 100644 --- a/src/sball.h +++ b/src/sball.h @@ -8,4 +8,8 @@ void sball_close(struct sball *sb); int sball_fd(struct sball *sb); int sball_read(struct sball *sb); +int sball_axis(struct sball *sb, int axis); +unsigned int sball_buttons(struct sball *sb); +int sball_num_buttons(struct sball *sb); + #endif /* SBALL_H_ */