Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Touch Broken #259

Open
Juason opened this issue Nov 1, 2015 · 11 comments
Open

Android Touch Broken #259

Juason opened this issue Nov 1, 2015 · 11 comments
Labels

Comments

@Juason
Copy link

Juason commented Nov 1, 2015

Howdy folks. I followed the Android instructions on the Wiki for setting up my development environment. My game compiles, downloads and launches on my Samsung Galaxy S3. However, the touch input is broken.

From my debugging in Eclipse I can see the first DOWN touch event occur. Then when a second finger presses I get two more DOWN touch events. When I release the second finger, only 1 UP event fires. Then when the second finger releases I get only 1 more UP event.

This results in the array indeces for touch events getting out of wack. After the first multi-touch the engine believes one finger is still down. So all single-touches act like zooming. After a second multi-touch, it believes 2 fingers are always down and touch input tends to cease working.

As these events are called from outside engine, I'm not entirely sure what is breaking or how to fix it just yet.

@marauder2k7
Copy link
Contributor

marauder2k7 commented Sep 14, 2019

I think im running into this problem, it may be due to

Point2I rawLastTouches[10];

because after 10 or so multi touches on any device it fails and reverts back to registering just 1 touch event

This is the only resource i have found so far on mutli touch events for android

 @Override
    public boolean onTouchEvent(MotionEvent event) {

        // get pointer index from the event object
        int pointerIndex = event.getActionIndex();

        // get pointer ID
        int pointerId = event.getPointerId(pointerIndex);

        // get masked (not specific to a pointer) action
        int maskedAction = event.getActionMasked();

        switch (maskedAction) {

        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN: {
            // We have a new pointer. Lets add it to the list of pointers

            PointF f = new PointF();
            f.x = event.getX(pointerIndex);
            f.y = event.getY(pointerIndex);
            mActivePointers.put(pointerId, f);
            break;
        }
        case MotionEvent.ACTION_MOVE: { // a pointer was moved
            for (int size = event.getPointerCount(), i = 0; i < size; i++) {
                PointF point = mActivePointers.get(event.getPointerId(i));
                if (point != null) {
                    point.x = event.getX(i);
                    point.y = event.getY(i);
                }
            }
            break;
        }
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL: {
            mActivePointers.remove(pointerId);
            break;
        }
        }
        invalidate();

        return true;
    }


@marauder2k7
Copy link
Contributor

it seems setting the MAX_TOUCH_EVENTS in AndroidInput.cpp to a higher value the multi touch lasts longer but still stops working

@greenfire27
Copy link
Contributor

Well it sounds like you're on the right trail. The touch event code is... complicated.

@marauder2k7
Copy link
Contributor

pull request with a quick and dirty fix put up

@greenfire27
Copy link
Contributor

Can you explain what you did to fix this? Just reading the code it looks like it will never exit early now if there's not a double touch event.

@marauder2k7
Copy link
Contributor

marauder2k7 commented Sep 14, 2019

when a touchUp is detected in the engine it is passed as a createMouseUpEvent to the AndroidInput.cpp

in the create mouse event

S32 currentSlot was being passed a value of -1

then this was being checked here

for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )

i removed this value from currentSlot and removed the check so this is always going to be true
for( int i = 0 ; i < MAX_TOUCH_EVENTS ; i++ )

for some reason i think this code


if(( (x == lastTouches[i].lastX) && (y == lastTouches[i].lastY )) ||
		   ( (lastX == lastTouches[i].lastX ) && (lastY == lastTouches[i].lastY )))
		{
			currentSlot = i;
		}

i don't think was passing the correct values to currentSlot and so currentSlot stayed as -1 which then called this

if( currentSlot == -1 ) 
        return false;

this way the slot was never being freed and the engine kept on reaching max_touch and wasn't allowing any more multi-touch events

this is an extremely hacky way of fixing the problem, i just needed to roll out a fix quickly to my app. It does work but im not too sure if slots are actually being freed up without putting logs to the console at each point to check it out.

@greenfire27
Copy link
Contributor

So I've buried myself in trying to understand this and here's what I've come up with. The problem is with the system that's supposed to match touchDown and touchUp events. Normally, the matching events would have a matching touchID. The for loop in the touch up code is just trying to make that match and for some reason never finds it and exits without throwing the actual touchUp event.

Now, what you've done is basically to guarantee that the touchUp event will fire by breaking the system thus quickly fixing the bug. However, you did so in a way that's hard on the engine. Those for loops are now useless and by increasing the max touch events to 16 you forced them to walk through 16 iterations every event even though they don't do anything. You could have broken it better by changing the max touch events to 0 and commenting out the early return in the touchUp function.

However, it would be even better to actually fix the bug. We know the if statement inside the for loop in the touchUp function works because it works for the first few touch events until max touch events is used up. So I think the bug is just that those touch event slots are not being released after they are used. Basically we just need a single line of code at the end of the touchUp function that returns the slot to a state that will allow the touchDown function to use it again.

Game->postEvent(event);

lastTouches[currentSlot].lastX = -1;

return true;//return false if we get bad values or something

This will allow that slot to become vacant again and should cause the whole bug to go away without breaking functionality. Can you please revert your changes on the file and see if this change fixes the bug?

@marauder2k7
Copy link
Contributor

after reverting back and putting that in it breaks multi touch after the same amount of tries as original =/

@greenfire27
Copy link
Contributor

Can you try just commenting out the early return in the touchUp function. That should also fix it, although it's still a hack.

@marauder2k7
Copy link
Contributor

marauder2k7 commented Sep 15, 2019

i commented it out and still the same result which only makes this even weirder =/

what does work is just commenting out the early return in createMouseDownEvent and the early return in createMouseUpEvent and i think i might know why.

bool createMouseDownEvent( S32 touchNumber, S32 x, S32 y, U32 numTouches )
{
    S32 vacantSlot = -1;

    if (Canvas == NULL)
        return false;

    for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (vacantSlot == -1) ; i++ )
    {
        if( lastTouches[i].lastX == -1 )
        {
            vacantSlot = i;
        }
    }

in thats block of code lastX is referenced but is never passed a value?

@greenfire27
Copy link
Contributor

LastX is initialized on line 196 in the init function. The problem is simply that all the slots for tacking these down/up pairs are getting used up and not being set back to -1 when then are done. Since there's no slots they exit early and removing that exit stops the bug, but it still doesn't give us the slots back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants