?? imagelist.cpp
字號:
// 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 + -