'=========================================================================== ' Subject: BUFFERED .BMP VIEWER Date: 04-06-97 (17:31) ' Author: Stephen L. Maxson Code: QB, QBasic, PDS ' Origin: smax@isc-durant.com Packet: GRAPHICS.ABC '=========================================================================== '------------------------------------------------------------------- 'DRAWBMP8.BAS '------------------------------------------------------------------- 'Stephen L. Maxson 'smax@isc-durant.com '------------------------------------------------------------------- 'This is the fastest 8-bit .BMP loader I've come up with so far. 'Uses Coridon Henshaw's "SetPalette" SUBroutine to speed up color 'loading; If you want to use DrawBMP8 in another program, SetPalette 'will have to go with it. DrawBMP8 reads from the file into a 'buffer of up to 32767 bytes, then decodes to screen from there, 'which is much faster then reading and decoding one byte at a time. 'Qbasic seems to have a problem with strings of that length; I would 'suggest setting BufferMax% to 19000 or so to take care of this. '------------------------------------------------------------------- 'To display an 8-bit .BMP file, just call the SUB, passing the name 'and the X and Y coordinates to start at. 'EXAMPLES: 'DrawBMP8 "funky.bmp", 0, 0 'File$ = "groovy.bmp": DrawBMP8 File$, 96, 32 '------------------------------------------------------------------- 'The SUB takes for granted that you are in screen mode 13 (MCGA/VGA '320x200x256), and that you are passing it the name of a valid 8-bit '.BMP file. It also will not clear the screen for you. If the .BMP 'image is larger than 320x200 (- X and Y), only the upper-left-hand 'portion of the image will be displayed. '------------------------------------------------------------------- 'Public Domain, (ab)use at your own risk. '------------------------------------------------------------------- DECLARE SUB DrawBMP8 (Pic$, X%, Y%) DECLARE SUB SetPalette (Attr%, Red%, Green%, Blue%) DEFINT A-Z CLS FILES "*.BMP" INPUT "Please enter name of an 8-bit .BMP file -> ", Pic$ IF Pic$ = "" THEN END IF INSTR(Pic$, ".") < 1 THEN Pic$ = Pic$ + ".BMP" SCREEN 13 DrawBMP8 Pic$, 0, 0 BEEP DO LOOP UNTIL INKEY$ <> "" SCREEN 0, 0, 0 WIDTH 80 END SUB DrawBMP8 (Pic$, X%, Y%) 'Maximum size of buffer, change to 19000 for QBasic- BufferMax% = 32767 OPEN Pic$ FOR BINARY AS #1 'Read width and height of image- GET #1, 19, BMPWidth% GET #1, 23, BMPHeight% 'Each raster must be a multiple of 4 bytes, this next line takes 'care of 'padded' bytes at the end of rasters of odd-width images- IF BMPWidth% / 4 <> BMPWidth% \ 4 THEN PadBytes% = 4 - (BMPWidth% MOD 4) 'Read the entire palette into a buffer- A$ = SPACE$(1024) GET #1, 55, A$ 'Decode the palette from the buffer- FOR I% = 0 TO 255 Blue% = ASC(MID$(A$, I% * 4 + 1, 1)) \ 4 Green% = ASC(MID$(A$, I% * 4 + 2, 1)) \ 4 Red% = ASC(MID$(A$, I% * 4 + 3, 1)) \ 4 'Henshaw's routine for faster palette setting SetPalette I%, Red%, Green%, Blue% NEXT I% N& = 1079 A% = BufferMax% A% = A% - (BufferMax% MOD (BMPWidth% + PadBytes%)) 'Find usable buffer size- B% = A% \ (BMPWidth% + PadBytes%) - 1 'Find rasters per buffer- A$ = SPACE$(A%) K% = BMPHeight% - 1 DO 'If current buffer is off screen, read another- DO WHILE K% - B% > (199 - Y%) 'Read a buffer's worth- GET #1, N&, A$ 'Move file pointer forward by buffer size- N& = N& + A% 'Decrease image line counter K% = K% - B% LOOP 'Read a buffer's worth- GET #1, N&, A$ '(B% + 1) worth of rasters in buffer- FOR I% = 0 TO B% 'BMPWidth% = pixels per raster- FOR J% = 0 TO (BMPWidth% - 1) 'Decode each pixel from buffer- C% = ASC(MID$(A$, I% * (BMPWidth% + PadBytes%) + J% + 1, 1)) 'If pixel falls in viewing area, plot it- IF J% < (320 - X%) AND K% < (200 - Y%) THEN PSET (J% + X%, K% + Y%), C% NEXT J% 'Done with this raster line, on to the next- K% = K% - 1 'K% < 0 condition must be checked, in case data at end of file 'does not completely fill the final buffer read- IF K% < 0 THEN EXIT FOR NEXT I% 'Move file pointer forward by buffer size- N& = N& + A% 'If K% is not < 0, there's more image- LOOP UNTIL K% < 0 'Put a fork in it, it's done- CLOSE #1 END SUB SUB SetPalette (Attr%, Red%, Green%, Blue%) OUT &H3C7, Attr% OUT &H3C8, Attr% OUT &H3C9, Red% OUT &H3C9, Green% OUT &H3C9, Blue% END SUB