BMP.C

/*========================================================================== 
*
* Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
* Copyright (C) 1994-1995 ATI Technologies Inc. All Rights Reserved.
*
* File:bmp.c
* Content:Bitmap reader
*
***************************************************************************/
#include "foxbear.h"

/*
* gfxLoadBitmap
*/
GFX_HBM gfxLoadBitmap(LPSTR szFileName)
{
HFASTFILE pfile;
BITMAPFILEHEADER UNALIGNED *pbf;
BITMAPINFOHEADER UNALIGNED *pbi;
GFX_HBM hbm;
BOOL trans = FALSE;

pfile = FastFileOpen( szFileName );

if( pfile == NULL )
{
return NULL;
}

pbf = (BITMAPFILEHEADER *)FastFileLock(pfile, 0, 0);
pbi = (BITMAPINFOHEADER *)(pbf+1);

if (pbf->bfType != 0x4d42 ||
pbi->biSize != sizeof(BITMAPINFOHEADER))
{
Msg("Failed to load");
Msg(szFileName);
FastFileClose( pfile );
return NULL;
}

/*
* TOTAL HACK for FoxBear, FoxBear does not use any masks, it draws
* sprites with transparent colors, but the code still loads the masks
* if a mask exists the sprite is transparent, else it is not, so
* you cant get rid of the masks or nothing will be transparent!!
*
* if the code tries to load a mask, just return a non-zero value.
*/

if( pbi->biBitCount == 1 )
{
Msg("some code is still using masks, stop that!");
FastFileClose( pfile );
return NULL;
}

/*
* ANOTHER TOTAL HACK for FoxBear, some of the bitmaps in FoxBear
* are a solid color, detect these and dont waste VRAM on them.
*/
if( !bTransDest && pbi->biBitCount == 8 )
{
int x,y;
BYTE c;
BYTE UNALIGNED *pb = (LPBYTE)pbi + pbi->biSize + 256 * sizeof(COLORREF);
RGBQUAD UNALIGNED *prgb = (RGBQUAD *)((LPBYTE)pbi + pbi->biSize);
COLORREF rgb;

c = *pb;

for(y=0; y<(int)pbi->biHeight; y++ )
{
for( x=0; x<(int)pbi->biWidth; x++ )
{
if (c != *pb++)
goto not_solid;
}
pb += ((pbi->biWidth + 3) & ~3) - pbi->biWidth;
}

rgb = RGB(prgb[c].rgbRed,prgb[c].rgbGreen,prgb[c].rgbBlue);
hbm = gfxCreateSolidColorBitmap(rgb);

FastFileClose( pfile );
return hbm;
}
not_solid:

/*
* figure out iff the bitmap has the transparent color in it.
*/
if( pbi->biBitCount == 8 )
{
int x,y;
BYTE UNALIGNED *pb = (LPBYTE)pbi + pbi->biSize + 256 * sizeof(COLORREF);
DWORD UNALIGNED *prgb = (DWORD *)((LPBYTE)pbi + pbi->biSize);

for(y=0; y<(int)pbi->biHeight && !trans; y++ )
{
for( x=0; x<(int)pbi->biWidth && !trans; x++ )
{
if (prgb[*pb++] == 0x00FFFFFF)
trans=TRUE;
}
pb += ((pbi->biWidth + 3) & ~3) - pbi->biWidth;
}
}

hbm = gfxCreateVramBitmap(pbi, trans);

if( hbm == NULL )
{
FastFileClose( pfile );
return GFX_FALSE;
}

#if 0
{
DDSCAPS ddscaps;

IDirectDrawSurface_GetCaps(((GFX_BITMAP *)hbm)->lpSurface, &ddscaps);

if( !(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY) )
{
Msg( "%s is in system memory", szFileName );
}
}
#endif

FastFileClose( pfile );

return hbm;

} /* gfxLoadBitmap */