hedgewars/uTouch.pas
branchhedgeroid
changeset 5609 9d66611e4d0a
parent 5605 31bd6e30df02
child 5615 104f69e798bb
equal deleted inserted replaced
5607:d3a3e80ad1da 5609:9d66611e4d0a
     3 unit uTouch;
     3 unit uTouch;
     4 
     4 
     5 interface
     5 interface
     6 
     6 
     7 uses sysutils, math, uConsole, uVariables, SDLh, uTypes, uFloat, uConsts, uIO, uCommands, GLUnit, uCommandHandlers;
     7 uses sysutils, math, uConsole, uVariables, SDLh, uTypes, uFloat, uConsts, uIO, uCommands, GLUnit, uCommandHandlers;
       
     8 
       
     9 type
       
    10     Touch_Finger = record
       
    11         id                       : SDL_FingerId;
       
    12         x,y                      : LongInt;
       
    13         historicalX, historicalY : LongInt;
       
    14         timeSinceDown            : Longword;
       
    15         end;
     8 
    16 
     9 procedure initModule;
    17 procedure initModule;
    10 
    18 
    11 
    19 
    12 procedure ProcessTouch;
    20 procedure ProcessTouch;
    13 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    21 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    14 procedure onTouchMotion(x,y: Longword; dx,dy: LongInt; pointerId: SDL_FingerId);
    22 procedure onTouchMotion(x,y: Longword; dx,dy: LongInt; pointerId: SDL_FingerId);
    15 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
    23 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
    16 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
    24 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
    17 procedure addFinger(x,y: Longword; id: SDL_FingerId);
    25 function addFinger(x,y: Longword; id: SDL_FingerId): Touch_Finger;
    18 procedure deleteFinger(id: SDL_FingerId);
    26 procedure deleteFinger(id: SDL_FingerId);
    19 procedure onTouchClick(x,y: Longword; pointerId: SDL_FingerId);
    27 procedure onTouchClick(finger: Touch_Finger);
    20 
    28 
    21 procedure aim(id: SDL_FingerId);
    29 function findFinger(id: SDL_FingerId): Touch_Finger;
    22 function isOnCurrentHog(id: SDL_FingerId): boolean;
    30 procedure aim(finger: Touch_Finger);
    23 function isOnFireButton(id: SDL_FingerId): boolean;
    31 function isOnCurrentHog(finger: Touch_Finger): boolean;
    24 procedure convertToWorldCoord(var x,y: hwFloat; id: SDL_FingerId);
    32 function isOnFireButton(finger: Touch_Finger): boolean;
    25 function fingerHasMoved(id: SDL_FingerId): boolean;
    33 procedure convertToWorldCoord(var x,y: hwFloat; finger: Touch_Finger);
    26 function calculateDelta(id1, id2: SDL_FingerId): hwFloat;
    34 function fingerHasMoved(finger: Touch_Finger): boolean;
    27 function getSecondPointer(id: SDL_FingerId): SDL_FingerId;
    35 function calculateDelta(finger1, finger2: Touch_Finger): hwFloat;
       
    36 function getSecondFinger(finger: Touch_Finger): Touch_Finger;
    28 implementation
    37 implementation
    29 
    38 
    30 const
    39 const
    31     clicktime = 200;
    40     clicktime = 200;
    32 var
    41 var
    33     leftButtonBoundary  : LongInt;
    42     leftButtonBoundary  : LongInt;
    34     rightButtonBoundary : LongInt;
    43     rightButtonBoundary : LongInt;
    35     topButtonBoundary   : LongInt;
    44     topButtonBoundary   : LongInt;
    36     
    45     
    37     pointerCount : Longword;
    46     pointerCount : Longword;
    38     xyCoord : array of LongInt;
    47     fingers: array of Touch_Finger;
    39     pointerIds : array of SDL_FingerId;
       
    40     timeSinceDown: array of Longword;
       
    41     historicalXY : array of LongInt;
       
    42 
       
    43     moveCursor : boolean;
    48     moveCursor : boolean;
    44 
    49 
    45     //Pinch to zoom 
    50     //Pinch to zoom 
    46     pinchSize : hwFloat;
    51     pinchSize : hwFloat;
    47     baseZoomValue: GLFloat;
    52     baseZoomValue: GLFloat;
    49     invertCursor : boolean;
    54     invertCursor : boolean;
    50 
    55 
    51     //aiming
    56     //aiming
    52     aiming, movingCrosshair: boolean; 
    57     aiming, movingCrosshair: boolean; 
    53     crosshairCommand: ShortString;
    58     crosshairCommand: ShortString;
    54     aimingPointerId: SDL_FingerId;
       
    55     targetAngle: LongInt;
    59     targetAngle: LongInt;
    56 
    60 
    57     stopFiring: boolean;
    61     stopFiring: boolean;
    58 
    62 
    59     //moving
    63     //moving
    60     stopLeft, stopRight, walkingLeft, walkingRight :  boolean;
    64     stopLeft, stopRight, walkingLeft, walkingRight :  boolean;
       
    65 procedure printFinger(finger: Touch_Finger);
       
    66 begin
       
    67     WriteToConsole(Format('id:%d, (%d,%d), (%d,%d), time: %d', [finger.id, finger.x, finger.y, finger.historicalX, finger.historicalY, finger.timeSinceDown]));
       
    68 end;
       
    69 
    61 
    70 
    62 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    71 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    63 begin
    72 var 
    64     addFinger(x,y,pointerId);
    73     finger: Touch_Finger;
    65     xyCoord[pointerId*2] := convertToCursor(cScreenWidth,x);
    74 begin
    66     xyCoord[pointerId*2+1] := convertToCursor(cScreenHeight,y);
    75     finger:= addFinger(x,y,pointerId);
    67     
    76     finger.x := convertToCursor(cScreenWidth,x);
    68    
    77     finger.y := convertToCursor(cScreenHeight,y);
       
    78     
       
    79     printFinger(finger); 
    69     case pointerCount of
    80     case pointerCount of
    70         1:
    81         1:
    71         begin
    82         begin
    72             moveCursor:= false;
    83             moveCursor:= false;
    73             if bShowAmmoMenu then
    84             if bShowAmmoMenu then
    74             begin
    85             begin
    75                 moveCursor := true;
    86                 moveCursor := true;
    76                 exit;
    87                 exit;
    77             end;
    88             end;
    78 
    89 
    79             if isOnCurrentHog(pointerId) then
    90             if isOnCurrentHog(finger) then
    80             begin
    91             begin
    81                 aiming:= true;
    92                 aiming:= true;
    82                 exit;
    93                 exit;
    83             end;
    94             end;
    84 
    95 
    85             if isOnFireButton(pointerId) then
    96             if isOnFireButton(finger) then
    86             begin
    97             begin
    87                 stopFiring:= false;
    98                 stopFiring:= false;
    88                 ParseCommand('+attack', true);
    99                 ParseCommand('+attack', true);
    89                 exit;
   100                 exit;
    90             end;
   101             end;
    91             if xyCoord[pointerId*2] < leftButtonBoundary then
   102             if finger.x < leftButtonBoundary then
    92             begin
   103             begin
    93                 ParseCommand('+left', true);
   104                 ParseCommand('+left', true);
    94                 walkingLeft := true;
   105                 walkingLeft := true;
    95                 exit;
   106                 exit;
    96             end;
   107             end;
    97             if xyCoord[pointerId*2] > rightButtonBoundary then
   108             if finger.x > rightButtonBoundary then
    98             begin
   109             begin
    99                 ParseCommand('+right', true);
   110                 ParseCommand('+right', true);
   100                 walkingRight:= true;
   111                 walkingRight:= true;
   101                 exit;
   112                 exit;
   102             end;
   113             end;
   103             WriteToConsole(Format('%d, %d', [xyCoord[pointerId*2+1], topButtonBoundary]));    
   114             if finger.y < topButtonBoundary then
   104             if xyCoord[pointerId*2+1] < topButtonBoundary then
       
   105             begin
   115             begin
   106                 ParseCommand('hjump', true);
   116                 ParseCommand('hjump', true);
   107                 exit;
   117                 exit;
   108             end;
   118             end;
   109             moveCursor:= true; 
   119             moveCursor:= true; 
   111         2:
   121         2:
   112         begin
   122         begin
   113             aiming:= false;
   123             aiming:= false;
   114             stopFiring:= true;
   124             stopFiring:= true;
   115             
   125             
   116             pinchSize := calculateDelta(pointerId, getSecondPointer(pointerId));
   126             pinchSize := calculateDelta(finger, getSecondFinger(finger));
   117             baseZoomValue := ZoomValue
   127             baseZoomValue := ZoomValue
   118         end;
   128         end;
   119     end;//end case pointerCount of
   129     end;//end case pointerCount of
   120 end;
   130 end;
   121 
   131 
   122 procedure onTouchMotion(x,y: Longword;dx,dy: LongInt; pointerId: SDL_FingerId);
   132 procedure onTouchMotion(x,y: Longword;dx,dy: LongInt; pointerId: SDL_FingerId);
   123 var
   133 var
   124     secondId : SDL_FingerId;
   134     finger, secondFinger: Touch_Finger;
   125     currentPinchDelta, zoom : hwFloat;
   135     currentPinchDelta, zoom : hwFloat;
   126 begin
   136 begin
   127     xyCoord[pointerId*2] := convertToCursor(cScreenWidth, x);
   137     finger:= findFinger(pointerId);
   128     xyCoord[pointerId*2+1] := convertToCursor(cScreenHeight, y);
   138     finger.x := convertToCursor(cScreenWidth, x);
       
   139     finger.y := convertToCursor(cScreenHeight, y);
   129     
   140     
   130     case pointerCount of
   141     case pointerCount of
   131        1:
   142        1:
   132            begin
   143            begin
   133                if aiming then 
   144                if aiming then 
   134                begin
   145                begin
   135                    aim(pointerId);
   146                    aim(finger);
   136                    exit
   147                    exit
   137                end;
   148                end;
   138                if moveCursor then
   149                if moveCursor then
   139                    if invertCursor then
   150                    if invertCursor then
   140                    begin
   151                    begin
   147                        CursorPoint.Y := CursorPoint.Y - convertToCursor(cScreenWidth,dy);
   158                        CursorPoint.Y := CursorPoint.Y - convertToCursor(cScreenWidth,dy);
   148                    end;
   159                    end;
   149            end;
   160            end;
   150        2:
   161        2:
   151            begin
   162            begin
   152                secondId := getSecondPointer(pointerId);
   163                secondFinger := getSecondFinger(finger);
   153                currentPinchDelta := calculateDelta(pointerId, secondId) - pinchSize;
   164                currentPinchDelta := calculateDelta(finger, secondFinger)- pinchSize;
   154                zoom := currentPinchDelta/cScreenWidth;
   165                zoom := currentPinchDelta/cScreenWidth;
   155                ZoomValue := baseZoomValue - ((hwFloat2Float(zoom) * cMinMaxZoomLevelDelta));
   166                ZoomValue := baseZoomValue - ((hwFloat2Float(zoom) * cMinMaxZoomLevelDelta));
   156                if ZoomValue < cMaxZoomLevel then ZoomValue := cMaxZoomLevel;
   167                if ZoomValue < cMaxZoomLevel then ZoomValue := cMaxZoomLevel;
   157                if ZoomValue > cMinZoomLevel then ZoomValue := cMinZoomLevel;
   168                if ZoomValue > cMinZoomLevel then ZoomValue := cMinZoomLevel;
   158             end;
   169             end;
   160 end;
   171 end;
   161 
   172 
   162 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
   173 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
   163 begin
   174 begin
   164     aiming:= false;
   175     aiming:= false;
   165     pointerCount := pointerCount-1;
       
   166     stopFiring:= true;
   176     stopFiring:= true;
   167     deleteFinger(pointerId);
   177     deleteFinger(pointerId);
   168 
   178 
   169     if walkingLeft then
   179     if walkingLeft then
   170     begin
   180     begin
   177         ParseCommand('-right', true);
   187         ParseCommand('-right', true);
   178         walkingRight := false;
   188         walkingRight := false;
   179     end;
   189     end;
   180 end;
   190 end;
   181 
   191 
   182 procedure onTouchClick(x,y: Longword; pointerId: SDL_FingerId);
   192 procedure onTouchClick(finger: Touch_Finger);
   183 begin
   193 begin
   184     if bShowAmmoMenu then 
   194     if bShowAmmoMenu then 
   185     begin
   195     begin
   186         doPut(CursorPoint.X, CursorPoint.Y, false); 
   196         doPut(CursorPoint.X, CursorPoint.Y, false); 
   187         exit
   197         exit
   188     end;
   198     end;
   189 
   199 
   190     if isOnCurrentHog(pointerId) then
   200     if isOnCurrentHog(finger) then
   191     begin
   201     begin
   192         bShowAmmoMenu := true;
   202         bShowAmmoMenu := true;
   193         exit;
   203         exit;
   194     end;
   204     end;
   195 
   205 
   196     if xyCoord[pointerId*2+1] < topButtonBoundary then
   206     if finger.y < topButtonBoundary then
   197     begin
   207     begin
   198         ParseCommand('hjump', true);
   208         ParseCommand('hjump', true);
   199         exit;
   209         exit;
   200     end;
   210     end;
   201 end;
   211 end;
   202 
   212 
   203 procedure addFinger(x,y: Longword; id: SDL_FingerId);
   213 function addFinger(x,y: Longword; id: SDL_FingerId): Touch_Finger;
   204 var 
   214 var 
   205     index, tmp: Longword;
   215     xCursor, yCursor, index : LongInt;
   206 begin
   216 begin
   207     pointerCount := pointerCount + 1;
       
   208 
       
   209     //Check array sizes
   217     //Check array sizes
   210     if length(pointerIds) < pointerCount then setLength(pointerIds, length(pointerIds)*2);
   218     if length(fingers) < pointerCount then 
   211     if length(xyCoord) < id*2+1 then 
   219     begin
   212     begin 
   220         setLength(fingers, length(fingers)*2);
   213         setLength(xyCoord, id*2+1);
   221         for index := length(fingers) div 2 to length(fingers) do fingers[index].id := -1;
   214         setLength(historicalXY, id*2+1);
   222     end;
   215     end;
   223     
   216     if length(timeSinceDown) < id then setLength(timeSinceDown, id); 
   224     
   217     for index := 0 to pointerCount do //place the pointer ids as far back to the left as possible
   225     xCursor := convertToCursor(cScreenWidth, x);
   218     begin
   226     yCursor := convertToCursor(cScreenHeight, y);
   219         if pointerIds[index] = -1 then 
   227     
   220            begin
   228     //on removing fingers all fingers are moved to the left, thus new fingers will be to the far right
   221                pointerIds[index] := id;
   229     //with dynamic arrays being zero based, 'far right' is the old pointerCount    
   222                break;
   230     fingers[pointerCount].id := id;
   223            end;
   231     fingers[pointerCount].historicalX := xCursor;
   224     end;
   232     fingers[pointerCount].historicalY := yCursor;
   225     //set timestamp
   233     fingers[pointerCount].x := xCursor;
   226     timeSinceDown[id] := SDL_GetTicks;
   234     fingers[pointerCount].y := yCursor;
   227     historicalXY[id*2] := convertToCursor(cScreenWidth,x);
   235     fingers[pointerCount].timeSinceDown:= SDL_GetTicks;
   228     historicalXY[id*2+1] := convertToCursor(cScreenHeight,y);
   236  
       
   237     inc(pointerCount);
       
   238     addFinger:= fingers[pointerCount];
   229 end;
   239 end;
   230 
   240 
   231 procedure deleteFinger(id: SDL_FingerId);
   241 procedure deleteFinger(id: SDL_FingerId);
   232 var
   242 var
   233     index, i : Longint;
   243     index : Longint;
   234 begin
   244 begin
   235     index := 0;
   245     
       
   246     dec(pointerCount);
   236     for index := 0 to pointerCount do
   247     for index := 0 to pointerCount do
   237     begin
   248     begin
   238          if pointerIds[index] = id then
   249          if fingers[index].id = id then
   239          begin
   250          begin
   240              pointerIds[index] := -1;
   251              //Check for onTouchevent
       
   252              if ((SDL_GetTicks - fingers[index].timeSinceDown) < clickTime) AND  not(fingerHasMoved(fingers[index])) then 
       
   253                  onTouchClick(fingers[index]);
       
   254              fingers[index].id := -1;
   241              break;
   255              break;
   242          end;
   256          end;
   243     end;
   257     end;
   244     //put the last pointerId into the stop of the id to be removed, so that all pointerIds are to the far left
   258     //put the last finger into the spot of the finger to be removed, so that all fingers are packed to the far left
   245     for i := pointerCount downto index do
   259     if fingers[pointerCount].id = -1 then
   246     begin
   260     begin
   247         if pointerIds[i] <> -1 then
   261         fingers[index] := fingers[pointerCount];    
   248         begin
   262         fingers[pointerCount].id := -1;
   249             pointerIds[index] := pointerIds[i];
   263     end;
   250             break;
   264 
   251         end;
       
   252     end;
       
   253     if ((SDL_GetTicks - timeSinceDown[id]) < clickTime) AND  not(fingerHasMoved(id)) then onTouchClick(xyCoord[id*2], xyCoord[id*2+1], id);
       
   254 end;
   265 end;
   255 
   266 
   256 procedure ProcessTouch;
   267 procedure ProcessTouch;
   257 var
   268 var
   258     deltaAngle: LongInt;
   269     deltaAngle: LongInt;
   300         ParseCommand('-left', true);
   311         ParseCommand('-left', true);
   301     end;
   312     end;
   302     
   313     
   303 end;
   314 end;
   304 
   315 
   305 procedure aim(id: SDL_FingerId);
   316 function findFinger(id: SDL_FingerId): Touch_Finger;
       
   317 begin
       
   318    for findFinger in fingers do
       
   319        if (findFinger.id = -1) and (findFinger.id = id) then break;
       
   320 end;
       
   321 
       
   322 procedure aim(finger: Touch_Finger);
   306 var 
   323 var 
   307     hogX, hogY, touchX, touchY, deltaX, deltaY, tmpAngle: hwFloat;
   324     hogX, hogY, touchX, touchY, deltaX, deltaY, tmpAngle: hwFloat;
   308     tmp: ShortString;
   325     tmp: ShortString;
   309 begin
   326 begin
   310     if CurrentHedgehog^.Gear <> nil then
   327     if CurrentHedgehog^.Gear <> nil then
   311     begin
   328     begin
   312         hogX := CurrentHedgehog^.Gear^.X;
   329         hogX := CurrentHedgehog^.Gear^.X;
   313         hogY := CurrentHedgehog^.Gear^.Y;
   330         hogY := CurrentHedgehog^.Gear^.Y;
   314 
   331 
   315         convertToWorldCoord(touchX, touchY, id);
   332         convertToWorldCoord(touchX, touchY, finger);
   316         deltaX := hwAbs(TouchX-HogX);
   333         deltaX := hwAbs(TouchX-HogX);
   317         deltaY := (TouchY-HogY);
   334         deltaY := (TouchY-HogY);
   318         
   335         
   319         tmpAngle:= DeltaY / Distance(deltaX, deltaY) *_2048;
   336         tmpAngle:= DeltaY / Distance(deltaX, deltaY) *_2048;
   320         targetAngle:= (hwRound(tmpAngle) + 2048) div 2;
   337         targetAngle:= (hwRound(tmpAngle) + 2048) div 2;
   334 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
   351 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
   335 begin
   352 begin
   336     convertToCursor := round(xy/32768*scale)
   353     convertToCursor := round(xy/32768*scale)
   337 end;
   354 end;
   338 
   355 
   339 function isOnFireButton(id: SDL_FingerId): boolean;
   356 function isOnFireButton(finger: Touch_Finger): boolean;
   340 begin
   357 begin
   341     isOnFireButton:= (xyCoord[id*2] < 150) and (xyCoord[id*2+1] > 390);
   358     isOnFireButton:= (finger.x < 150) and (finger.y > 390);
   342 end;
   359 end;
   343 
   360 
   344 function isOnCurrentHog(id: SDL_FingerId): boolean;
   361 function isOnCurrentHog(finger: Touch_Finger): boolean;
   345 var
   362 var
   346     x,y, fingerX, fingerY : hwFloat;
   363     x,y, fingerX, fingerY : hwFloat;
   347 begin
   364 begin
   348     x := CurrentHedgehog^.Gear^.X;
   365     x := CurrentHedgehog^.Gear^.X;
   349     y := CurrentHedgehog^.Gear^.Y;
   366     y := CurrentHedgehog^.Gear^.Y;
   350 
   367 
   351     convertToWorldCoord(fingerX, fingerY, id);
   368     convertToWorldCoord(fingerX, fingerY, finger);
   352     isOnCurrentHog := Distance(fingerX-x, fingerY-y) < _20;
   369     isOnCurrentHog := Distance(fingerX-x, fingerY-y) < _20;
   353 end;
   370 end;
   354 
   371 
   355 procedure convertToWorldCoord(var x,y: hwFloat; id: SDL_FingerId);
   372 procedure convertToWorldCoord(var x,y: hwFloat; finger: Touch_Finger);
   356 begin
   373 begin
   357 //if x <> nil then 
   374 //if x <> nil then 
   358     x := int2hwFloat((xyCoord[id*2]-WorldDx) - (cScreenWidth div 2));
   375     x := int2hwFloat((finger.x-WorldDx) - (cScreenWidth div 2));
   359 //if y <> nil then 
   376 //if y <> nil then 
   360     y := int2hwFloat(xyCoord[id*2+1]-WorldDy);
   377     y := int2hwFloat(finger.y-WorldDy);
   361 end;
   378 end;
   362 
   379 
   363 //Method to calculate the distance this finger has moved since the downEvent
   380 //Method to calculate the distance this finger has moved since the downEvent
   364 function fingerHasMoved(id: SDL_FingerId): boolean;
   381 function fingerHasMoved(finger: Touch_Finger): boolean;
   365 begin
   382 begin
   366 //    fingerHasMoved := hwAbs(DistanceI(xyCoord[id*2]-historicalXY[id*2], xyCoord[id*2+1]-historicalXY[id*2+1])) > int2hwFloat(2000); // is 1% movement
   383     fingerHasMoved := trunc(sqrt(Power(finger.X-finger.historicalX,2) + Power(finger.y-finger.historicalY, 2))) > 330;
   367     fingerHasMoved := trunc(sqrt(Power(xyCoord[id*2]-historicalXY[id*2],2) + Power(xyCoord[id*2+1]-historicalXY[id*2+1], 2))) > 330;
   384 end;
   368 end;
   385 
   369 
   386 function calculateDelta(finger1, finger2: Touch_Finger): hwFloat;
   370 function calculateDelta(id1, id2: SDL_FingerId): hwFloat;
       
   371 begin
   387 begin
   372 //    calculateDelta := Distance(xyCoord[id2*2] - xyCoord[id1*2], xyCoord[id2*2+1] - xyCoord[id1*2+1]);
   388 //    calculateDelta := Distance(xyCoord[id2*2] - xyCoord[id1*2], xyCoord[id2*2+1] - xyCoord[id1*2+1]);
   373     calculateDelta := int2hwFloat(trunc(sqrt(Power(xyCoord[id2*2]-xyCoord[id1*2],2) + Power(xyCoord[id2*2+1]-xyCoord[id1*2+1], 2))));
   389     calculateDelta := int2hwFloat(trunc(sqrt(Power(finger2.x-finger1.x, 2) + Power(finger2.y-finger1.y, 2))));
   374 end;
   390 end;
   375 
   391 
   376 // Under the premise that all pointer ids in pointerIds:SDL_FingerId are pack to the far left.
   392 // Under the premise that all pointer ids in pointerIds:SDL_FingerId are pack to the far left.
   377 // If the pointer to be ignored is not pointerIds[0] the second must be there
   393 // If the pointer to be ignored is not pointerIds[0] the second must be there
   378 function getSecondPointer(id: SDL_FingerId): SDL_FingerId;
   394 function getSecondFinger(finger: Touch_Finger): Touch_Finger;
   379 begin
   395 begin
   380     if pointerIds[0] = id then getSecondPointer := pointerIds[1]
   396     if fingers[0].id = finger.id then getSecondFinger := fingers[0]
   381     else getSecondPointer := pointerIds[0];
   397     else getSecondFinger := fingers[1];
   382 end;
   398 end;
   383 
   399 
   384 procedure initModule;
   400 procedure initModule;
   385 var
   401 var
   386     index: Longword;
   402     finger: Touch_Finger;
   387 begin
   403 begin
   388     setLength(xyCoord, 10);
       
   389     setLength(pointerIds, 5);
       
   390     setLength(timeSinceDown, 5);
       
   391     setLength(historicalXY, 10);    
       
   392     for index := Low(xyCoord) to High(xyCoord) do xyCoord[index] := -1;
       
   393     for index := Low(pointerIds) to High(pointerIds) do pointerIds[index] := -1;
       
   394     movingCrosshair := false;
   404     movingCrosshair := false;
   395     stopFiring:= false;
   405     stopFiring:= false;
   396     walkingLeft := false;
   406     walkingLeft := false;
   397     walkingRight := false;
   407     walkingRight := false;
   398 
   408 
   399     leftButtonBoundary := cScreenWidth div 4;
   409     leftButtonBoundary := cScreenWidth div 4;
   400     rightButtonBoundary := cScreenWidth div 4*3;
   410     rightButtonBoundary := cScreenWidth div 4*3;
   401     topButtonBoundary := cScreenHeight div 6;
   411     topButtonBoundary := cScreenHeight div 6;
   402    
   412     
       
   413     setLength(fingers, 5);
       
   414     for finger in fingers do finger.id := -1;
   403 end;
   415 end;
   404 
   416 
   405 begin
   417 begin
   406 end.
   418 end.