Posted: 25th Nov 2021 1:35
I am trying to understand why this is happening. I have some code below that looks for a swipe left or right.

I only look at the touch position if GetPointerstate()

During the touch event GetRawTouchCurrentX() returns correct values. However, after the finger is lifted, it returns a zero even while GetPointerstate() is still true.
I expect GetRawTouchCurrentX() to return actual values until GetPointerstate() returns zero.

Here is the code the demonstrates the issue:

+ Code Snippet
iTouch as integer
msg as String
tx as float // initial touch position
swipe as float // distance swiped, negative to left, positive to right
bIncludeUnknown  as integer = 1 // all touch events
do
	if GetPointerstate() = 1 // pointer is down
		iTouch = GetRawFirstTouchEvent(bIncludeUnknown )
		tx = GetRawTouchStartX(iTouch) // this is where the touch event started
	
		while GetPointerstate()=1  // finger is still in touch
			
			//if GetRawTouchCurrentx(iTouch) > 0.0 // How can this be zero if finger never touches the left edge?
				swipe = GetRawTouchCurrentx(iTouch) - tx // distance has the finger moved
			//endif
			print(swipe) // show that DURING the touch event we get correct values
			msg = "last swipe start:" + str(tx) + " swipe:" + str(swipe) // keep the values to show after the event
			sync() // update screen during the finger movement
		endwhile	// finger on screen
	endif // pointer down
	print(msg) // show the result obtained in the last pass through the while loop

	sync()
loop


When running the code, swipe your finger left or right, it can be seen that the swipe value is correct DURING the touch event but as soon as the event ends, it is always negative, even if you moved from left to right.
This is because GetRawTouchCurrentX() returned a zero and the original start position is subtracted from zero.

If you then uncomment the if and endif that checks for GetRawTouchCurrentX() returning 0.0 the code works as one would expect.
Even if one inspects the return value of GetPointerstate() after GetRawTouchCurrentX() one sees it is still non-zero so it not that the finger is being lifted between the execution of the GetPointerstate() and GetRawTouchCurrentX() calls.

Note that when moving the finger from left to right, and the initial position (tx) is positive, at no time is the finger ever at x position zero. Yet GetRawTouchCurrentX() returns 0.0

Excluding iterations where GetRawTouchCurrentX() = 0.0 avoids the problem for most cases but of course would fail if GetRawTouchCurrentX() is supposed to be zero.

This happens to me on Android 12

Can others reproduce this?
Am I missing something ?

The problem may be that GetPointerstate() is returning true for too long.
Posted: 25th Nov 2021 2:37
well,
+ Code Snippet
while not GetRawTouchReleased( iTouch )


works much better!
I guess GetRawTouchReleased( ) is more responsive.

It implies that GetRawTouchReleased( ) and GetPointerstate() can both be true at the same time, but I have not tested that.
Posted: 25th Nov 2021 16:18
Bear in mind, Touch functions use dedicated touch libs, Pointer use wrapped generic OS libs ....

This is an emulated input method that uses whatever device inputs are available to produce a screen pointer.


I would not expect GetPointerState to be compatible with Touch functions without producing some side effects, use all RawTouch
Posted: 26th Nov 2021 21:37
after the finger is lifted, it returns a zero


This is when flags are important I believe.

So holding a value in a different flag might help.

if GetPointerstate()=1 then mypointflag=1

if mypointflag=1
do what ever
endif

Your saying

while GetPointerstate()=1

So for the state to be always active

+ Code Snippet
while mypointflag=1

            //if GetRawTouchCurrentx(iTouch) > 0.0 // How can this be zero if finger never touches the left edge?
                swipe = GetRawTouchCurrentx(iTouch) - tx // distance has the finger moved
            //endif
            print(swipe) // show that DURING the touch event we get correct values
            msg = "last swipe start:" + str(tx) + " swipe:" + str(swipe) // keep the values to show after the event
            sync() // update screen during the finger movement
        endwhile    // finger on screen
    endif // pointer down
    print(msg) // show the result obtained in the last pass through the while loop
 
    sync()
Posted: 26th Nov 2021 22:32
if GetPointerstate()=1 then mypointflag=1


well keeping a copy of the fact that the pointer was down in a separate flag, that never gets updated, would mean the loop would repeat forever. The object of the while loop is to only loop while the pointer is pressed.

So your suggestion would be the same at

+ Code Snippet
if GetPointerstate()=1
 while 1 // always true
       //stuff done forever
endwhile
endif


We don't want to only loop forever, only while the pointer is down. We need to loop until the pointer is released so that we can get the x coordinate.
The bugs is that after we are told the pointer is still down, after it has in fact been released, so we then we get an incorrect value of the pointer X coordinate.
We cant keep a copy of the last 'good' return value because we don't know when it is the last good call.
The workaround for the bug is to check if we get a zero and ignore that value. That workaround would, however, fail if the correct result happened to be a zero.
Posted: 27th Nov 2021 0:00
this might help with Swipes: https://forum.thegamecreators.com/thread/195049

i think it's part of the larger Useful Community Functions (UCF) project listed referenced HERE.

meanwhile THIS re: inertia scroll/swipes mentions an android "bug" that was "fixed".
Posted: 27th Nov 2021 2:07
We don't want to only loop forever


Yes and this is a good way to stop the loop

If pointerisrelesed=1 then mypointflag=0

I understand where your going but if I had to do this and I have lately this is what I did.
Posted: 27th Nov 2021 2:54
If pointerisrelesed=1 then mypointflag=0


There is no pointer release function. As I mentioned above there is a GetRawTouchReleased() function which does not return a false result (but does not work with a mouse on Windows)

All your code is doing is making a copy of the bad data. Using a copy of the bad data will not make a difference.
The workaround using the 'pointer' call is to check for a zero value and ignore it.

As as I said, I could also get it to work with GetRawTouchReleased() but because of the platform limitation of rawtouch calls, I have gone back to using 'pointer' and check for zero.

Part of the aim of this post is to check that I have not made a stupid coding error before writing up a bug report. It helps to have other eyes pick up something I have missed.

@VirtualNomad, thanks, I'll check out those links and bug to see if they are related before submitting a bug.
Posted: 27th Nov 2021 3:00
GetRawMouseReleased() is what I use, it works the same way on all devises I've tested it on.

Mabey it will work, I don't know.

I find it funny how there is raw mouse and raw touch commands that do the same things.
Posted: 27th Nov 2021 3:17
Indeed, it looks like IronManhood ran into the same bug:

Edit: Found a bug. Seems like on android it takes an extra frame to reset the pointer button commands.


This describes the same symptom.

I suspect that by
Edit: Fixed.

he means he also worked around the problem, not that the bug got fixed.
Posted: 3rd Dec 2021 4:42
I find it funny how there is raw mouse and raw touch commands that do the same things.


They do not do the same things, they may look similar but internally they use different messaging and callback systems, mouse: for example does not support multitouch, the latter is processed in a completely different way to mouse, if your game uses both (desktop and mobile0 you need to separate the logic.

entions an android "bug" that was "fixed".


Its not a bug, Android is waiting to process the input type, a long tap for example needs to process a few frames to register, so does a drag or swipe event, its the nature of multitouch and input gestures on capacitive input devices, this is why you MUST use only raw touch functions as a set because they work in conjunction with each other and are not compatible with raw mouse or pointer functions .....

a press and release on the droid needs at least 2 frames, if the press is still valid after frame 2 then it waits to process a long tap (about 3 seconds I think, depending on the device and your settings) if its still a press after that time its a touch, if on the second frame its not pressed it is a tap ..... if you think about it, it makes perfect sense.
Posted: 3rd Dec 2021 4:47
Here, this explains it better

Possible return values are 0 to indicate unknown, 1 for a short touch, 2 for a hold and 3 for dragging.