
		Source Docs
		===========

 This file is biased towards the VSprite source. There is a reason for
this, the other code hase been covered before in other incarnations.


 Start.s
 -------

 This is the basic startup routine I developed for disc 13. The code opens
an Intuition window and waits for the user to click on the close gadget.

 The event loop is set up to deal with gadget selection. The address of the
subroutine to call when a gadget is selected should be stored in the
UserData field. See the Intuition tutorial on this disc for more
information.

 ilbm.code.s
 -----------

 This is Steve Marshalls ILBM loader code from disc 12. I have used this
code in two example programs this month. See disc 12 for more information.

 IFF2INT
 -------

 This is the start of a utility program I am writing. When complete it will
be able to load an ILBM picture and save this as either an Intuition Image,
an Intuition Gadget or as RAW data.

 The idea is to make the creation of illustrative Gadgets easier. When a
gadget ( or Image ) is saved, the assembly structure will be saved with it.

 At present an ILBM file can be loaded and a saved as an Image ( along with
a correct Image structure ). Be warned that this is not functioning
correctly yet as all images are assumed to be 8 words wide ( a balls up on
my part ). This will be fixed by next month.

 All details about the image are obtained from the extended bitmap
structure returned by Steves loader code. I have also included a subroutine
to view the graphics once loaded. This was again written by SM.

  SlideShow
  ---------

 Another experiment using Steves ILBM loader code and viewport display
routines.

 When run, this program will look for a file called Muzak in the current
directory. If found this file will be loaded and played ( using
NoiseTracker replay routine I put together for PPPlay ).

 Once the music has started the show begins. The program expects to find a
collection of IFF ( ILBM ) files in the current directory. These should be
named a, b, c, d, e,........ Each picture is displayed in turn.

 Use the left mouse button to quit and the right button to step forward.

 I used a subroutine to display a blank view between each piccy, this could
be changed to a title page or even a basis for a scroll text.

 VSprites
 --------

 Where do I start with this lot?

 I have owned the RKM Libraries and Devices manual for a few months now and
for most of this time I have been thinking about tackling the graphics
library GELs ( Graphic ELements ) and Animation system.

 Problem: All examples are in C. We're talking heavy C here.

 Solution: Convert C to assembler.

 'This seems quite straight forward', I thought. What a mug!

 The C code revolves around a suite of subroutines designed to make the
GELs system easier to handle. I have built up an equivalent assembler suite
of routines and jumbled these into a file called animtools.s

 As well as subroutines this file contains structures designed to make the
allocation of VSprites and Bobs easier. I have yet to progress to the
animation section, but will try to have this ready soon.

 Once I had built the file animtools.s, I wrote a few example programs. A
couple of these are adaptions of the C examples in the RKM manual while
others are experiments of my own.

 Before looking at the source, let me explain the GELs system a little
further. 

 Simple Sprites :	These are hardware sprites, such as the mouse
			pointer. Simple Sprites are restricted to a width
			of 16 pixels and consist of only 4 colours.

 Bob :			A bob is a Blitter OBject, a sprite that is shoved
			into a playfield by the blitter. A Bob can be any
			size and can consist of any colour in the playfield

 VSprites :		A VSprite is a GEL maintained by the GELs system.
			A True VSprite is based on a Simple Sprite, though
			a Bob is also described by the VSprite structure.

 The GELs system is coordinated through the GelsInfo structure attached to
all rastports. If you wish to display a Bob or Simple Sprite in a
particular rastport ( such as an Intuition window ) you must initialise a
VSprite structure that describes the Simple Sprite and attach this to the
rastport.

 The GELs system does not draw a VSprite unless instructed to do so. This
means that it is up to the calling task to syncronise any drawing to the
video beam in order to eliminate flickering. Not an easy task in a multi-
tasking enviroment!

 The GELs system cannot be told to display a particular VSprite, it can
only be instructed to refresh ALL VSprites attached to a particular
rastport.

 Before the VSprite list attached to a rastport ( via the GelsInfo ) the
list must be sorted into a suitable order. There is a function to do this
in the graphics library. The list is sorted so that VSprites in the top
left of the display are drawn before sprites in the bottom right. This
sets up a pseudo priority for each sprite, though control of this is
allowed. I may cover this later.

 So lets sum all this up in a diagram:
					     ___ VSprite ____ Bob
 ________________	 		    /
 |		|			   /
 |		|  _________    __________/
 |		|  |	   |   | 	  |----- VSprite ---- Bob
 |  Display 	|--| RPort |---| GelsInfo |----- VSprite ---- Simple Sprite
 |		|  |_______|   |__________|----- VSprite ---- Simple Sprite
 |		|			  \
 |______________|			   \
					    \___ VSprite ____ Bob
  

 This shows how 2 simple sprites and 3 bobs would be linked to a GelsInfo
by their VSprite structure. The link from GelsInfo to the display, via the
rastport, is also shown.

 So where do you start? Well, I used my old faithful start.s to provide a
rastport ( check the source, the windows rastport address is stored at
label window.rp ).

 Next we need a GelsInfo structure, so I'd better explain this. The
GelsInfo structure contains pointers to various other structures that the
GELs system requires. For instance there are pointers to the Head and Tail
of the VSprite list to be displayed in this rastport ( both of these are
dummy VSprites that do not actually get displayed ). There is also a
pointer to a matrix of 16 long words, each long word can contain the
address of a collision routine that will be called when a suitable
collision occurs.

 This all sounds very complicated. To simplify life there is a subroutine
that will allocate memory for and initialise a GelsInfo structure. The
subroutine will even attach this structure to the rastport for you. If you
are not interested in collision detection, just calling this subroutine is
all that is required to set up a GelsInfo structure ( why didn't I just say
so earlier ??? ). The subroutine is called SetUpGelSys.

 Here is a description of the subroutine taken from the file animtools.s:

Entry		a0 must hold the address of an initialised rastport
		d0 must contain reserved sprite mask

Exit		d0 will contain the address of the initialised GelsInfo
		structure or 0 if a memory allocation error occurred.

 So what is the reserved sprite mask? You can specify which Simple Sprites
not to be used by the VSprites in this GelsInfo. For instance, I am using
an Intuition window, so I do not want the mouse pointer to suddenly
transform into a rampant alien, I must protect the Simple Sprite ( sprite 0 )
used by Intuition from the GELs system. This is done by clearing bit zero
of the mask word, ie using a mask of %11111110 or $FE. To be safe I have
used $FC or %11111100, so sprites 0 and 1 will not be used.

 An example call would be:

		move.l		window.rp,a0		rastport
		move.l		#$FC,d0			sprrsvd
		jsr		SetUpGelsSys		init GelsInfo
		move.l		d0,MyGINFO		save it's addr
		beq		error			quit if no mem

 Once the GelsInfo has been attached to the rastport we can start adding
VSprites. To do this we need to know what a VSprite is and how to set one
up:

 A VSprite ( Virtual Sprite ) is a block graphic that will be displayed on
the screen. It can be moved about the screen under software control and
collisions with other VSprites can be detected. Beyond the scope of this
months discussion ( monologue ) VSprites can also be linked together to
form animation objects in which the whole moves as one and the individual
components move relative to each other ( I cant wait to get onto this ).

 The VSprite structure itself is a daunting beast so I'll take the easier
RKM method and introduce a shorter, easier to use version ( cop-out version
). Here is the NewVSprite structure, defined in animtools.s:

nvs_Image	<LONG>		address of image data ( the graphics )
nvs_ColourSet	<LONG>		address of colour array ( word values )
nvs_WordWidth	<WORD>		width of the sprite ( in words )
nvs_LineHeight	<WORD>		height of the sprite ( in raster lines )
nvs_ImageDepth	<WORD>		depth of image ( num of bitplanes )
nvs_X		<WORD>		Starting X position
nvs_Y		<WORD>		Starting Y position
nvs_Flags	<WORD>		Simple Sprite, Bob, etc.
nvs_SizeOf	<WORD>		Size of this structure in bytes

 Please note that this structure is not compatible with the graphics
library functions, it is for use with the MakeVSprite subroutine in
animtools.s file only!

 I will explain a couple of the fields in this structure and then give an
example. I hope this is easier than ploughing through loads of theory.

nvs_Image
~~~~~~~~~
 This should contain the address of the image data which must be in CHIP
ram. If you are defining a Simple Sprite the data for the planes must be
interleaved, just as if you were setting the sprite up using the hardware:

		1st word of bpl 1
		1st word of bpl 2
		2nd word of bpl 1
		2nd word of bpl 2
		 :   :   :   :  :
		 :   :   :   :  :
		 :   :   :   :  :
		nth word of bpl 1
		nth word of bpl 2

 If you are setting up a Bob, planes should be stored consecutivley:

		1st word of bpl 1
		2nd word of bpl 1
		3rd word of bpl 1
		 :   :   :   :  :
		 :   :   :   :  :
		 :   :   :   :  :
		last word of bpl 1

		1st word of bpl 2
		2nd word of bpl 2
		3rd word of bpl 2
		 :   :   :   :  :
		 :   :   :   :  :
		 :   :   :   :  :
		last word of bpl 2

 and so on for all the bitplanes.


nvs_Flags
~~~~~~~~~

 Here's the fun part. For now I will only describe the supported types
Simple Sprites and Bobs.

 { I've been staring at this screen for ages now ---- mental block. Time to
take a break }

 If this VSprite is describing a True VSprite ( Simple Sprite )  set this
flag to 1. If it is describing a Bob, set equal to zero. 

nvs_ColourSet
~~~~~~~~~~~~~
 If you are defining a True Vsprite, this field should point to a table of
three words of data that the system will push into the hardware colour
register used by the Simple Sprite ( the fourth colour is transparent ).

 Although the system is only equipted with 8 hardware sprites, the GELs
system can reuse a sprite dma allowing more than 8 VSprites to be
displayed.

 The other fields define the dimensions of the sprite and it's starting
position. If you are defining a True VSprite, the width will always be one
word ( 16 pixels ) and the depth will always be 2 planes ( four colours ).

 A word of warning about x,y positioning. For True VSprites ( simple
sprites ) (0,0) is the top left corner of the rastport. If using an
Intuition display, this is top left of the video display area. A Bobs (0,0)
position is the top left of the bitplane it is going to be rendered into.
If you are using an Intuition window this is the top left of the window.
This confused me a little to start with.

 Here is an example of a NewSprite structure defining a True VSprite:

MySprite	dc.l		SprData		ptr to Image Date
		dc.l		SprCols		ptr to colours
		dc.w		1		width	( True VSprite )
		dc.w		4		height
		dc.w		2		depth	( True VSprite )
		dc.w		160		x pos
		dc.w		100		y pos
		dc.w		1		VSPRITE ( True VSprite )

 Somewhere in a CHIP data section you will have to define the image data
and colours assosiated with this structure:

		section		vs,data_c

;				bpl1 , bpl2  < as binary for illustration >

SprData		dc.w		$7ffe,$80ff 0111111111111110 1000000011111111
		dc.w		$7c3e,$803f 0111110000111110 1000000000111111
		dc.w		$7c3e,$803f 0111110000111110 1000000000111111
		dc.w		$7ffe,$80ff 0111111111111110 1000000011111111


SprCols		dc.w		$f,$f00,$ff0


 Once a VSprite has been set up like this, we can add it to the GelsInfo by
calling MakeVSprite. This subroutine is in the file animtools.s. The
subroutine is called with the following information:

Entry		a0 must point to a NewVSprite structure.

Exit		d0 will hold the address of the VSprite structure created
		or a 0 if memory allocation error occured.

 So a suitable call for the above structure would be:

		lea		MySprite,a0	a0->NewVSprite
		jsr		MakeVSprite	and add it to GelsInfo
		move.l		d0,spr.ptr	save add of vsprite
		beq		error		quit if error

 If you have more than one VSprite, just repeat the above code for each
one.

 Now the VSprites are attached to the GelsInfo. They are still not visible
in the display yet as we have not instructed the system to display them. To
do this two system routines must be called, SortGList() and DrawGList().

 SortGList() must be called to sort the VSprites into order prior to
display.

 SortGList ( RastPort )
		a1

 DrawGList ( RastPort, ViewPort )
		a1	  a0

 The address of the ViewPort is obtained by calling the Intuition function
ViewPortAddress:

 ViewPortAddress ( Window )
		     a0

 To save having to keep calling this function, the address can be stored in
a variable:

		move.l		window.ptr,a0		a0->window
		CALLINT		ViewPortAddress 	get addr of viewport
		move.l		d0,window.vp		and save it

 Now we can display the VSprites:

		move.l		window.rp,a1		a1->rastport
		CALLGRAF	SortGList		sort sprites
		move.l		window.vp,a0		a0->viewport
		move.l		window.rp,a1		a1->rastport
		CALLGRAF	DrawGList		and display sprites

 The VSprites are now visible on the display!

 To be able to move or animate the VSprites you need to know about a couple
of the fields in the VSprite structure, the address of which was returned
by the subroutine MakeVSprite:

vs_Y ( word value )
~~~~~~~~~~~~~~~~~~~
 The Y position of the sprite. Change this to move the VSprite.

vs_X ( word value )
~~~~~~~~~~~~~~~~~~~
 The X position of the sprite. Change this to move the VSprite.

vs_ImageData ( long word address )
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 The address of the data that defines what appears on the display. Change
this for very simple animated sequences.

vs_SprColors ( long word address )
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 The address of the colours to use if this is a True VSprite. Change this
to point to a new set of colours.

 Altering any of the above fields is not enough to effect the image being
displayed. After making the required changes calls should again be made to
SortGList() and DrawGList(). The updated information will then come in to
play.

 To move a sprite around you need some sort of timing sequence. I use
