Microsoft KB Archive/76729

From BetaArchive Wiki

Microsoft Knowledge Base

Complete Program to BLOAD/BSAVE Four Plane PICEM Images

Last reviewed: September 25, 1997
Article ID: Q76729

7.00 7.10 MS-DOS kbprg kbcode kbfile

SUMMARY

This article contains a program that combines information from several Microsoft Knowledge Base articles for a more complete example of BLOAD and BSAVE for graphics images. It incorporates information on how to shell to PICEM210 (a shareware utility) to display a graphics image, how to BLOAD/BSAVE the graphics file with four color planes, and how to save the video card palette registers associated with the image.

This information applies to Microsoft Basic Professional Development System (PDS) versions 7.0 and 7.1 for MS-DOS.

NOTE: Some portions of this code may be modified to make it compatible with Microsoft QuickBasic versions 4.0, 4.0b, and 4.5, and Microsoft Basic Compiler versions 6.0 and 6.0b. See the notes below.

You can find BCPICSAV.EXE, a self-extracting file, on these services:

  • Microsoft's World Wide Web site on the Internet

          On the www.microsoft.com home page, click the Support icon
          Click Knowledge Base, and select the product
          Enter kbfile BCPICSAV.EXE, and click GO!
          Open the article, and click the button to download the file
  • Internet (anonymous FTP)

          ftp ftp.microsoft.com
          Change to the Softlib/Mslfiles folder
          Get BCPICSAV.EXE
  • The Microsoft Network

          On the Edit menu, click Go To, and then click Other Location
          Type "mssupport" (without the quotation marks)
          Double-click the MS Software Library icon
          Find the appropriate product area
          Locate and Download BCPICSAV.EXE
  • Microsoft Download Service (MSDL)

          Dial (425) 936-6735 to connect to MSDL
          Download BCPICSAV.EXE

For additional information about downloading, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q119591
   TITLE     : How to Obtain Microsoft Support Files from Online Services

MORE INFORMATION

The program below, PIC.BAS, shows one method of using PICEM210 to display a .GIF, .PCX, or .PIC graphics image file and BSAVE the image to disk. This program is intended to save and load images in screen modes with more than one bit plane. Screen modes 9 (640-by-350-by-16) and 12 (640-by-480-by-16) fall into this category (they each have four bit planes). This program can also save screen mode 13 (320-by-200-by-256) graphics images, but PICEM210 already has the ability to save one bit plane images in the Basic BSAVE format without using a separate Basic program.

PICEM210 is a freeware graphics file viewing utility that can display .GIF, .PCX, and .PIC file formats, and is required to make this program run. PICEM210 is available as a shareware product. For more information on PICEM, please read the PICEM README file PICEM210.DOC, or query on the following:

   PICEM

PICEM210 has the ability to set most of its viewing options from the command line in addition to leaving the image on the screen when it ends. The options used in this program are as follows:

  /e    -leaves image on screen after displaying
  /k    -tells PICEM to not wait for a keypress after displaying image
  /v:x  -which mode to display the image

        values for x used are:
          i    -Screen mode 9, change to "g" for EGA cards
          m    -Screen mode 12
          l    -Screen mode 13

In addition to BSAVEing the graphics image, the program below also saves the palette registers used by the picture. It does so because when you shell to another process then return to Basic, Basic does not know that the screen mode and palette have changed during the shell. If this step is not performed, the next time the image is loaded, Basic's default palette is used rather than the palette needed for the image, so the picture will not display in the correct colors. For more information on saving the palette registers, query on the following words:

   SAVE and PALETTE and REGISTERS and INTERRUPT

For more information on how to BLOAD/BSAVE graphics images, please query on the following words:

   BLOAD and BSAVE and EGA and VGA

Information About the Program

The program first finds if it is loading a previously BSAVEd file or if it is BSAVEing a graphics file. It then gets information about the file to load or save, and which screen mode the file is to be displayed in (valid values are 9, 12, and 13). It then either shells to PICEM or BLOADs the image to the screen.

When an image is saved, there are four image files (saved as "<file>.B_X") and one register file (saved as "<file>.REG") saved. The image files each contain one bit plane of the image, and the register file contains the values of the palette registers for the image.

When an image is loaded, the program looks for the "<file>.REG" to make sure that the image has been previously BSAVED (where <file> is the filename of the image BSAVEd). This is where the code needs to be changed to make the program compatible with QuickBasic version 4.5. The DIR$ function in Basic PDS 7.x checks to see if a specified file exists; if the file does not exist, DIR$ returns a null string. QuickBasic does not support the DIR$ function, but there are ways to work around this (for example, shelling a directory listing into a file, or calling interrupts to load a directory listing into an array). For more information on these techniques, please query on the following words:

   LOAD and DIRECTORY and LISTING and ARRAY

PIC.BAS will also accept command line parameters. The format is as follows:

   pic [<save/load> /mode [<GIF-file>] <bsave-name>]

where

   <Save/Load>:   /S = Save a GIF, /L = Load a BSAVE file
   /mode:         /9 = 640x350x16, /12 = 640x480x16, /13 = 320x200x256
   <GIF-file>:    Filename of .GIF, .PCX, .PIC file to BSAVE, extension
                  required. (Not used when loading a BSAVE file.)
   <bsave-file>:  Eight character filename to BLOAD or BSAVE GIF

An example of loading the 640-by-480-by-16 GIF file COLORS.GIF and BSAVEing it as COLORS is as follows (where COLORS.GIF is in the current directory):

   pic /s /12 colors.gif colors

The above command will create five files: COLORS.B_0, COLORS.B_1, COLORS.B_2, COLORS.B_3, and COLORS.REG. To load the BSAVE files back into video memory, use the following command:

   pic /l /12 colors

The steps used to compile the program are as follows:

    bc /o pic;

    link pic,,,qbx.lib;

Disclaimer

This program is NOT a retail product of Microsoft Corporation. It was developed by a private technician as a utility to be used by programmers using Microsoft Basic PDS. This program is provided AS IS, without warranty of any kind, either expressed or implied. The entire risk as to the quality and performance of this program is with the user. Neither Microsoft or the programmer of the application shall be responsible for any problems, including, but not limited to, any lost profits, lost savings, or other incidental or consequential damages arising from the use or inability to use this program.

Code Example

'PIC.BAS--An interface for Basic PDS to use with PICEM version 2.1.
'This program requires the user to have a copy of PICEM210.EXE,
'available through bulletin boards.

DEFINT A-Z CONST TRUE = -1 CONST FALSE = NOT TRUE

CONST Save = 2        'Constants to tell if we are loading or
CONST Load = 1        'saving GIF and bsave files

TYPE ColorType        'Type used to store Palette register information
     red AS STRING * 1
     green AS STRING * 1
     blue AS STRING * 1

END TYPE

REM $INCLUDE: 'qbx.bi'                 'use qb.bi for QuickBasic 4.50

DECLARE SUB LoadBSAVE (NumRegs%, mode, BSAVEfile$) DECLARE SUB SaveGif (NumRegs%, mode, Giffile$, BSAVEfile$) DECLARE SUB SaveBasicPalette (NumRegs%, LoadSave%) DECLARE SUB EgaVgaSub (filename$, mode AS INTEGER, RW AS INTEGER) DECLARE SUB ComLine (cmd$, SL$, mode%, Bfile$, Gif$)

COMMON SHARED ColorBuf() AS ColorType, BasicPalette() AS ColorType

'$DYNAMIC
'Buffers for Basic's and PICEM's Palette Registers

DIM ColorBuf(0 TO 15) AS ColorType DIM BasicPalette(0 TO 15) AS ColorType DIM NumRegs AS INTEGER

NumRegs = 16        'Initialize variables, assume SCREEN 9 or 12

Giffile$ = " " BSAVEfile$ = " "

cmd$ = COMMAND$     'Check for command line arguements

IF cmd$ = "" THEN

 SCREEN 0
 CLS
 COLOR 14, 8
 LOCATE 1, 5
 PRINT "Welcome to the GIF/PCX/PIC picture BSAVE/BLOAD utility"
 LOCATE 3, 5
 PRINT "Would you like to Save a GIF, Load a BSAVE file, or"
 LOCATE 4, 5: INPUT "Quit the application? (S,L,Q): ", SaveorLoad$

ELSE

 'Parse command$
 CALL ComLine(cmd$, SaveorLoad$, mode, BSAVEfile$, Giffile$)

END IF SELECT CASE UCASE$(SaveorLoad$)

  CASE "S"
     CALL SaveGif(NumRegs, mode, Giffile$, BSAVEfile$)
  CASE "L"
     CALL LoadBSAVE(NumRegs, mode, BSAVEfile$)
  CASE "H"
     PRINT "Usage: /s-save GIF, /l-load bsave file,"
     PRINT
     PRINT "  PIC [<Save/Load> /mode <GIF-file> <bsavefile>]"
     PRINT
     PRINT "Save/Load: /s = Save a GIF, /l = Load BSAVE files"
     PRINT "/mode: /9 = 640x350x16, /12 = 640x480x16, /13 = ";
     PRINT "320x200x256"
     PRINT "GIF-file: path, name, and extention of GIF-file to BSAVE"
     PRINT "bsavefile: 8 character filename to BLOAD, or BSAVE GIF"
  END SELECT

END

SUB ComLine (cmd$, SL$, mode, Bfile$, Gif$)

'This slightly modified code is in the On-Line help for Command$

   DIM Args$(1 TO 4)
   MaxArgs = 4
   NumArgs = 0: In = FALSE
   L = LEN(cmd$)
   'Go through the command line a character at a time.
   FOR I = 1 TO L
      C$ = MID$(cmd$, I, 1)
      'Test for character being a blank or a tab.
      IF ((C$ <> " ") AND (C$ <> CHR$(9)) AND (C$ <> "/")) THEN
      'Neither blank nor tab. Test if you're inside an argument.
      IF NOT In THEN
      'You've found the start of a new argument.
         IF NumArgs = MaxArgs THEN EXIT FOR
         NumArgs = NumArgs + 1
         In = TRUE
      END IF
      'Add the character to the current argument.
      Args$(NumArgs) = Args$(NumArgs) + C$
      ELSE
      'Found a blank or a tab.
      'Set "Not in an argument" flag to FALSE.
     In = FALSE
      END IF
   NEXT I

   IF NumArgs > 2 THEN       'at least 3 arguments, or print help
     SL$ = Args$(1)          'first param should be /s or /l
     mode = VAL(Args$(2))    'next param should be video mode
     IF SL$ = "S" THEN
     Gif$ = Args$(3)      'if /s, get GIF-file name
     Bfile$ = Args$(4)    'assign bsave file-name
     ELSEIF SL$ = "L" THEN
     Bfile$ = Args$(3)    'if /l get bsave file-name
     END IF
   ELSE
     SL$ = "H"
   END IF

END SUB

SUB EgaVgaSub (filename$, mode AS INTEGER, RW AS INTEGER) STATIC

'This code is essentially the same as BLOAD/BSAVE application note,
'the name the file is BSAVEd as is the only thing changed

  SELECT CASE mode     'Determine how much to BSAVE.

  'Mode 7 is 320x200- save/load 8000 bytes.
  'Mode 8 is 640x200- save/load 16000 bytes.
  'Modes 9 and 10 are 640x350- save/load 28000 bytes.
  'Modes 11 and 12 are 640x480- save/load 38400 bytes.
  'Mode 13 is 320x200x(1byte/256 colors)- save/load 64000 bytes.

    CASE 7
     total! = 8000
    CASE 8
     total! = 16000
    CASE 9 TO 10
     total! = 28000
    CASE 11 TO 12
     total! = 38400
    CASE 13
     total! = 64000
    CASE ELSE
     PRINT "ERROR: Non EGA/VGA graphics mode!"
     GOTO NonEGAorVGA
  END SELECT

  IF mode = 10 THEN   'SCREEN mode 10 only has two bit planes
    cycle = 1         'because it is used on a monochrome display.
  ELSE
    cycle = 3         'SCREEN modes 7, 8, 9, 11, and 12 have four
  END IF              'bit planes.

  DEF SEG = &HA000   'Define the segment for EGA/VGA graphics.
               'BSAVEing and BLOADing SCREEN mode 13 does not
  IF mode = 13 THEN  'require the use of the graphics map register.
    IF RW = 1 THEN                   'BLOAD the file.
      f$ = filename$ + ".B_0"        'Load the file into VGA memory.
      BLOAD f$, 0                    '0 is the offset to page 0.
    ELSE                             'BSAVE the file.
      f$ = filename$ + ".B_0"    'Save VGA memory in a file.
      BSAVE f$, 0, total!        'Save the visual page, at offset 0.
    END IF
  ELSE
    FOR I = 0 TO cycle     'Cycle through each bit plane of EGA/VGA.
      IF RW = 1 THEN          'BLOAD files.
      OUT &H3C4, 2         'We want to index the map register.
      OUT &H3C5, 2 ^ I     'Bit plane we want to reference.

      'Load each file into its corresponding bit plane.
      f$ = filename$ + ".B_" + CHR$(I + 48)
      BLOAD f$, 0          '0 is the offset to page 0.
      ELSE                    'BSAVE files.
      OUT &H3CE, 4         'Select Read Map Select Register.
      OUT &H3CF, I         'Select the bit plane to save.

      'Save each bit plane in its own file.
      f$ = filename$ + ".B_" + CHR$(I + 48)
      BSAVE f$, 0, total!  'Save the visual page, at offset 0.
      END IF
    NEXT I
  END IF
  DEF SEG                      'Restore the segment.

NonEGAorVGA: END SUB

SUB LoadBSAVE (NumRegs, mode, SaveFile$)

'This sub loads BSAVE files from disk into video
'memory, also restores the Picture's Palette registers
'The DIR$() function is code that needs to be changed for QB4.50

  DIM inregx AS RegTypeX
  DIM outregx AS RegTypeX

  DO UNTIL DIR$(SaveFile$ + ".reg") <> ""   'Get valid filename
    LOCATE 3, 1: PRINT SPACE$(79)           'Clear previous print lines
    LOCATE 4, 1: PRINT SPACE$(79)
    LOCATE 3, 5
    INPUT "Please enter the BSAVE filename (8 chars,no ext):", SaveFile$
  LOOP
        'Get valid screen mode
  DO UNTIL (mode = 9) OR (mode = 12) OR (mode = 13)
  LOCATE 4, 5: INPUT "Which screen mode is it? (9,12,13): ", mode
  LOOP

  IF mode = 13 THEN                 'if screen 13, change array sizes
     REDIM ColorBuf(0 TO 255) AS ColorType
     REDIM BasicPalette(0 TO 255) AS ColorType
     NumRegs = 256
  END IF

  SCREEN mode     'Change to the specified screen mode
  CLS

  CALL SaveBasicPalette(NumRegs, Save)       'Save Basic's Palette

  DEF SEG = VARSEG(ColorBuf(0))     'Bload the picture's Palette
  BLOAD SaveFile$ + ".reg", VARPTR(ColorBuf(0))  'into an array
  DEF SEG

  inregx.ax = &H1012                   'restore picture's palette
  inregx.bx = 0                        'to the palette registers
  inregx.cx = NumRegs
  inregx.es = VARSEG(ColorBuf(0))
  inregx.dx = VARPTR(ColorBuf(0))
  CALL InterruptX(&H10, inregx, outregx)

  CALL EgaVgaSub(SaveFile$, mode, Load) 'reload the BSAVEd picture

  COLOR 3
  PRINT "Picture should be displayed, hit key to continue"
  DO: LOOP UNTIL INKEY$ <> ""
  ERASE ColorBuf

  CALL SaveBasicPalette(NumRegs, Load)  'Restore Basic's Palette
  SCREEN 0
  CLS

END SUB

SUB SaveBasicPalette (NumRegs, LoadSave)

'This sub Saves/Restores Basic's internal Palette registers

  DIM inregx AS RegTypeX
  DIM outregx AS RegTypeX

  IF LoadSave = Save THEN
    inregx.ax = &H1017                 'Save Basic's palette
  ELSE
    inregx.ax = &H1012                 'Load Basic's palette
  END IF
  inregx.bx = 0
  inregx.cx = NumRegs
  inregx.es = VARSEG(BasicPalette(0))
  inregx.dx = VARPTR(BasicPalette(0))
  CALL InterruptX(&H10, inregx, outregx) 'interrupt to load/save
                          'palette registers

END SUB

SUB SaveGif (NumRegs, mode, Giffile$, SaveName$)

'This sub shells to PICEM210 to display the
'GIF file, then BSAVEs the image to disk

  DIM inregx AS RegTypeX
  DIM outregx AS RegTypeX

  DO UNTIL DIR$(Giffile$) <> ""         'Get a valid file name
    LOCATE 3, 5: PRINT SPACE$(70)       'Clear previous print lines
    LOCATE 4, 5: PRINT SPACE$(70)
    LOCATE 3, 5: PRINT "Please enter the drive,path and name"
    LOCATE 4, 5
    INPUT "of the GIF file you would like to save: ", Giffile$
    Giffile$ = LTRIM$(RTRIM$(Giffile$))
  LOOP
      'Get valid screen mode
  DO UNTIL (mode = 9) OR (mode = 12) OR (mode = 13)
    LOCATE 6, 5: INPUT "which screen mode? (9,12,13): ", mode
  LOOP
      'Get valid filename for BSAVE
  DO UNTIL (LEN(SaveName$) < 9) AND (SaveName$ <> " ")
    LOCATE 7, 5
    INPUT "Filename you want to save it as? (8 chars): ", SaveName$
  LOOP

  IF mode = 9 THEN       'values used by PICEM210 to select screen mode
     view$ = "i"         'for EGA cards this should be "g"
  ELSEIF mode = 12 THEN
     view$ = "m"
  ELSEIF mode = 13 THEN
    REDIM ColorBuf(0 TO 255) AS ColorType
    REDIM BasicPalette(0 TO 255) AS ColorType
    view$ = "l"
    NumRegs = 256
  END IF

  SCREEN mode
  CALL SaveBasicPalette(NumRegs, Save)       'Save Basic's Palette

  LOCATE 1, 1
  shellstr$ = view$ + " " + Giffile$
  picem$ = "picem210 /e /k /v:" + shellstr$  'Shell string for picem210
  PRINT "hit a key when ready to display picture"
  PRINT picem$
  DO: LOOP UNTIL INKEY$ <> ""

  SHELL picem$                    'shell to picem

  inregx.ax = &H1017              'save picture's palette registers
  inregx.bx = 0
  inregx.cx = NumRegs
  inregx.es = VARSEG(ColorBuf(0))
  inregx.dx = VARPTR(ColorBuf(0))
  CALL InterruptX(&H10, inregx, outregx)

  DEF SEG = VARSEG(ColorBuf(0))   'BSAVE registers to file
  BSAVE SaveName$ + ".reg", VARPTR(ColorBuf(0)), 3 * NumRegs
  DEF SEG

  CALL EgaVgaSub(SaveName$, mode, Save)              'BSAVE picture

  ERASE ColorBuf
  COLOR 3
  LOCATE 1, 1: PRINT "Picture has been saved, press key to quit"
  DO: LOOP UNTIL INKEY$ <> ""

  'Restore Basic's Palette
  CALL SaveBasicPalette(NumRegs, Load)
  SCREEN 0
  CLS

END SUB

Additional Reference Words: BasicCom 4.00 4.00a 4.00b 6.00 6.00b 7.00 7.10


KBCategory: kbprg kbcode kbfile

KBSubcategory:
Keywords : kbcode kbfile kbprg
Version : 7.00 7.10
Platform : MS-DOS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 25, 1997
©1997 Microsoft Corporation. All rights reserved. Legal Notices.