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

📄 imagelist.cpp

📁 diablo图形引擎例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ImageList.cpp: implementation of the ImageList class.
//
//////////////////////////////////////////////////////////////////////

#include "assert.h"
#include "stdio.h"
#include "DirectDraw.h"
#include "ImageList.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ImageList::ImageList()
{
	m_iTotalFrame=-1;
	m_lpDataBuffer=NULL;
	m_lpOffsetTable=NULL;
}

ImageList::~ImageList()
{
	if (m_lpDataBuffer!=NULL) delete m_lpDataBuffer;
	if (m_lpOffsetTable!=NULL) delete m_lpOffsetTable;

}

bool ImageList::Create(char *lpszFilename, bool bColorMode,int light)
{
	
	FILE *fp=fopen(lpszFilename,"rb");
	if ( fp == NULL ) return false;

	fseek(fp,0,SEEK_END);
	int size=ftell(fp)-sizeof(CGL_FILE_HEADER);
	//
	CGL_FILE_HEADER cglhdr;
	fseek(fp,0,SEEK_SET);
	fread(&cglhdr,sizeof(CGL_FILE_HEADER),1,fp);
	//
	m_lpOffsetTable= new DWORD [cglhdr.dwTotalFiles];
	fseek(fp,cglhdr.dwInfoTableOffset,SEEK_SET);
	fread(m_lpOffsetTable,cglhdr.dwTotalFiles,sizeof(DWORD),fp);

	m_lpDataBuffer = new WORD [size/2];
	assert(m_lpDataBuffer);
	
	fseek(fp,cglhdr.dwDataOffset,SEEK_SET);
	fread(m_lpDataBuffer,size,1,fp);
	
	m_iTotalFrame=cglhdr.dwTotalFiles;
	fclose(fp);

	SetLight(light);

	if(!bColorMode)
	{
		ConvertColorMode();
		m_dwAlphaMask_SHR1=MASK_MODE_565_SHR1;
		m_dwAlphaMask_SHR2=MASK_MODE_565_SHR2;
		m_dwAlphaMask_SHR3=MASK_MODE_565_SHR3;
	}
	else
	{
		m_dwAlphaMask_SHR1=MASK_MODE_555_SHR1;
		m_dwAlphaMask_SHR2=MASK_MODE_555_SHR2;
		m_dwAlphaMask_SHR3=MASK_MODE_555_SHR3;
	}
	return true;
}


void ImageList::ConvertColorMode()
{
	int index;
	for(index=0;index<m_iTotalFrame;index++)
	{
		
		int  ofs=m_lpOffsetTable[index]/2;
		WORD *s = m_lpDataBuffer+ofs;
		WORD Width  = *s++;
		WORD Height = *s++;
		while( 1 )
		{
			WORD c = *s++, count = c & BitDataMask;
			if( c == BitEndOfImageMask )	// 图像结束
				break;			
			else
			if( c & BitWhiteLineMask )		// 空白行
			{
				//??
			} 
			else	
		    if(c & BitPixelMask)		// 像素点
			{
				
				for( int i=0; i<count; i++ ) 
				{
					WORD color=*s;//chang color
					WORD r,g,b;
					b=color & 0x1f;
					g=( color >> 5 ) & 0x1f;
					r=( color >>10 ) & 0x1f;
					g=g<<1;
					color= b | (g << 5) | (r << 11);
					*s=color;
					*s++;
				}


				
				//{
				 //*d++ = *s++;						
				//}
			}
		else
		if(c & BitTransparentMask) // 透明点
		{
						//d += count;
		}
		else
		if( c == BitEndOfLineMask )		// 行结束
		{
			//d //+= Gap;
			//d+=(SCREEN_WIDTH-Width);				
		}
		}
 
	} 
}




