
     /####\  ######\  ######\   ####   ###\   ##  ##  /#/  ##      ######
     ##/     ##   )#  ##   )#    ##    ##\#\  ##  ## /#/   ##      ##
     \####\  ######/  ######/    ##    ## \#\ ##  ##<#<    ##      #####
        \##  ##       ##  \#\    ##    ##  \#\##  ## \#\   ##      ##
     \####/  ##       ##   \#\  ####   ##   \###  ##  \#\  ######  ######

                         1 9 9 5   S t r a y l i g h t

_____________________________________________________________________________


                                About Sprinkle

	Sprite areas are just big blocks of memory with lots of sprites in,
	and this is all well and good.  Until you want to add some more
	without making the whole area move.

	The problem becomes particularly awkward when you start writing
	extendable applications (e.g., using Straylight's Dynamic Linking
	System) and you want to allow each extension DLL to have its own
	sprites file which are joined to the main one.

	There are traditionally three possible solutions to the problem:

	 1. Forget it.  Force the sprites to be in the main application's
	    sprites file.  Extensions can't have their own sprites, or
	    they have to merge them with the main file at installation
	    time

	 2. Make the block bigger and then merge the files.  This will cause
	    your heap to fragment, and the sprite area to move, so you
	    mustn't have any windows created which use the sprite area.
	    Alternatively, you could put the sprite area at the bottom of a
	    shifting heap, and extend it there, so that the area itself
	    doesn't move.  This prevents you from having a non-shifting heap
	    there, though.  I think this is the approach which ArtWorks uses.

	 3. Make each extension have its own sprite area, which it has to
	    manage itself.  This makes it awkward to use shared sprites
	    from the kernel's sprite file, and can be wasteful of space.

	Sprinkle is `Option 4 -- make the Operating System nicer.'

_____________________________________________________________________________


                              The basic concept

	The whole problem outlined above is caused by the sprite areas being
	in big contiguous blocks.  It would all go away if you could instead
	put sprites into linked lists, which you could extend at run-time
	without any of the heartache normally caused by this.  Sprinkle is
	a small patch which allows you to link sprite areas together, so
	you can access a sprite in any of the linked areas just by pointing
	at the first one.

_____________________________________________________________________________


                          Linking your sprite areas

	Sprinkle simply extends the functionality of OS_SpriteOp.  It doesn't
	have any SWIs of its own.  It makes use of a special part of the
	sprite area definition called the `extension area', which as far as
	I can make out is not defined anywhere.

	You identify a sprite area as being linked by putting the following
	data into the extension area:

		Offset	Size	Value
		0	4	&4B4C5053 (`SPLK')
		4	4	Address of next sprite area, or 0

	The list is terminated either by a sprite area which doesn't
	have this data in its extension area, or by a 0 pointer in its
	link word.

	Loading a sprite file into an area and allowing it to be linked is
	fairly simple:

	[In basic]

	SYS "OS_File",17,name$ TO ,,,,sz%
	DIM blk% sz%+16
	blk%!0=sz%
	SYS "OS_File",16,name$,blk%+4+8,0
	blk%!4=blk%!12
	blk%!8=24
	blk%!12=blk%!20+8
	$(blk%+16)="SPLK"
	blk%!20=0

	[In assembler]

	; On entry:	R0 == pointer to filename

			MOV	R1,R0
			MOV	R0,#17
			SWI	OS_File
			ADD	R0,R4,#16
			BL	alloc	 ;allocate r0 bytes, return in r0
			STMFD	R13!,{R0}
			ADD	R2,R0,#12
			MOV	R3,#0
			MOV	R0,#16
			SWI	OS_File
			LDMFD	R13!,{R0}
			ADD	R14,R0,#12
			LDMIA	R14,{R1-R3}
			MOV	R2,#24
			ADD	R3,R3,#8
			LDR	R4,=&4B4C5053
			MOV	R5,#0
			ADD	R14,R0,#4
			STMIA	R14,{R1-R5}

	; On exit:	R0 == pointer to area
	;		R1-R5, R14 corrupted

	(Obviously you need to do some more error checking than this code
	has done.)

_____________________________________________________________________________


                                 Restrictions

	Sprinkle isn't intended for really heavy use -- ensuring that all
	the OS_SpriteOp calls worked exactly as expected on linked areas
	would be fairly prohibitive in terms of effort.  Instead, it does
	a `reasonable' job on the read-only SpriteOp calls.  It provides
	enough support to allow you to use sprites from linked areas in
	your dialogue boxes, and that's about it.  If you do try writing-
	type operations which don't have enough memory, they will probably
	fail with strange errors (like `Sprite not found').

_____________________________________________________________________________
