lights.pp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. {
  2. Ported to FPC by Nikolay Nikolov ([email protected])
  3. }
  4. {
  5. Lights demo for OpenPTC 1.0 C++ API
  6. Copyright (c) Glenn Fiedler ([email protected])
  7. This source code is licensed under the GNU GPL
  8. }
  9. Program Lights;
  10. {$MODE objfpc}
  11. Uses
  12. ptc;
  13. Var
  14. { distance lookup table }
  15. distance_table : Array[0..299, 0..511] Of DWord; { note: 16.16 fixed }
  16. { intensity calculation }
  17. Function CalcIntensity(dx, dy : Integer; i : DWord) : DWord;{ Inline;}
  18. Begin
  19. { lookup intensity at [dx,dy] }
  20. CalcIntensity := i * distance_table[dy, dx];
  21. End;
  22. Var
  23. console : TPTCConsole;
  24. surface : TPTCSurface;
  25. format : TPTCFormat;
  26. palette : TPTCPalette;
  27. dx, dy : Integer;
  28. divisor : Single;
  29. data : PUint32;
  30. pixels, line : PUint8;
  31. width : Integer;
  32. i : Integer;
  33. x, y, x1, y1, x2, y2, x3, y3, x4, y4 : Integer;
  34. cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4 : Single;
  35. dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4 : Single;
  36. _dx1, _dx2, _dx3, _dx4 : Integer;
  37. _dy1, _dy2, _dy3, _dy4 : Integer;
  38. ix1, ix2, ix3, ix4 : Integer;
  39. i1, i2, i3, i4 : DWord;
  40. length : Integer;
  41. move_t, move_dt, move_ddt : Single;
  42. flash_t, flash_dt, flash_ddt : Single;
  43. intensity : DWord;
  44. max_intensity, max_intensity_inc : Single;
  45. Begin
  46. console := Nil;
  47. format := Nil;
  48. surface := Nil;
  49. palette := Nil;
  50. Try
  51. Try
  52. { create console }
  53. console := TPTCConsole.Create;
  54. format := TPTCFormat.Create(8);
  55. { open console }
  56. console.open('Lights demo', 320, 200, format);
  57. { create surface }
  58. surface := TPTCSurface.Create(320, 200, format);
  59. { setup intensity table }
  60. For dy := 0 To 199 Do
  61. For dx := 0 To 511 Do
  62. Begin
  63. divisor := sqrt((dx * dx) + (dy * dy));
  64. If divisor < 0.3 Then
  65. divisor := 0.3;
  66. distance_table[dy, dx] := Trunc(65535 / divisor);
  67. End;
  68. { create palette }
  69. palette := TPTCPalette.Create;
  70. { generate greyscale palette }
  71. data := palette.lock;
  72. Try
  73. For i := 0 To 255 Do
  74. data[i] := (i Shl 16) Or (i Shl 8) Or i;
  75. Finally
  76. palette.unlock;
  77. End;
  78. { set console palette }
  79. console.palette(palette);
  80. { set surface palette }
  81. surface.palette(palette);
  82. { data }
  83. cx1 := 60;
  84. cy1 := 110;
  85. cx2 := 100;
  86. cy2 := 80;
  87. cx3 := 250;
  88. cy3 := 110;
  89. cx4 := 200;
  90. cy4 := 90;
  91. dx1 := 0;
  92. dy1 := 0;
  93. dx2 := 0;
  94. dy2 := 0;
  95. dx3 := 0;
  96. dy3 := 0;
  97. dx4 := 0;
  98. dy4 := 0;
  99. i1 := 0;
  100. i2 := 0;
  101. i3 := 0;
  102. i4 := 0;
  103. { time data }
  104. move_t := 0.3;
  105. move_dt := 0.1;
  106. move_ddt := 0.0006;
  107. flash_t := 0.1;
  108. flash_dt := 0.0;
  109. flash_ddt := 0.0004;
  110. { control data }
  111. max_intensity := 30;
  112. max_intensity_inc := 0.2;
  113. { main loop }
  114. While Not console.KeyPressed Do
  115. Begin
  116. { source positions }
  117. x1 := Trunc(cx1 + dx1);
  118. y1 := Trunc(cy1 + dy1);
  119. x2 := Trunc(cx2 + dx2);
  120. y2 := Trunc(cy2 + dy2);
  121. x3 := Trunc(cx3 + dx3);
  122. y3 := Trunc(cy3 + dy3);
  123. x4 := Trunc(cx4 + dx4);
  124. y4 := Trunc(cy4 + dy4);
  125. { lock surface }
  126. pixels := surface.lock;
  127. Try
  128. { get surface dimensions }
  129. width := surface.width;
  130. { line loop }
  131. For y := 0 To 199 Do
  132. Begin
  133. { calcalate pointer to start of line }
  134. line := pixels + y * width;
  135. { get y deltas }
  136. _dy1 := abs(y - y1);
  137. _dy2 := abs(y - y2);
  138. _dy3 := abs(y - y3);
  139. _dy4 := abs(y - y4);
  140. { setup x }
  141. x := 0;
  142. { line loop }
  143. While x < width Do
  144. Begin
  145. { get x deltas }
  146. _dx1 := abs(x1 - x);
  147. _dx2 := abs(x2 - x);
  148. _dx3 := abs(x3 - x);
  149. _dx4 := abs(x4 - x);
  150. { get increments }
  151. ix1 := 1;
  152. ix2 := 1;
  153. ix3 := 1;
  154. ix4 := 1;
  155. If x1 > x Then
  156. ix1 := -1;
  157. If x2 > x Then
  158. ix2 := -1;
  159. If x3 > x Then
  160. ix3 := -1;
  161. If x4 > x Then
  162. ix4 := -1;
  163. { set span length to min delta }
  164. length := width - x;
  165. If (x1 > x) And (_dx1 < length) Then
  166. length := _dx1;
  167. If (x2 > x) And (_dx2 < length) Then
  168. length := _dx2;
  169. If (x3 > x) And (_dx3 < length) Then
  170. length := _dx3;
  171. If (x4 > x) And (_dx4 < length) Then
  172. length := _dx4;
  173. { pixel loop }
  174. While length > 0 Do
  175. Begin
  176. Dec(length);
  177. { calc intensities }
  178. intensity := CalcIntensity(_dx1, _dy1, i1);
  179. Inc(intensity, CalcIntensity(_dx2, _dy2, i2));
  180. Inc(intensity, CalcIntensity(_dx3, _dy3, i3));
  181. Inc(intensity, CalcIntensity(_dx4, _dy4, i4));
  182. intensity := intensity Shr 16;
  183. If intensity > 255 Then
  184. intensity := 255;
  185. { update deltas }
  186. Inc(_dx1, ix1);
  187. Inc(_dx2, ix2);
  188. Inc(_dx3, ix3);
  189. Inc(_dx4, ix4);
  190. { store the pixel }
  191. line[x] := intensity;
  192. Inc(x);
  193. End;
  194. End;
  195. End;
  196. Finally
  197. { unlock surface }
  198. surface.unlock;
  199. End;
  200. { move the lights around }
  201. dx1 := 50 * sin((move_t + 0.0) * 0.10);
  202. dy1 := 80 * sin((move_t + 0.6) * 0.14);
  203. dx2 := 100 * sin((move_t + 0.1) * 0.10);
  204. dy2 := 30 * sin((move_t - 0.4) * 0.30);
  205. dx3 := 39 * sin((move_t + 9.9) * 0.20);
  206. dy3 := 50 * sin((move_t + 0.4) * 0.30);
  207. dx4 := 70 * sin((move_t - 0.3) * 0.25);
  208. dy4 := 40 * sin((move_t - 0.1) * 0.31);
  209. { flash intensity }
  210. i1 := Trunc(max_intensity * (sin((flash_t + 0.000) * 1.000) + 1));
  211. i2 := Trunc(max_intensity * (sin((flash_t + 2.199) * 0.781) + 1));
  212. i3 := Trunc(max_intensity * (sin((flash_t - 1.450) * 1.123) + 1));
  213. i4 := Trunc(max_intensity * (sin((flash_t + 0.000) * 0.500) + 1));
  214. { update time }
  215. move_t := move_t + move_dt;
  216. move_dt := move_dt + move_ddt;
  217. flash_t := flash_t + flash_dt;
  218. flash_dt := flash_dt + flash_ddt;
  219. { reset on big flash... }
  220. If (move_t > 600) And (i1 > 10000) And (i2 > 10000) And
  221. (i3 > 10000) And (i4 > 10000) Then
  222. Begin
  223. move_t := 0.3;
  224. move_dt := 0.1;
  225. move_ddt := 0.0006;
  226. flash_t := 0.1;
  227. flash_dt := 0.0;
  228. flash_ddt := 0.0004;
  229. max_intensity := 0.0;
  230. max_intensity_inc := 0.2;
  231. End;
  232. { update intensity }
  233. max_intensity := max_intensity + max_intensity_inc;
  234. max_intensity_inc := max_intensity_inc + 0.008;
  235. { copy surface to console }
  236. surface.copy(console);
  237. { update console }
  238. console.update;
  239. End;
  240. Finally
  241. console.close;
  242. surface.Free;
  243. console.Free;
  244. palette.Free;
  245. format.Free;
  246. End;
  247. Except
  248. On error : TPTCError Do
  249. { report error }
  250. error.report;
  251. End;
  252. End.