📄 cfire.cpp
字号:
#include <math.h>
#include "gif89a.h"
#include "cfire.h"
extern WORD (*RGBto16bit)(unsigned char r,unsigned char g,unsigned char b);
CFire::CFire(int w,int h)
{ error = FALSE;
seedMap = NULL;
coolMap = NULL;
lightMap = NULL;
lightBuf1 = NULL;
lightBuf2 = NULL;
imgWidth = 0;
imgHeight = 0;
if(w < seedMapWidth || h < seedMapHeight)
{ error = TRUE;
return;
}
if((lightBuf1 = new unsigned char[w*h]) == NULL)
{ error = TRUE;
return;
}
if((lightBuf2 = new unsigned char[w*h]) == NULL)
{ error = TRUE;
delete[] lightBuf1;
return;
}
memset(lightBuf1,0,w*h);
memset(lightBuf2,0,w*h);
imgWidth = w,imgHeight = h;
}
CFire::~CFire()
{ clear();
}
BOOL CFire::operator!()
{ return error;
}
void CFire::clear()
{ if(seedMap != NULL)
delete[] seedMap;
if(coolMap != NULL)
delete[] coolMap;
if(lightMap != NULL)
delete[] lightMap;
if(lightBuf1 != NULL)
delete[] lightBuf1;
if(lightBuf2 != NULL)
delete[] lightBuf2;
}
BOOL CFire::loadSeedMap(LPCSTR fileName)
{ LPCFRAME f;
LPCGLOBAL_INFO g;
BYTE* b;
CGif89a gif(fileName,TRUE);
if(!gif)
return FALSE;
g = gif.getGlobalInfo();
f = gif.getNextFrame();
if(f == NULL || f->imageWidth != seedMapWidth || f->imageHeight != seedMapHeight)
return FALSE;
seedMap = new unsigned char[seedMapWidth*seedMapHeight];
if(seedMap == NULL)
return FALSE;
b = f->dataBuf;
for(UINT i=0;i<seedMapWidth*seedMapHeight;i++)
seedMap[i] = g->gColorTable[b[i]*3];
return TRUE;
}
BOOL CFire::loadCoolMap(LPCSTR fileName)
{ LPCFRAME f;
LPCGLOBAL_INFO g;
BYTE* b;
CGif89a gif(fileName,TRUE);
if(!gif)
return FALSE;
g = gif.getGlobalInfo();
f = gif.getNextFrame();
if(f == NULL || f->imageWidth != coolMapWidth || f->imageHeight != coolMapHeight)
return FALSE;
coolMap = new unsigned char[coolMapWidth*coolMapHeight];
if(coolMap == NULL)
return FALSE;
b = f->dataBuf;
for(UINT i=0;i<coolMapWidth*coolMapHeight;i++)
coolMap[i] = g->gColorTable[b[i]*3]>>4;
return TRUE;
}
BOOL CFire::loadLightMap(LPCSTR fileName)
{ LPCFRAME f;
LPCGLOBAL_INFO g;
BYTE* b;
WORD rr,gg,bb;
CGif89a gif(fileName,TRUE);
if(!gif)
return FALSE;
g = gif.getGlobalInfo();
f = gif.getNextFrame();
if(f == NULL || f->imageWidth != lightLevel || f->imageHeight != 1)
return FALSE;
lightMap = new WORD[lightLevel];
if(lightMap == NULL)
return FALSE;
b = f->dataBuf;
for(UINT i=0;i<lightLevel;i++)
{ rr = g->gColorTable[b[i]*3];
gg = g->gColorTable[b[i]*3+1];
bb = g->gColorTable[b[i]*3+2];
lightMap[i] = (*RGBto16bit)((BYTE)rr,(BYTE)gg,(BYTE)bb);
}
return TRUE;
}
void CFire::generateSeed()
{ unsigned char *p,*p1,*ps;
int topX,topY,j,k;
int t = RAND_MAX/5;
topX = (imgWidth - seedMapWidth)/2;
topY = (imgHeight - seedMapHeight)/2;
p = lightBuf1 + (topY+2)*imgWidth + topX;
ps = seedMap + seedMapWidth*2;
for(j=0;j<(seedMapHeight-4);j++)
{ p1 = p;
for(k=0;k<seedMapWidth;k++)
{ if(*ps != 0)
{ if(rand() < t)
*p1 = 255;
}
p1++,ps++;
}
p += imgWidth;
}
}
void CFire::cooling()
{ int i;
unsigned char *p,*pp,*p1,*p2,*p3,*p4,*p5;
p = lightBuf2+imgWidth*2;
pp = coolMap + coolMapWidth*2;
p1 = lightBuf1+imgWidth*2;
p2 = p1 - imgWidth;
p3 = p1 - 1;
p4 = p1 + 1;
p5 = p1 + imgWidth;
unsigned char c1,c2;
for(i=0;i<imgWidth*(imgHeight-4);i++)
{
c1 = (unsigned char)(((UINT)*p1+(UINT)*p2+(UINT)*p3+(UINT)*p4+(UINT)*p5)/5);
c2 = *pp;
if(c1>c2)
c1 -= c2;
*p = c1;
pp++,p++,p1++,p2++,p3++,p4++,p5++;
}
}
void CFire::render(WORD *p)
{ int i;
unsigned char *ps;
WORD *pd;
pd = p;
ps = lightBuf2;
//火焰上滚
memcpy(lightBuf1,lightBuf1+imgWidth*3,imgWidth*(imgHeight-3));
generateSeed();
cooling();
for(i=0;i<imgWidth*imgHeight;i++)
{
*pd++ = lightMap[*ps++];
}
ps = lightBuf1;
lightBuf1 = lightBuf2;
lightBuf2 = ps;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -