[comp.sys.atari.8bit] Unsprites -- Some documentation

fseipel@hpuxa.ircc.ohio-state.edu (Frank E. Seipel) (03/03/91)

UN-SPRITES: Copy & Paste Graphics

by Jason Leigh

 Sprites (Player/Missile Graphics) has always been the easiest method of
animating objects on Atari computers. But what about computers like the
Apple IIs and IBM PCs that do not have Sprites? They achieve animation by
actually moving parts of the graphics screen. Although this is a less
efficient method, it does have capabilities that Sprites does not; that is,
they are not limited to the 8/255 resolution that Sprites has, and they can
have as many colors as a graphics mode will allow. Un-sprites is a machine
language program that will allow you to paste or copy windows to or from any
of the 16 Atari graphics modes.

Setting Un-sprites Up

 Type in Listing 1 using BASIC Editor II found elsewhere in this issue, and
save it to disk or cassette. Executing this program will cause it to POKE
the machine-language program directly into memory. For cassette users,
append listing 1 to the end of your program that will use Un-sprites and call
a GOSUB to load in the data. Disk users should save the data at address
$6000 to $6300 using the "save binary" command in DOS.
 Two demonstration programs have been included (Listing 2 and 3) to give you
an idea of how Un-sprites can be used for animation. Listing 4 is the BASIC
equivalent of Unsprites; the BASIC program should make it easier for you to
understand the assembly listing.

Using Un-sprites in BASIC

Copying a window

 The command in BASIC to copy a window is:

COPY=USR(24842,Screen Start, StartX, StartY, EndX, EndY, Buffer Address,
         Graphics Mode)

 Screen Start is the address of the start of the screen memory. This can
easily be computed by entering the desired graphics mode and reading memory
locations $58 (88) and $59 (89). Here's an example:

10 GRAPHICS 7
20 SCRNSTART=PEEK(88)+PEEK(89)*256

 You ae not limited to just that screen area; you may also specify a totally
different memory address and copy a window from that by assigning the
appropriate values for Screen Start.

 StartX, StartY & EndX, EndY

 These specify the boundaries of the copy window. Although there is no limit
to the size of the window you can copy, it is advisable to keep the
coordinates within the limits of the declared graphics mode.

+-----------------------------------------------------------+
|                                                           |
|   (StartX,StartY)                                         |
|          *------------------------+                       |
|          |                        |                       |
|          |                        |                       |
|          |                        |                       |
|          |                        |                       |
|          +------------------------*                       |
|                              (EndX,EndY)                  |
|                                                           |
+-----------------------------------------------------------+

                         Figure 1

Buffer Address

 The window you copy must be stored somewhere in memory, and so a storage
buffer is needed. The advantage of having a user-definable buffer is that
several windows can be copied, saved, pasted and repasted as needed by
specifying the same buffer address. A buffer space can be declared at any
address where nothing else occupies the memory. This can safely be done by
dimensioning a relatively large string and using that as a buffer pool for
many windows or just one window. The alternative is to dimension many little
strings and store only one window in each of them.
 The short program segment below dimensions a string 8K in size and assigns
zeros to it. BUFFADRS holds the starting address of the string buffer.

10 DIM BUFFER$(8192)
20 BUFFADRS=ADR(BUFFER$)
30 BUFFER$(1)=" ":BUFFER$(8192)=" ":BUFFER$(2)=BUFFER$(1)

Graphics Mode

 These correspond exactly to those of the XL and XE Ataris. Graphics modes 0
to 11 are the same for all 8-bit machines, but graphics modes 12 to 15 are
defined as follows:

Graphics Mode 12: ANTIC Mode 4 (four color text mode 40/24)

Graphics Mode 13: ANTIC Mode 5 (four color text mode 40/12)

Graphics Mode 14: ANTIC Mode 12 (two color graphics mode 160/192)

Graphics Mode 15: ANTIC Mode 14 (four color graphics mode 160/192)

Pasting a Window

 The command in BASIC to paste a window is:

PASTE=USR(25077,Screen Start, StartX, StartY, Buffer Address)

 Screen Start is the address of the screen memory in which you wish to paste
the window.
 StartX, StartY specify the position to place the top-left corner of the
window.
 Buffer Address is the address of the buffer that holds data from a
previously copied window.
 It is assumed that you will past a window in the same graphics mode it was
cut from. You may, however, choose to paste it in a different graphics mode;
the effects can be quite interesting (or disasterous).
 Warning: If you accidentally omit a parameter or put them in incorrect
order, you could experience a serious lockup that will result in the loss of
your program.

Explanation

 Listing 4 is the BASIC equivalent of Unsprites. It would probably be a good
idea to flip between the BASIC and assembly listings while reading the
following explanation.

Copying

 When start and end coordinates are specified, Un-sprites will find the
closest byte that encloses those coordinates (See Figure 2).
 DX holds the width of the window and DY, the height. Before the window is
saved, these are used as headers in the buffer, as shown in Figure 3.
 The number of bytes user per window can therefore be calculated as: (DX * DY).
After DX and DY have been calculated, the top-left memory (TLMEM) location
of the window is computed. When all this is done, DX and DY will be saved to
the buffer followed by the data in the window.

Pasting

 Whereas Copy saved the entire byte that enclosed StartX and StartY, Paste
allows exact alignment. Un-sprites will automatically shift the required
number of bits to place the window at the exact StartX and StartY position.
 There are two methods of performing these shifts:

 Method 1.

      a. Calculate TLMEM
      b. Find from the shift table, the number of shifts needed
      c. Shift to the right

 Byte a i{ shifted the required number of bits to the right. Shift Store 1
acts as a bit bucket that collects all the bits that have shifted out of a.
The data in the shift store is then ORed with shifted byte b. But in order to
shift b, a separate shift store (Shift Store 2) is needed. This method
therefore requires two shift-storage registers that alternate in use, plus it
needs registers to keep track of the address of the next byte. There isn't
(at least not to me) an obvious way to alternate the use of two registers
efficiently, so I came up with an alternative method.

Method 2. (figure 5)

      a. Calculate TLMEM
      b. Add 1 to TLMEM (TLMEM+1).
      c. Find from shift table the number of shifts needed
      d. Shift to the left

 Instead of shifting to the right, we move to TLMEM+1 and shift the required
number of bits to the left. This is much easier, as only one shift-storage
register is needed; there is no intriguing alternation between two shift
registers, as in method 1.

Calculating the Shift

 The code needed to do this is:

 Shift_Pointer = STX -(INT(STX/Pixels_Per_Byte)*Pixelx_Per_Byte)

 With the shift pointer computed, the number of shifts is then found from
SHFTABLE.
 An example of calculating the shift is shown below:

 Let Pixelx_Per_Byte (PPB) = 4 and STX = 9;

 STX/PPB = 00001001 / 100 = 10 = 2 (all binary #'s);
then 2*4 = 8 and (STX-8) = (9-8) = 1

 Look up 1 in SHFTABLE4 and we get 6. That means we need to do six left-
shifts from byte to byte 1. (Figure 6)

 Note: Two PPB graphics modes (GTIA modes 9, 10, 11) need four shifts per
pixel, four PPB modes (Graphics Modes 3,5,7,15) need two shifts
per pixel, eight PPB modes (Graphics Modes 4,6,8,14) need one shift and one
PPB modes (the text modes) need no shifts.
 That should be enough information for you to tailor the Unsprites assembly
listing to your own needs. If $6000 is not a convenient location for this
program, you could always move the start of the program to another location.
The .OPT LIST command has been included so that it will always display the
new location of COPY and PASTE routines.
 Note that for larger windows that program could get rather slow, but if you
are page flipping, the window canbe made to appear instantaneously by
pasting on one screen while displaying another.
 There are many applications for windowing: animating frames, editing
graphics screens and manipulating GEM-like windows are just a few. Sprites and
Un-sprites should be the complete pair that will allow you to perform the
graphics manipulation you've always wanted on that Atari. Enjoy.


                                     Saved Window
(StartX, StartY)                         \/
    +----------+----------+----------+----------+----------+
 /  | Enclosing|          |          |          |          | 
 |  |   Byte   |          |          |          |          | 
 |  |          |          |          |          |          | 
 |  +----------+----------+----------+----------+----------+
 |  |          |          |          |          |          | 
 |  |          |          |          |          |          | 
 |  |          |          |          |          |          | 
DY  +----------+----------+----------+----------+----------+
 |  |          |          |          |          |          | 
 |  |          |          |          |          |          | 
 |  |          |          |          |          |          | 
 |  +----------+----------+----------+----------+----------+
 |  |          |          |          |          |          | 
 |  |          |          |          |          |          | 
 \  |          |          |          |          |          |
    +----------+----------+----------+----------+----------+
                                                       (EndX, EndY)
      \_______________________DX__________________________/

                             Figure 2.



+----------+----------+----------+         +----------+----------+
|  Start   |          |          |         |          |          | 
|    of    |          |          |  * * *  |          |          | 
|  BUFFER$ |          |          |         |          |          |
+----------+----------+----------+         +----------+----------+
    Dx          Dy      \______________window data______________/



                             Figure 3.

 Sorry, I haven't the patience to key in the other figures; you'll have
to 'figure' them out on your own!