tunnel.pp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. {
  2. Ported to FPC by Nikolay Nikolov ([email protected])
  3. }
  4. {
  5. Tunnel demo for OpenPTC 1.0 C++ API
  6. Originally coded by Thomas Rizos ([email protected])
  7. Adapted for OpenPTC by Glenn Fiedler ([email protected])
  8. This source code is licensed under the GNU GPL
  9. }
  10. Program Tunnel;
  11. {$MODE objfpc}
  12. Uses
  13. ptc, Math;
  14. Type
  15. { tunnel class }
  16. TTunnel = Class(TObject)
  17. Public
  18. Constructor Create;
  19. Destructor Destroy; Override;
  20. Procedure setup;
  21. Procedure draw(buffer : PUint32; t : Single);
  22. Private
  23. { tunnel data }
  24. tunnel : PUint32;
  25. texture : PUint8;
  26. End;
  27. Constructor TTunnel.Create;
  28. Begin
  29. tunnel := Nil;
  30. texture := Nil;
  31. { allocate tables }
  32. tunnel := GetMem(320*200*SizeOf(Uint32));
  33. texture := GetMem(256*256*2*SizeOf(Uint8));
  34. { setup }
  35. setup;
  36. End;
  37. Destructor TTunnel.Destroy;
  38. Begin
  39. { free tables }
  40. If assigned(tunnel) Then
  41. FreeMem(tunnel);
  42. If assigned(texture) Then
  43. FreeMem(texture);
  44. Inherited Destroy;
  45. End;
  46. Procedure TTunnel.setup;
  47. Var
  48. index : Integer;
  49. x, y : Integer;
  50. angle, angle1, angle2, radius, u, v : Double;
  51. Begin
  52. { tunnel index }
  53. index := 0;
  54. { generate tunnel table }
  55. For y := 100 DownTo -99 Do
  56. For x := -160 To 159 Do
  57. Begin
  58. { calculate angle from center }
  59. angle := arctan2(y, x) * 256 / pi / 2;
  60. { calculate radius from center }
  61. radius := sqrt(x * x + y * y);
  62. { clamp radius to minimum }
  63. If radius < 1 Then
  64. radius := 1;
  65. { texture coordinates }
  66. u := angle;
  67. v := 6000 / radius;
  68. { calculate texture index for (u,v) }
  69. tunnel[index] := (Trunc(v) And $FF) * 256 + (Trunc(u) And $FF);
  70. Inc(index);
  71. End;
  72. { generate blue plasma texture }
  73. index := 0;
  74. angle2 := pi * 2/256 * 230;
  75. For y := 0 To 256 * 2 - 1 Do
  76. Begin
  77. angle1 := pi * 2/256 * 100;
  78. For x := 0 To 256-1 Do
  79. Begin
  80. texture[index] := Trunc(sin(angle1)*80 + sin(angle2)*40 + 128);
  81. angle1 := angle1 + pi*2/256*3;
  82. Inc(index);
  83. End;
  84. angle2 := angle2 + pi * 2/256 *2;
  85. End;
  86. End;
  87. Procedure TTunnel.draw(buffer : PUint32; t : Single);
  88. Var
  89. x, y : Integer;
  90. scroll : Uint32;
  91. i : Integer;
  92. Begin
  93. { tunnel control functions }
  94. x := Trunc(sin(t) * 99.9);
  95. y := Trunc(t * 200);
  96. { calculate tunnel scroll offset }
  97. scroll := ((y And $FF) Shl 8) + (x And $FF);
  98. { loop through each pixel }
  99. For i := 0 To 64000-1 Do
  100. { lookup tunnel texture }
  101. buffer[i] := texture[tunnel[i] + scroll];
  102. End;
  103. Var
  104. format : TPTCFormat;
  105. console : TPTCConsole;
  106. surface : TPTCSurface;
  107. TheTunnel : TTunnel;
  108. time, delta : Single;
  109. buffer : PUint32;
  110. Begin
  111. format := Nil;
  112. surface := Nil;
  113. console := Nil;
  114. TheTunnel := Nil;
  115. Try
  116. Try
  117. { create format }
  118. format := TPTCFormat.Create(32, $00FF0000, $0000FF00, $000000FF);
  119. { create console }
  120. console := TPTCConsole.Create;
  121. { open console }
  122. console.open('Tunnel demo', 320, 200, format);
  123. { create surface }
  124. surface := TPTCSurface.Create(320, 200, format);
  125. { create tunnel }
  126. TheTunnel := TTunnel.Create;
  127. { time data }
  128. time := 0;
  129. delta := 0.03;
  130. { loop until a key is pressed }
  131. While Not console.KeyPressed Do
  132. Begin
  133. { lock surface }
  134. buffer := surface.lock;
  135. Try
  136. { draw tunnel }
  137. TheTunnel.draw(buffer, time);
  138. Finally
  139. { unlock surface }
  140. surface.unlock;
  141. End;
  142. { copy to console }
  143. surface.copy(console);
  144. { update console }
  145. console.update;
  146. { update time }
  147. time += delta;
  148. End;
  149. Finally
  150. TheTunnel.Free;
  151. surface.Free;
  152. console.close;
  153. console.Free;
  154. format.Free;
  155. End;
  156. Except
  157. On error : TPTCError Do
  158. { report error }
  159. error.report;
  160. End;
  161. End.