'=========================================================================== ' Subject: JOYSTICK LIBRARY Date: 08-30-00 (14:48) ' Author: Jeremiah Hyde Code: QB, QBasic, PDS ' Origin: fishoffire@yahoo.com Packet: KEYBOARD.ABC '=========================================================================== 'PPPPPP 'PP PP 'PP PP rr rrr oooo ggg gg rr rrr aaaa mm mm eeee rr rrr zzzzzz 'PPPPP rrr rr oo oo gg gg rrr rr aa mmmmmmm ee ee rrr rr z zz 'PP rr rr oo oo gg gg rr rr aaaaa mmmmmmm eeeeee rr rr zz 'PP rr oo oo ggggg rr aa aa mm m mm ee rr zz z 'PP rrrr oooo gg rrrr aaaaa mm mm eeee rrrr zzzzzz ' ggggg ( /\__________/\ ) ' \(^ @___..___@ ^)/ ' ########### /\ (\/\/\/\/) /\ ' # ___ ___ # RRRRR lll !! !! / \(/\/\/\/\)/ \ ' { (0) (0) } RR RR ll !!!! !!!! ( """""""""" ) ' | P | RR RR uu uu ll zzzzzz !!!! !!!! \ _____ / ' \ \___/ / RRRRR uu uu ll z zz !!!! !!!! ( /( )\ ) ' \_____/ RR RR uu uu ll zz !! !! _) (_V) (V_) (_ ' Jeremiah "BJ" RR RR uu uu ll zz z (V)(V)(V) (V)(V)(V) ' Hyde RR RR uuu uu llll zzzzzz !! !! My dog Smokey, ' aka Stupid Mutt ' ' This code released under the GNU General Public License. This means you ' can use it, compile it, pass it around, modify it, WHATEVER! However, ' if you do this, I will expect notification and a copy of whatever you've ' done, unless it's a virus, or breaking into the CIA, etc. ' Jeremiah "BJ" Hyde 'E-Mail me at: fishoffire@yahoo.com fishoffire Industries: ' Visit me at: www.fishoffire.com Your source for ' EVERYTHING QBasic 'Note: ' This code has been tested on my machines: ' ASUS TX97x WOA: AMD K6-266, 160MB RAM, 20.5 GB HD, 15" PnP(SVGA+) Monitor, ' Win98 DOSBox ' AT&T Globalyst 520: Intel 486 DX 66mhz, 19MB RAM, 14" SVGA Monitor, ' Win95 DOSBox ' Compaq Deskpro 4/33i: Intel 386 33mhz, 4MB RAM, 14" SVGA Monitor, ' MS-DOS 6.22/Win3.11 ' and has run correctly under those environments. However, no guarantee, ' warranty, or any other declaration of safety, etc. is offered. If your ' computer system is taken over by smurfs, or the ROM is RAMed, or ' anything else of a detrimental nature happens to your PC as a result ' of this code, I am *not* responsible for it. The full burden of blame ' rests squarely on your shoulders.(Of course, if something GOOD happens to ' your computer as a result of this code, well, obviously, I did it!) ' ------------- ' In other words: You're on your own, pal! ' This piece of code is one of the simplest joystick libraries out there. ' Not only does it handle 4 buttons, a rudder, AND a 4-position hat-switch, ' but it is about a bajillion times faster than QB's STRIG and STICK commands. ' At least, on my PCs it is. Anyway, I figure its more useful as a tutorial ' or learning code, than as a finished product to drop into your game. ' BTW: If you want to use this in a commercial program email me ' and we'll talk. ' Okay, enough chatter, time to get to the CODE!!! DEFINT A-Z ' Ahh, the holy DEFINT command! ' At last! Clear, fast(?) and simple joystick routines! DECLARE SUB jsCalibrate () ' Yes, I think we know what calibrating ' is. And yes, you DO have to call it ' before jsGet%(). However, jsGetRaw% is ' fine to call whenever. DECLARE FUNCTION jsGet% (Value%) ' Hmm...Lemme guess what this does...Well ' DUHH! It gets values from the joystick! ' Value%=0 | return buttons as bitfield ' =1 | return X-coordinate(values ' | scaled from -100 to 100) ' =2 | return Y-coordinate(values ' | scaled from -100 to 100) ' =3 | return Z-coordinate(values ' | scaled from -100 to 100) ' =4 | return hat-switch. 0=center, ' | 1=up,2=right,3=down,4=left DECLARE FUNCTION jsGetRaw% (Value%) ' This, obviously, returns the raw data ' straight from the joystick. Use this if ' you don't want to calibrate, or you ' just can't stand my coordinate scheme. ' The joystick port! There should never be any reason to change this. ' At least, I can't think of any. On a different port, all kinds of ' NASTY things could happen(ex: low-level hard-drive formatting). CONST jsPort = &H201 ' This can be anything from &H200 to &H207. It doesn't ' seem to make any difference. ' The value to send to the port! When you write to the joystick port, ' the lower nybble of data from the port remain set for as many port ' reads as the value of that particular coordinate. So, you read until ' a bit goes dead, and the number of reads is the value of that coordinate. ' This CONST is only here because someday, I might find a stick that ' requires a particular value to read say, its Q-coordinate, or the other ' 16 positions on its hat-switch. CONST jsInitVal = 0 ' These variables are used by jsGet%, to scale the values from the ' joystick to a 100x100 playing area, and to calibrate the hat switch. ' They are all set by jsCalibrate, and could be used in conjungtion(sp?!?!) ' with jsGetRaw% to make your own jsGet% DIM SHARED jsCenterX% ' Center X DIM SHARED jsCenterY% ' Center Y DIM SHARED jsCenterZ% ' Center Rudder DIM SHARED jsMaxX% '\ DIM SHARED jsMinX% ' \ DIM SHARED jsMaxY% ' \__Limits DIM SHARED jsMinY% ' / DIM SHARED jsMaxZ% ' / DIM SHARED jsMinZ% '/ DIM SHARED jsHatUp% '\ DIM SHARED jsHatRight% ' \__Hat switch positions DIM SHARED jsHatDown% ' / DIM SHARED jsHatLeft% '/ DIM SHARED jsDeadZone% ' How much the stick can move ' without the program noticing. ' Ahh, the unholy demo. This demo should be deleted within seconds of ' your downloading this file. It was used only for me to ensure I had ' it all right, and displays all the current values from the joystick CLS jsCalibrate ' Calibrate the joystick. No NASTY comments about my anti-GUI. CLS DO ' The main loop. Read the values, print 'em, then do it again. LOCATE 1, 1 PRINT "Buttons: "; tmpBtn% = jsGet%(0) IF tmpBtn% AND 1 THEN PRINT " "; ELSE PRINT " A "; IF tmpBtn% AND 2 THEN PRINT " "; ELSE PRINT " B "; IF tmpBtn% AND 4 THEN PRINT " "; ELSE PRINT " C "; IF tmpBtn% AND 8 THEN PRINT " "; ELSE PRINT " D "; PRINT "" PRINT " X-Pos: "; jsGet%(1); " " PRINT " Y-Pos: "; jsGet%(2); " " PRINT " Rudder: "; jsGet%(3); " " PRINT " HatSw: "; jsGet%(4) ' There should probably be a delay loop here, but ' I never had any need for it. Also, if your computer ' is slow enough, the read from the joystick will be ' more than enough of a drag LOOP UNTIL INKEY$ = CHR$(27) SUB jsCalibrate jsDeadZone% = 6 PRINT "Center joystick, and press ." GOSUB Pause jsCenterX% = jsGetRaw%(1) jsCenterY% = jsGetRaw%(2) jsCenterZ% = jsGetRaw%(3) PRINT "Move joystick all the way to the top-left corner, and press " GOSUB Pause jsMinX% = jsGetRaw%(1) jsMinY% = jsGetRaw%(2) PRINT "Move joystick all the way to the bottom-right corner, and press " GOSUB Pause jsMaxX% = jsGetRaw%(1) jsMaxY% = jsGetRaw%(2) PRINT "Does your joystick have a Z-axis(rudder)? "; DO: key$ = UCASE$(INKEY$): LOOP UNTIL key$ = "Y" OR key$ = "N" PRINT key$ IF key$ = "Y" THEN PRINT "Move the rudder all the way to the left, and press " GOSUB Pause jsMinZ% = jsGetRaw%(3) PRINT "Move the rudder all the way to the right, and press " GOSUB Pause jsMaxZ% = jsGetRaw%(3) END IF PRINT "Does your joystick have a hat-switch? "; DO: key$ = UCASE$(INKEY$): LOOP UNTIL key$ = "Y" OR key$ = "N" PRINT key$ IF key$ = "Y" THEN PRINT "Move the hat-switch to the top, and press " GOSUB Pause jsHatUp% = jsGetRaw%(4) PRINT "Move the hat-switch to the right, and press " GOSUB Pause jsHatRight% = jsGetRaw%(4) PRINT "Move the hat-switch to the bottom, and press " GOSUB Pause jsHatDown% = jsGetRaw%(4) PRINT "Move the hat-switch to the left, and press " GOSUB Pause jsHatLeft% = jsGetRaw%(4) END IF PRINT "Joystick succesfully calibrated!" EXIT SUB Pause: DO: LOOP UNTIL INKEY$ = "" ' Clear keyboard DO: LOOP UNTIL INKEY$ = CHR$(13) ' Wait for RETURN END SUB FUNCTION jsGet% (Value%) ' Return a current joystick value ' Value%= ' ------------------------------------ ' 0, return buttons as bitfield ' = 1, = 2, = 4, = 8 ' 1, return current X-position. X is scaled from -100 to 100, ' to make things easier. ' 2, return current Y-position. Y is scaled from -100 to 100. ' 3, return current Z-position(rudder). Z is scaled from -100 to 100. ' 4, return current hat-switch position. Returns 0=Center, 1=Up, 2=Right, ' 3=Down, 4=Left. SELECT CASE Value% CASE 0 ' Buttons jsGet% = jsGetRaw%(0)' Get buttons as bit-field. 1=A, 2=B, 4=C, 8=D CASE 1 ' X-Position X% = jsGetRaw%(1) - jsCenterX% IF X% < 0 THEN X% = (X% / (jsCenterX% - jsMinX%)) * 100 ELSE X% = (X% / (jsMaxX% - jsCenterX%)) * 100 END IF IF ABS(X%) <= jsDeadZone% THEN X% = 0 jsGet% = X% CASE 2 ' Y-Position Y% = jsGetRaw%(2) - jsCenterY% IF Y% < 0 THEN Y% = -(Y% / (jsCenterY% - jsMinY%)) * 100 ELSE Y% = -(Y% / (jsMaxY% - jsCenterY%)) * 100 END IF IF ABS(Y%) <= jsDeadZone% THEN Y% = 0 jsGet% = Y% CASE 3 ' Z-Position, rudder Z% = jsGetRaw%(3) - jsCenterZ% IF Z% < 0 THEN Z% = (Z% / (jsCenterZ% - jsMinZ%)) * 100 ELSE Z% = (Z% / (jsMaxZ% - jsCenterZ%)) * 100 END IF IF ABS(Z%) <= jsDeadZone% THEN Z% = 0 jsGet% = Z% CASE 4 ' Hat-switch tmpHat% = jsGetRaw%(4) Hat% = 0 ' IF tmpHat% IS WITHIN 5 OF jsHatUp% THEN Hat% = 1 ' IF tmpHat% IS . . . IF (((tmpHat% + 5) > jsHatUp%) AND ((tmpHat% - 5) < jsHatUp%)) THEN Hat% = 1 IF (((tmpHat% + 5) > jsHatRight%) AND ((tmpHat% - 5) < jsHatRight%)) THEN Hat% = 2 IF (((tmpHat% + 5) > jsHatDown%) AND ((tmpHat% - 5) < jsHatDown%)) THEN Hat% = 3 IF (((tmpHat% + 5) > jsHatLeft%) AND ((tmpHat% - 5) < jsHatLeft%)) THEN Hat% = 4 jsGet% = Hat% CASE ELSE ERROR 5 END SELECT END FUNCTION FUNCTION jsGetRaw% (Value%) ' Returns the current position of the joystick. ' This is RAW, straight from port &H200. ' Coord%=0, return buttons as a bitfield ' Coord%=1, return X-coord ' Coord%=2, return Y-coord ' Coord%=3, return Z-coord ' Coord%=4, return hat-switch ' Anything else, return -1 SELECT CASE Value% CASE 0 tmp% = INP(jsPort) tmp% = ((NOT (tmp% \ 16)) AND 15) Coord% = tmp% CASE 1 OUT jsPort, jsInitVal DO tmp% = INP(jsPort) IF tmp% AND 1 THEN Coord% = Coord% + 1 LOOP UNTIL (tmp% AND 1) = 0 CASE 2 OUT jsPort, jsInitVal DO tmp% = INP(jsPort) IF tmp% AND 2 THEN Coord% = Coord% + 1 LOOP UNTIL (tmp% AND 2) = 0 CASE 3 OUT jsPort, jsInitVal DO tmp% = INP(jsPort) IF tmp% AND 4 THEN Coord% = Coord% + 1 LOOP UNTIL (tmp% AND 4) = 0 CASE 4 OUT jsPort, jsInitVal DO tmp% = INP(jsPort) IF tmp% AND 8 THEN Coord% = Coord% + 1 LOOP UNTIL (tmp% AND 8) = 0 CASE ELSE Coord% = -1 END SELECT jsGetRaw% = Coord% END FUNCTION