fire.pp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. {
  2. Ported to FPC by Nikolay Nikolov ([email protected])
  3. }
  4. {
  5. Fire 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 Fire;
  10. {$MODE objfpc}
  11. Uses
  12. ptc;
  13. Function pack(r, g, b : Uint32) : Uint32;
  14. Begin
  15. { pack color integer }
  16. pack := (r Shl 16) Or (g Shl 8) Or b;
  17. End;
  18. Procedure generate(palette : TPTCPalette);
  19. Var
  20. data : PUint32;
  21. i, c : Integer;
  22. Begin
  23. { lock palette data }
  24. data := palette.lock;
  25. Try
  26. { black to red }
  27. i := 0;
  28. c := 0;
  29. While i < 64 Do
  30. Begin
  31. data[i] := pack(c, 0, 0);
  32. Inc(c, 4);
  33. Inc(i);
  34. End;
  35. { red to yellow }
  36. c := 0;
  37. While i < 128 Do
  38. Begin
  39. data[i] := pack(255, c, 0);
  40. Inc(c, 4);
  41. Inc(i);
  42. End;
  43. { yellow to white }
  44. c := 0;
  45. While i < {192}128 Do
  46. Begin
  47. data[i] := pack(255, 255, c);
  48. Inc(c, 4);
  49. Inc(i);
  50. End;
  51. { white }
  52. While i < 256 Do
  53. Begin
  54. data[i] := pack(255, 255, 255);
  55. Inc(i);
  56. End;
  57. Finally
  58. { unlock palette }
  59. palette.unlock;
  60. End;
  61. End;
  62. Var
  63. format : TPTCFormat;
  64. console : TPTCConsole;
  65. surface : TPTCSurface;
  66. palette : TPTCPalette;
  67. state : Integer;
  68. intensity : Single;
  69. pixels, pixel, p : PUint8;
  70. width, height : Integer;
  71. x, y : Integer;
  72. top, bottom, c1, c2 : Uint32;
  73. generator : PUint8;
  74. color : Integer;
  75. area : TPTCArea;
  76. Begin
  77. format := Nil;
  78. console := Nil;
  79. surface := Nil;
  80. palette := Nil;
  81. area := Nil;
  82. Try
  83. Try
  84. { create format }
  85. format := TPTCFormat.Create(8);
  86. { create console }
  87. console := TPTCConsole.Create;
  88. { open console }
  89. console.open('Fire demo', 320, 200, format);
  90. { create surface }
  91. surface := TPTCSurface.Create(320, 208, format);
  92. { create palette }
  93. palette := TPTCPalette.Create;
  94. { generate palette }
  95. generate(palette);
  96. { set console palette }
  97. console.palette(palette);
  98. { set surface palette }
  99. surface.palette(palette);
  100. { flame data }
  101. state := 0;
  102. intensity := 0;
  103. { setup copy area }
  104. area := TPTCArea.Create(0, 0, 320, 200);
  105. { main loop }
  106. Repeat
  107. { lower flame on keypress }
  108. If console.KeyPressed Then
  109. state := 2;
  110. { state machine }
  111. Case state Of
  112. 0 : Begin
  113. { raise flame }
  114. intensity += 0.007;
  115. { maximum flame height }
  116. If intensity > 0.8 Then
  117. state := 1;
  118. End;
  119. 1 : Begin
  120. { constant flame }
  121. End;
  122. 2 : Begin
  123. { lower flame }
  124. intensity := intensity - 0.005;
  125. { exit program when flame is out }
  126. If intensity < 0.01 Then
  127. Begin
  128. console.close;
  129. Exit;
  130. End;
  131. End;
  132. End;
  133. { lock surface pixels }
  134. pixels := surface.lock;
  135. Try
  136. { get surface dimensions }
  137. width := surface.width;
  138. height := surface.height;
  139. { flame vertical loop }
  140. y := 1;
  141. While y < height - 4 Do
  142. Begin
  143. { current pixel pointer }
  144. pixel := pixels + y * width;
  145. { flame horizontal loop }
  146. For x := 0 To width - 1 Do
  147. Begin
  148. { sum top pixels }
  149. p := pixel + (width Shl 1);
  150. top := p^;
  151. Inc(top, (p - 1)^);
  152. Inc(top, (p + 1)^);
  153. { bottom pixel }
  154. bottom := (pixel + (width Shl 2))^;
  155. { combine pixels }
  156. c1 := (top + bottom) Shr 2;
  157. If c1 > 1 Then
  158. Dec(c1);
  159. { interpolate }
  160. c2 := (c1 + bottom) Shr 1;
  161. { store pixels }
  162. pixel^ := c1;
  163. (pixel + width)^ := c2;
  164. { next pixel }
  165. Inc(pixel);
  166. End;
  167. Inc(y, 2);
  168. End;
  169. { setup flame generator pointer }
  170. generator := pixels + width * (height - 4);
  171. { update flame generator bar }
  172. x := 0;
  173. While x < width Do
  174. Begin
  175. { random block color taking intensity into account }
  176. color := random(Integer(Trunc(255 * intensity)));
  177. { write 4x4 color blocks }
  178. (generator + 0)^ := color;
  179. (generator + 1)^ := color;
  180. (generator + 2)^ := color;
  181. (generator + 3)^ := color;
  182. (generator + width + 0)^ := color;
  183. (generator + width + 1)^ := color;
  184. (generator + width + 2)^ := color;
  185. (generator + width + 3)^ := color;
  186. (generator + width * 2 + 0)^ := color;
  187. (generator + width * 2 + 1)^ := color;
  188. (generator + width * 2 + 2)^ := color;
  189. (generator + width * 2 + 3)^ := color;
  190. (generator + width * 3 + 0)^ := color;
  191. (generator + width * 3 + 1)^ := color;
  192. (generator + width * 3 + 2)^ := color;
  193. (generator + width * 3 + 3)^ := color;
  194. { next block }
  195. Inc(generator, 4);
  196. Inc(x, 4);
  197. End;
  198. Finally
  199. { unlock surface }
  200. surface.unlock;
  201. End;
  202. { copy surface to console }
  203. surface.copy(console, area, area);
  204. { update console }
  205. console.update;
  206. Until False;
  207. Finally
  208. console.Free;
  209. surface.Free;
  210. format.Free;
  211. palette.Free;
  212. area.Free;
  213. End;
  214. Except
  215. On error : TPTCError Do
  216. { report error }
  217. error.report;
  218. End;
  219. End.