CFireRoutine.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // CFireRoutine.cpp: implementation of the CFireRoutine class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CFireRoutine.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12. CFireRoutine::CFireRoutine()
  13. {
  14. m_iWidth = 0;
  15. m_iHeight = 0;
  16. m_pFireBits = NULL;
  17. m_pYIndexes = NULL;
  18. m_iFireSource = 2;
  19. m_iFireChance = 10;
  20. m_iFlameHeight = 50;
  21. m_iAlpha = 255;
  22. m_FireColors[0] = RGB(0,0,0);// Black
  23. m_FireColors[1] = RGB(255,0,0);// Red
  24. m_FireColors[2] = RGB(255,255,0);// Yellow
  25. m_FireColors[3] = RGB(255,255,255);// White
  26. m_iAvgFlameWidth = 35;
  27. }
  28. CFireRoutine::~CFireRoutine()
  29. {
  30. LOG4C((LOG_NOTICE,"~CFireRoutine"));
  31. // 下面这块内存越界了,所以才会delete错误;
  32. if(m_pYIndexes != NULL)
  33. {
  34. delete []m_pYIndexes;
  35. m_pYIndexes = NULL;
  36. }
  37. if(m_pFireBits != NULL)
  38. {
  39. delete []m_pFireBits;
  40. m_pFireBits = NULL;
  41. }
  42. }
  43. void CFireRoutine::InitFire()
  44. {
  45. // Get Rid of anything already there
  46. if(m_pYIndexes != NULL)
  47. delete []m_pYIndexes;
  48. if(m_pFireBits != NULL)
  49. delete [] m_pFireBits;
  50. // Add three to the height
  51. m_iHeight += 3;
  52. m_pYIndexes = new long[m_iHeight]; // 492字节内存泄漏;
  53. m_pFireBits = new BYTE[m_iWidth*m_iHeight]; // 49446字节内存泄漏;
  54. // Clear the Fire bits
  55. memset(m_pFireBits,0,(m_iWidth*m_iHeight));
  56. // do all the y index pre-calc..
  57. for (int y = m_iHeight - 1; y > 0; y--)
  58. m_pYIndexes[y] = y * m_iWidth;
  59. // Create our pallete
  60. InitPallette();
  61. ClrHotSpots();
  62. }
  63. void CFireRoutine::ClrHotSpots()
  64. {
  65. LOG4C((LOG_NOTICE,"ClrHotSpots"));
  66. // clear the fire line
  67. memset(&m_pFireBits[m_pYIndexes[m_iFireSource]], 0, m_iWidth);
  68. }
  69. void CFireRoutine::InitPallette()
  70. {
  71. // Create a gradient between all the colors we have for our fire..
  72. long iCount = 0;
  73. COLORREF clrStart;
  74. COLORREF clrEnd;
  75. for(int iColor = 1;iColor<4;iColor++)
  76. {
  77. clrStart = m_FireColors[iColor-1];
  78. clrEnd = m_FireColors[iColor];
  79. int r, g, b; // First distance, then starting value
  80. float rStep, gStep, bStep; // Step size for each color
  81. // Get the color differences
  82. r = (GetRValue(clrEnd) - GetRValue(clrStart));
  83. g = (GetGValue(clrEnd) - GetGValue(clrStart));
  84. b = (GetBValue(clrEnd) - GetBValue(clrStart));
  85. int nSteps = max(abs(r), max(abs(g), abs(b)));
  86. float fStep = (float)(255/3)/ (float)nSteps;
  87. // Calculate the step size for each color
  88. rStep = r/(float)nSteps;
  89. gStep = g/(float)nSteps;
  90. bStep = b/(float)nSteps;
  91. // Reset the colors to the starting position
  92. r = GetRValue(clrStart);
  93. g = GetGValue(clrStart);
  94. b = GetBValue(clrStart);
  95. for (int iOnBand = 0; iOnBand < nSteps; iOnBand++)
  96. {
  97. //COLORREF color = RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand);
  98. COLORREF color = RGB(b + bStep *iOnBand, g + gStep*iOnBand,r+rStep*iOnBand);
  99. long lIndex = (int)(iOnBand * fStep);
  100. if(lIndex+((iColor-1)*85) < 255)
  101. m_pPalletteBuffer[lIndex+((iColor-1)*85)] = color;
  102. }
  103. }
  104. // Step on the second color a little bit...
  105. clrStart = m_FireColors[0];
  106. clrEnd = m_FireColors[1];
  107. for(int kj = 0; kj < m_iFlameHeight; kj ++)
  108. m_pPalletteBuffer[kj] = 0;
  109. int r, g, b; // First distance, then starting value
  110. float rStep, gStep, bStep; // Step size for each color
  111. // Get the color differences
  112. r = (GetRValue(clrEnd) - GetRValue(clrStart));
  113. g = (GetGValue(clrEnd) - GetGValue(clrStart));
  114. b = (GetBValue(clrEnd) - GetBValue(clrStart));
  115. int nSteps = max(abs(r), max(abs(g), abs(b)));
  116. float fStep = (float)(85-m_iFlameHeight)/ (float)nSteps;
  117. // Calculate the step size for each color
  118. rStep = r/(float)nSteps;
  119. gStep = g/(float)nSteps;
  120. bStep = b/(float)nSteps;
  121. // Reset the colors to the starting position
  122. r = GetRValue(clrStart);
  123. g = GetGValue(clrStart);
  124. b = GetBValue(clrStart);
  125. for (int iOnBand = 0; iOnBand < nSteps; iOnBand++)
  126. {
  127. //COLORREF color = RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand);
  128. COLORREF color = RGB(b + bStep *iOnBand, g + gStep*iOnBand,r+rStep*iOnBand);
  129. long lIndex = (int)(iOnBand * fStep);
  130. m_pPalletteBuffer[lIndex+(85-m_iFlameHeight)] = color;
  131. }
  132. }
  133. // Macro to get a random integer within a specified range */
  134. #define getrandom( min, max ) (( rand() % (int)((( max ) + 1 ) - ( min ))) + ( min ))
  135. #include <time.h>
  136. void CFireRoutine::SetHotSpots()
  137. {
  138. ClrHotSpots();
  139. //m_iAvgFlameWidth
  140. long lPosition = 0;
  141. while(lPosition < m_iWidth)
  142. {
  143. // see if we should do a flame
  144. if (getrandom(0,100) < m_iFireChance)
  145. {
  146. // get a flame width
  147. long lFlameWidth = getrandom(1,m_iAvgFlameWidth);
  148. for(int i=0;i<lFlameWidth;i++)
  149. {
  150. if(lPosition < m_iWidth)
  151. {
  152. m_pFireBits[m_pYIndexes[m_iFireSource]+lPosition] =254;// set a hot spot!
  153. lPosition++;
  154. }
  155. }
  156. }
  157. lPosition++;
  158. }
  159. // for (x = 0; x < m_iWidth; x++)
  160. // {
  161. // if (getrandom(0,100) < m_iFireChance)
  162. // {
  163. // }
  164. // }
  165. }
  166. void CFireRoutine::MakeLines()
  167. {
  168. int x, y;
  169. for (x = 0; x < m_iWidth; x++)
  170. {
  171. for (y = m_iFireSource; y<m_iHeight-1; y++)
  172. // for (y = m_iHeight; y > m_iFireSource; y--)
  173. {
  174. //m_pFireBits[m_pYIndexes[y-1]+x] =Average(x,y);
  175. m_pFireBits[m_pYIndexes[y+1]+x] =Average(x,y);
  176. }
  177. }
  178. }
  179. unsigned char CFireRoutine::Average(int x, int y)
  180. {
  181. unsigned char ave_color;
  182. unsigned char ave1, ave2, ave3, ave4, ave5, ave6, ave7;
  183. // Make sure we are not at the last line...
  184. if(y == m_iHeight)
  185. ave1 = m_pFireBits[m_pYIndexes[y-1] + x];
  186. else
  187. ave1 = m_pFireBits[m_pYIndexes[y + 1] + x];
  188. ave2 = m_pFireBits[m_pYIndexes[y - 1] + x];
  189. ave3 = m_pFireBits[m_pYIndexes[y] + x + 1];
  190. ave4 = m_pFireBits[m_pYIndexes[y] + x - 1];
  191. ave5 = m_pFireBits[m_pYIndexes[y] + x + 2];
  192. ave6 = m_pFireBits[m_pYIndexes[y] + x - 2];
  193. ave7 = m_pFireBits[m_pYIndexes[y] + x];
  194. ave_color = (ave1 + ave2 + ave3 + ave4 + ave5 + ave6 + ave7) / 7;
  195. return(ave_color);
  196. }
  197. void CFireRoutine::Render(DWORD* pVideoMemory,int iwidth,int iheight)
  198. {
  199. SetHotSpots(); // generate random hotspots
  200. MakeLines(); // do all the math and screen updating
  201. // Right now Im just going to blit it right onto the video memory
  202. unsigned char* pSrcBitlin;// = m_pFireBits+(m_iWidth*3);// get rid of our fire source
  203. BYTE *dst;//=(BYTE*)Dib->pVideoMemory;
  204. BYTE r;
  205. BYTE g;
  206. BYTE b;
  207. for(int i=0;i<m_iHeight-3;i++)
  208. {
  209. dst = (BYTE*)&pVideoMemory[(iwidth*i)];
  210. pSrcBitlin =&m_pFireBits[m_pYIndexes[i+3]];
  211. for(int x=0;x<m_iWidth;x++)
  212. {
  213. r = GetRValue(m_pPalletteBuffer[pSrcBitlin[x]]);
  214. g = GetGValue(m_pPalletteBuffer[pSrcBitlin[x]]);
  215. b = GetBValue(m_pPalletteBuffer[pSrcBitlin[x]]);
  216. dst[0]=(BYTE)(((r-dst[0])*m_iAlpha+(dst[0]<<8))>>8);
  217. dst[1]=(BYTE)(((g-dst[1])*m_iAlpha+(dst[1]<<8))>>8);
  218. dst[2]=(BYTE)(((b-dst[2])*m_iAlpha+(dst[2]<<8))>>8);
  219. dst+=4;
  220. }
  221. }
  222. }