Part 1
First we need to capture the multi-touch information from AppGameKit and turn it into something we can use. I started this process by making a UDT array to store the data for each touch event. My UDT looks like this:
`multitouch
type multiType
ID as integer
sx as float
sy as float
lx as float
ly as float
cx as float
cy as float
pressed as integer
state as integer
released as integer
start as float
updated as integer
startZoom as float
startX as float
startY as float
endtype
global dim multi[5] as multiType
I am also calling a single function from within my “pinchZoom()” function to fill in the data in this array. Here is (basically) what that function does.
First I reset some data that needs to be worked out in each loop as touch data changes constantly depending on what the user is doing:
function getMultitouchInput()
rem prepare data
for i=1 to 5
multi[i].updated = 0
next
ptc = pz.touchCount
if ptc=0
pz.touchID1 = 0
pz.touchID2 = 0
endif
pz.touchCount = getRawTouchCount(1)
pz.PRESSED = 0
Next I loop through all of the current touch events. I check the ID of the touch event to check if it is new or an event I am already aware of:
rem loop through events
ID = getRawFirstTouchEvent(1)
while ID>0
found = 0
for i=1 to 5
if ID=multi[i].ID
rem existing touch event
found = 1
rem update data for this event
multi[i].updated = 1
multi[i].pressed = 0
multi[i].sx = GetRawTouchStartX(ID)
multi[i].sy = GetRawTouchStartY(ID)
multi[i].lx = GetRawTouchLastX(ID)
multi[i].ly = GetRawTouchLastY(ID)
multi[i].cx = GetRawTouchCurrentX(ID)
multi[i].cy = GetRawTouchCurrentY(ID)
multi[i].released = GetRawTouchReleased(ID)
if multi[i].released>0 then multi[i].state = 0
exit
endif
next
rem check for new event
if found=0
rem new touch event
`find a free slot
for i=1 to 5
if multi[i].ID=0
slot = i
exit
endif
next
if slot>0
i = slot
multi[i].ID = ID
multi[i].start = time.current
multi[i].state = 1
multi[i].updated = 1
multi[i].sx = GetRawTouchStartX(ID)
multi[i].sy = GetRawTouchStartY(ID)
multi[i].lx = GetRawTouchLastX(ID)
multi[i].ly = GetRawTouchLastY(ID)
multi[i].cx = GetRawTouchCurrentX(ID)
multi[i].cy = GetRawTouchCurrentY(ID)
multi[i].released = GetRawTouchReleased(ID)
select pz.touchCount
case 1 : pz.touchID1 = i : endcase
case 2
if pz.touchID1=0
pz.touchID1 = i
else
pz.touchID2 = i
multi[i].startZoom = getViewZoom()
multi[i].startX = getViewOffsetX()
multi[i].startY = getViewOffsetY()
endif
endcase
endselect
endif
endif
ID = getRawNextTouchEvent()
Endwhile
Then I check for any events that no longer exist and remove them from the array:
rem check data
for i=1 to 5
ud = multi[i].updated
if ud=0
multi[i].ID = 0
endif
next
Finally I update some data to keep track of which is the first / second event, also I track when the last event took place so that the pinch zoom code can zoom out after 5 seconds of inactivity. Perhaps it would be sensible to move this code into the pinch zoom function but I am happy keeping it in this function for now:
rem swap from multitouch to single touch drag
if ptc=2 and pz.touchCount=1
if multi[pz.touchID1].ID=0
pz.touchID1 = pz.touchID2
endif
endif
if ptc>0 and pz.touchCount=0
multi[0].start = time.current + 5.0
endif
if pz.touchCount=1 and ptc=0
pz.tapStart = time.current
endif
endfunction
As you can see I am ignoring anything more than two touch events. If you wanted to use the data for more it is still being stored. Keeping track of multi touch ID’s is vital when using multi touch to make sure we are looking at the same touch event as before. If we assume that because there was one touch event in the last loop and there is still only one touch event in this loop that they are the same event we might miss a crossover that produces unexpected results.
In Part 2 I will explain how I use this data to control the view offsets and zoom.
this.mess = abs(sin(times#))