fire.pp 5.5 KB

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