INTUITICKS as sent by Intuition on a ( fairly ) regular basis. This serves
for demonstration purposes, but would not be sufficient for any real
programming.

 As an example, to add 1 to the X,Y position of a VSprite:

		move.l		spr.ptr,a0		a0->VSprite
		addq.w		#1,vs_X(a0)		inc x pos
		addq.w		#1,vs_Y(a0)		inc y pos

		move.l		window.rp,a1		a1->rastport
		CALLGRAF	SortGList		sort sprites
		move.l		window.vp,a0		a0->viewport
		move.l		window.rp,a1		a1->rastport
		CALLGRAF	DrawGList		and display sprites


 I am not going to cover collision detection at this point. It's to
involved. I have included a collision detectionroutine in the VSprite.s
example code, refer to the RKM Libraries and devices for more info.

 When you have finished with the Gels system, all memory allocated by the
subroutines in animtools.s must be released. This requires two subroutines
to be called: FreeVSprite and CleanUpGelSys.

 CleanUpGelSys

Entry		a0 must hold address of rastport.

 FreeSprite

Entry		a0 must hold address of VSprite struct supplied by
		MakeVSprite.

 So to free the example VSprite and GelsInfo the following fragment could
be used:

		move.l		spr.ptr,a0	a0->VSprite
		jsr		FreeVSprite	and free sprite
		move.l		window.rp,a0	a0->rastport
		jsr		CleanUpGelSys	remove GelsInfo

 That takes care of True VSprites, Bobs offer more potential. To create a
Bob you must set up a NewBob structure and then call MakeBob from
animtools.s. MakeBob will build the required NewVsprite structure from the
information contained in the NewBob structure and then calls MakeVSprite
for you. This makes creating Bobs and True VSprites appear to be two
distinct processes. Do not forget that a Bob is still defined by a VSprite
structure and the same method of movement and animation is used.

 The NewBob structure then:

nb_Image	<LONG>		address of Image Data (CHIP)
nb_WordWidth	<WORD>		width of bob in words
nb_LineHeight	<WORD>		height of bob in lines
nb_ImageDepth	<WORD>		depth of image in raster lines
nb_PlanePick	<BYTE>		planes to put image in
nb_PlaneOnOff	<BYTE>		what to do with other planes
nb_BFlags	<WORD>		bob flags
nb_DBuf		<WORD>		1=double buffer 0=not
nb_RasDepth	<WORD>		depth of destination raster
nb_X		<WORD>		initial X position
nb_Y		<WORD>		initial Y position
nb_SizeOf	<WORD>		structure size in bytes

 Firstly forget double buffering for now, you need to set up a double
buffered display and thats beyond the scope of this little discussion.
So always set this field to zero.

 What of the other fields. PlanePick and PlaneOnOFF work the same as for
Images ( last months Intuition tutorial, which I'm sure you've read ). By
setting bits in these masks you determine which bitplanes of the display
the bob gets drawn in and what happens to the other plane.

 You must set the RasDepth to the display depth, in the case of the
WorkBench screen this is two planes. All other fields should be set as for
a VSprite image, in fact these fields are used to set up the NewVSprite
structure by the MakeBob routine.

 If the bob has the same depth as the raster, then the PlaneOnOff byte has
no meaning since the bob occupies all bitplanes.

 The BFlags field needs some explaining. If you set this to SAVEBACK then
the bob can be moved over a display without destroying any data already
visible. The system stores a copy of the display under the bob and replaces
this when the bob is next moved.

 What more can I say? The routines for making and freeing a bob are in the
file animtools.s, they are called as follows:

 MakeBob

Entry		a0 must hold the address of an initialised NewBob structure

Exit		d0 will contain the address of the VSprite structure
		created or a 0 if a memory allocation error occured.

 FreeBob

Entry		a0 must hold the address of the VSprite returned by MakeBob

		d0 must hold the depth of the display. This is required for
		memory deallocation.

 There are a number of Bob examples in thisa directory, as you will see
using Bobs is very similar to using True VSprites.

 The examples range from conversions of the C programs in the RKM book to
some extensions of my own.

 If there is room left on this disc when I have put everything else on it
I will include an executable example of what is possible using the GELs
system. The example will be taken from the RKM PD disc. This contains all C
source examples from the Libraries and Devices manual along with the
executable version.

 I hope to develop the file animtools.s so that programs like this are easy
to create in assembler. I will be working towards an assembler version of
this example.  

 ShowFile.i
 ~~~~~~~~~~

 This is another text file viewer subroutine. When called, the option to
supply a pointer to a NULL terminated filename is supported. This pointer
should be passed in register D0.

 This subroutine was cribbed from the PPMMore program I wrote a while ago.

 As an extra from last month, files may be loaded into and saved from this
subroutine. PowerPacked subroutines still not supported, though only the
Save routine need be altered!

 There are instructions at the start of the source.

 Well that's it for now. More to come next month.

						  Mark.
