diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2010-09-19 22:10:28 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2010-09-19 22:10:28 +0000 |
commit | b4aae1d93780f36a185bfbddb42adfc61549a313 (patch) | |
tree | 532521bcf8ff30208643404a1c9502164d5bdfdf /packages/ptc/examples/land.pp | |
parent | 5eb38ea4682fbad6dfcc7bf09e717412ef494dff (diff) | |
download | fpc-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.pp | 413 |
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. |