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
