⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfire.cpp

📁 这是书上的代码
💻 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 + -