--- a/hedgewars/uGearsRender.pas Thu May 23 13:41:14 2019 +0200
+++ b/hedgewars/uGearsRender.pas Thu May 23 20:37:41 2019 +0300
@@ -95,102 +95,64 @@
end;
-function DrawRopeLine(X1, Y1, X2, Y2, roplen: LongInt; LayerIndex: Longword): LongInt;
-var eX, eY, dX, dY: LongInt;
- i, sX, sY, x, y, d: LongInt;
- b: boolean;
- angle: real;
+procedure DrawRopeLine(X1, Y1, X2, Y2: Real; LayerIndex: Longword; var linesLength, ropeLength: Real);
+var dX, dY, angle, length: Real;
+ FrameIndex: LongWord;
begin
if (X1 = X2) and (Y1 = Y2) then
- begin
- //OutError('WARNING: zero length rope line!', false);
- DrawRopeLine:= 0;
- exit
- end;
- eX:= 0;
- eY:= 0;
+ exit;
+
dX:= X2 - X1;
dY:= Y2 - Y1;
+ length:= sqrt(sqr(dX) + sqr(dY));
angle:= arctan2(dY, dX) * 180 / PI - 90;
- if (dX > 0) then
- sX:= 1
- else
- if (dX < 0) then
- begin
- sX:= -1;
- dX:= -dX
- end
- else sX:= dX;
-
- if (dY > 0) then
- sY:= 1
- else
- if (dY < 0) then
- begin
- sY:= -1;
- dY:= -dY
- end
- else
- sY:= dY;
-
- if (dX > dY) then
- d:= dX
- else
- d:= dY;
+ dX:= dX / length;
+ dY:= dY / length;
- x:= X1;
- y:= Y1;
-
- for i:= 0 to d do
- begin
- inc(eX, dX);
- inc(eY, dY);
- b:= false;
- if (eX > d) then
- begin
- dec(eX, d);
- inc(x, sX);
- b:= true
- end;
- if (eY > d) then
- begin
- dec(eY, d);
- inc(y, sY);
- b:= true
- end;
- if b then
- begin
- inc(roplen);
- if (roplen mod (cRopeNodeStep * cRopeLayers)) = (cRopeNodeStep * LayerIndex) then
- DrawSpriteRotatedF(sprRopeNode, x, y, roplen div cRopeNodeStep, 1, angle);
- end
+ while (ropeLength - linesLength) <= length do
+ begin
+ FrameIndex:= round(ropeLength / cRopeNodeStep);
+ if (FrameIndex mod cRopeLayers) = LayerIndex then
+ DrawSpriteRotatedFReal(sprRopeNode,
+ X1 + (ropeLength - linesLength) * dX,
+ Y1 + (ropeLength - linesLength) * dY,
+ FrameIndex, 1, angle);
+ ropeLength:= ropeLength + cRopeNodeStep;
end;
- DrawRopeLine:= roplen;
+ linesLength:= linesLength + length
end;
procedure DrawRopeLayer(Gear: PGear; LayerIndex: LongWord);
-var roplen, i: LongInt;
+var i: LongInt;
+ linesLength, ropeLength: Real;
begin
- roplen:= 0;
+ linesLength:= 0;
+ ropeLength:= cRopeNodeStep;
if RopePoints.Count > 0 then
begin
i:= 0;
while i < Pred(RopePoints.Count) do
begin
- roplen:= DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy,
- hwRound(RopePoints.ar[Succ(i)].X) + WorldDx, hwRound(RopePoints.ar[Succ(i)].Y) + WorldDy, roplen, LayerIndex);
+ DrawRopeLine(hwFloat2Float(RopePoints.ar[i].X) + WorldDx, hwFloat2Float(RopePoints.ar[i].Y) + WorldDy,
+ hwFloat2Float(RopePoints.ar[Succ(i)].X) + WorldDx, hwFloat2Float(RopePoints.ar[Succ(i)].Y) + WorldDy,
+ LayerIndex, linesLength, ropeLength);
inc(i)
end;
- roplen:= DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy,
- hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, roplen, LayerIndex);
- roplen:= DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
- hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy, roplen, LayerIndex);
+
+ DrawRopeLine(hwFloat2Float(RopePoints.ar[i].X) + WorldDx, hwFloat2Float(RopePoints.ar[i].Y) + WorldDy,
+ hwFloat2Float(Gear^.X) + WorldDx, hwFloat2Float(Gear^.Y) + WorldDy,
+ LayerIndex, linesLength, ropeLength);
+
+ DrawRopeLine(hwFloat2Float(Gear^.X) + WorldDx, hwFloat2Float(Gear^.Y) + WorldDy,
+ hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) + WorldDy,
+ LayerIndex, linesLength, ropeLength);
end
else
if Gear^.Elasticity.QWordValue > 0 then
- roplen:= DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
- hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy, roplen, LayerIndex);
+ DrawRopeLine(hwFloat2Float(Gear^.X) + WorldDx, hwFloat2Float(Gear^.Y) + WorldDy,
+ hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) + WorldDy,
+ LayerIndex, linesLength, ropeLength);
end;
procedure DrawRope(Gear: PGear);
--- a/hedgewars/uRender.pas Thu May 23 13:41:14 2019 +0200
+++ b/hedgewars/uRender.pas Thu May 23 20:37:41 2019 +0300
@@ -34,6 +34,7 @@
procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
+procedure DrawSpriteRotatedFReal(Sprite: TSprite; X, Y: Real; Frame, Dir: LongInt; Angle: real);
procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
procedure DrawTexture (X, Y: LongInt; Texture: PTexture); inline;
@@ -1152,7 +1153,7 @@
if Angle <> 0 then
begin
- // Check the bounding circle
+ // Check the bounding circle
if isCircleOffscreen(X, Y, (sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) div 4) then
exit;
end
@@ -1186,6 +1187,45 @@
end;
+procedure DrawSpriteRotatedFReal(Sprite: TSprite; X, Y: Real; Frame, Dir: LongInt; Angle: real);
+begin
+
+ if Angle <> 0 then
+ begin
+ // Check the bounding circle
+ if isCircleOffscreen(round(X), round(Y), (sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) div 4) then
+ exit;
+ end
+ else
+ begin
+ if isDxAreaOffscreen(round(X) - SpritesData[Sprite].Width div 2, SpritesData[Sprite].Width) <> 0 then
+ exit;
+ if isDYAreaOffscreen(round(Y) - SpritesData[Sprite].Height div 2 , SpritesData[Sprite].Height) <> 0 then
+ exit;
+ end;
+
+
+ openglPushMatrix;
+ openglTranslatef(X, Y, 0);
+
+// mirror
+ if Dir < 0 then
+ openglScalef(-1.0, 1.0, 1.0);
+
+// apply angle after (conditional) mirroring
+ if Angle <> 0 then
+ openglRotatef(Angle, 0, 0, 1);
+
+ UpdateModelviewProjection;
+
+ DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
+
+ openglPopMatrix;
+
+ UpdateModelviewProjection;
+
+end;
+
procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
begin
if Angle <> 0 then