I am working on a SDL2 project that I have ported to iOS. I am having trouble getting 2 touches to register to use as game controls.
The controls work like this:
iOS Device
+---------------+
| F | | |
|-------| L | R |
| B | | |
+---------------+
F - Move forward
B - Move backwards
L - Turn left
R - Turn right
The player should be able to move forward and turn at the same time - which means I have to handle two individual touches at the same time that are NOT a multitouch gesture.
Here is a sample of the code that does this in my project.
while (SDL_PollEvent(&event)) {
printf("event %#010x\n", event.type);
switch (event.type) {
case SDL_FINGERDOWN:
//case SDL_FINGERMOTION:
if (event.tfinger.x < 0.5) {
lastMoveFinger = event.tfinger.fingerId;
isMoving = true;
if (event.tfinger.y < 0.5) {
mvForward = true;
} else {
mvForward = false;
}
} else {
lastTurnFinger = event.tfinger.fingerId;
isTurning = true;
if (event.tfinger.x < 0.75) {
turnRight = false;
} else {
turnRight = true;
}
}
break;
case SDL_FINGERUP:
if (event.tfinger.x < 0.5 || event.tfinger.fingerId == lastMoveFinger) {
lastMoveFinger = -1;
isMoving = false;
} else {
lastTurnFinger = -1;
isTurning = false;
}
break;
}
}
Here is what happens:
printf
). One interesting thing I found is that if I handle SDL_FINGERMOTION
both touches are register in the correct locations - but this wont work because it doesn't detect a single tap, but instead only works when fingers are moved around. So it seems multitouch is working but perhaps I am not handling it correctly.
For reference here are the touch events from SDL_events.h
/* Touch events */
SDL_FINGERDOWN = 0x700,
SDL_FINGERUP,
SDL_FINGERMOTION,
Here is a sample of the event stream. I placed down 1 finger, then a second, then lifted the first, then lifted the second.
event 0x00000401
event 0x00000700 // Finger down
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000402
event 0x00000701 // Finger up
Notice that there is lots of finger motion - but only 1 finger up and down event. If I get some time later I will update this with a printout of the current number of fingers on the screen to illustrate that the second finger down event is never fired.
Looking at the source code I see that SDL_SendTouch()
should be getting called for every finger (NSEvent
) sent to the SDL_uikitview::touchesBegan
handler (SDL subclass of UIView
). I dont remember enough about UIKit to comment on the expected behavior here, but you can attach a debugger and see for yourself if it gets the expected number of NSEvents
.
If the number and type of NSEvents
don't match what you expect then it seems there is little SDL could do. If they are as you expect then it points to a bug in SDL.
Specifically, look at the source for SDL_SendTouch
as another place to put some breakpoints. There are a few cases where that function can bail out:
228 SDL_Touch* touch = SDL_GetTouch(id);
229 if (!touch) {
230 return -1;
231 }
232
233 finger = SDL_GetFinger(touch, fingerid);
234 if (down) {
235 if (finger) {
236 /* This finger is already down */
237 return 0;
238 }
239
240 if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
241 return 0;
242 }
User contributions licensed under CC BY-SA 3.0