178 lines
4.4 KiB
C
178 lines
4.4 KiB
C
|
#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);
|
||
|
}
|
||
|
|