Version 2.1 of PSTUFF (Unit of fast graphic/sprite routines 
                        for Atari Portfolio)
(C) 1994 Robert Quezada

Contains simulation routines so it will work on an IBM (intended for
    design purposes only)

  The following are procedures and functions in this unit I designed
  for Turbo Pascal 7.  Its main use is for high speed graphics use and 
  can be best utilized in game designing.
  
  These routines are the most recent version and is one version after
  the version that Punkman jr 2 was designed with.

  MAIN FEATURES:
    32  (8x7) sized sprites (graftype)
    240x200 scrollable screens
    Simulates Portfolio graphics on an IBM allowing for easy development
        of games on the IBM
 
 Place the TPU file in the "EXE & TPU " directory.  Check under the 
 DIRECTORIES menu under Turbo Pascal 7 for this path.

 CONSTANTS
 =========
  screenheight;
     Height of the Portfolio graphics screen in pixels

  totalsprites=32;
     Total amount of sprites supported

  screenlinelength;
     Number of bytes that compose one screen line

  screenlength=screenlinelength*200;
     Size of screens {equivalent to 240*200 resolution}

  onescreensize=screenlinelength*screenheight;
     Size of the regular graphics screen

 TYPES
 =====
  graftype=array[1..7] of byte;
     Used for all sprites, letters, and PUTSCREENS.  These represent an
     8x7 graphics shape.

  doublescreen=array[0..screenlength] of byte;
     This type is used when defining screens.

  windowscreen=array[0..8,0..40] of byte;
     This type is used when defining windows for use in "moveable" screen
     routines.

 VARs
 ====
  FULL_GRAPH:graftype;
     Every bit in this array is on.  i.e. every byte value is 255.

  null_graph:graftype;
     Every byte value in this type is 0.  Can be used as a mask in
     PUTDIRECTMASKED or CHANGESPRITE when no mask is needed.

  sprite:array[0..totalsprites] of
   record
    SLOW:boolean;
      By default this is FALSE, but if set to TRUE, the sprite will be
      erased from its previous position and then displayed in its new
      position.
    used:boolean;
      Used by UPDATESPRITES to determine whether to draw the sprite when
      updating.
    pos_x,pos_y:integer;
      Horizontal and vertical positions of sprite.
    oldpos_x,oldpos_y:integer;
      Used by UPDATESPRITES to tell where the previous position of the sprite
      was so it can be cleared if SLOW is set to TRUE.
    grafsprite:graftype;
      This is the sprite shape to be drawn.
    masksprite:graftype;
      Mask value of sprite.
   end;

  HORIZLIM:byte;
    This must be divisble by 8 and tells updatesprite what point not to draw
    past when using PUTSCREEN.

  SCANCODE:byte;
    This value is changed by KEYHIT and tells the scancode of the key
    pressed.  Needed when reading arrow keys, function keys, etc.

  LCDPOSITION:integer;
    This value should NOT be changed by the programmer, but used only as a
    reference to the position of the "virtual" screen.

  DOUBLELOGIC:doublescreen;
    Logical screen buffer used for sprite updating, APPEAR, and other
    routines.

  DOUBLEBACKG:doublescreen;
    Background screen buffer used for sprite updating mostly.  When a sprite
    is drawn, the background screen is taken into account and the sprite is
    placed on top of it.

  LETR:array[0..42] of GRAFTYPE;
    These represent the letters used by RITE and other related RITE routines.

  LCD_OK:boolean;
    This returns TRUE if running on a Portfolio and FALSE if running on
    an IBM.

  INT60,INT61:boolean;
    Returns TRUE if INT $60/INT $61 is valid.  It's TRUE when using
    Portfolio emulation software from Atari or when using the Portfolio.



                                ROUTINES
                                --------

 PROCEDURE LOADLETTERS(n:string);
    Loads the graphic letters used by the RITE commands.  Can be changed to
 any shape of letter (8x7) in size.

 DIRECT to LCD ROUTINES
 ----------------------
   FUNCTION reverse(V:BYTE):BYTE;
      A fast assembly language routine that reverses the bits in one BYTE.
      Used for direct to LCD writes.  i.e. %00100110 will become %01100100

   PROCEDURE setlcdcursor(i:WORD);
      Sets the LCD drawing cursor to "I".

   PROCEDURE putlcdcursor(i:BYTE);
      Places a value at the current LCD drawing position and increases the
      LCD drawing cursor by one.

   PROCEDURE pokedirect(ad:WORD;v:BYTE);
      Puts a BYTE at a location on the screen.

   PROCEDURE appear(VAR screen:doublescreen);
      Causes the screen at "SCREEN" to be copied to the logical screen and
      its visible portion, depending on where the screen's vertical position
      is, will be quickly shown.

 SCREEN MANIPULATION ROUTINES
 ----------------------------
   PROCEDURE getscreen(VAR screen:doublescreen;x,y:INTEGER;VAR n:graftype);
        Copies an (8x7) block from the position at (x,y) on screen "SCREEN"
        and puts in into "N"

   PROCEDURE copyscreen
    (VAR SOURCE:doublescreen;x,y:INTEGER;VAR DEST:doubleSCREEN;x1,y1:INTEGER);
        Same as GETSCREEN, but puts it to another screen.

   PROCEDURE copylogic2lcd(x,y:INTEGER);
        Copies an (8x7) block from (x,y) on the logic screen direct to the
        LCD at the same location.

   PROCEDURE putdirect(x,y:INTEGER;VAR n:graftype);
        Places a graftype (8x7) image to the LCD at (x,y).  X is to be
        divisible by 8.

   PROCEDURE putdirectmasked(x,y:INTEGER;VAR n,masked:graftype);
        Same as PUTDIRECT, but allows a masked image to be placed.

   PROCEDURE putscreen(VAR screen:doublescreen;x,y:INTEGER;VAR n:graftype);
        Puts a graftype (8x7) image to the "SCREEN" at (x,y).  X is to be
        divisible by 8.

   PROCEDURE putmaskedscreen(VAR screen:doublescreen;x,y:INTEGER;VAR n,msk:graftype);
        Allows you to put a masked image onto the "SCREEN" at (x,y).

 WINDOW DISPLAYS
 ===============
      While these are not windows as in the Windows for the PC or the
 GEM on the Atari ST/STe/TT/Falcon030 computers, these are routines primarily
 used as a bigger graftype image and allow the programmer to make a "virtual"
 small screen.

 PROCEDURE moveablewin(x,y:INTEGER;VAR what:windowscreen);
        This routine copies, from one of the "screens" in memory, a section
        of the screen to a "window".  This position can be anywhere on that
        "screen" and can be used to give the illusion of horizontal scrolling
        but have it displayed later in a smaller window.

 PROCEDURE windowdisplay(x,y:integer;VAR what:windowscreen);
        This displays the window on the screen at (x,y).  X must be divisible
        by 8.


 "VIRTUAL" SCREEN ROUTINES
 =========================

        These routines are designed for displaying and manipulating the
 240x200 screen on the Portfolio.


 PROCEDURE slidescreen(dest:INTEGER);
        This slides the screen from its current location to the location
        specified in DEST.  Its results are quite fast.

 PROCEDURE movescreen(i:INTEGER);
        This routine is called by SLIDESCREEN and is used to do the actual
        moving.

 PROCEDURE locatelcd(i:INTEGER);
        Tells the program what part of the "virtual" screen is to be shown.


 MISCELLANEOUS ROUTINES
 ======================

 PROCEDURE convert(n:string);
        This takes an 8 character string of periods and 'X' and converts
        it into a byte (used with GRAFTYPE).  The 'X's are used to
        indicate on and a period is used to indicate off.

        i.e.:  convert('...XX..X')  is equivalent to binary 00011001

 PROCEDURE melodytone(note:BYTE;length:WORD);
        Plays a note of a specified length from the Portfolio's speaker.

 FUNCTION keybuffer:boolean;
        Returns TRUE if a key was hit.  This routine is written in assembly
        language and takes up very little space.

 FUNCTION keyhit:char;
        Returns the value of the key hit.  Also, places the scancode of the
        key hit into a global variable: SCANCODE.


 INT $10 ROUTINES
 ================

 PROCEDURE videomode(i:BYTE);
        Sets the video mode of the computer.  Sending 4 will put the IBM
        into CGA graphics mode and the Portfolio into regular graphics mode.
        While sending 3 will put the IBM and Portfolio back into text mode.

        
        
 NOTE:  The box, plot, and line drawing will only show up on the regular
        240x64 graphics screen.

 PROCEDURE pbox(X1,Y1,X2,Y2:WORD;c:BYTE);
        Draws a box from (x1,y1) to (x2,y2) on the screen.

 PROCEDURE pplot(X,Y:WORD;C:BYTE);
        Plots a dot at (x,y)

 PROCEDURE hline(X1,X2,Y1:WORD;C:BYTE);
        Draws a horizontal line from (x1,y1) to (x2,y1)

 PROCEDURE vline(y1,y2,x1:WORD;C:BYTE);
        Draws a vertical line from (x1,y1) to (x1,y2)


 TEXT DISPLAY
 ============
    All of these routines require that the text letters are loaded in
    using LOADLETTERS, or unknown shapes will appear instead of the
    letters.

 PROCEDURE CENTER(Y:INTEGER;N:STRING;B:BOOLEAN);
        Will center a string at the Y vertical position

 PROCEDURE rite(xx,yx:INTEGER;n:string;B:BOOLEAN);
        Will show a string using the letters loaded with LOADLETTERS
        at (xx,yx)  When B is TRUE, the text will be copied to the
        background screen.

 PROCEDURE LOGICRITE(xx,yx:integer;n:string;B:BOOLEAN);
        Similar to RITE, but this routine will not display the string.
        It will only be placed on the DOUBLELOGIC screen.


 SPRITE ROUTINES
 ===============

 PROCEDURE movesprite(x,y,sp:INTEGER);
        This will move the sprite #SP to position (x,y), but will not display
        it.

 PROCEDURE updatesprites(display:boolean);
        This updates all the sprites and their positions to the LCD and
        logic screens.  If DISPLAY is TRUE, then the sprites will be drawn
        to the display.  If DISPLAY is FALSE, the sprites will only be drawn
        on the DOUBLELOGIC screen.  Using FALSE can be useful when using the
        moveable windows and sprites at the same time.
 
 PROCEDURE SPRITEOFF(SP:INTEGER);
        This will remove a sprite from the screen.

 PROCEDURE changesprite(sp:INTEGER;VAR graf,msk:graftype);
        By using this, the sprite can be changed to any masked shape.  Useful
        when doing animations.


------------------------------------------------
Send any inquiries or comments to me via e-mail:
        CompuServe: 72122,2651
  or you can post the messages in the RoundTable
  so more will benefit.
------------------------------------------------

These routines can be used in any of your programs, without limitation.
All that I require is that you mention that you used these routines.

Have fun with these routines!

Rob Quezada


