tunnel.pp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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
  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. { allocate tables }
  30. tunnel := GetMem(320*200*SizeOf(Uint32));
  31. texture := GetMem(256*256*2*SizeOf(Uint8));
  32. { setup }
  33. setup;
  34. end;
  35. destructor TTunnel.Destroy;
  36. begin
  37. { free tables }
  38. FreeMem(tunnel);
  39. FreeMem(texture);
  40. inherited Destroy;
  41. end;
  42. procedure TTunnel.setup;
  43. var
  44. index: Integer;
  45. x, y: Integer;
  46. angle, angle1, angle2, radius, u, v: Double;
  47. begin
  48. { tunnel index }
  49. index := 0;
  50. { generate tunnel table }
  51. for y := 100 DownTo -99 do
  52. for x := -160 to 159 do
  53. begin
  54. { calculate angle from center }
  55. angle := arctan2(y, x) * 256 / pi / 2;
  56. { calculate radius from center }
  57. radius := sqrt(x * x + y * y);
  58. { clamp radius to minimum }
  59. if radius < 1 then
  60. radius := 1;
  61. { texture coordinates }
  62. u := angle;
  63. v := 6000 / radius;
  64. { calculate texture index for (u,v) }
  65. tunnel[index] := (Trunc(v) and $FF) * 256 + (Trunc(u) and $FF);
  66. Inc(index);
  67. end;
  68. { generate blue plasma texture }
  69. index := 0;
  70. angle2 := pi * 2/256 * 230;
  71. for y := 0 to 256 * 2 - 1 do
  72. begin
  73. angle1 := pi * 2/256 * 100;
  74. for x := 0 to 256-1 do
  75. begin
  76. texture[index] := Trunc(sin(angle1)*80 + sin(angle2)*40 + 128);
  77. angle1 := angle1 + pi*2/256*3;
  78. Inc(index);
  79. end;
  80. angle2 := angle2 + pi * 2/256 *2;
  81. end;
  82. end;
  83. procedure TTunnel.draw(buffer: PUint32; t: Single);
  84. var
  85. x, y: Integer;
  86. scroll: Uint32;
  87. i: Integer;
  88. begin
  89. { tunnel control functions }
  90. x := Trunc(sin(t) * 99.9);
  91. y := Trunc(t * 200);
  92. { calculate tunnel scroll offset }
  93. scroll := ((y and $FF) shl 8) + (x and $FF);
  94. { loop through each pixel }
  95. for i := 0 to 64000-1 do
  96. { lookup tunnel texture }
  97. buffer[i] := texture[tunnel[i] + scroll];
  98. end;
  99. var
  100. format: IPTCFormat;
  101. console: IPTCConsole;
  102. surface: IPTCSurface;
  103. TheTunnel: TTunnel = nil;
  104. time, delta: Single;
  105. buffer: PUint32;
  106. begin
  107. try
  108. try
  109. { create format }
  110. format := TPTCFormatFactory.CreateNew(32, $00FF0000, $0000FF00, $000000FF);
  111. { create console }
  112. console := TPTCConsoleFactory.CreateNew;
  113. { open console }
  114. console.open('Tunnel demo', 320, 200, format);
  115. { create surface }
  116. surface := TPTCSurfaceFactory.CreateNew(320, 200, format);
  117. { create tunnel }
  118. TheTunnel := TTunnel.Create;
  119. { time data }
  120. time := 0;
  121. delta := 0.03;
  122. { loop until a key is pressed }
  123. while not console.KeyPressed do
  124. begin
  125. { lock surface }
  126. buffer := surface.lock;
  127. try
  128. { draw tunnel }
  129. TheTunnel.draw(buffer, time);
  130. finally
  131. { unlock surface }
  132. surface.unlock;
  133. end;
  134. { copy to console }
  135. surface.copy(console);
  136. { update console }
  137. console.update;
  138. { update time }
  139. time := time + delta;
  140. end;
  141. finally
  142. TheTunnel.Free;
  143. if Assigned(console) then
  144. console.close;
  145. end;
  146. except
  147. on error: TPTCError do
  148. { report error }
  149. error.report;
  150. end;
  151. end.