hedgewars/uCollisions.pas
branchwebgl
changeset 9950 2759212a27de
parent 9521 8054d9d775fd
parent 9737 f0769402350c
child 10015 4feced261c68
--- a/hedgewars/uCollisions.pas	Fri Oct 11 17:43:13 2013 +0200
+++ b/hedgewars/uCollisions.pas	Sat Jan 04 23:55:54 2014 +0400
@@ -38,29 +38,29 @@
 
 function  CheckGearsCollision(Gear: PGear): PGearArray;
 
-function  TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean;
+function  TestCollisionXwithGear(Gear: PGear; Dir: LongInt): Word;
 function  TestCollisionYwithGear(Gear: PGear; Dir: LongInt): Word;
 
-function  TestCollisionXKick(Gear: PGear; Dir: LongInt): boolean;
-function  TestCollisionYKick(Gear: PGear; Dir: LongInt): boolean;
+function  TestCollisionXKick(Gear: PGear; Dir: LongInt): Word;
+function  TestCollisionYKick(Gear: PGear; Dir: LongInt): Word;
 
-function  TestCollisionX(Gear: PGear; Dir: LongInt): boolean;
-function  TestCollisionY(Gear: PGear; Dir: LongInt): boolean;
+function  TestCollisionX(Gear: PGear; Dir: LongInt): Word;
+function  TestCollisionY(Gear: PGear; Dir: LongInt): Word;
 
-function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; inline;
-function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean;
-function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; inline;
-function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean;
+function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): Word; inline;
+function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word;
+function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): Word; inline;
+function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word;
 
 function  TestRectancleForObstacle(x1, y1, x2, y2: LongInt; landOnly: boolean): boolean;
 
 // returns: negative sign if going downhill to left, value is steepness (noslope/error = _0, 45 = _0_5)
 function  CalcSlopeBelowGear(Gear: PGear): hwFloat;
 function  CalcSlopeNearGear(Gear: PGear; dirX, dirY: LongInt): hwFloat;
-function  CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): Boolean;
+function  CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean;
 
 implementation
-uses uConsts, uLandGraphics, uVariables, uDebug, uGearsList;
+uses uConsts, uLandGraphics, uVariables, uDebug;
 
 type TCollisionEntry = record
     X, Y, Radius: LongInt;
@@ -95,7 +95,7 @@
     while (t <> nil) and (t^.Kind <> gtMine) do 
         t:= t^.NextGear;
     if (t <> nil) then
-        DeleteGear(t)
+        t^.State:= t^.State or gmDelete
     end;
 end;
 
@@ -135,7 +135,7 @@
                 end
 end;
 
-function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean;
+function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): Word;
 var x, y, i: LongInt;
 begin
 // Special case to emulate the old intersect gear clearing, but with a bit of slop for pixel overlap
@@ -150,7 +150,6 @@
 else
     x:= x + Gear^.Radius;
 
-TestCollisionXwithGear:= true;
 if (x and LAND_WIDTH_MASK) = 0 then
     begin
     y:= hwRound(Gear^.Y) - Gear^.Radius + 1;
@@ -158,11 +157,11 @@
     repeat
         if (y and LAND_HEIGHT_MASK) = 0 then
             if Land[y, x] and Gear^.CollisionMask <> 0 then
-                exit;
+                exit(Land[y, x] and Gear^.CollisionMask);
         inc(y)
     until (y > i);
     end;
-TestCollisionXwithGear:= false
+TestCollisionXwithGear:= 0
 end;
 
 function TestCollisionYwithGear(Gear: PGear; Dir: LongInt): Word;
@@ -188,8 +187,7 @@
         if (x and LAND_WIDTH_MASK) = 0 then
             if Land[y, x] and Gear^.CollisionMask <> 0 then
                 begin
-                TestCollisionYwithGear:= Land[y, x];
-                exit;
+                exit(Land[y, x] and Gear^.CollisionMask)
                 end;
         inc(x)
     until (x > i);
@@ -197,34 +195,33 @@
 TestCollisionYwithGear:= 0
 end;
 
-function TestCollisionXKick(Gear: PGear; Dir: LongInt): boolean;
+function TestCollisionXKick(Gear: PGear; Dir: LongInt): Word;
 var x, y, mx, my, i: LongInt;
-    flag: boolean;
+    pixel: Word;
 begin
-flag:= false;
+pixel:= 0;
 x:= hwRound(Gear^.X);
 if Dir < 0 then
     x:= x - Gear^.Radius
 else
     x:= x + Gear^.Radius;
 
-TestCollisionXKick:= true;
 if (x and LAND_WIDTH_MASK) = 0 then
     begin
     y:= hwRound(Gear^.Y) - Gear^.Radius + 1;
     i:= y + Gear^.Radius * 2 - 2;
     repeat
         if (y and LAND_HEIGHT_MASK) = 0 then
-            if Land[y, x] > 255 then
-                exit
-            else if Land[y, x] <> 0 then
-                flag:= true;
+            if Land[y, x] and Gear^.CollisionMask > 255 then
+                exit(Land[y, x] and Gear^.CollisionMask)
+            else if Land[y, x] and Gear^.CollisionMask <> 0 then
+                pixel:= Land[y, x] and Gear^.CollisionMask;
     inc(y)
     until (y > i);
     end;
-TestCollisionXKick:= flag;
+TestCollisionXKick:= pixel;
 
-if flag then
+if pixel <> 0 then
     begin
     if hwAbs(Gear^.dX) < cHHKick then
         exit;
@@ -255,24 +252,22 @@
                         Active:= true
                         end;
                     DeleteCI(cGear);
-                    TestCollisionXKick:= false;
-                    exit;
+                    exit(0);
                     end
     end
 end;
 
-function TestCollisionYKick(Gear: PGear; Dir: LongInt): boolean;
+function TestCollisionYKick(Gear: PGear; Dir: LongInt): Word;
 var x, y, mx, my,  myr, i: LongInt;
-    flag: boolean;
+    pixel: Word;
 begin
-flag:= false;
+pixel:= 0;
 y:= hwRound(Gear^.Y);
 if Dir < 0 then
     y:= y - Gear^.Radius
 else
     y:= y + Gear^.Radius;
 
-TestCollisionYKick:= true;
 if (y and LAND_HEIGHT_MASK) = 0 then
     begin
     x:= hwRound(Gear^.X) - Gear^.Radius + 1;
@@ -280,16 +275,16 @@
     repeat
     if (x and LAND_WIDTH_MASK) = 0 then
         if Land[y, x] > 0 then
-            if Land[y, x] > 255 then
-                exit
+            if Land[y, x] and Gear^.CollisionMask > 255 then
+                exit(Land[y, x] and Gear^.CollisionMask)
             else if Land[y, x] <> 0 then
-                flag:= true;
+                pixel:= Land[y, x] and Gear^.CollisionMask;
     inc(x)
     until (x > i);
     end;
-TestCollisionYKick:= flag;
+TestCollisionYKick:= pixel;
 
-if flag then
+if pixel <> 0 then
     begin
     if hwAbs(Gear^.dY) < cHHKick then
         exit;
@@ -318,18 +313,17 @@
                         Active:= true
                         end;
                     DeleteCI(cGear);
-                    TestCollisionYKick:= false;
-                    exit
+                    exit(0)
                     end
     end
 end;
 
-function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; inline;
+function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): Word; inline;
 begin
     TestCollisionXwithXYShift:= TestCollisionXwithXYShift(Gear, ShiftX, ShiftY, Dir, true);
 end;
 
-function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean;
+function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word;
 begin
 Gear^.X:= Gear^.X + ShiftX;
 Gear^.Y:= Gear^.Y + int2hwFloat(ShiftY);
@@ -340,7 +334,7 @@
 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY)
 end;
 
-function TestCollisionX(Gear: PGear; Dir: LongInt): boolean;
+function TestCollisionX(Gear: PGear; Dir: LongInt): Word;
 var x, y, i: LongInt;
 begin
 x:= hwRound(Gear^.X);
@@ -349,22 +343,21 @@
 else
     x:= x + Gear^.Radius;
 
-TestCollisionX:= true;
 if (x and LAND_WIDTH_MASK) = 0 then
     begin
     y:= hwRound(Gear^.Y) - Gear^.Radius + 1;
     i:= y + Gear^.Radius * 2 - 2;
     repeat
         if (y and LAND_HEIGHT_MASK) = 0 then
-            if Land[y, x] > 255 then
-                exit;
+            if Land[y, x] and Gear^.CollisionMask > 255 then
+                exit(Land[y, x] and Gear^.CollisionMask);
     inc(y)
     until (y > i);
     end;
-TestCollisionX:= false
+TestCollisionX:= 0
 end;
 
-function TestCollisionY(Gear: PGear; Dir: LongInt): boolean;
+function TestCollisionY(Gear: PGear; Dir: LongInt): Word;
 var x, y, i: LongInt;
 begin
 y:= hwRound(Gear^.Y);
@@ -373,33 +366,32 @@
 else
     y:= y + Gear^.Radius;
 
-TestCollisionY:= true;
 if (y and LAND_HEIGHT_MASK) = 0 then
     begin
     x:= hwRound(Gear^.X) - Gear^.Radius + 1;
     i:= x + Gear^.Radius * 2 - 2;
     repeat
         if (x and LAND_WIDTH_MASK) = 0 then
-            if Land[y, x] > 255 then
-                exit;
+            if Land[y, x] and Gear^.CollisionMask > 255 then
+                exit(Land[y, x] and Gear^.CollisionMask);
     inc(x)
     until (x > i);
     end;
-TestCollisionY:= false
+TestCollisionY:= 0
 end;
 
-function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; inline;
+function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): Word; inline;
 begin
     TestCollisionYwithXYShift:= TestCollisionYwithXYShift(Gear, ShiftX, ShiftY, Dir, true);
 end;
 
-function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean;
+function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): Word;
 begin
 Gear^.X:= Gear^.X + int2hwFloat(ShiftX);
 Gear^.Y:= Gear^.Y + int2hwFloat(ShiftY);
 
 if withGear then
-  TestCollisionYwithXYShift:= TestCollisionYwithGear(Gear, Dir) <> 0
+  TestCollisionYwithXYShift:= TestCollisionYwithGear(Gear, Dir)
 else
   TestCollisionYwithXYShift:= TestCollisionY(Gear, Dir);