--- a/hedgewars/uRender.pas Wed May 16 18:22:28 2018 +0200
+++ b/hedgewars/uRender.pas Wed Jul 31 23:14:27 2019 +0200
@@ -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;
@@ -53,6 +54,8 @@
procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline;
procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
+procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); inline;
+procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; r, g, b, a: Byte);
procedure DrawLineOnScreen (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean);
procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
@@ -65,7 +68,7 @@
procedure RenderClear (mode: TRenderMode);
{$ENDIF}
procedure RenderSetClearColor (r, g, b, a: real);
-procedure Tint (r, g, b, a: Byte); inline;
+procedure Tint (r, g, b, a: Byte);
procedure Tint (c: Longword); inline;
procedure untint(); inline;
procedure setTintAdd (enable: boolean); inline;
@@ -527,7 +530,10 @@
{$IFNDEF PAS2C}
if not Load_GL_VERSION_2_0 then
- halt;
+ begin
+ WriteLnToConsole('Load_GL_VERSION_2_0 returned false!');
+ halt(HaltStartupError);
+ end;
{$ENDIF}
shaderWater:= CompileProgram('water');
@@ -718,7 +724,7 @@
end;
procedure openglRotatef(RotX, RotY, RotZ: GLfloat; dir: LongInt); inline;
-{ workaround for pascal bug http://bugs.freepascal.org/view.php?id=27222 }
+{ workaround for pascal bug https://bugs.freepascal.org/view.php?id=27222 }
var tmpdir: LongInt;
begin
tmpdir:=dir;
@@ -1147,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
@@ -1181,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
@@ -1213,6 +1258,8 @@
openglTranslatef(-PivotX, -PivotY, 0);
end;
+UpdateModelviewProjection;
+
DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
openglPopMatrix;
@@ -1334,11 +1381,17 @@
end;
end;
+// Same as below, but with color as LongWord
procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline;
begin
DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF)
end;
+// Draw line between 2 points
+// X0, Y0: Start point
+// X0, Y1: End point
+// Width: Visual line width
+// r, g, b, a: Color
procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
begin
openglPushMatrix();
@@ -1353,6 +1406,106 @@
UpdateModelviewProjection;
end;
+// Same as below, but with color as a longword
+procedure DrawLineWrapped(X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); inline;
+begin
+DrawLineWrapped(X0, Y0, X1, Y1, Width, goesLeft, Wraps, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF);
+end;
+
+// Draw a line between 2 points, but it wraps around the
+// world edge for a given number of times.
+// goesLeft: true if the line direction from the start point is left
+// Wraps: Number of times the line intersects the wrapping world edge
+// r, g, b, a: color
+procedure DrawLineWrapped(X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; r, g, b, a: Byte);
+var w: LongWord;
+ startX, startY, endX, endY: Single;
+ // total X and Y distance the line travels if you would unwrap it
+ // with this we know the slope of the line.
+ totalX, totalY: Single;
+ // x variable for the line formula
+ x: Single;
+begin
+ openglPushMatrix();
+ openglTranslatef(WorldDx, WorldDy, 0);
+
+ UpdateModelviewProjection;
+
+ startX:= X0;
+ startY:= Y0;
+ if (Wraps = 0) then
+ begin
+ // Wraps=0 is trivial: Just draw one direct connection
+ endX:= X1;
+ endY:= Y1;
+ DrawLineOnScreen(startX, startY, endX, endY, Width, r, g, b, a);
+ end
+ else
+ begin
+ // A wrapping line is drawn using multiple line segments
+ // which stop at the left and right border. We
+ // calculate the points at which the line intersects with the border.
+ // Then we draws all line segments.
+
+ // Calculate position of first wrap point
+ if goesLeft then
+ begin
+ endX:= LeftX;
+ totalX:= (RightX - X1) + (X0 - LeftX);
+ x:= X0 - LeftX;
+ end
+ else
+ begin
+ endX:= RightX;
+ totalX:= (RightX - X0) + (X1 - LeftX);
+ x:= RightX - X0;
+ end;
+ if (Wraps >= 2) then
+ totalX:= totalX + ((RightX - LeftX) * (Wraps-1));
+ totalY:= Y1 - Y0;
+ // Calculate Y of first wrap point using the line formula
+ endY:= Y0 + (totalY / totalX) * x;
+ // Draw line segment between starting point and first wrap point
+ DrawLineOnScreen(startX, startY, endX, endY, Width, r, g, b, a);
+
+ // Calculate and draw all remaining line segments
+ for w:=1 to Wraps do
+ begin
+ startY:= endY;
+ if goesLeft then
+ begin
+ startX:= RightX;
+ if w < Wraps then
+ endX:= LeftX
+ else
+ endX:= X1;
+ end
+ else
+ begin
+ startX:= LeftX;
+ if w < Wraps then
+ endX:= RightX
+ else
+ endX:= X1;
+ end;
+ if w < Wraps then
+ begin
+ x:= x + (RightX - LeftX);
+ endY:= Y0 + (totalY / totalX) * x;
+ end
+ else
+ endY:= Y1;
+
+ DrawLineOnScreen(startX, startY, endX, endY, Width, r, g, b, a);
+ end;
+
+ end;
+
+ openglPopMatrix();
+
+ UpdateModelviewProjection;
+end;
+
procedure DrawLineOnScreen(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
begin
glEnable(GL_LINE_SMOOTH);
@@ -1734,8 +1887,8 @@
else
PrepareVbForWater(true,
OffsetY + WorldDy + cWaterLine, ViewTopY,
- LongInt(LeftX) + WorldDx - OffsetX, ViewLeftX,
- LongInt(RightX) + WorldDx + OffsetX, ViewRightX,
+ leftX + WorldDx - OffsetX, ViewLeftX,
+ rightX + WorldDx + OffsetX, ViewRightX,
ViewBottomY,
first, count);
@@ -1825,8 +1978,8 @@
dY:= -cWaveHeight + dy;
ox:= -cWaveHeight + ox;
-lx:= LongInt(LeftX) + WorldDx - ox;
-rx:= LongInt(RightX) + WorldDx + ox;
+lx:= leftX + WorldDx - ox;
+rx:= rightX + WorldDx + ox;
topy:= cWaterLine + WorldDy + dY;
@@ -1933,7 +2086,7 @@
{$ENDIF}
end;
-procedure Tint(r, g, b, a: Byte); inline;
+procedure Tint(r, g, b, a: Byte);
var
nc, tw: Longword;
begin