void ImageList::Draw(int index, int x, int y, WORD *lpBitmap, long lPitch)
{

	int  ofs=m_lpOffsetTable[index]/2;
	WORD *s = m_lpDataBuffer+ofs;
		

	WORD Width  = *s++;
	WORD Height = *s++;
	// 如果图像不在可见范围内,就不画了
	if( (x + Width ) < 0 || x >= DisplayMode_Width || (y + Height) < 0 || y >= DisplayMode_Height) return;
	// 如果图像完全在可见范围内,就直接调用PutImage
	if( x >= 0 && (x + Width) < DisplayMode_Width && y >= 0 && (y + Height) < DisplayMode_Height )
	{
		WORD *d = lpBitmap + y * lPitch + x;
		while( 1 )
		{ 
			WORD c = *s++, count = c & BitDataMask;
			if( c == BitEndOfImageMask )	// 图像结束
			break;			
			else
			if( c & BitWhiteLineMask )		// 空白行
			{ 
				d += lPitch * count;
			} 
			else
			if(c & BitPixelMask)		// 像素点
			{ 
				for( int i=0; i<count; i++ ) 
				{ 
					*d++ = *s++;						
				} 
			} 
			else 
			if(c & BitTransparentMask) // 透明点
			{ 
			 	d += count;
			} 
			else
			if( c == BitEndOfLineMask )		// 行结束
				{
					d+=(lPitch-Width);				
			}  
		}  
		return;
	}
	// 图像只有部分可见,要考虑各个边界相交的情况
	int ix=x, iy=y;	// 当前处理的行列坐标
	// 屏幕范围以上不可见部分
	while( iy < 0 )
	{
		WORD c = *s++, count = c & BitDataMask;
		if( c == BitEndOfImageMask ) return;			// 图像结束
		if( c & BitWhiteLineMask )			// 忽略空白行(通常在图像顶部和底部)
		{
			iy +=count;
		}
		else if( c & BitPixelMask )		// 跳过图像数据
		{
			s +=count;
		}
		else						// 忽略透明部分
		{
		}
		if( c & BitEndOfLineMask )		// 一行结束,换行
		{
			iy++;	
		}
	}
	// 屏幕可见范围以内
	WORD *d = (WORD *)lpBitmap + iy * lPitch;
	if( ix > 0 && ix < DisplayMode_Width) d+=ix;
	while(iy<DisplayMode_Height)
	{
		WORD c = *s++, count = c & BitDataMask;
		if( c == BitEndOfImageMask ) return;		// 图像结束
		if( c & BitWhiteLineMask )		// 忽略空白行(通常在图像顶部和底部)
		{
			iy +=count;
			d += lPitch * count;
		}
		else						// 非空白行,要考虑如何画
		{
			if( ix < 0  )
			{
				if( ix + count < 0 )	// 1 不画 .... /
				{
					if( c & BitPixelMask ) s +=count;	// 忽略像素
					ix += count;
				}
				else					// 2 部分画 ../..
				{
					if( c & BitPixelMask )
					{
						s += -ix;		// 忽略不可见部分
						ix += count;
						for( int i=0; i<ix; i++ ) *d++ = *s++;
					}
					else				// 透明部分
					{
						ix += count;
						d += ix;	
					}
				}
			}
			else if( ix >= DisplayMode_Width )			// 5 不画	\ ....
			{
				if( c & BitPixelMask ) s +=count;		// 忽略像素
				// ix += count;						// 没有必要,反正已经出界了
			}
			else // ( ix > 0 && ix <= GraphWidth )
			{
				if( ix + count >= DisplayMode_Width)	// 4 部分画  ..\..`
				{
					if( c & BitPixelMask )
					{
						for( int i=ix; i<DisplayMode_Width; i++ ) *d++ = *s++;
						ix += count;
						s += (ix - DisplayMode_Width);		// 跳过超出部分
					}
					else
					{
						ix += count;
					}
				}
				else							// 3 全画	 /....\`
				{
					if( c & BitPixelMask )				// 显示图像
					{
						for( int i=0; i<count; i++ ) *d++ = *s++;
					}
					else							// 跳过透明部分
					{
						d += count;
					}
					ix += count;
				}
			}
		}
		if( c & BitEndOfLineMask )		// 一行结束,换行
		{
			ix = x;
			iy++;
	
			d = (WORD *)lpBitmap + iy * lPitch;
			if( ix > 0 && ix < DisplayMode_Width ) d += ix;
		}
	}
}

