Customized Joystick using keyboard remapping instead of device driver
Purpose: To create a custom interface for my favorite game Joint Operations without having to figure out how to make a joystick driver in Windows.
The work around: Making a serial connection between the propeller based joystick control and a Visual Basic program that uses sendkey to make the keyboard presses in response.
Current progress: I can use a thumb joystick to send a single alphanumeric code to the Visual Basic program that does send out the key press to window programs like notepad.
Current roadblock 1: DirectX programs use directinput that sendkey does not work with. I can send numbers but not letters of the keyboard.
Current roadblock 2: Repeating keys. Don't mind the directional keys causing multiple key presses, but the joystick button (and future buttons) are going to toggle weapons like rifle/grenade.
The work around: Making a serial connection between the propeller based joystick control and a Visual Basic program that uses sendkey to make the keyboard presses in response.
Current progress: I can use a thumb joystick to send a single alphanumeric code to the Visual Basic program that does send out the key press to window programs like notepad.
Current roadblock 1: DirectX programs use directinput that sendkey does not work with. I can send numbers but not letters of the keyboard.
Current roadblock 2: Repeating keys. Don't mind the directional keys causing multiple key presses, but the joystick button (and future buttons) are going to toggle weapons like rifle/grenade.
CON _CLKMODE = xtal1 + pll16x '80_000_000 times a sec _XINFREQ = 5_000_000 ' 5MHz Crystal VAR long RCStack[16],RC2[16] long RCTemp,rctemp2 long Mode,toggle long cog,cog2,x,y,buttonpressed,lr,tb OBJ 'vp : "Conduit" pst : "Parallax Serial Terminal" PUB Main 'vp.config(string("start:dso")) 'vp.config(string("var:call1,call2,x,y,button")) 'vp.config(string("dso:view=[y(offset=5.463e+07,scale=4e+08),x(offset=122.5,scale=1000),button(offset=0,scale=1)],timescale=0.5s,ymode=manual")) 'vp.share(@cog,@tb) pst.Start(9600) start1(0,1,@x) start2(4,1,@y) dira[3]~ toggle:=1 repeat buttonpressed := ina[3] if x > 1_400 and x < 1_800 lr := 0 elseif x > 1_800 lr := 1 elseif x < 1_400 lr:= 2 if y > 1_400 and y < 1_800 tb := 0 elseif y > 1_800 tb := 1 elseif x < 1_400 tb:= 2 case lr 0: case tb 0: pst.str(string("A")) 1: pst.str(string("B")) 2: pst.str(string("C")) 1: case tb 0: pst.str(string("D")) 1: pst.str(string("E")) 2: pst.str(string("F")) 2: case tb 0: pst.str(string("G")) 1: pst.str(string("H")) 2: pst.str(string("I")) if buttonpressed if toggle == 1 pst.str(string("J")) toggle:=0 else pst.str(string("K")) toggle:=1 PUB start1(Pin,State,RCValueAddress) '' Start RCTIME - starts a cog '' returns false if no cog available '' '' RCTIME_ptr = pointer to RCTIME parameters 'stop cog := cognew(RCTIME(Pin,State,RCValueAddress),@RCStack) PUB start2(Pin,State,RCValueAddress) '' Start RCTIME - starts a cog '' returns false if no cog available '' '' RCTIME_ptr = pointer to RCTIME parameters 'stop cog2 := cognew(RCTIME2(Pin,State,RCValueAddress),@RC2) PUB RCTIME(Pin,State,RCValueAddress) repeat outa[Pin] := State 'make I/O an output in the State you wish to measure... and then charge cap dira[Pin] := 1 Pause1ms(1) 'pause for 1mS to charge cap dira[Pin] := 0 'make I/O an input RCTemp := cnt 'grab clock tick counter value WAITPEQ(1-State,|< Pin,0) 'wait until pin goes into the opposite state you wish to measure; State: 1=discharge 0=charge RCTemp := cnt - RCTemp 'see how many clock cycles passed until desired State changed RCTemp := RCTemp - 1600 'offset adjustment (entry and exit clock cycles Note: this can vary slightly with code changes) RCTemp := RCTemp >> 4 'scale result (divide by 16) <<-number of clock cycles per itteration loop long [RCValueAddress] := RCTemp 'Write RCTemp to RCValue PUB RCTIME2(Pin,State,RCValueAddress) repeat outa[Pin] := State 'make I/O an output in the State you wish to measure... and then charge cap dira[Pin] := 1 Pause1ms(1) 'pause for 1mS to charge cap dira[Pin] := 0 'make I/O an input RCTemp2 := cnt 'grab clock tick counter value WAITPEQ(1-State,|< Pin,0) 'wait until pin goes into the opposite state you wish to measure; State: 1=discharge 0=charge RCTemp2 := cnt - RCTemp2 'see how many clock cycles passed until desired State changed RCTemp2 := RCTemp2 - 1600 'offset adjustment (entry and exit clock cycles Note: this can vary slightly with code changes) RCTemp2 := RCTemp2 >> 4 'scale result (divide by 16) <<-number of clock cycles per itteration loop long [RCValueAddress] := RCTemp2 'Write RCTemp to RCValue PUB Pause1ms(Period)|ClkCycles {{Pause execution for Period (in units of 1 ms).}} ClkCycles := ((clkfreq / 1000 * Period) - 4296) #> 381 'Calculate 1 ms time unit waitcnt(ClkCycles + cnt) 'Wait for designated time