' =======================================================================
'  Name:  PSHOP.BAS
'  Ver:   1.10
'  Date:  1/21/1991
'  Lang:  Microsoft QuickBASIC v4.00+.  Optional PDQ.
'  Purp:  Read a *Print Shop* graphics file and display the icon on
'	  the screen.  Originally, I designed this to default to VGA
'	  such that it could be compiled with PDQ.  By request from your
'	  QBNews Editor, however, I have designed it to work with the
'	  CGA SCREEN 2 ("high res") mode, black and white.  If you would
'	  like to use this utility with PDQ, comment out all of the PSET
'	  statements and uncomment the DEF SEG statement and one of the
'	  two POKE statements that display the image.  As it now stands,
'	  PSHOP will work in the QB environment.  Be sure, though, that
'	  you have set the COMMAND$ to the appropriate file name.
'
'	  Also, version 1.10 includes a switch (/n) which will allow
'	  you to display even the New Print Shop (supposedly higher
'	  resolution) images.  Dave Cleary informed me that a 10 byte
'	  header exists in the beginning of each PS *file* (not image)
'	  such that by initially bypassing this header, the files are
'	  read exactly the same as the old printshop graphics.
'  Note:  THIS ROUTINE WILL NOT WORK ON Print Master FILES!  PM files
'         have a delimiter in them denoted by CHR$(11)+CHR$(52)+CHR$(88)
'         which tells about the image type and also truncates a part
'         of the 572 byte block.  Use a conversion utility to convert
'         your PM files to PS before reading with this routine!
'  Kudos: Richard Randless for the GetBit% routine (the one here is a
'         modification for this specific program).  Ryan Snodgrass for
'         the original from which this code is based.  I spent about
'         12 hours analyzing the files and their format, and really
'         simplified this code a lot.  Ryan did not comment his
'         program at all.  Here, I have done so such that it should make
'         a little more sense.  (C)opyright 1991 by Mike Welch and Ryan
'         Snodgrass.  Submitted to the public domain and the QBNews
'         but the Copyright is reserved.  
' =======================================================================
DEFINT A-Z					' we'll use integers mostly
DECLARE FUNCTION GetBit%(Byte%, BPos%)		' BitRead routine

'GrafFile$ = UCASE$(COMMAND$)			' use this if PDQ!!!
GrafFile$ = COMMAND$				' search command line
IF LEN(GrafFile$) = 0 THEN			' if no file given
   PRINT

   ' PRINT "PSHOP - Read and display PrintShop icons on VGA"   ' unREM if PDQ

   PRINT "PSHOP - Read and display PrintShop icons on CGA"	' as defaults
   PRINT "(C)opyright 1991 by Mike Welch and Ryan Snodgrass"
   PRINT "Use /n when displaying New Print Shop graphics"
   PRINT
   PRINT "Syntax:  PSHOP Filename.dat [/n]"
   END
END IF

' Check for the /N[ew] switch and act accordingly
x% = INSTR(GrafFile$, "/N")			' check for /n[ew] PS
IF x% THEN					' switch was passed
   GrafFile$ = RTRIM$(MID$(GrafFile$, 1, x% - 1))	' strip /n from name
   n% = -1					' set boolean value
END IF

'SCREEN 13					' use this if using PDQ
SCREEN 2					' "high" [low] res CGA mode

' Uncomment the following code if you're using VGA and PDQ.  It
' will be useless in regular QuickBASIC!
'IF ERR THEN			' if not a VGA system
'   PRINT
'   PRINT "Sorry, this PDQ-compiled version requires a VGA!"
'   END
'END IF

' Uncomment this if you are using the PDQ version/option
'DEF SEG = &HA000		' this is for POKEing in VGA memory

' If you're using PDQ, you'll want to include the following
'COLOR 0, 0				' unremark if using PDQ!!!


OPEN GrafFile$ FOR BINARY AS 1 LEN = 572	' open PS file
SizeF& = LOF(1)					' get it's length
TotalPics% = SizeF& \ 572			' how many icons?
' If the /n[ew] switch was present, the boolean flag n%
' will have a non-zero value.  If so, we should strip
' the first 10 bytes from the "New Print Shop" file
' at the beginning.  All else works the same!
IF n% THEN Temp$ = INPUT$(10, #1)		' strip 10-byte header
FOR DoAll% = 1 TO TotalPics%			' process them all
   x% = 0: Y% = 1				' initialize coords
   Temp$ = INPUT$(572, #1)			' read 1 icon
   FOR i% = 1 TO 572				' process all bytes
     Pix% = ASC(MID$(Temp$, i%, 1))		' get 1 byte value
     FOR k% = 0 TO 7				' process 8 bits
  	Bit% = GetBit%(Pix%, k%)		' Bit% is 0 or 1
	' Here, I hard code the colors.  Change
	' as desired.  Refer to the SCREEN and
	' COLOR areas of the QB manual for what
	' can be legally accomplished

	IF Bit% THEN p% = 0 ELSE p% = 1
	'IF Bit% THEN p% = 1 ELSE p% = 15	' set colors for VGA

	' UnREMark what follows as desired.  I
	' have included two options.  One centers the
	' image on the screen, the other in the left.
	' Also, you can just add to the x% +... and
	' the y% +... values to position the icon whereever
	' you want it, with the PSET statement!  The second
	' PSET statement centers the icon in SCREEN 2.  Use
	' only one PSET though!
	'PSET (x% + 7 - k%, y%), p%		' print in left corner

	PSET (x% + 7 - k% + 276, y% + 74), p%	' center for SCREEN 2

	'POKE (y% - 1) * 320& + (x% + 7 - k%), p% ' write pixel at left VGA
	'POKE (y% - 1 + 74) * 320& + (x% + 7 - k% + 116), p%  ' CENTER VGA
     NEXT k%					' next BIT
     ' Although at this time we've actually only read 1 byte,
     ' it has been translated into 8 bit values, where each
     ' bit represents a pixel (on or off: 1 or 0).  Therefore,
     ' we must move the x-coordinate value over 8 places to
     ' compensate for this bit reading.  This part in particular
     ' was a tough one to analyze!  Also, if we've processed
     ' 11 bytes (11 * 8Bits = 88 pixels, which is the column value
     ' for all of the older PM/PS icons) then x% will be > than 87
     ' [or x% will = 88, whatever] so we need to move to the
     ' next "row."  This explains the y% = y% + 1 below.
     x% = x% + 8				' move COLUMN
     IF x% > 87 THEN				' if end of 1 column
         x% = 0					' reset column value
	 y% = y% + 1				' go to next ROW
     END IF
   NEXT i%					' loop for all of icon

   ' Usage note:  Press a key after each icon is printed.  If you
   ' press the ESC key, the program terminates.
   DO
	KeyCk$ = INKEY$			' check for keypress
   LOOP UNTIL LEN(KeyCk$)		' loop until keypress
   IF KeyCk$ = CHR$(27) THEN EXIT FOR	' if pressed ESC, exit loop
   CLS					' erase old pixel
NEXT DoAll				' next picture/icon
'DEF SEG				' ret DGROUP, unREM if using PDQ/VGA
SCREEN 0				' back to screen 0, text mode
END					' end program here

' ======================================================
'  Name:    GetBit%
'  Type:    FUNCTION
'  Lang:    Microsoft QuickBASIC 4.00+
'  Date:    Sept. 1990
'  Vers:    1.00m
'  By:      Richard Randles
'  Purp:    Check the bit status of any BYTE.  This is
'	    a modified version of the WORD GetBit%.
'  Syntax:  OneOrZero% = GetBit%(Byte%, BPos%)
'  Notes:   Does not process negative numbers.  This
'           routine is specific to PSHOP.BAS and is
'           designed to get the bit value of an unsigned
'           byte value, range 0-255 only.
' ======================================================
'
FUNCTION GetBit%(Byte%, BPos%)

Work% = Byte%			' backup 2 byte variable
FOR BitC% = 1 TO BPos%		' BPos% range is 0 to 7
   Work% = Work% \ 2		' shift bits right BPos% times
NEXT
GetBit% = Work% AND 1		' return Boolean: ON or OFF

END FUNCTION
