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

📄 imagex.cpp

📁 冰人引擎,本2d游戏引擎定位于游戏次中层引擎。他不像CDX等引擎那样
💻 CPP
字号:
#include "StdAfx.h"
#include "imagex.h"

CImageX::CImageX(void)
{
	m_pImageBuffer = NULL;
	m_pAlphaBuffer = NULL;
	m_dwCurrentFrame = 1;
}

CImageX::~CImageX(void)
{
	Free();
}

CImageX::CImageX(char* file)
{
	m_pImageBuffer = NULL;
	m_pAlphaBuffer = NULL;
	m_dwCurrentFrame = 1;

	LoadImage(file);
}

bool CImageX::LoadImage(char* file)
{
	stImageHeader ImageHeader;

	FILE *fp;
	fp = fopen(file,"rb");
	assert(fp != NULL);
	if(fp == NULL)
	{
		DebugMsg("Read Image file Error\n");
		return false;
	}

	//读文件头
	fread( (void*)&ImageHeader, sizeof(stImageHeader), 1, fp );
	
	m_dwType = ImageHeader.dwType;
	
	m_dwWidth = ImageHeader.dwWidth;
	m_dwHeight = ImageHeader.dwHeight;
	
	m_dwImagePitch = ImageHeader.dwPitch;

	m_dwColorKey = ImageHeader.dwColorKey;

	m_dwMaxFrame = ImageHeader.dwMaxFrame;
	m_dwFrameWidth = ImageHeader.dwFrameWidth;
	m_dwFrameHeight = ImageHeader.dwFrameHeight;

	//创建图片缓冲,因为是32bit的,按unsigned long读
	m_pImageBuffer = new DWORD[m_dwWidth*m_dwHeight];

	//读入图片数据到图片缓冲
	fread(m_pImageBuffer,sizeof(DWORD),m_dwWidth*m_dwHeight,fp);

	if(m_dwType == CUSTOM_IMAGE_ALPHA)
	{
        //创建图片Alpha缓冲(8bit)
		m_pAlphaBuffer = new BYTE[m_dwWidth*m_dwHeight];
		
		DWORD Offset = 0;
		for( DWORD i = 0; i < m_dwHeight; i ++ )
		{
			NesDrawLineAlphaMask(m_pAlphaBuffer,Offset,m_pImageBuffer,Offset,m_dwWidth);
			Offset += m_dwImagePitch;
		}
	}

	fclose(fp);

	//设置缺省源矩形,等于每帧的大小
	m_SrcRect.dwX = 0;
	m_SrcRect.dwY = 0;
	m_SrcRect.dwWidth = m_dwFrameWidth;
	m_SrcRect.dwHeight = m_dwFrameHeight;
	return true;
}

void CImageX::Free(void)
{
	if(m_pImageBuffer != NULL)
		delete []m_pImageBuffer;
	if(m_pAlphaBuffer != NULL)
		delete []m_pAlphaBuffer;
}

void CImageX::SetRect(RECT* rect)
{
	assert(m_dwMaxFrame  == 1);
	m_SrcRect.dwX = rect->left;						//设置矩形顶点坐标
	m_SrcRect.dwY = rect->top;
	//设置矩形边长
	if(m_dwFrameWidth - (rect->right - rect->left) >= 0)		//判断是否非法
	{
		m_SrcRect.dwWidth = rect->right - rect->left;
	}
	if(m_dwFrameHeight - (rect->bottom - rect->top) >= 0)
	{
		m_SrcRect.dwHeight = rect->bottom - rect->top;
	}
}

void CImageX::Draw(long x, long y,bool isTrans)
{
	//因为memcpy的参数是void*,所以不会自动判定size的单位大小,必须在size上标明单位才行
	//花了半个小时查错,才突然想到的,悲惨。
	//进行裁减判断
	m_ClipperRect.dwX = m_SrcRect.dwX;
	m_ClipperRect.dwY = m_SrcRect.dwY;
	m_ClipperRect.dwWidth = m_SrcRect.dwWidth;
	m_ClipperRect.dwHeight = m_SrcRect.dwHeight;

	if(x < 0)
	{
		m_ClipperRect.dwX = m_SrcRect.dwX - x;
		m_ClipperRect.dwWidth = m_SrcRect.dwWidth + x;
		x = 0;
	}

	if(y < 0)
	{
		m_ClipperRect.dwY = m_SrcRect.dwY - y;
		m_ClipperRect.dwHeight = m_SrcRect.dwHeight + y;
		y = 0;
	}

	if(CDisplay::Instance()->GetScreenWidth() - x < m_SrcRect.dwWidth)		//宽溢出
		m_ClipperRect.dwWidth = CDisplay::Instance()->GetScreenWidth() - x;

	if(CDisplay::Instance()->GetScreenHeight() - y < m_SrcRect.dwHeight)	//高溢出
		m_ClipperRect.dwHeight = CDisplay::Instance()->GetScreenHeight() - y;

	LPDWORD dest;
	LPDWORD src;
	dest = CDisplay::Instance()->GetEngineBuffer();
	src = m_pImageBuffer;

	DWORD DestOff,SrcOff;
	DestOff = y * CDisplay::Instance()->GetEngineBufferPitch() + x * sizeof(DWORD);
	SrcOff  = m_ClipperRect.dwY * m_dwImagePitch + m_ClipperRect.dwX * sizeof(DWORD);

	if(isTrans)
	{
		for(DWORD i = 0;i < m_ClipperRect.dwHeight;i ++)
		{
			NesDrawLineNormalColorKey(dest,DestOff,src,SrcOff,m_ClipperRect.dwWidth,m_dwColorKey);
			DestOff += CDisplay::Instance()->GetEngineBufferPitch();
			SrcOff += m_dwImagePitch;
		}
	}
	else
	{
		for(DWORD i = 0;i < m_ClipperRect.dwHeight;i ++)
		{
			NesDrawLineNormal(dest,DestOff,src,SrcOff,m_ClipperRect.dwWidth);
			DestOff += CDisplay::Instance()->GetEngineBufferPitch();
			SrcOff += m_dwImagePitch;
		}
	}
}

