Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.4 KiB

  1. #include <dos.h>
  2. #include <share.h>
  3. #include <mytypes.h>
  4. #include <misclib.h>
  5. #include <displib.h>
  6. #define VGA_WIDTH_PIXELS 640
  7. #define VGA_HEIGHT_SCAN_LINES 480
  8. typedef struct _BITMAPFILEHEADER {
  9. USHORT bfType;
  10. ULONG bfSize;
  11. USHORT bfReserved1;
  12. USHORT bfReserved2;
  13. ULONG bfOffBits;
  14. } BITMAPFILEHEADER;
  15. typedef struct _BITMAPINFOHEADER{
  16. ULONG biSize;
  17. long biWidth;
  18. long biHeight;
  19. USHORT biPlanes;
  20. USHORT biBitCount;
  21. ULONG biCompression;
  22. ULONG biSizeImage;
  23. long biXPelsPerMeter;
  24. long biYPelsPerMeter;
  25. ULONG biClrUsed;
  26. ULONG biClrImportant;
  27. } BITMAPINFOHEADER;
  28. BITMAPFILEHEADER FileHeader;
  29. BITMAPINFOHEADER InfoHeader;
  30. //
  31. // Pixel maps. This is set up so that when bitmaps using the standard
  32. // Windows VGA palette are displayed from a file, monochrome ones have
  33. // a dark blue foreground and black background. Color bitmaps use the
  34. // dark blue index as the background; pixels that are dark blue are
  35. // assigned to be background and not placed into the video buffer.
  36. //
  37. BYTE PixMapMono[2] = { VGAPIX_BLACK, VGAPIX_BLUE };
  38. BYTE PixMapColor[16] = { VGAPIX_BLACK,
  39. VGAPIX_RED,
  40. VGAPIX_GREEN,
  41. VGAPIX_YELLOW,
  42. VGAPIX_BLUE,
  43. VGAPIX_MAGENTA,
  44. VGAPIX_CYAN,
  45. VGAPIX_LIGHT_GRAY,
  46. VGAPIX_DARK_GRAY,
  47. VGAPIX_LIGHT_RED,
  48. VGAPIX_LIGHT_GREEN,
  49. VGAPIX_LIGHT_YELLOW,
  50. VGAPIX_LIGHT_BLUE,
  51. VGAPIX_TRANSPARENT,
  52. VGAPIX_LIGHT_CYAN,
  53. VGAPIX_WHITE
  54. };
  55. BOOL
  56. _far
  57. VgaDisplayBitmapFromFile(
  58. IN FPCHAR Filename,
  59. IN USHORT x,
  60. IN USHORT y,
  61. IN FPVOID ScratchBuffer,
  62. IN UINT ScratchBufferSize
  63. )
  64. {
  65. unsigned FileHandle;
  66. unsigned Count;
  67. unsigned BytesPerLine;
  68. unsigned MaxLines;
  69. unsigned Lines;
  70. unsigned Bottom;
  71. BOOL b = FALSE;
  72. //
  73. // Open the file.
  74. //
  75. if(_dos_open(Filename,SH_DENYWR,&FileHandle)) {
  76. goto c0;
  77. }
  78. //
  79. // Read the bitmap file header and validate it.
  80. //
  81. if(_dos_read(FileHandle,&FileHeader,sizeof(BITMAPFILEHEADER),&Count)
  82. || (Count != sizeof(BITMAPFILEHEADER))
  83. || (FileHeader.bfType != 0x4d42)) {
  84. goto c1;
  85. }
  86. //
  87. // Read the bitmap info header and validate it.
  88. //
  89. if(_dos_read(FileHandle,&InfoHeader,sizeof(BITMAPINFOHEADER),&Count)
  90. || (Count != sizeof(BITMAPINFOHEADER))
  91. || (InfoHeader.biSize != sizeof(BITMAPINFOHEADER))
  92. || (InfoHeader.biHeight < 0)
  93. || ((y + InfoHeader.biHeight) > VGA_HEIGHT_SCAN_LINES)
  94. || ((x + InfoHeader.biWidth) > VGA_WIDTH_PIXELS)
  95. || (InfoHeader.biPlanes != 1)
  96. || ((InfoHeader.biBitCount != 1) && (InfoHeader.biBitCount != 4))
  97. || InfoHeader.biCompression) {
  98. goto c1;
  99. }
  100. //
  101. // Calculate the number of bytes per line. Rows are padded to
  102. // dword boundary.
  103. //
  104. Count = 8 / InfoHeader.biBitCount;
  105. BytesPerLine = (unsigned)(InfoHeader.biWidth / Count);
  106. if(InfoHeader.biWidth % Count) {
  107. BytesPerLine++;
  108. }
  109. BytesPerLine = (BytesPerLine+3) & 0xfffc;
  110. //
  111. // Ignore the color table for now. Seek to the start of the
  112. // actual bits.
  113. //
  114. if(DosSeek(FileHandle,FileHeader.bfOffBits,DOSSEEK_START) != FileHeader.bfOffBits) {
  115. goto c1;
  116. }
  117. //
  118. // Figure out how many lines fit into the buffer we were given.
  119. //
  120. MaxLines = ScratchBufferSize / BytesPerLine;
  121. Bottom = (y + (USHORT)InfoHeader.biHeight) - 1;
  122. while(InfoHeader.biHeight) {
  123. Lines = (unsigned)InfoHeader.biHeight;
  124. if(Lines > MaxLines) {
  125. Lines = MaxLines;
  126. }
  127. if(_dos_read(FileHandle,ScratchBuffer,Lines*BytesPerLine,&Count)
  128. || (Count != (Lines*BytesPerLine))) {
  129. goto c1;
  130. }
  131. VgaBitBlt(
  132. x,
  133. Bottom,
  134. (unsigned)InfoHeader.biWidth,
  135. -Lines,
  136. BytesPerLine,
  137. InfoHeader.biBitCount != 1,
  138. (InfoHeader.biBitCount != 1) ? PixMapColor : PixMapMono,
  139. ScratchBuffer
  140. );
  141. InfoHeader.biHeight -= Lines;
  142. Bottom -= Lines;
  143. }
  144. b = TRUE;
  145. c1:
  146. _dos_close(FileHandle);
  147. c0:
  148. return(b);
  149. }