windows-nt/Source/XPSP1/NT/base/ntsetup/mpk/displib/vgac.c
2020-09-26 16:20:57 +08:00

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);
}