void CImageX::DrawAlpha(long x, long y, bool isTrans,DWORD dwType,DWORD dwValue)
{
	//进行裁减判断
	m_ClipperRect.dwX = m_SrcRect.dwX;
	m_ClipperRect.dwY = m_SrcRect.dwY;
	m_ClipperRect.dwWidth = m_SrcRect.dwWidth;
	m_ClipperRect.dwHeight = m_SrcRect.dwHeight;

	if(x < 0)
	{
		m_ClipperRect.dwX = m_SrcRect.dwX - x;
		m_ClipperRect.dwWidth = m_SrcRect.dwWidth + x;
		x = 0;
	}

	if(y < 0)
	{
		m_ClipperRect.dwY = m_SrcRect.dwY - y;
		m_ClipperRect.dwHeight = m_SrcRect.dwHeight + y;
		y = 0;
	}

	if(CDisplay::Instance()->GetScreenWidth() - x < m_SrcRect.dwWidth)		//宽溢出
		m_ClipperRect.dwWidth = CDisplay::Instance()->GetScreenWidth() - x;

	if(CDisplay::Instance()->GetScreenHeight() - y < m_SrcRect.dwHeight)	//高溢出
		m_ClipperRect.dwHeight = CDisplay::Instance()->GetScreenHeight() - y;

	LPDWORD dest;
	LPDWORD src;
	dest = CDisplay::Instance()->GetEngineBuffer();
	src = m_pImageBuffer;

	DWORD DestOff,SrcOff;
	DestOff = y * CDisplay::Instance()->GetEngineBufferPitch() + x * sizeof(DWORD);
	SrcOff  = m_ClipperRect.dwY * m_dwImagePitch + m_ClipperRect.dwX * sizeof(DWORD);

	DWORD i;

	if(isTrans)		//带透明色
	{
		switch(dwType)		//Alpha类型
		{
			case DRAW_ALPHA_SPEED:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaSpeedColorKey(dest,DestOff,src,SrcOff,m_ClipperRect.dwWidth,m_dwColorKey);
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
			break;
			case DRAW_ALPHA_QUALITY:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaQualityColorKey(dest,DestOff,src,SrcOff,m_ClipperRect.dwWidth,dwValue,m_dwColorKey);
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
			break;
			case DRAW_ALPHA_ADD:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaAddColorKey( dest , DestOff , src , SrcOff ,m_ClipperRect.dwWidth , m_dwColorKey);
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
			break;
		}
	}
	else
	{
		switch( dwType )
		{
			case DRAW_ALPHA_SPEED:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaSpeed( dest, DestOff , src , SrcOff , m_ClipperRect.dwWidth );
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
				break;
			case DRAW_ALPHA_QUALITY:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaQuality( dest , DestOff , src , SrcOff , m_ClipperRect.dwWidth , dwValue );
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
				break;
			case DRAW_ALPHA_ADD:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaAdd( dest , DestOff , src , SrcOff ,m_ClipperRect.dwWidth );
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
				break;
			case DRAW_ALPHA_CHANNELS:
				for( i = 0; i < m_ClipperRect.dwHeight; i ++ )
				{
					NesDrawLineAlphaChannels( dest , DestOff , src , SrcOff , m_pAlphaBuffer , m_ClipperRect.dwWidth);
					DestOff	+= CDisplay::Instance()->GetEngineBufferPitch();
					SrcOff	+= m_dwImagePitch;
				}
				break;
		}
	}
}

void CImageX::SetPixel(DWORD x, DWORD y, DWORD pixel)
{
	//这是我第一个inline asm。终于,代表我,可以使用asm了!!2003-4-20
	DWORD* pBuffer = m_pImageBuffer;
	DWORD dwPitch = m_dwImagePitch;

	_asm
	{
		mov esi,pBuffer;			//储存缓冲指针

		mov eax,y;
		mov ebx,dwPitch;
		mul ebx;					//计算y的偏移量
		mov ebx,eax;				//储存到ebx

		mov eax,x;
		mov cx,4;
		mul cx;						//计算x的偏移量
        
		add eax,ebx;				//计算最终的偏移量
		
		mov ebx,pixel;				//储存像素数据

		
		add esi,eax;				//更改指针

		mov [esi],ebx;				//写
	}
}

DWORD CImageX::GetPixel(DWORD x, DWORD y)
{
	DWORD* pBuffer = m_pImageBuffer;
	DWORD dwPitch = m_dwImagePitch;
	DWORD dwPixel = 0;

	_asm
	{
		mov esi,pBuffer;

		mov eax,y;
		mov ebx,dwPitch;
		mul ebx;					//计算y的偏移量
		mov ebx,eax;				//储存到ebx

		mov eax,x;
		mov cx,4;
		mul cx;						//计算x的偏移量
        
		add eax,ebx;				//计算最终的偏移量

		add esi,eax;				//更改指针

		mov eax,[esi];
		mov dwPixel,eax;
	}

	return dwPixel;
}

void CImageX::SetCurrentFrame(DWORD frame)
{
	assert(frame <= m_dwMaxFrame);
	assert(frame != 0);
	m_SrcRect.dwX = m_SrcRect.dwWidth*(frame - 1);
	m_SrcRect.dwY = 0;
	m_dwCurrentFrame = frame;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -