summaryrefslogtreecommitdiff
path: root/packages/ptc/examples/land.pp
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2010-09-19 22:10:28 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2010-09-19 22:10:28 +0000
commitb4aae1d93780f36a185bfbddb42adfc61549a313 (patch)
tree532521bcf8ff30208643404a1c9502164d5bdfdf /packages/ptc/examples/land.pp
parent5eb38ea4682fbad6dfcc7bf09e717412ef494dff (diff)
downloadfpc-b4aae1d93780f36a185bfbddb42adfc61549a313.tar.gz
* updated ptc
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@16018 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/ptc/examples/land.pp')
-rw-r--r--packages/ptc/examples/land.pp413
1 files changed, 199 insertions, 214 deletions
diff --git a/packages/ptc/examples/land.pp b/packages/ptc/examples/land.pp
index 930828c108..5a708b828b 100644
--- a/packages/ptc/examples/land.pp
+++ b/packages/ptc/examples/land.pp
@@ -13,121 +13,116 @@ Ported to FPC by Nikolay Nikolov (nickysn@users.sourceforge.net)
Cursor keys to move, <Pause> to brake and <Esc> to quit
}
-Program Land;
+program Land;
{$MODE objfpc}
-Uses
+uses
ptc;
-Const
+const
SCREENWIDTH = 320;
SCREENHEIGHT = 200;
- FOV : Integer = 256; { half of the xy field of view (This is based on the 0-2048 convention) }
+ FOV: Integer = 256; { half of the xy field of view (This is based on the 0-2048 convention) }
-Var
- HMap : Array[0..256*256 - 1] Of Uint8; { Height field }
- CMap : Array[0..256*256 - 1] Of Uint8; { Color map }
+var
+ HMap: array [0..256*256 - 1] of Uint8; { Height field }
+ CMap: array [0..256*256 - 1] of Uint8; { Color map }
lasty, { Last pixel drawn on a given column }
- lastc : Array[0..SCREENWIDTH - 1] Of Integer; { Color of last pixel on a column }
- CosT, SinT : Array[0..2047] Of Integer; { Cosine and Sine tables }
+ lastc: array [0..SCREENWIDTH - 1] of Integer; { Color of last pixel on a column }
+ CosT, SinT: array [0..2047] of Integer; { Cosine and Sine tables }
{ Reduces a value to 0..255 (used in height field computation) }
-Function Clamp(x : Integer) : Integer;
-
-Begin
- If x < 0 Then
- Clamp := 0
- Else
- If x > 255 Then
- Clamp := 255
- Else
- Clamp := x;
-End;
+function Clamp(x: Integer): Integer;
+begin
+ if x < 0 then
+ Result := 0
+ else
+ if x > 255 then
+ Result := 255
+ else
+ Result := x;
+end;
{ Heightfield and colormap computation }
-Procedure ComputeMap;
-
-Var
- p, i, j, k, k2, p2, a, b, c, d : Integer;
-
-Begin
+procedure ComputeMap;
+var
+ p, i, j, k, k2, p2, a, b, c, d: Integer;
+begin
{ Start from a plasma clouds fractal }
HMap[0] := 128;
p := 256;
- While p > 1 Do
- Begin
- p2 := p Shr 1;
+ while p > 1 do
+ begin
+ p2 := p shr 1;
k := p * 8 + 20;
- k2 := k Shr 1;
+ k2 := k shr 1;
i := 0;
- While i < 256 Do
- Begin
+ while i < 256 do
+ begin
j := 0;
- While j < 256 Do
- Begin
- a := HMap[(i Shl 8) + j];
- b := HMap[(((i + p) And 255) Shl 8) + j];
- c := HMap[(i Shl 8) + ((j + p) And 255)];
- d := HMap[(((i + p) And 255) Shl 8) + ((j + p) And 255)];
-
- HMap[(i Shl 8) + ((j + p2) And 255)] :=
- Clamp(((a + c) Shr 1) + (Random(k) - k2));
- HMap[(((i + p2) And 255) Shl 8) + ((j + p2) And 255)] :=
- Clamp(((a + b + c + d) Shr 2) + (Random(k) - k2));
- HMap[(((i + p2) And 255) Shl 8) + j] :=
- Clamp(((a + b) Shr 1) + (Random(k) - k2));
- Inc(j, p);
- End;
+ while j < 256 do
+ begin
+ a := HMap[(i shl 8) + j];
+ b := HMap[(((i + p) and 255) shl 8) + j];
+ c := HMap[(i shl 8) + ((j + p) and 255)];
+ d := HMap[(((i + p) and 255) shl 8) + ((j + p) and 255)];
+
+ HMap[(i shl 8) + ((j + p2) and 255)] :=
+ Clamp(((a + c) shr 1) + (Random(k) - k2));
+ HMap[(((i + p2) and 255) shl 8) + ((j + p2) and 255)] :=
+ Clamp(((a + b + c + d) shr 2) + (Random(k) - k2));
+ HMap[(((i + p2) and 255) shl 8) + j] :=
+ Clamp(((a + b) shr 1) + (Random(k) - k2));
+ Inc(j, p);
+ end;
Inc(i, p);
- End;
+ end;
p := p2;
- End;
+ end;
{ Smoothing }
- For k := 0 To 2 Do
- Begin
+ for k := 0 to 2 do
+ begin
i := 0;
- While i < 256*256 Do
- Begin
- For j := 0 To 255 Do
- HMap[i + j] := (HMap[((i + 256) And $FF00) + j] +
- HMap[i + ((j + 1) And $FF)] +
- HMap[((i - 256) And $FF00) + j] +
- HMap[i + ((j - 1) And $FF)]) Shr 2;
+ while i < 256*256 do
+ begin
+ for j := 0 to 255 do
+ HMap[i + j] := (HMap[((i + 256) and $FF00) + j] +
+ HMap[i + ((j + 1) and $FF)] +
+ HMap[((i - 256) and $FF00) + j] +
+ HMap[i + ((j - 1) and $FF)]) shr 2;
Inc(i, 256);
- End;
- End;
+ end;
+ end;
{ Color computation (derivative of the height field) }
i := 0;
- While i < 256*256 Do
- Begin
- For j := 0 To 255 Do
- Begin
- k := 128 + (HMap[((i + 256) And $FF00) + ((j + 1) And 255)] - HMap[i + j])*4;
- If k < 0 Then
- k := 0;
- If k > 255 Then
- k := 255;
+ while i < 256*256 do
+ begin
+ for j := 0 to 255 do
+ begin
+ k := 128 + (HMap[((i + 256) and $FF00) + ((j + 1) and 255)] - HMap[i + j])*4;
+ if k < 0 then
+ k := 0;
+ if k > 255 then
+ k := 255;
CMap[i + j] := k;
- End;
+ end;
Inc(i, 256);
- End;
-End;
+ end;
+end;
{ Calculate the lookup tables }
-Procedure InitTables;
-
-Var
- a : Integer;
- result : Single;
-
-Begin
- For a := 0 To 2047 Do
- Begin
+procedure InitTables;
+var
+ a: Integer;
+ result: Single;
+begin
+ for a := 0 to 2047 do
+ begin
{ Precalculate cosine }
result := cos(a * PI / 1024) * 256;
CosT[a] := Trunc(result);
@@ -135,8 +130,8 @@ Begin
{ and sine }
result := sin(a * PI / 1024) * 256;
SinT[a] := Trunc(result);
- End;
-End;
+ end;
+end;
{
Draw a "section" of the landscape; x0,y0 and x1,y1 and the xy coordinates
@@ -144,29 +139,27 @@ End;
for the distance. x0,y0,x1,y1 are 16.16 fixed point numbers and the
scaling factor is a 16.8 fixed point value.
}
-Procedure Line(x0, y0, x1, y1, hy, s : Integer; surface_buffer : PUint32; fadeout : Integer);
-
-Var
- sx, sy, i, a, b, u0, u1, v0, v1, h0, h1, h2, h3, h, c, y : Integer;
- coord_x, coord_y, sc, cc, currentColor : Integer;
- pixel : PUint32;
-
-Begin
+procedure Line(x0, y0, x1, y1, hy, s: Integer; surface_buffer: PUint32; fadeout: Integer);
+var
+ sx, sy, i, a, b, u0, u1, v0, v1, h0, h1, h2, h3, h, c, y: Integer;
+ coord_x, coord_y, sc, cc, currentColor: Integer;
+ pixel: PUint32;
+begin
{ Compute xy speed }
- sx := (x1 - x0) Div SCREENWIDTH;
- sy := (y1 - y0) Div SCREENWIDTH;
+ sx := (x1 - x0) div SCREENWIDTH;
+ sy := (y1 - y0) div SCREENWIDTH;
- For i := 0 To SCREENWIDTH - 1 Do
- Begin
+ for i := 0 to SCREENWIDTH - 1 do
+ begin
{ Compute the xy coordinates; a and b will be the position inside the }
{ single map cell (0..255). }
- a := (x0 Shr 8) And $FF;
- b := (y0 Shr 8) And $FF;
+ a := (x0 shr 8) and $FF;
+ b := (y0 shr 8) and $FF;
- u0 := (x0 Shr 16) And $FF;
- u1 := (u0 + 1) And $FF;
- v0 := (y0 Shr 8) And $FF00;
- v1 := (v0 + 256) And $FF00;
+ u0 := (x0 shr 16) and $FF;
+ u1 := (u0 + 1) and $FF;
+ v0 := (y0 shr 8) and $FF00;
+ v1 := (v0 + 256) and $FF00;
{ Fetch the height at the four corners of the square the point is in }
h0 := HMap[u0 + v0];
@@ -175,9 +168,9 @@ Begin
h3 := HMap[u1 + v1];
{ Compute the height using bilinear interpolation }
- h0 := (h0 Shl 8) + a * (h1 - h0);
- h2 := (h2 Shl 8) + a * (h3 - h2);
- h := ((h0 Shl 8) + b * (h2 - h0)) Shr 16;
+ h0 := (h0 shl 8) + a * (h1 - h0);
+ h2 := (h2 shl 8) + a * (h3 - h2);
+ h := ((h0 shl 8) + b * (h2 - h0)) shr 16;
{ Fetch the color at the centre of the square the point is in }
h0 := CMap[u0 + v0];
@@ -186,72 +179,70 @@ Begin
h3 := CMap[u1 + v1];
{ Compute the color using bilinear interpolation (in 16.16) }
- h0 := (h0 Shl 8) + a * (h1 - h0);
- h2 := (h2 Shl 8) + a * (h3 - h2);
- c := ((h0 Shl 8) + b * (h2 - h0));
+ h0 := (h0 shl 8) + a * (h1 - h0);
+ h2 := (h2 shl 8) + a * (h3 - h2);
+ c := ((h0 shl 8) + b * (h2 - h0));
{ Compute screen height using the scaling factor }
- y := (((h - hy) * s) Shr 11) + (SCREENHEIGHT Shr 1);
+ y := (((h - hy) * s) shr 11) + (SCREENHEIGHT shr 1);
{ Draw the column }
a := lasty[i];
- If y < a Then
- Begin
+ if y < a then
+ begin
coord_x := i;
coord_y := a;
- If lastc[i] = -1 Then
- lastc[i] := c;
+ if lastc[i] = -1 then
+ lastc[i] := c;
- sc := (c - lastc[i]) Div (a - y);
+ sc := (c - lastc[i]) div (a - y);
cc := lastc[i];
- If a > (SCREENHEIGHT - 1) Then
- Begin
- Dec(coord_y, a - (SCREENHEIGHT - 1));
- a := SCREENHEIGHT - 1;
- End;
- If y < 0 Then
- y := 0;
-
- While y < a Do
- Begin
- currentColor := cc Shr 18;
- pixel := surface_buffer + (coord_y * SCREENWIDTH) + coord_x;
- pixel^ := ((currentColor Shl 2) * (150 - fadeout) Div 150) Shl 8;
- Inc(cc, sc);
- Dec(coord_y);
- Dec(a);
- End;
+ if a > (SCREENHEIGHT - 1) then
+ begin
+ Dec(coord_y, a - (SCREENHEIGHT - 1));
+ a := SCREENHEIGHT - 1;
+ end;
+ if y < 0 then
+ y := 0;
+
+ while y < a do
+ begin
+ currentColor := cc shr 18;
+ pixel := surface_buffer + (coord_y * SCREENWIDTH) + coord_x;
+ pixel^ := ((currentColor shl 2) * (150 - fadeout) div 150) shl 8;
+ Inc(cc, sc);
+ Dec(coord_y);
+ Dec(a);
+ end;
lasty[i] := y;
- End;
+ end;
lastc[i] := c;
{ Advance to next xy position }
Inc(x0, sx); Inc(y0, sy);
- End;
-End;
+ end;
+end;
{ Draw the view from the point x0,y0 (16.16) looking at angle a }
-Procedure View(x0, y0, angle, height : Integer; surface_buffer : PUint32);
-
-Var
- d, u0, a, v0, u1, v1, h0, h1, h2, h3 : Integer;
-
-Begin
+procedure View(x0, y0, angle, height: Integer; surface_buffer: PUint32);
+var
+ d, u0, a, v0, u1, v1, h0, h1, h2, h3: Integer;
+begin
{ Initialize last-y and last-color arrays }
- For d := 0 To SCREENWIDTH - 1 Do
- Begin
+ for d := 0 to SCREENWIDTH - 1 do
+ begin
lasty[d] := SCREENHEIGHT;
lastc[d] := -1;
- End;
+ end;
{ Compute the xy coordinates; a and b will be the position inside the }
{ single map cell (0..255). }
- u0 := (x0 Shr 16) And $FF;
- a := (x0 Shr 8) And $FF;
- v0 := (y0 Shr 8) And $FF00;
- u1 := (u0 + 1) And $FF;
- v1 := (v0 + 256) And $FF00;
+ u0 := (x0 shr 16) and $FF;
+ a := (x0 shr 8) and $FF;
+ v0 := (y0 shr 8) and $FF00;
+ u1 := (u0 + 1) and $FF;
+ v1 := (v0 + 256) and $FF00;
{ Fetch the height at the four corners of the square the point is in }
h0 := HMap[u0 + v0];
@@ -260,47 +251,41 @@ Begin
h3 := HMap[u1 + v1];
{ Compute the height using bilinear interpolation }
- h0 := (h0 Shl 8) + a * (h1 - h0);
- h2 := (h2 Shl 8) + a * (h3 - h2);
+ h0 := (h0 shl 8) + a * (h1 - h0);
+ h2 := (h2 shl 8) + a * (h3 - h2);
{ Draw the landscape from near to far without overdraw }
d := 0;
- While d < 150 Do
- Begin
- Line(x0 + (d Shl 8)*CosT[(angle - FOV) And $7FF],
- y0 + (d Shl 8)*SinT[(angle - FOV) And $7FF],
- x0 + (d Shl 8)*CosT[(angle + FOV) And $7FF],
- y0 + (d Shl 8)*SinT[(angle + FOV) And $7FF],
- height, (100 Shl 8) Div (d + 1),
- surface_buffer,
- d);
- Inc(d, 1 + (d Shr 6));
- End;
-End;
-
-Var
- format : TPTCFormat;
- console : TPTCConsole;
- surface : TPTCSurface;
- timer : TPTCTimer;
- key : TPTCKeyEvent;
- pixels : PUint32;
- Done : Boolean;
-
- x0, y0 : Integer;
- height : Integer;
- angle, deltaAngle, deltaSpeed, CurrentSpeed, scale, delta : Double;
- index : Integer;
-
-Begin
+ while d < 150 do
+ begin
+ Line(x0 + (d shl 8)*CosT[(angle - FOV) and $7FF],
+ y0 + (d shl 8)*SinT[(angle - FOV) and $7FF],
+ x0 + (d shl 8)*CosT[(angle + FOV) and $7FF],
+ y0 + (d shl 8)*SinT[(angle + FOV) and $7FF],
+ height, (100 shl 8) div (d + 1),
+ surface_buffer,
+ d);
+ Inc(d, 1 + (d shr 6));
+ end;
+end;
+
+var
+ format: TPTCFormat = nil;
+ console: TPTCConsole = nil;
+ surface: TPTCSurface = nil;
+ timer: TPTCTimer = nil;
+ key: TPTCKeyEvent = nil;
+ pixels: PUint32;
+ Done: Boolean;
+
+ x0, y0: Integer;
+ height: Integer;
+ angle, deltaAngle, deltaSpeed, CurrentSpeed, scale, delta: Double;
+ index: Integer;
+begin
Done := False;
- format := Nil;
- console := Nil;
- surface := Nil;
- timer := Nil;
- key := Nil;
- Try
- Try
+ try
+ try
key := TPTCKeyEvent.Create;
format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
console := TPTCConsole.Create;
@@ -330,7 +315,7 @@ Begin
timer.start;
{ main loop }
- Repeat
+ repeat
{ get time delta between frames }
delta := timer.delta;
@@ -339,13 +324,13 @@ Begin
{ lock surface pixels }
pixels := surface.lock;
- Try
+ try
{ draw current landscape view }
View(x0, y0, Trunc(angle), height, pixels);
- Finally
+ finally
{ unlock surface }
surface.unlock;
- End;
+ end;
{ copy surface to console }
surface.copy(console);
@@ -354,49 +339,49 @@ Begin
console.update;
{ check key press }
- While console.KeyPressed Do
- Begin
+ while console.KeyPressed do
+ begin
{ read key press }
- console.ReadKey(key);
+ console.ReadKey(key);
{ handle key press }
- Case key.code Of
+ case key.code of
{ increase speed }
- PTCKEY_UP : CurrentSpeed += deltaSpeed * delta * scale;
+ PTCKEY_UP: CurrentSpeed := CurrentSpeed + deltaSpeed * delta * scale;
{ decrease speed }
- PTCKEY_DOWN : CurrentSpeed -= deltaSpeed * delta * scale;
+ PTCKEY_DOWN: CurrentSpeed := CurrentSpeed - deltaSpeed * delta * scale;
{ turn to the left }
- PTCKEY_LEFT : deltaAngle -= 1;
+ PTCKEY_LEFT: deltaAngle := deltaAngle - 1;
{ turn to the right }
- PTCKEY_RIGHT : deltaAngle += 1;
- PTCKEY_SPACE : Begin
+ PTCKEY_RIGHT: deltaAngle := deltaAngle + 1;
+ PTCKEY_SPACE: begin
{ stop moving }
- CurrentSpeed := 0;
- deltaAngle := 0;
- End;
+ CurrentSpeed := 0;
+ deltaAngle := 0;
+ end;
{ exit }
- PTCKEY_ESCAPE : Done := True;
- End;
- End;
+ PTCKEY_ESCAPE: Done := True;
+ end;
+ end;
{ Update position/angle }
- angle += deltaAngle * delta * scale;
+ angle := angle + deltaAngle * delta * scale;
- index := Trunc(angle) And $7FF;
- Inc(x0, Trunc(CurrentSpeed * CosT[index]) Div 256);
- Inc(y0, Trunc(CurrentSpeed * SinT[index]) Div 256);
- Until Done;
- Finally
+ index := Trunc(angle) and $7FF;
+ Inc(x0, Trunc(CurrentSpeed * CosT[index]) div 256);
+ Inc(y0, Trunc(CurrentSpeed * SinT[index]) div 256);
+ until Done;
+ finally
console.close;
console.Free;
surface.Free;
timer.Free;
format.Free;
key.Free;
- End;
- Except
- On error : TPTCError Do
+ end;
+ except
+ on error: TPTCError do
{ report error }
error.report;
- End;
-End.
+ end;
+end.