void ImageList::DrawAlpha250(int index, int x, int y, WORD *lpBitmap, long lPitch)
{
	
	WORD mask1=m_dwAlphaMask_SHR1;
	WORD mask2=m_dwAlphaMask_SHR2;
	int  ofs=m_lpOffsetTable[index]/2;
	WORD *s = m_lpDataBuffer+ofs;

	WORD Width  = *s++;
	WORD Height = *s++;
	// 如果图像不在可见范围内,就不画了
	if( (x + Width ) < 0 || x >= DisplayMode_Width || (y + Height) < 0 || y >= DisplayMode_Height) return;
	// 如果图像完全在可见范围内,就直接调用PutImage
	if( x >= 0 && (x + Width) < DisplayMode_Width && y >= 0 && (y + Height) < DisplayMode_Height )
	{
		WORD *d = lpBitmap + y * lPitch + x;
		while( 1 )
		{ 
			WORD c = *s++, count = c & BitDataMask;
			if( c == BitEndOfImageMask )	// 图像结束
			break;			
			else
			if( c & BitWhiteLineMask )		// 空白行
			{ 
				d += lPitch * count;
			} 
			else
			if(c & BitPixelMask)		// 像素点
			{ 
				for( int i=0; i<count; i++ ) 
				{ 
					_asm
						{
							mov edi,d
							mov esi,s
							mov ax,[esi]
							shr ax,2
							and ax,mask2
							mov dx,[edi]
							mov bx,dx
							shr bx,1
							and bx,mask1
							shr dx,2
							and dx,mask2
							add dx,bx
							add ax,dx
							mov [edi],ax
						}
						d++;s++;
					//*d++ = *s++;						
				} 
			} 
			else 
			if(c & BitTransparentMask) // 透明点
			{ 
			 	d += count;
			} 
			else
			if( c == BitEndOfLineMask )		// 行结束
				{
					d+=(lPitch-Width);				
			}  
		}  
		return;
	}
	// 图像只有部分可见,要考虑各个边界相交的情况
	int ix=x, iy=y;	// 当前处理的行列坐标
	// 屏幕范围以上不可见部分
	while( iy < 0 )
	{
		WORD c = *s++, count = c & BitDataMask;
		if( c == BitEndOfImageMask ) return;			// 图像结束
		if( c & BitWhiteLineMask )			// 忽略空白行(通常在图像顶部和底部)
		{
			iy +=count;
		}
		else if( c & BitPixelMask )		// 跳过图像数据
		{
			s +=count;
		}
		else						// 忽略透明部分
		{
		}
		if( c & BitEndOfLineMask )		// 一行结束,换行
		{
			iy++;	
		}
	}
	// 屏幕可见范围以内
	WORD *d = (WORD *)lpBitmap + iy * lPitch;
	if( ix > 0 && ix < DisplayMode_Width) d+=ix;
	while(iy<DisplayMode_Height)
	{
		WORD c = *s++, count = c & BitDataMask;
		if( c == BitEndOfImageMask ) return;		// 图像结束
		if( c & BitWhiteLineMask )		// 忽略空白行(通常在图像顶部和底部)
		{
			iy +=count;
			d += lPitch * count;
		}
		else						// 非空白行,要考虑如何画
		{
			if( ix < 0  )
			{
				if( ix + count < 0 )	// 1 不画 .... /
				{
					if( c & BitPixelMask ) s +=count;	// 忽略像素
					ix += count;
				}
				else					// 2 部分画 ../..
				{
					if( c & BitPixelMask )
					{
						s += -ix;		// 忽略不可见部分
						ix += count;
						for( int i=0; i<ix; i++ ) 
						{
							_asm
							{ 
							mov edi,d
							mov esi,s
							mov ax,[esi]
							shr ax,2
							and ax,mask2
							mov dx,[edi]
							mov bx,dx
							shr bx,1
							and bx,mask1
							shr dx,2
							and dx,mask2
							add dx,bx
							add ax,dx
							mov [edi],ax
							}
							d++;s++;
							//*d++ = *s++;
						}
					}
					else				// 透明部分
					{
						ix += count;
						d += ix;	
					}
				}
			}
			else if( ix >= DisplayMode_Width )			// 5 不画	\ ....
			{
				if( c & BitPixelMask ) s +=count;		// 忽略像素
				// ix += count;						// 没有必要,反正已经出界了
			}
			else // ( ix > 0 && ix <= GraphWidth )
			{
				if( ix + count >= DisplayMode_Width)	// 4 部分画  ..\..`
				{
					if( c & BitPixelMask )
					{
						for( int i=ix; i<DisplayMode_Width; i++ ) 
						{
							_asm
							{ 
							mov edi,d
							mov esi,s
							mov ax,[esi]
							shr ax,2
							and ax,mask2
							mov dx,[edi]
							mov bx,dx
							shr bx,1
							and bx,mask1
							shr dx,2
							and dx,mask2
							add dx,bx
							add ax,dx
							mov [edi],ax
							}
							d++;s++;
							//*d++ = *s++;
						}
						ix += count;
						s += (ix - DisplayMode_Width);		// 跳过超出部分
					}
					else
					{
						ix += count;
					}
				}
				else							// 3 全画	 /....\`
				{
					if( c & BitPixelMask )				// 显示图像
					{
						for( int i=0; i<count; i++ ) 
						{
							_asm
							{ 
							mov edi,d
							mov esi,s
							mov ax,[esi]
							shr ax,2
							and ax,mask2
							mov dx,[edi]
							mov bx,dx
							shr bx,1
							and bx,mask1
							shr dx,2
							and dx,mask2
							add dx,bx
							add ax,dx
							mov [edi],ax
							}
							d++;s++;
							
						//	*d++ = *s++;
						}
					}
					else							// 跳过透明部分
					{
						d += count;
					}
					ix += count;
				}
			}
		}
		if( c & BitEndOfLineMask )		// 一行结束,换行
		{
			ix = x;
			iy++;
	
			d = (WORD *)lpBitmap + iy * lPitch;
			if( ix > 0 && ix < DisplayMode_Width ) d += ix;

⌨️ 快捷键说明

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