/####\ ######\ ######\ #### ###\ ## ## /#/ ## ###### ##/ ## )# ## )# ## ##\#\ ## ## /#/ ## ## \####\ ######/ ######/ ## ## \#\ ## ##<#< ## ##### \## ## ## \#\ ## ## \#\## ## \#\ ## ## \####/ ## ## \#\ #### ## \### ## \#\ ###### ###### © 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'). _____________________________________________________________________________