|
|
#include <dos.h>
#include <share.h>
#include <mytypes.h>
#include <misclib.h>
#include <displib.h>
#define VGA_WIDTH_PIXELS 640
#define VGA_HEIGHT_SCAN_LINES 480
typedef struct _BITMAPFILEHEADER { USHORT bfType; ULONG bfSize; USHORT bfReserved1; USHORT bfReserved2; ULONG bfOffBits; } BITMAPFILEHEADER;
typedef struct _BITMAPINFOHEADER{ ULONG biSize; long biWidth; long biHeight; USHORT biPlanes; USHORT biBitCount; ULONG biCompression; ULONG biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; ULONG biClrUsed; ULONG biClrImportant; } BITMAPINFOHEADER;
BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER InfoHeader;
//
// Pixel maps. This is set up so that when bitmaps using the standard
// Windows VGA palette are displayed from a file, monochrome ones have
// a dark blue foreground and black background. Color bitmaps use the
// dark blue index as the background; pixels that are dark blue are
// assigned to be background and not placed into the video buffer.
//
BYTE PixMapMono[2] = { VGAPIX_BLACK, VGAPIX_BLUE };
BYTE PixMapColor[16] = { VGAPIX_BLACK, VGAPIX_RED, VGAPIX_GREEN, VGAPIX_YELLOW, VGAPIX_BLUE, VGAPIX_MAGENTA, VGAPIX_CYAN, VGAPIX_LIGHT_GRAY, VGAPIX_DARK_GRAY, VGAPIX_LIGHT_RED, VGAPIX_LIGHT_GREEN, VGAPIX_LIGHT_YELLOW, VGAPIX_LIGHT_BLUE, VGAPIX_TRANSPARENT, VGAPIX_LIGHT_CYAN, VGAPIX_WHITE };
BOOL _far VgaDisplayBitmapFromFile( IN FPCHAR Filename, IN USHORT x, IN USHORT y, IN FPVOID ScratchBuffer, IN UINT ScratchBufferSize ) { unsigned FileHandle; unsigned Count; unsigned BytesPerLine; unsigned MaxLines; unsigned Lines; unsigned Bottom; BOOL b = FALSE;
//
// Open the file.
//
if(_dos_open(Filename,SH_DENYWR,&FileHandle)) { goto c0; }
//
// Read the bitmap file header and validate it.
//
if(_dos_read(FileHandle,&FileHeader,sizeof(BITMAPFILEHEADER),&Count) || (Count != sizeof(BITMAPFILEHEADER)) || (FileHeader.bfType != 0x4d42)) { goto c1; }
//
// Read the bitmap info header and validate it.
//
if(_dos_read(FileHandle,&InfoHeader,sizeof(BITMAPINFOHEADER),&Count) || (Count != sizeof(BITMAPINFOHEADER)) || (InfoHeader.biSize != sizeof(BITMAPINFOHEADER)) || (InfoHeader.biHeight < 0) || ((y + InfoHeader.biHeight) > VGA_HEIGHT_SCAN_LINES) || ((x + InfoHeader.biWidth) > VGA_WIDTH_PIXELS) || (InfoHeader.biPlanes != 1) || ((InfoHeader.biBitCount != 1) && (InfoHeader.biBitCount != 4)) || InfoHeader.biCompression) {
goto c1; }
//
// Calculate the number of bytes per line. Rows are padded to
// dword boundary.
//
Count = 8 / InfoHeader.biBitCount; BytesPerLine = (unsigned)(InfoHeader.biWidth / Count); if(InfoHeader.biWidth % Count) { BytesPerLine++; } BytesPerLine = (BytesPerLine+3) & 0xfffc;
//
// Ignore the color table for now. Seek to the start of the
// actual bits.
//
if(DosSeek(FileHandle,FileHeader.bfOffBits,DOSSEEK_START) != FileHeader.bfOffBits) { goto c1; }
//
// Figure out how many lines fit into the buffer we were given.
//
MaxLines = ScratchBufferSize / BytesPerLine;
Bottom = (y + (USHORT)InfoHeader.biHeight) - 1;
while(InfoHeader.biHeight) {
Lines = (unsigned)InfoHeader.biHeight; if(Lines > MaxLines) { Lines = MaxLines; }
if(_dos_read(FileHandle,ScratchBuffer,Lines*BytesPerLine,&Count) || (Count != (Lines*BytesPerLine))) {
goto c1; }
VgaBitBlt( x, Bottom, (unsigned)InfoHeader.biWidth, -Lines, BytesPerLine, InfoHeader.biBitCount != 1, (InfoHeader.biBitCount != 1) ? PixMapColor : PixMapMono, ScratchBuffer );
InfoHeader.biHeight -= Lines; Bottom -= Lines; }
b = TRUE;
c1: _dos_close(FileHandle); c0: return(b); }
|