JoyHit does the same as JoyDown

Archives Forums/Blitz3D Bug Reports/JoyHit does the same as JoyDown

Teddyfles(Posted 2006) [#1]
I just noticed something rather strange. It seems like the JoyHit command doesn't work properly. The following is taken straight from the Blitz3D documentation:

; JoyHit Example

; Set up the timer
current=MilliSecs()
Print "Press FireButton 1 a bunch of times for five seconds..."

; Wait 5 seconds
While MilliSecs() < current+5000
Wend

; Print the results
Print "Pressed button " + JoyHit(1) + " times."

For me this program always tells me I hit the button 0 times. Only when I hold down the button until the end it says I pressed it 1 time. Did the behavior of JoyHit and JoyDown get mixed up?


EDIT: I just did another test and found out that JoyHit and JoyDown actually do not behave exactly the same.

Try keeping Button 1 down while running this:

Print JoyHit(1)
Print JoyHit(1)
Print JoyDown(1)
Print JoyDown(1)

It gave me the output:
1
0
1
1

So JoyHit and JoyDown don't do the same thing, but JoyHit is still broken I think. In this example the first JoyHit should return 0, because I started holding down the button before I ran the program. Also, as shown in my first example, JoyHit never returns an integer higher than 1.


Jams(Posted 2006) [#2]
Your second example is expected behaviour:

Print JoyHit(1)
Print JoyHit(1)
Print JoyDown(1)
Print JoyDown(1)


If you're holding down the button when running this - output of 1, 0, 1, 1 is entirely correct, since you've pressed the button once (not twice), and are holding it down...

"the first JoyHit should return 0, because I started holding down the button before I ran the program"

Flushjoy() when you program starts :)

I can't offer an explanation why the first example doesn't work for you though..


Teddyfles(Posted 2006) [#3]
Actually, I'm pretty sure 1, 0, 1, 1 is incorrect, Jams.

Because you press the button BEFORE the program starts, it shouldn't count as a JoyHit.

Here, try this:

Print KeyHit(66)

Just that line. Press and hold down F8 (that's scancode 66) and after that run the program. It will print 0, because the program didn't register the pressing down of F8. That is the correct behavior. Should be the same with JoyHit, but it isn't.


TomToad(Posted 2006) [#4]
Windows sends an EVENT_KEYDOWN when a key is pressed and the program can only recieve it when the program is running. On the otherhand, the joystick must be polled individually. Blitz starts running, sees that the button is pressed, then sets JoyHit to 1.

However there does seem to be a bug
Graphics 640,480,0
SetBuffer BackBuffer()

JF = 0
JC = 0
While Not KeyHit(1)
 Cls
 If KeyHit(57)
  time = MilliSecs()
  Repeat
   Cls
   Text 10,10,"Waiting... "+(5000-(MilliSecs()-time))
   Flip
  Until MilliSecs() - time > 5000
 End If
 JH = JoyHit(1)
 JC = JC + JH
 JD = JoyDown(1)
 If JH Then JF = 1 - JF
 Text 10,10,"JoyHit = "+JC
 Text 10,30,"JoyDown = "+JD
 If JF
  Color 255,0,0
 Else
  Color 255,255,255
 End If
 Oval 100,10,10,10
 Color 255,255,255
 Flip
Wend

When you run the program, it prints the total number of times you pressed the joybutton and also returns the JoyDown status. When you press SPACE, it will delay for 5 seconds. If you press the joybutton during this time, it should increment the joyhit value accordinly, but it doesn't. It seems that JoyHit behaves just like JoyDown except that it reads the button only once per press instead of every call.


Yan(Posted 2006) [#5]
AFAIK the joyHit() command returns the number of times the button was hit between calls to JoyHit(), so it needs to be called at least twice to work...
; JoyHit Example

; Set up the timer
current=MilliSecs()
Print "Press FireButton 1 a bunch of times for five seconds..."
Delay(100)

Print JoyHit(1)

; Wait 5 seconds
While MilliSecs() < current+5000
Wend

; Print the results
Print "Pressed button " + JoyHit(1) + " times."

WaitKey()
Although having said that, I can only ever get it to register one hit?


TomToad(Posted 2006) [#6]
Aha! I figured it out. JoyHit only polls the button when a joystick command is executed. If you modify the above program to read
Graphics 640,480,0
SetBuffer BackBuffer()

JF = 0
JC = 0
While Not KeyHit(1)
 Cls
 If KeyHit(57)
  time = MilliSecs()
  Repeat
   Cls
   Text 10,10,"Waiting... "+(5000-(MilliSecs()-time))
   a = JoyX() ;Added this line!!!!!!!
   Flip
  Until MilliSecs() - time > 5000
 End If
 JH = JoyHit(1)
 JC = JC + JH
 JD = JoyDown(1)
 If JH Then JF = 1 - JF
 Text 10,10,"JoyHit = "+JC
 Text 10,30,"JoyDown = "+JD
 If JF
  Color 255,0,0
 Else
  Color 255,255,255
 End If
 Oval 100,10,10,10
 Color 255,255,255
 Flip
Wend

Line 31 has been changed to poll JoyX() every loop in the delay cycle. This causes JoyHit to behave like expected.


skidracer(Posted 2006) [#7]
Calling joyx or any other joystick command that polls the joystick inside the while..wend seems to fix it.


Teddyfles(Posted 2006) [#8]
Oops, sorry, double post.


Teddyfles(Posted 2006) [#9]
Calling joyx or any other joystick command that polls the joystick inside the while..wend seems to fix it.

Hm, yes, that workaround seems to fix it. Although I just tried it in the game I'm writing, and now something else seems wrong. Almost as if two button-hits cancel each other out. But when I press the button a third time it registers again. Same for any other even and unever number of button-hits. But I don't really have time to look into it now.

EDIT: Ok, I found out why the above was happening (two button-hits cancelling each other out). It had to do with my program doing a bitwise-And instead of a logic-And.

Anyway, still it would be nice if the JoyHit thing could be fixed though. The JoyX workaround kind of works, but not really. All it does is put in an extra check for joystick activity. But imagine a game that draws a lot to the screen (resulting in low framerate) and the user presses the joystick button while Blitz is drawing to the screen. The button-hit won't be registered because Blitz at that moment doesn't see any JoyX or JoyHit commands.