hedgewars/uTouch.pas
branchhedgeroid
changeset 5599 2e4b90f33a83
parent 5595 480d451152a5
child 5605 31bd6e30df02
equal deleted inserted replaced
5597:14b3cdb23c2c 5599:2e4b90f33a83
     2 
     2 
     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, GLUnit;
     7 uses sysutils, math, uConsole, uVariables, SDLh, uTypes, uFloat, uConsts, uIO, uCommands, GLUnit, uCommandHandlers;
     8 
     8 
     9 procedure initModule;
     9 procedure initModule;
    10 
    10 
       
    11 
       
    12 procedure ProcessTouch;
    11 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    13 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    12 procedure onTouchMotion(x,y: Longword; dx,dy: LongInt; pointerId: SDL_FingerId);
    14 procedure onTouchMotion(x,y: Longword; dx,dy: LongInt; pointerId: SDL_FingerId);
    13 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
    15 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
    14 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
    16 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
    15 procedure addFinger(x,y: Longword; id: SDL_FingerId);
    17 procedure addFinger(x,y: Longword; id: SDL_FingerId);
    16 procedure deleteFinger(id: SDL_FingerId);
    18 procedure deleteFinger(id: SDL_FingerId);
    17 procedure onTouchClick(x,y: Longword; pointerId: SDL_FingerId);
    19 procedure onTouchClick(x,y: Longword; pointerId: SDL_FingerId);
    18 
    20 
       
    21 procedure aim(id: SDL_FingerId);
    19 function isOnCurrentHog(id: SDL_FingerId): boolean;
    22 function isOnCurrentHog(id: SDL_FingerId): boolean;
       
    23 procedure convertToWorldCoord(var x,y: hwFloat; id: SDL_FingerId);
    20 function fingerHasMoved(id: SDL_FingerId): boolean;
    24 function fingerHasMoved(id: SDL_FingerId): boolean;
    21 function calculateDelta(id1, id2: SDL_FingerId): hwFloat;
    25 function calculateDelta(id1, id2: SDL_FingerId): hwFloat;
    22 function getSecondPointer(id: SDL_FingerId): SDL_FingerId;
    26 function getSecondPointer(id: SDL_FingerId): SDL_FingerId;
    23 implementation
    27 implementation
    24 
    28 
    35     pinchSize : hwFloat;
    39     pinchSize : hwFloat;
    36     baseZoomValue: GLFloat;
    40     baseZoomValue: GLFloat;
    37 
    41 
    38     invertCursor : boolean;
    42     invertCursor : boolean;
    39 
    43 
       
    44     //aiming
       
    45     aiming, movingCrosshair: boolean; 
       
    46     crosshairCommand: ShortString;
       
    47     aimingPointerId: SDL_FingerId;
       
    48     targetAngle: LongInt;    
       
    49 
    40 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    50 procedure onTouchDown(x,y: Longword; pointerId: SDL_FingerId);
    41 begin
    51 begin
    42     WriteToConsole('down'); 
       
    43     addFinger(x,y,pointerId);
    52     addFinger(x,y,pointerId);
    44     xyCoord[pointerId*2] := convertToCursor(cScreenWidth,x);
    53     xyCoord[pointerId*2] := convertToCursor(cScreenWidth,x);
    45     xyCoord[pointerId*2+1] := convertToCursor(cScreenHeight,y);
    54     xyCoord[pointerId*2+1] := convertToCursor(cScreenHeight,y);
       
    55     
    46    
    56    
    47     case pointerCount of
    57     case pointerCount of
       
    58         1:
       
    59             if isOnCurrentHog(pointerId) then aiming:= true;
    48         2:
    60         2:
    49         begin
    61         begin
       
    62             aiming:= false;
       
    63             
    50             pinchSize := calculateDelta(pointerId, getSecondPointer(pointerId));
    64             pinchSize := calculateDelta(pointerId, getSecondPointer(pointerId));
    51             baseZoomValue := ZoomValue
    65             baseZoomValue := ZoomValue
    52         end;
    66         end;
    53     end;//end case pointerCount of
    67     end;//end case pointerCount of
    54 end;
    68 end;
    62     xyCoord[pointerId*2+1] := convertToCursor(cScreenHeight, y);
    76     xyCoord[pointerId*2+1] := convertToCursor(cScreenHeight, y);
    63     
    77     
    64     case pointerCount of
    78     case pointerCount of
    65        1:
    79        1:
    66            begin
    80            begin
       
    81                if aiming then 
       
    82                begin
       
    83                    aim(pointerId);
       
    84                    exit
       
    85                end;
    67                if invertCursor then
    86                if invertCursor then
    68                begin
    87                begin
    69                    CursorPoint.X := CursorPoint.X - convertToCursor(cScreenWidth,dx);
    88                    CursorPoint.X := CursorPoint.X - convertToCursor(cScreenWidth,dx);
    70                    CursorPoint.Y := CursorPoint.Y + convertToCursor(cScreenWidth,dy);
    89                    CursorPoint.Y := CursorPoint.Y + convertToCursor(cScreenWidth,dy);
    71                end
    90                end
    79            begin
    98            begin
    80                secondId := getSecondPointer(pointerId);
    99                secondId := getSecondPointer(pointerId);
    81                currentPinchDelta := calculateDelta(pointerId, secondId) - pinchSize;
   100                currentPinchDelta := calculateDelta(pointerId, secondId) - pinchSize;
    82                zoom := currentPinchDelta/cScreenWidth;
   101                zoom := currentPinchDelta/cScreenWidth;
    83                ZoomValue := baseZoomValue - ((hwFloat2Float(zoom) * cMinMaxZoomLevelDelta));
   102                ZoomValue := baseZoomValue - ((hwFloat2Float(zoom) * cMinMaxZoomLevelDelta));
    84                //WriteToConsole(Format('Zoom in/out. ZoomValue = %f', [ZoomValue]));
   103                WriteToConsole(Format('Zoom in/out. ZoomValue = %f, %f', [ZoomValue, cMaxZoomLevel]));
    85 //              if ZoomValue > cMaxZoomLevel then ZoomValue := cMaxZoomLevel;
   104                if ZoomValue > cMaxZoomLevel then ZoomValue := cMaxZoomLevel;
    86 //               if ZoomValue < cMinZoomLevel then ZoomValue := cMinZoomLevel;
   105 //               if ZoomValue < cMinZoomLevel then ZoomValue := cMinZoomLevel;
    87             end;
   106             end;
    88     end; //end case pointerCount of
   107     end; //end case pointerCount of
    89 end;
   108 end;
    90 
   109 
    91 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
   110 procedure onTouchUp(x,y: Longword; pointerId: SDL_FingerId);
    92 begin
   111 begin
       
   112     aiming:= false;
    93     pointerCount := pointerCount-1;
   113     pointerCount := pointerCount-1;
    94     deleteFinger(pointerId);
   114     deleteFinger(pointerId);
    95 end;
   115 end;
    96 
   116 
    97 procedure onTouchClick(x,y: Longword; pointerId: SDL_FingerId);
   117 procedure onTouchClick(x,y: Longword; pointerId: SDL_FingerId);
    98 begin
   118 begin
    99     if bShowAmmoMenu then 
   119     if bShowAmmoMenu then 
   100     begin
   120     begin
   101         doPut(CursorPoint.X, CursorPoint.Y, false); 
   121         doPut(CursorPoint.X, CursorPoint.Y, false); 
   102         invertCursor := true;
       
   103         exit
   122         exit
   104     end;
   123     end;
   105 
   124 
   106     if isOnCurrentHog(pointerId) then
   125     if isOnCurrentHog(pointerId) then
   107     begin
   126     begin
   108     bShowAmmoMenu := true;
   127     bShowAmmoMenu := true;
   109     invertCursor := false;
       
   110     end;
   128     end;
   111     //WriteToConsole(Format('%s, %s : %d, %d', [cstr(CurrentHedgehog^.Gear^.X), cstr(CurrentHedgehog^.Gear^.Y), x-WorldDX, y-WorldDY]));
   129     //WriteToConsole(Format('%s, %s : %d, %d', [cstr(CurrentHedgehog^.Gear^.X), cstr(CurrentHedgehog^.Gear^.Y), x-WorldDX, y-WorldDY]));
   112 end;
       
   113 
       
   114 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
       
   115 begin
       
   116     convertToCursor := round(xy/32768*scale)
       
   117 end;
   130 end;
   118 
   131 
   119 procedure addFinger(x,y: Longword; id: SDL_FingerId);
   132 procedure addFinger(x,y: Longword; id: SDL_FingerId);
   120 var 
   133 var 
   121     index, tmp: Longword;
   134     index, tmp: Longword;
   167         end;
   180         end;
   168     end;
   181     end;
   169     if ((SDL_GetTicks - timeSinceDown[id]) < clickTime) AND  not(fingerHasMoved(id)) then onTouchClick(xyCoord[id*2], xyCoord[id*2+1], id);
   182     if ((SDL_GetTicks - timeSinceDown[id]) < clickTime) AND  not(fingerHasMoved(id)) then onTouchClick(xyCoord[id*2], xyCoord[id*2+1], id);
   170 end;
   183 end;
   171 
   184 
       
   185 procedure ProcessTouch;
       
   186 var
       
   187     deltaAngle: LongInt;
       
   188 begin
       
   189     invertCursor := not(bShowAmmoMenu);
       
   190     if aiming then
       
   191     begin
       
   192         if CurrentHedgehog^.Gear <> nil then
       
   193         begin
       
   194             deltaAngle:= CurrentHedgehog^.Gear^.Angle - targetAngle;
       
   195             if (deltaAngle <> 0) and not(movingCrosshair) then 
       
   196             begin
       
   197                 ParseCommand('+' + crosshairCommand, true);
       
   198                 movingCrosshair := true;
       
   199             end
       
   200             else 
       
   201                 if movingCrosshair then 
       
   202                 begin
       
   203                     ParseCommand('-' + crosshairCommand, true);
       
   204                     movingCrosshair:= false;
       
   205                 end;
       
   206         end;
       
   207     end
       
   208     else if movingCrosshair then 
       
   209     begin
       
   210         ParseCommand('-' + crosshairCommand, true);
       
   211         movingCrosshair := false;
       
   212     end;
       
   213 end;
       
   214 
       
   215 procedure aim(id: SDL_FingerId);
       
   216 var 
       
   217     hogX, hogY, touchX, touchY, deltaX, deltaY, tmpAngle: hwFloat;
       
   218     tmp: ShortString;
       
   219 begin
       
   220     if CurrentHedgehog^.Gear <> nil then
       
   221     begin
       
   222         hogX := CurrentHedgehog^.Gear^.X;
       
   223         hogY := CurrentHedgehog^.Gear^.Y;
       
   224 
       
   225         convertToWorldCoord(touchX, touchY, id);
       
   226         deltaX := hwAbs(TouchX-HogX);
       
   227         deltaY := (TouchY-HogY);
       
   228         
       
   229         tmpAngle:= DeltaY / Distance(deltaX, deltaY) *_2048;
       
   230         targetAngle:= (hwRound(tmpAngle) + 2048) div 2;
       
   231 
       
   232         tmp := crosshairCommand;
       
   233         if CurrentHedgehog^.Gear^.Angle - targetAngle < 0 then crosshairCommand := 'down'
       
   234         else crosshairCommand:= 'up';
       
   235         if movingCrosshair and (tmp <> crosshairCommand) then 
       
   236         begin
       
   237             ParseCommand('-' + tmp, true);
       
   238             movingCrosshair := false;
       
   239         end;
       
   240 
       
   241     end; //if CurrentHedgehog^.Gear <> nil
       
   242 end;
       
   243 
       
   244 function convertToCursor(scale: LongInt; xy: LongInt): LongInt;
       
   245 begin
       
   246     convertToCursor := round(xy/32768*scale)
       
   247 end;
       
   248 
   172 function isOnCurrentHog(id: SDL_FingerId): boolean;
   249 function isOnCurrentHog(id: SDL_FingerId): boolean;
   173 var
   250 var
   174      x,y : hwFloat;
   251     x,y, fingerX, fingerY : hwFloat;
   175 begin
   252 begin
   176     x := CurrentHedgehog^.Gear^.X;
   253     x := CurrentHedgehog^.Gear^.X;
   177     y := CurrentHedgehog^.Gear^.Y;
   254     y := CurrentHedgehog^.Gear^.Y;
   178     isOnCurrentHog := Distance(int2hwFloat((xyCoord[id*2] -  WorldDX) - (cScreenWidth div 2))-x, int2hwFloat(xyCoord[id*2+1] - WorldDy)-y) < int2hwFloat(20);
   255 
       
   256     convertToWorldCoord(fingerX, fingerY, id);
       
   257     isOnCurrentHog := Distance(fingerX-x, fingerY-y) < _20;
       
   258 end;
       
   259 
       
   260 procedure convertToWorldCoord(var x,y: hwFloat; id: SDL_FingerId);
       
   261 begin
       
   262 //if x <> nil then 
       
   263     x := int2hwFloat((xyCoord[id*2]-WorldDx) - (cScreenWidth div 2));
       
   264 //if y <> nil then 
       
   265     y := int2hwFloat(xyCoord[id*2+1]-WorldDy);
   179 end;
   266 end;
   180 
   267 
   181 //Method to calculate the distance this finger has moved since the downEvent
   268 //Method to calculate the distance this finger has moved since the downEvent
   182 function fingerHasMoved(id: SDL_FingerId): boolean;
   269 function fingerHasMoved(id: SDL_FingerId): boolean;
   183 begin
   270 begin
   207     setLength(pointerIds, 5);
   294     setLength(pointerIds, 5);
   208     setLength(timeSinceDown, 5);
   295     setLength(timeSinceDown, 5);
   209     setLength(historicalXY, 10);    
   296     setLength(historicalXY, 10);    
   210     for index := Low(xyCoord) to High(xyCoord) do xyCoord[index] := -1;
   297     for index := Low(xyCoord) to High(xyCoord) do xyCoord[index] := -1;
   211     for index := Low(pointerIds) to High(pointerIds) do pointerIds[index] := -1;
   298     for index := Low(pointerIds) to High(pointerIds) do pointerIds[index] := -1;
   212 
   299     movingCrosshair := false;
   213 end;
   300 end;
   214 
   301 
   215 begin
   302 begin
   216 end.
   303 end.