Archive(d!AmnesiaEg4<!BootVEV$!HelpElL#i!RunfEerf!SpritesPE{Pg!Sprites22E$Amnesia>E> Amnesia0>E@O>oIAmnesia2>ET>WAmsHelpE5<!ReadMeE\l2:?Basics,E,ColCheckIE%+IOFlagsEe BModules\Eȅ\OverView E + ProcessEs  dKStartHeref Ef7[f d)SWIDocscE|;c4TechnicalE6<Header;E|;ϘObjFoundEk.PlotCodeE?- ںReadMeEs9Windowsy Ef]hy 1HelpTextEO`!FastSprE7< !BootEJI!HelpD|beN!RunrD0T3r!SpritesD(5Ec!Sprites22\ D/i\ FastSpr4 BWYi}4 FSprHelpEd8<History[Eg[[ManualESWIDocsEHelpTextEf"?)!FSPConvEI9<!FSPConvy$EM{+!HelpObey$EJ5!Run. FileData!Help !StasisE;< !BootallacAE_EHAv!HelpallacDN!RunWallacdD.kNd!SpritesacDKqx]!Sprites22\ DW\ AlienallacEH<< DataVoxEZ<< AlSourceacE)p ConvTab1acE|+ConvTab2acE#|z,ConvTab3acEE|.ReadMellacnEgA%:n)/SetupallacE|/StasisDVoxEʹ/CSI::Wallace.$.Final.Freeware.GaesRawE=< AlSourceacEjE{17ReadMellacE{AFHStasisRawcE@,[ICSI::Wallace.$.Final.Freeware.GaesHelpTextacEKLStasisllacDEcADiMStasisHelpEy>< ManualE#qaSWIDocsE4:CTechnicalE>< HeaderllacE{N$CSI::Wallace.$.Final.Freeware.GaesCSI::Wallace.$.Final.Freeware.Gaes3rdPartyE?<1erE4?<|!CircleDemEI?<0X!helprEk#r9!RunerE06 !RunImager EYZ" AMNExtendrE'0FSPSprites4Enb4Eer|!Run file for !AmndiaReadMer"E"f Eer|!Run file for !AmndiaExamplesE@<!BallBncn E@<P!HelpaE}a!RunEL*1!RunImageqBכDq!RunImage0+E HF+Commented E2 FSPSpritesE} &%ReadMe|E |:9Spritesh+E}9.!Boot Set/mnShipEOzUnCruchedBn҇VoicesED<bigzapRun Dj}Bonus Run ,DSf&,Explo Run ,@DKD,@mnesia Run .!Boot Set/mn!ScrlText EE<!HelpaE}a`!RunEsjx/y!RunImage] E] FSPCharspcE&!a3pcH!SpeedTestEF<!RunBJ9`!RunImage!EҖ_!bFSPSpritesXE X[eSprites8EgX>8~ReadMeRun KE^oK3StasisRun EG<DataVoxEG<AyeKarumba60CԻF360ReadMeRun EO#}ګStasisDVoxEJ} mnesia Run .!Boot Set/mnProdigy,EQ% L,ReadMeE<ւXmnesia Run .!Boot Set/mnReadMeEdӼUtilitiesEI<Effectsun EI<EffectsE#EffSourceEP#.FadeSpr8E6!98IFadeTestEoҰ!LinFadeEqzh%ReadMeEÃB5Setup1E0gh^>19HammerRun E*K<tDecSource EZ 5:FDecSourceEa9/FHammer ECV 6XReadMeE ^ ymnesia Run .!Boot SetL'mn .!Sprites Set Amnesia$Path . FileData!HelpElL#i| !Help file for !Amnesia Run .!Boot Set Amnesia$Temp Yes RMEnsure UtilityModule 3.00 Set FastSpr$Temp No If Amnesia$Temp = "Yes" Then Filer_OpenDir Amnesia:AmsHelp If Amnesia$Temp = "Yes" Then Filer_Run Amnesia:HelpText Else Type HelpText Unset Amnesia$Temp FileData!RunfEer|!Run file for !Amnesia Set Amnesia$Path . Run Amnesia:!Boot RMLoad Amnesia:Amnesia FileData!SpritesPE{TD!amnesiax wwwwwwUUUUUUFileData!BootVE|!Boot file for !Amnesia IconSprites .!Sprites Set Amnesia$Path . FileData!HelpElL#i| !Help file for !Amnesia Run .!Boot Set Amnesia$Temp Yes RMEnsure UtilityModule 3.00 Set FastSpr$Temp No If Amnesia$Temp = "Yes" Then Filer_OpenDir Amnesia:AmsHelp If Amnesia$Temp = "Yes" Then Filer_Run Amnesia:HelpText Else Type HelpText Unset Amnesia$Temp FileData!RunfEer|!Run file for !Amnesia Set Amnesia$Path . Run Amnesia:!Boot RMLoad Amnesia:Amnesia FileData!SpritesPE{TD!amnesiax wwwwwwUUUUUU333333DDUUpww wwy { y pyw pwy pww y w {y yg ppFileData!Sprites22E$|!amnesia!,pwwwwwypwwy pw wwwwwy w wy pw wy pwwwww wy pw wypw pwwwy pw pywwwwwwpyww py ww py {wwww wy pyww ww py wy pywy pw  FileDataAmnesia>E5<55t5,4P(AmnesiaAmnesia 1.10 (20 Jan 1995)AmnesiaAmnesia ;>AmnesiaFlagsAmnesiaObjectsAmnesiaSWIs  is a module which provides memory allocation functions and handling routines for on-screen objects in a versatile form. See the help files in the  application for details. Copyright A.Southgate 1994 - may be used and distributed freely. Amnesia was written and is maintained by Andy Southgate - permanent address 5 Longview, Sutton, Cambs.  issues an Amnesia SWI from the command line. Its mainly used by me for testing. The SWI tail means the letters after Amnesia_ . If TO is appended register results are returned. String parameters should be entered in SINGLE quotes ('These ones') Syntax : *Amnesia [ [ [ .... ]]] [TO] Example: *Amnesia ClaimBlock 0 &800 'Aliens' 2_1101Amnesia area types area 0 - Tidy mode 1 - Messy mode 2 - Static mode Amnesia block flags are (bit - action) 0 - Block is static - must not be moved 1 - Quad word align block 2 - Disable interrupts while moving block Amnesia table flags are (bit - action) 0 - Objects require collision checking facilities Amnesia object flags are (bit - action) 0 - FastSpr plot 1 - User plot 2 - Use velocity 3 - Apply Gravity 4 - Use plot offsets 5 - Use timer for FastSpr animation 6 - Make up the object size (from FastSpr file) 7 - Collison check object 8 - Generate attention request if timer expires 9 - Destroy object if timer expires 10 - Request attention always 11 - Run timer 2 12 - Zero velocity (and this bit) after first addition 13 - Attention if outside game window (horizontal) 14 - Attention if outside game window (vertical) 15 - Use plot window 16 - Use kill window 17 - Add to the collision checking table only if object inside plot window 18 - Object needs saving by Amnesia_TableSave 19 - reserved Bits 20-23 are transient flags for the user. They are zeroed on each process pass Bits 24-31 are the user attention trigger bits. If a user attention request bit is set when calling Amnesia_SelectTable, then all of the objects with that bit set in their flags will return for attention. The structure of an amnesia object is as follows : base+0 The object type. If this is zero the object is ignored. This number is passed to FastSpr as a sprite number when requested. base+4 The flag word (see AmnesiaFlags) base+8 The x coordinate (pixels per process pass << 12) base+12 The y coordinate base+16 The x velocity (added to the x coord every process pass base+20 The y velocity base+24 The timer. Amnesia performs a SUB R0,R0,R0,LSL #16 to this value on each process pass base+28 The object size [x size][y size] in pixels, 16 bit values base+32 The second timer Only the first two entries are always required. The rest may be required depending on the settings of the flag word Amnesia supports the following SWIs. "Amnesia_Init",start_address,size,area_type "Amnesia_ClaimBlock",ptr_address,size,name,block_flags "Amnesia_ReleaseBlock",ptr_address "Amnesia_ExtendBlock",ptr_address,length "Amnesia_DescribeBlock",block_address or block_number TO block_address,size,data_start,data_size,name,ptr_address,block_flags "Amnesia_ClaimTable",table_number,table_flags,name,number_of_objects,object_size "Amnesia_ReleaseTable",table_number "Amnesia_ExtendTable",table_number,,number_of_objects "Amnesia_WipeTable",table_number "Amnesia_CountObjects",table_number TO number_of_objects "Amnesia_Tidy" "Amnesia_MakeObject",table_number,object parameters in R1-R8 "Amnesia_MakeObjectSpace",table_number TO ,object_address "Amnesia_SelectTable",table_number,process_type,plot TO R0,R1,R2 "Amnesia_ProcessTable",R0,R1,R2 (from above) TO R0,obj_address,reason code "Amnesia_DeleteObject",,obj_address "Amnesia_SetWindow",window_number,min_x,min_y,max_x,max_y "Amnesia_ReadWindow",window_number TO ,min_x,min_y,max_x,max_y "Amnesia_SetPlotOffset",x,y "Amnesia_ReadPlotOffset" TO x,y "Amnesia_CollisionCheck",table_number,table_number TO object_address,object_address,R2,R3 "Amnesia_GetColchBoxes" TO minx1,miny1,maxx1,maxy1,minx2,miny2,maxx2,maxy2 "Amnesia_LoadFile",ptr_address,filename,pathname "Amnesia_SaveFile",block_address,filename,filetype "Amnesia_LoadTable",table_number,filename,pathname "Amnesia_SaveTable",table_number,filename "Amnesia_GetTableAddress",table_number TO table_address "Amnesia_Blocks" O-v>p P  .P P  Q QQ Q O@ P P@@ 唠 Q@唠T0TStS" S 'S *!j @D0 S'S ᔠ`-pܰ[  ?ဏ@--锠R0 = &  [[ [Mode QSVCQUSR flags set: nNzZcCvViIfFTidyMessyStatic*Unknown*C-Amnesia area - type : FOQ`OQcOQeO. Address  :C(H *, size PC@ :C(: *, free >k{, available =k{. KY ;z Z CChjdPCd,:pp@-Error occurred during attempt to access block at . @-Error occurred during access to table number  . Block TBlock O-u0j-,O,O  X dX -0P  P.0S w data r space m ptr h*** Cannot find reference to next block - table list corrupt I@-(Py Q@-*** Block corrupt : guard word is ;, should be 4 '@-Gap I P P *** IN TIDY HEAP *** size I bytes. P*** Negative Gap - area corrupt @-*Unknown*@-& AmnesiaInitClaimBlockReleaseBlockClaimTableReleaseTableTidySelectTableProcessTableCollisionCheckGetColchBoxesSetPlotOffsetReadPlotOffsetSetWindowReadWindowMakeObjectMakeObjectSpaceDeleteObjectLoadFileSaveFileExtendBlockExtendTableWipeTableCountObjectsSetGravityReadGravityDescribeBlockBlocksSaveTableLoadTableGetTableAddressLoadHammered[[&Z#  |  4DX\"Ddp[ C-Q,QC P jPQ :*ChjCCAmBl@-O $D 6 $0 @Header@-P@ȻQR@ @-P@ȯ C-PhP@- ` :Y `Fy X@T @   X@  pU hUUU@C-APUCP@P``UR `R` PP RCTableLst@-h A, O0@hxj @-A  Q@-0  1r@v PZG-`p`GhjP 2Ghj0 Ghj@ p@$ hColChkG-O  P  0_hHD-#hhP>@- >@hyj@(P0@$0S>@- hQ@8 @- R@ PP@ C-h[C KkhPC  pᔠ 0@ h ` VP 0RS2P(UP h XPUC~@- 0 PE~C-h[C K(`0hP p. *kh.'khP   0 kh`X` 0@  kh @-FRD @- @- AmTb@- O0@ h 0@ h 0 @ hl O0@ C-@REQFQ @hQ  @(   !P8ZqPo ZjPh ZcPa Z\PZ ZUPS ZNPL ZGPE Z@P> Z8S8 4 Z/- Z(& Z! Z Z Z   Z !C-hp@ WZ CRk R  Z& P%Z! P Z PZ PZ PZ P Z PZ P J-& J  0@ P`^2xGW P / -(XhXC2"DB  QWRX ,QURV    OP#QPkh@Amnesia : Release of non-existent block (failed to find) - continuing... @Amnesia : Release of corrupt block (incorrect guard word) - continuing... @Amnesia : Release of non-existent block (zero entry) - continuing... @-@0Q . O|NoneO-O- P@#OhXj 0A@P`倏O-zOtP `:Y y `POP  O-  X!:Y Y y O- zOu X:Y Y y PO ဏO:y :O(*XZ:y Y POiXZ@- hA@-hO-zOtvP @ 0:y :O(*0CPY PO/ P@CO-P- O0@2 00 u@- @- 0_<@<@File$Path-C-0@T$@O-`hPG 6-P PP ER 0TPh>- 0>hC--@Ph C-pR O@Eh`SC -P PP ER 0$h 0Eh@-@ c @-@ k  @-@-@0S0'S 0 R'T0'@0'S0NQ_-f_-0 jDH借_-B - P ! +ɀAmnesia : Unrecognised SWIɀAmnesia : Unrecognised SWI tailɀAmnesia : Invalid memory blockɀAmnesia : Not enough memory in module areaɀAmnesia : Not enough memory in Amnesia areaɀAmnesia : Cannot perform operation - no area initialisedɀAmnesia : *** Aborting - Too many errorsɀAmnesia : Bad block detected when calculating used space ɀAmnesia : Bad block detected when scanning block table{ ɀAmnesia : Supplied pointer address is not in valid memory-@- D@b ɀAmnesia : Failed to make a table listS ɀAmnesia : Block does not existH ɀAmnesia : Cannot produce table - no internal table list6ɀAmnesia : Table number is too high)ɀAmnesia : Reference to table which does not existɀAmnesia : Cannot find requested block ɀAmnesia : Area is corrupted. Use *Ams Blocks-@-@ɀAmnesia : Amnesia area is not consistent with normal operationɀAmnesia : Attempt to move a bad blockɀAmnesia : Block position and pointer to position do not agreeɀAmnesia : Abbreviated SWI tails with parameters must be followed by a spaceɀAmnesia : ProcessTable has received an object address outside of the tableɀAmnesia : Bad window number - must be 0-2ɀAmnesia : Bad window - minimum greater than maximumzɀAmnesia : Collision checking not requested when claiming tableg ɀAmnesia : No room in collision checking block-@-@US!ɀAmnesia : ***** Internal error ***** - please report any appearance of this error to the author, together with the circumstances in which the error occured.'"ɀAmnesia : Area tidy would require a forward block shift. Area corrupt?$ɀAmnesia : SWI not supported by this version%ɀAmnesia : Failed to save@-@-Amnesia : LoadTable warning - The table name does not match that in the file @-Amnesia : LoadTable warning - Object length does not match that in the file FileDataAmnesia0>E-5<O55t5,4P(AmnesiaAmnesia 1.10 (20 Jan 1995)AmnesiaAmnesia ;>AmnesiaFlagsAmnesiaObjectsAmnesiaSWIs  is a module which provides memory allocation functions and handling routines for on-screen objects in a versatile form. See the help files in the  application for details. Copyright A.Southgate 1994 - may be used and distributed freely. Amnesia was written and is maintained by Andy Southgate - permanent address 5 Longview, Sutton, Cambs.  issues an Amnesia SWI from the command line. Its mainly used by me for testing. The SWI tail means the letters after Amnesia_ . If TO is appended register results are returned. String parameters should be entered in SINGLE quotes ('These ones') Syntax : *Amnesia [ [ [ .... ]]] [TO] Example: *Amnesia ClaimBlock 0 &800 'Aliens' 2_1101Amnesia area types area 0 - Tidy mode 1 - Messy mode 2 - Static mode Amnesia block flags are (bit - action) 0 - Block is static - must not be moved 1 - Quad word align block 2 - Disable interrupts while moving block Amnesia table flags are (bit - action) 0 - Objects require collision checking facilities Amnesia object flags are (bit - action) 0 - FastSpr plot 1 - User plot 2 - Use velocity 3 - Apply Gravity 4 - Use plot offsets 5 - Use timer for FastSpr animation 6 - Make up the object size (from FastSpr file) 7 - Collison check object 8 - Generate attention request if timer expires 9 - Destroy object if timer expires 10 - Request attention always 11 - Run timer 2 12 - Zero velocity (and this bit) after first addition 13 - Attention if outside game window (horizontal) 14 - Attention if outside game window (vertical) 15 - Use plot window 16 - Use kill window 17 - Add to the collision checking table only if object inside plot window 18 - Object needs saving by Amnesia_TableSave 19 - reserved Bits 20-23 are transient flags for the user. They are zeroed on each process pass Bits 24-31 are the user attention trigger bits. If a user attention request bit is set when calling Amnesia_SelectTable, then all of the objects with that bit set in their flags will return for attention. The structure of an amnesia object is as follows : base+0 The object type. If this is zero the object is ignored. This number is passed to FastSpr as a sprite number when requested. base+4 The flag word (see AmnesiaFlags) base+8 The x coordinate (pixels per process pass << 12) base+12 The y coordinate base+16 The x velocity (added to the x coord every process pass base+20 The y velocity base+24 The timer. Amnesia performs a SUB R0,R0,R0,LSL #16 to this value on each process pass base+28 The object size [x size][y size] in pixels, 16 bit values base+32 The second timer Only the first two entries are always required. The rest may be required depending on the settings of the flag word Amnesia supports the following SWIs. "Amnesia_Init",start_address,size,area_type "Amnesia_ClaimBlock",ptr_address,size,name,block_flags "Amnesia_ReleaseBlock",ptr_address "Amnesia_ExtendBlock",ptr_address,length "Amnesia_DescribeBlock",block_address or block_number TO block_address,size,data_start,data_size,name,ptr_address,block_flags "Amnesia_ClaimTable",table_number,table_flags,name,number_of_objects,object_size "Amnesia_ReleaseTable",table_number "Amnesia_ExtendTable",table_number,,number_of_objects "Amnesia_WipeTable",table_number "Amnesia_CountObjects",table_number TO number_of_objects "Amnesia_Tidy" "Amnesia_MakeObject",table_number,object parameters in R1-R8 "Amnesia_MakeObjectSpace",table_number TO ,object_address "Amnesia_SelectTable",table_number,process_type,plot TO R0,R1,R2 "Amnesia_ProcessTable",R0,R1,R2 (from above) TO R0,obj_address,reason code "Amnesia_DeleteObject",,obj_address "Amnesia_SetWindow",window_number,min_x,min_y,max_x,max_y "Amnesia_ReadWindow",window_number TO ,min_x,min_y,max_x,max_y "Amnesia_SetPlotOffset",x,y "Amnesia_ReadPlotOffset" TO x,y "Amnesia_CollisionCheck",table_number,table_number TO object_address,object_address,R2,R3 "Amnesia_GetColchBoxes" TO minx1,miny1,maxx1,maxy1,minx2,miny2,maxx2,maxy2 "Amnesia_LoadFile",ptr_address,filename,pathname "Amnesia_SaveFile",block_address,filename,filetype "Amnesia_LoadTable",table_number,filename,pathname "Amnesia_SaveTable",table_number,filename "Amnesia_GetTableAddress",table_number TO table_address "Amnesia_Blocks" O-v>p P  .P P  Q QQ Q O@ P P@@ 唠 Q@唠T0TStS" S 'S *!j @D0 S'S ᔠ`-pܰ[  ?ဏ@--锠R0 = &  [[ [Mode QSVCQUSR flags set: nNzZcCvViIfFTidyMessyStatic*Unknown*C-Amnesia area - type : FOQ`OQcOQeO. Address  :C(H *, size PC@ :C(: *, free >k{, available =k{. KY ;z Z CChjdPCd,:pp@-Error occurred during attempt to access block at . @-Error occurred during access to table number  . Block TBlock O-u0j-,O,O  X dX -0P  P.0S w data r space m ptr h*** Cannot find reference to next block - table list corrupt I@-(Py Q@-*** Block corrupt : guard word is ;, should be 4 '@-Gap I P P *** IN TIDY HEAP *** size I bytes. P*** Negative Gap - area corrupt @-*Unknown*@-& AmnesiaInitClaimBlockReleaseBlockClaimTableReleaseTableTidySelectTableProcessTableCollisionCheckGetColchBoxesSetPlotOffsetReadPlotOffsetSetWindowReadWindowMakeObjectMakeObjectSpaceDeleteObjectLoadFileSaveFileExtendBlockExtendTableWipeTableCountObjectsSetGravityReadGravityDescribeBlockBlocksSaveTableLoadTableGetTableAddressLoadHammered[[&Z#  |  4DX\"Ddp[ C-Q,QC P jPQ :*ChjCCAmBl@-O $D 6 $0 @Header@-P@ȻQR@ @-P@ȯ C-PhP@- ` :Y `Fy X@T @   X@  pU hUUU@C-APUCP@P``UR `R` PP RCTableLst@-h A, O0@hxj @-A  Q@-0  1r@v PZG-`p`GhjP 2Ghj0 Ghj@ p@$ hColChkG-O  P  0_hHD-#hhP>@- >@hyj@(P0@$0S>@- hQ@8 @- R@ PP@ C-h[C KkhPC  pᔠ 0@ h ` VP 0RS2P(UP h XPUC~@- 0 PE~C-h[C K(`0hP p. *kh.'khP   0 kh`X` 0@  kh @-FRD @- @- AmTb@- O0@ h 0@ h 0 @ hl O0@ C-@REQFQ @hQ  @(   !P8ZqPo ZjPh ZcPa Z\PZ ZUPS ZNPL ZGPE Z@P> Z8S8 4 Z/- Z(& Z! Z Z Z   Z !C-hp@ WZ CRk R  Z& P%Z! P Z PZ PZ PZ P Z PZ P J-& J  0@ P`^2xGW P / -(XhXC8(DH  QWRX ,QURV    OP#QPkh@Amnesia : Release of non-existent block (failed to find) - continuing... @Amnesia : Release of corrupt block (incorrect guard word) - continuing... @Amnesia : Release of non-existent block (zero entry) - continuing... @-@0Q . O|NoneO-O- P@#OhXj 0A@P`倏O-zOtP `:Y y `POP  O-  X!:Y Y y O- zOu X:Y Y y PO ဏO:y :O(*XZ:y Y POiXZ@- hA@-hO-zOtvP @ 0:y :O(*0CPY PO/ P@CO-P- O0@2 00 u@- @- 0_<@<@File$Path-C-0@T$@O-`hPG 6-P PP ER 0TPh>- 0>hC--@Ph C-pR O@Eh`SC -P PP ER 0$h 0Eh@-@ c @-@ k  @-@-@0S0'S 0 R'T0'@0'S0NQ_-f_-0 jDH借_-B - P ! +ɀAmnesia : Unrecognised SWIɀAmnesia : Unrecognised SWI tailɀAmnesia : Invalid memory blockɀAmnesia : Not enough memory in module areaɀAmnesia : Not enough memory in Amnesia areaɀAmnesia : Cannot perform operation - no area initialisedɀAmnesia : *** Aborting - Too many errorsɀAmnesia : Bad block detected when calculating used space ɀAmnesia : Bad block detected when scanning block table{ ɀAmnesia : Supplied pointer address is not in valid memory-@- D@b ɀAmnesia : Failed to make a table listS ɀAmnesia : Block does not existH ɀAmnesia : Cannot produce table - no internal table list6ɀAmnesia : Table number is too high)ɀAmnesia : Reference to table which does not existɀAmnesia : Cannot find requested block ɀAmnesia : Area is corrupted. Use *Ams Blocks-@-@ɀAmnesia : Amnesia area is not consistent with normal operationɀAmnesia : Attempt to move a bad blockɀAmnesia : Block position and pointer to position do not agreeɀAmnesia : Abbreviated SWI tails with parameters must be followed by a spaceɀAmnesia : ProcessTable has received an object address outside of the tableɀAmnesia : Bad window number - must be 0-2ɀAmnesia : Bad window - minimum greater than maximumzɀAmnesia : Collision checking not requested when claiming tableg ɀAmnesia : No room in collision checking block-@-@US!ɀAmnesia : ***** Internal error ***** - please report any appearance of this error to the author, together with the circumstances in which the error occured.'"ɀAmnesia : Area tidy would require a forward block shift. Area corrupt?$ɀAmnesia : SWI not supported by this version%ɀAmnesia : Failed to save@-@-Amnesia : LoadTable warning - The table name does not match that in the file @-Amnesia : LoadTable warning - Object length does not match that in the file FileDataAmnesia2>ES5<T55t5,4P(AmnesiaAmnesia 1.10 (20 Jan 1995)AmnesiaAmnesia ;>AmnesiaFlagsAmnesiaObjectsAmnesiaSWIs  is a module which provides memory allocation functions and handling routines for on-screen objects in a versatile form. See the help files in the  application for details. Copyright A.Southgate 1994 - may be used and distributed freely. Amnesia was written and is maintained by Andy Southgate - permanent address 5 Longview, Sutton, Cambs.  issues an Amnesia SWI from the command line. Its mainly used by me for testing. The SWI tail means the letters after Amnesia_ . If TO is appended register results are returned. String parameters should be entered in SINGLE quotes ('These ones') Syntax : *Amnesia [ [ [ .... ]]] [TO] Example: *Amnesia ClaimBlock 0 &800 'Aliens' 2_1101Amnesia area types area 0 - Tidy mode 1 - Messy mode 2 - Static mode Amnesia block flags are (bit - action) 0 - Block is static - must not be moved 1 - Quad word align block 2 - Disable interrupts while moving block Amnesia table flags are (bit - action) 0 - Objects require collision checking facilities Amnesia object flags are (bit - action) 0 - FastSpr plot 1 - User plot 2 - Use velocity 3 - Apply Gravity 4 - Use plot offsets 5 - Use timer for FastSpr animation 6 - Make up the object size (from FastSpr file) 7 - Collison check object 8 - Generate attention request if timer expires 9 - Destroy object if timer expires 10 - Request attention always 11 - Run timer 2 12 - Zero velocity (and this bit) after first addition 13 - Attention if outside game window (horizontal) 14 - Attention if outside game window (vertical) 15 - Use plot window 16 - Use kill window 17 - Add to the collision checking table only if object inside plot window 18 - Object needs saving by Amnesia_TableSave 19 - reserved Bits 20-23 are transient flags for the user. They are zeroed on each process pass Bits 24-31 are the user attention trigger bits. If a user attention request bit is set when calling Amnesia_SelectTable, then all of the objects with that bit set in their flags will return for attention. The structure of an amnesia object is as follows : base+0 The object type. If this is zero the object is ignored. This number is passed to FastSpr as a sprite number when requested. base+4 The flag word (see AmnesiaFlags) base+8 The x coordinate (pixels per process pass << 12) base+12 The y coordinate base+16 The x velocity (added to the x coord every process pass base+20 The y velocity base+24 The timer. Amnesia performs a SUB R0,R0,R0,LSL #16 to this value on each process pass base+28 The object size [x size][y size] in pixels, 16 bit values base+32 The second timer Only the first two entries are always required. The rest may be required depending on the settings of the flag word Amnesia supports the following SWIs. "Amnesia_Init",start_address,size,area_type "Amnesia_ClaimBlock",ptr_address,size,name,block_flags "Amnesia_ReleaseBlock",ptr_address "Amnesia_ExtendBlock",ptr_address,length "Amnesia_DescribeBlock",block_address or block_number TO block_address,size,data_start,data_size,name,ptr_address,block_flags "Amnesia_ClaimTable",table_number,table_flags,name,number_of_objects,object_size "Amnesia_ReleaseTable",table_number "Amnesia_ExtendTable",table_number,,number_of_objects "Amnesia_WipeTable",table_number "Amnesia_CountObjects",table_number TO number_of_objects "Amnesia_Tidy" "Amnesia_MakeObject",table_number,object parameters in R1-R8 "Amnesia_MakeObjectSpace",table_number TO ,object_address "Amnesia_SelectTable",table_number,process_type,plot TO R0,R1,R2 "Amnesia_ProcessTable",R0,R1,R2 (from above) TO R0,obj_address,reason code "Amnesia_DeleteObject",,obj_address "Amnesia_SetWindow",window_number,min_x,min_y,max_x,max_y "Amnesia_ReadWindow",window_number TO ,min_x,min_y,max_x,max_y "Amnesia_SetPlotOffset",x,y "Amnesia_ReadPlotOffset" TO x,y "Amnesia_CollisionCheck",table_number,table_number TO object_address,object_address,R2,R3 "Amnesia_GetColchBoxes" TO minx1,miny1,maxx1,maxy1,minx2,miny2,maxx2,maxy2 "Amnesia_LoadFile",ptr_address,filename,pathname "Amnesia_SaveFile",block_address,filename,filetype "Amnesia_LoadTable",table_number,filename,pathname "Amnesia_SaveTable",table_number,filename "Amnesia_GetTableAddress",table_number TO table_address "Amnesia_Blocks" O-v>p P  .P P  Q QQ Q O@ P P@@ 唠 Q@唠T0TStS" S 'S *!j @D0 S'S ᔠ`-pܰ[  ?ဏ@--锠R0 = &  [[ [Mode QSVCQUSR flags set: nNzZcCvViIfFTidyMessyStatic*Unknown*C-Amnesia area - type : FOQ`OQcOQeO. Address  :C(H *, size PC@ :C(: *, free >k{, available =k{. KY ;z Z CChjdPCd,:pp@-Error occurred during attempt to access block at . @-Error occurred during access to table number  . Block TBlock O-u0j-,O,O  X dX -0P  P.0S w data r space m ptr h*** Cannot find reference to next block - table list corrupt I@-(Py Q@-*** Block corrupt : guard word is ;, should be 4 '@-Gap I P P *** IN TIDY HEAP *** size I bytes. P*** Negative Gap - area corrupt @-*Unknown*@-& AmnesiaInitClaimBlockReleaseBlockClaimTableReleaseTableTidySelectTableProcessTableCollisionCheckGetColchBoxesSetPlotOffsetReadPlotOffsetSetWindowReadWindowMakeObjectMakeObjectSpaceDeleteObjectLoadFileSaveFileExtendBlockExtendTableWipeTableCountObjectsSetGravityReadGravityDescribeBlockBlocksSaveTableLoadTableGetTableAddressLoadHammered[[&Z#  |  4DX\"Ddp[ C-Q,QC P jPQ :*ChjCCAmBl@-O $D 6 $0 @Header@-P@ȻQR@ @-P@ȯ C-PhP@- ` :Y `Fy X@T @   X@  pU hUUU@C-APUCP@P``UR `R` PP RCTableLst@-h A, O0@hxj @-A  Q@-0  1r@v PZG-`p`GhjP 2Ghj0 Ghj@ p@$ hColChkG-O  P  0_hHD-#hhP>@- >@hyj@(P0@$0S>@- hQ@8 @- R@ PP@ C-h[C KkhPC  pᔠ 0@ h ` VP 0RS2P(UP h XPUC~@- 0 PE~C-h[C K(`0hP p. *kh.'khP   0 kh`X` 0@  kh @-FRD @- @- AmTb@- O0@ h 0@ h 0 @ hl O0@ C-@REQFQ @hQ  @(   !P8ZqPo ZjPh ZcPa Z\PZ ZUPS ZNPL ZGPE Z@P> Z8S8 4 Z/- Z(& Z! Z Z Z   Z !C-hp@ WZ CRk R  Z& P%Z! P Z PZ PZ PZ P Z PZ P J-& J  0@ P`^2xGW P / -(XhXC7'DG  QWRX ,QURV    OP#QPkh@Amnesia : Release of non-existent block (failed to find) - continuing... @Amnesia : Release of corrupt block (incorrect guard word) - continuing... @Amnesia : Release of non-existent block (zero entry) - continuing... @-@0Q . O|NoneO-O- P@#OhXj 0A@P`倏O-zOtP `:Y y `POP  O-  X!:Y Y y O- zOu X:Y Y y PO ဏO:y :O(*XZ:y Y POiXZ@- hA@-hO-zOtvP @ 0:y :O(*0CPY PO/ P@CO-P- O0@2 00 u@- @- 0_<@<@File$Path-C-0@T$@O-`hPG 6-P PP ER 0TPh>- 0>hC--@Ph C-pR O@Eh`SC -P PP ER 0$h 0Eh@-@ c @-@ k  @-@-@0S0'S 0 R'T0'@0'S0NQ_-f_-0 jDH借_-B - P ! +ɀAmnesia : Unrecognised SWIɀAmnesia : Unrecognised SWI tailɀAmnesia : Invalid memory blockɀAmnesia : Not enough memory in module areaɀAmnesia : Not enough memory in Amnesia areaɀAmnesia : Cannot perform operation - no area initialisedɀAmnesia : *** Aborting - Too many errorsɀAmnesia : Bad block detected when calculating used space ɀAmnesia : Bad block detected when scanning block table{ ɀAmnesia : Supplied pointer address is not in valid memory-@- D@b ɀAmnesia : Failed to make a table listS ɀAmnesia : Block does not existH ɀAmnesia : Cannot produce table - no internal table list6ɀAmnesia : Table number is too high)ɀAmnesia : Reference to table which does not existɀAmnesia : Cannot find requested block ɀAmnesia : Area is corrupted. Use *Ams Blocks-@-@ɀAmnesia : Amnesia area is not consistent with normal operationɀAmnesia : Attempt to move a bad blockɀAmnesia : Block position and pointer to position do not agreeɀAmnesia : Abbreviated SWI tails with parameters must be followed by a spaceɀAmnesia : ProcessTable has received an object address outside of the tableɀAmnesia : Bad window number - must be 0-2ɀAmnesia : Bad window - minimum greater than maximumzɀAmnesia : Collision checking not requested when claiming tableg ɀAmnesia : No room in collision checking block-@-@US!ɀAmnesia : ***** Internal error ***** - please report any appearance of this error to the author, together with the circumstances in which the error occured.'"ɀAmnesia : Area tidy would require a forward block shift. Area corrupt?$ɀAmnesia : SWI not supported by this version%ɀAmnesia : Failed to save@-@-Amnesia : LoadTable warning - The table name does not match that in the file @-Amnesia : LoadTable warning - Object length does not match that in the file FileData!ReadMeE\l2:Amnesia Help Documents - Version 1.10 ===================================== This directory contains the help documents for the Amnesia module. Index ===== Overview A quick list of what Amnesia can do, plus the conditions of use. Basics A first tutorial in using Amnesia. SWIDocs The full SWI documentation for reference. Technical The nasty technical bits which youll never need to use. The other files are small bite size chunks of information on specific areas of Amnesia. Flags Details of the Amnesia object flags. Windows Amnesia window checking facilities. ColCheck Collision checking with Amnesia. Process Processing tables. FileDataBasics,EThe Basics - Amnesia - Version 1.00 =================================== Basic Use --------- This file contains the information necessary to use Amnesia for simple tasks in a form suitable for the inexperienced programmer. It describes how to write a simple program in BASIC. A Simple Amnesia Program ------------------------ Programs using Amnesia to display and move objects on the screens must do the following things: (1) Initialise Amnesia (2) Arrange a way to plot sprites (3) Set up some sort of table of objects (4) Create objects in that table (5) Process the table Ill deal with each of these in turn. (1) Initialising Amnesia ======================== When you initialise Amnesia you basically tell it which bit of memory you want it to use. Instruction SYS "Amnesia_Init",address,length,type address= the address of the memory you want Amnesia to use length = the amount of memory available to it there type = the type of area. Type 2 is best suited for BASIC programs. Example At the start of your program you would code something like arealen=&4000 ;16Kbytes DIM area arealen ;Tell BASIC to reserve some memory for you ;of length arealen, and put the address of the ;memory its reserved in the variable 'area' SYS "Amnesia_Init",area,arealen,2 ;Tell Amnesia If you want to keep it really simple you can put the Amnesia area in the RMA.Simply pass zero as your area address. Only one line is needed SYS "Amnesia_Init",0,&4000,2 This has the advantage that if you return to the Desktop, your Amnesia area will still be there so you can use the debugging command *Amnesia Blocks. Notes You can work out the right value of arealen by trial and error. If its too small, Amnesia will give you a 'Not enough memory' error, so you can increase arealen and try again. (2) Arranging a Way to Plot Sprites =================================== Amnesia is designed to work with the FastSpr module. You should have received a copy with Amnesia, with instructions and a sprite file maker. You dont have to use FastSpr, but it will make things easier. Firstly, make sure FastSpr is loaded: *Run FastSpr:!Run This will load the module. Its best placed in your !Run file (more of that later) but can be in your main program if you wish. FastSpr loads files using the following command: *FastSprLoad 1 FSPSprites This will load a file called FSPSprites into sprite pool 1. You can load lots of sprite files - each into a different pool. See the instructions with FastSpr for more information. (3) Set Up Some Sort of Table of Objects ======================================== Tables of objects are Amnesias bread and butter. They are a powerful way to handle the player, aliens, bombs, bullets and really anything that needs to be plotted as a sprite on the screen. Before you can use a table, you must tell Amnesia what sort of table you want. Instruction SYS "Amnesia_ClaimTable",table number,flags,name$,number of objects, length of objects The table number is a number from 1-31, which you will use to identify the table later. If flags=1 Amnesia will prepare this table for collision checking - otherwise not. name$ is for your use only. It is used to make the debugging information more readable. The name may be up to 8 letters long. Names like "Aliens" or "Bullets" are good. The number of objects is just that. If you want 20 aliens, set this number to 20. Note that this is the maximum number - if you specified 20, you could have any number up to 20, but no more. The length of the objects is the number of bytes given to each object. Use 32 for standard objects. Example SYS "Amnesia_ClaimTable",1,1,"Aliens",27,32 This command sets up table 1 with 27 spaces for objects 32 bytes long, and tells Amnesia that we will need to collision check these objects. (4) Create Objects In That Table ================================ So youve created an empty table. You need to create some objects in that table, like bullets or aliens etc. There are various ways to do this, but the easiest is with the purpose built SWI. Instruction SYS "Amnesia_MakeObject",table number,sprite number,flags,x coord,y coord,x velocity,y velocity,timer,size Its a big one, isnt it! Ill go through each number in turn. Table number : The same number you gave to Amnesia_ClaimTable as a table number. Sprite number : See the information with FastSpr for full info, but briefly the number is in the form &xx00yyyy where x is the sprite pool, and y is the sprite number. &02000003 would mean sprite 3 from sprite pool 2. Flags : This value tells Amnesia what sort of properties the object has. Whether it moves, whether it has a timer, whether it is animated, whether it obeys gravity etc etc. A full list of flags is in the flags help file. Heres a couple for the moment. If bit 0 is set, the object is plotted by FastSpr If bit 2 is set, the object moves x coord : The x position of the sprite (remember, x is a cross 8-) ). Amnesia uses different coordinates to normal BASIC. The top-left of the screen is (0,0) and in MODE 13 (320x256) the bottom right is (320<<12,256<<12). 320<<12 means 320 shifted right 12 places in binary, which is the same as multiplying by 4096. y coord : Similarly x velocity : The velocity is added to the x coordinate every time the table is processed (see later in (5)) if and only if bit 2 is set in the flags. y velocity : Similarly timer : The timer can be thought of as split into two halves, like &xxxxyyyy. x is the timer value, and y is the value subtracted from the timer on each process pass (see (5)). So if the timer value is &012C0003, the timer value is &12C and 3 is subtracted on each process pass. With this value, the timer will expire after 100 process passes (&12C=300). size : Again this is split like the timer. The value is of the form &xxxxyyyy, where x is the x size in pixels, and y is the y size. So for a sprite 32 pixels wide and 16 high, the value would be &00200010. You can ask Amnesia to work out the size from the FastSpr file by setting bit 6 in the flags. This is usually a good idea. (5) Processing the Table ======================== Table processing is controlled by two SWIs - Amnesia_SelectTable and Amnesia_ProcessTable. These SWIs communicate using registers R0, R1 and R2. A typical table process goes like this: SYS "Amnesia_SelectTable",1,0,0 TO R0,R1,R2 REPEAT SYS "Amnesia_ProcessTable",R0,R1,R2 TO R0,R1,R2 UNTIL R2=0 Amnesia_SelectTable is called to tell Amnesia which table you wish to processand what you want to do with that table. Read its entry in the SWI docs for a full explanation. With the parameters above it selects table 1 for a standard process. This table process will simply plot and move your objects. You can do a lot more than this when you process a table. See the help file called Process for more information. FileDataColCheckIE%+Collision Checking - for Amnesia 1.10 ===================================== This file describes the collision checking facilities within Amnesia. Overview -------- Collision checking within games always places a high demand on computing power. If you check 50 objects to see if they are touching any of another 50 objects, thats 2,500 checks that need to be done! To cope with this sort of load Amnesia handles collision checking in a special way. When a table of objects is processed, the bounding boxes (rectangles which enclose an object just touching its edges) are stored in another table. When you need to collision check two sets of objects, Amnesia checks two of these tables against each other. This can be done very quickly. The three steps to collision checking ------------------------------------- This is what you need to do to get collision checking working. (1) When you set up your tables using Amnesia_ClaimTable, you set bit 0 of R1. This reserves space for the tables of bounding boxes. (2) When you create your objects using Amnesia_MakeObject, you set bit 7 in the objects flags. (3) Use the following code to do the checking. R0=1 ;table 1 R1=2 ;with table 2 REPEAT SYS "Amnesia_CollisionCheck",R0,R1 TO R0,R1 IF R0<>0 THEN PROChit UNTIL R0=0 This code would check table 1 against table 2. If there was a collision, it would call PROChit with R0 pointing to the object in table 1, and R1 pointing to the object in table 2. It is possible to collision check a table with itself. The BallBnc demo is a good example of this. **************************************************** This document is copyright A.Southgate 1994. It may be freely distibuted and copied but should not be modified, otherwise things will get very confusing. **************************************************** FileDataFlagsEe BAmnesia Flags - for Amnesia 1.00 ================================ Amnesia flags are contained in a 4 byte word at offset +4 from the start of an Amnesia object. Bit 0 is the least signifacant bit (its on the right when the number is written down). An Amnesia Object ----------------- An Amnesia object is made up of 8 or more bytes in the following form: Offset | Use ------------------------- 0 | sprite number - set to zero to indicate a dead object +4 | flags +8 | x position +12 | y position +16 | x velocity +20 | y velocity +24 | timer +28 | object size in pixels +32 | timer 2 The following describes the meaning of the flags at offset +4. The bits determine what happens to the object on each process pass. Bit 0 - Plot with FastSpr ------------------------- If this bit is set the object is plotted by FastSpr as a sprite. The first word of the object is passed to FastSpr as a sprite number in R0. The x and y positions are shifted right 12 places before being passed to the FastSpr_Plot SWI in R1 and R2. Bit 1 - User Plot ----------------- If this bit is set the object is returned to the user for plotting. The user routine must extract the coordinates as necessary and plot the object itself. Bit 2 - Use velocities ---------------------- If this bit is set the velocities at offsets +16 and +20 are added to the position values at +8 and +12 and the results stored back at +8 and +12. This is a simple way to move an object around. Bit 3 - Apply gravity --------------------- If this bit is set the current gravity value, set by Amnesia_SetGravity, is added to the velocity at +16 and +20, and the result stored back to +16 and +20. Note that gravity may be in any direction. Bit 4 - Use plot offsets ------------------------ If this bit is set the plot offsets, set by Amnesia_SetPlotOffset, are added to the object coordinates before the object plotted by FastSpr. The offsets are added before the values are shifted right. Note that user plot routines must handle this for themselves. Bit 5 - Use timer for FastSpr animation --------------------------------------- If this bit is set the timer (offset +24) is used for animation. FastSpr supports animation using bits 23-16 of the sprite number. If this bit is set, Amnesia will ORR the top 8 bits of the timer value into this position so that an animation will run without user intervention. The help files in FSPConv have more information about FastSpr animation. Bit 6 - Make up the object size from FastSpr file ------------------------------------------------- If this bit is set the object size (offset +28) is derived from the FastSpr file using the SWI FastSpr_ReadSize. This can be a handy timesaver in most cases. Note that the sprite number at offset 0 must be the number of a valid sprite, and that sprite must already be loaded when the object is made. FastSpr_ReadSize is called once when the object is created and the result stored at offset +28. Any subsequent changes in the sprite file or object will not update the size entry. Bit 7 - Object needs collision checking --------------------------------------- If this bit is set the position of the object (strictly speaking the bounding box) is added to the collision checking table. See the docs on collision checking for more details. Bit 8 - Generate attention request if timer expires --------------------------------------------------- If this bit is set Amnesia will generate an attention for the object when the timer value is negative - ie the timer expires. See the timer docs for further information. Note that care must be taken to ensure to stop this attention occuring repeatedly once the timer has expired. Bit 9 - Destroy object if timer expires --------------------------------------- If this bit is set the object will be destroyed if the timer becomes negative. The object is not returned for attention before the object is destroyed. Set bit 8 as well if you want this to happen. Bit 10 - Always request an attention ------------------------------------ If this bit is set the object is returned for attention on each process pass. Bit 11 - Run timer 2 -------------------- If this bit is set Amnesia will run a second timer at offset +32. This timer will not generate attention or destroy objects regardless of the settings of bits 8 and 9. Bit 12 - Zero velocities ------------------------ If this bit is set Amnesia will zero the object velocities at offsets +16 and +20 after they have been added to the positions (at +8 and +12) once. It will also zero this bit in the flags. Bit 13 and 14 - Object uses the game window ------------------------------------------- If bit 13 is set the object will return for attention if it is outside the game window in the x (horizontal) direction. If bit 14 is set the object will return for attention if it is outside the game window in the y (vertical) direction. It is possible for both to occur at once. See the window docs for further information. Bit 15 - Object obeys the plot window ------------------------------------- If this bit is set the object will only be plotted (either by FastSpr or a user routine) if any part of it is inside the plot window. The plot offset is added to the coordinates before the comparison. See the window docs for further information. Bit 16 - Object obeys the kill window ------------------------------------- If this bit is set the object will be killed (deleted) if it is outside of the kill window. The object will be returned for attention before it is deleted. See the window docs for further information. Bit 17 - Add to collision checking table only if within plot window ------------------------------------------------------------------- If this bit is set the object will only be added to the collision checking table if it is inside the plot window. It may be used to reduce the load on collision checking routines if necessary. Bit 18 - Object should be saved ------------------------------- The objects in a table may be saved using the SWI Amnesia_SaveTable. Objects will only be saved if this bit is set in their flags. Bit 19 - Reserved for future expansion -------------------------------------- Set this bit to zero. Bits 20-23 - User transient flags --------------------------------- These bits are set to zero on each process pass. They may be used for any purpose by the user. These flags were primarily intended to store collision handling information. Bits 24-31 - User attention flags --------------------------------- These bits can be set by the user to generate attention request for specified groups of objects. If, say, bit 27 is set in the table number passed to Amnesia_SelectTable all objects with bit 27 set in their flags will be returned for attention. **************************************************** This document is copyright A.Southgate 1994. It may be freely distibuted and copied but should not be modified, otherwise things will get very confusing. **************************************************** FileDataModules\EȅModules ======= The instructions in this directory relate directly to the module Amnesia12. This module is designed for machine code programs where the coordinates are shifted left 12 places. This gives fine control over velocities and is recommended for high quality games. For games written in BASIC it is sometimes nice to be able to forget about shifting everything left 12 places before you use it. With this in mind the module named Amnesia0 has no shift. The screen coordinates range from (0,0) to (320,256). Although this makes things simpler remember that velocities will be much coarser. The file Amnesia2 is included for those of you who like a MODE 13 screen to have coordinates ranging from (0,0) to (1280,1024). Don't forget the (0,0) is at the TOP left, mind you. You may include whatever module you wish in any games that you write. FileDataOverView E Amnesia - Version 1.10 ====================== Overview -------- Amnesia is a module which is part of a set of modules designed to speed up the process of game writing. At the basic level it provides memory management for the programmer where blocks of memory can be allocated, extended and released. Amnesia also provides a structure for handling tables of objects. An explanation follows later in this document. The module may be used under the following conditions: ------------------------------------------------------ (1) The module may be freely included in commercial or non-commercial software with no liability for royalty payments. (2) My copyright notice and contact address should not be removed from the module. (3) The module is supplied as is, and no liabilty can be accepted for damage or loss resulting from the use or misuse of the software. The Module ---------- Amnesia supplies a set of memory allocation routines which should serve for most purposes. It also contains versatile object handling routines. As far as Amnesia is concerned an object is a small chunk of memory, usually 40 bytes or so. An object is very general in Amnesia, but will usually have the following properties: It will represent a sprite on the screen, be it a moving ball, a missile or bullet, the player, stars in the background, scrolling text etc. The object will usually be plotted by the module FastSpr. The object may perform a wide variety of actions. It may move about, be animated, perform an action after a certain time, produce other objects etc. It may be collision checked with a number of other objects. A table is the space allocated for a number of objects. All objects in the table are the same length, but they need not have the same properties. For example, aliens and explosions could be in the same table. Collision checking ------------------ The module will collision check objects as instructed by the user. It has a notion of the size of an object (which it will deduce from the sprite file if necessary) and will usually check if the bounding boxes (rectangles which completely enclose the relevant sprite) overlap. The objects are then pointed out to the user who can deal with them. Coordinates ----------- The module uses the same coordinates as FastSpr, but shifted left 12 places (ie multiplied by 4096). FastSpr uses memory-like coordinates. The top left of the screen is (0,0), and the bottom right of a mode 13 screen would be (320,256). Therefore to Amnesia the bottom right of the screen is (320<<12,256<<12). Versatility ----------- All properties of an object can be disabled by the user. The use of the first eight bytes of an object is fixed, but the rest is up to you. If the features listed above are enabled, the module expects the first few words of an object to be in a standard form. Support ------- Enquiries, bug reports and requests for help should be sent by post to Andy Southgate, at 14 Madingley Road, Cambridge until 10/95, and thereafter to 5 Longview, Sutton, Cambs. FileDataProcessEs  dAmnesia Table Processing - for Amnesia 1.00 =========================================== This file describes the technique of processing tables with Amnesia. Overview -------- The method of table processing is designed to take most of the workload involved in a game away from the game program and into the optimised machine code routines within Amnesia. This allows the game program to be written in a slower language, such as BASIC, whilst keeping the game fast and responsive. The Process ----------- Table processing is controlled by two SWIs - Amnesia_SelectTable and Amnesia_ProcessTable. These SWIs communicate using registers R0, R1 and R2. A typical table process goes like this: SYS "Amnesia_SelectTable",1,0,0 TO R0,R1,R2 REPEAT SYS "Amnesia_ProcessTable",R0,R1,R2 TO R0,R1,R2 IF (R2 AND (1<<8)) THEN PROCtimer IF (R2 AND (1<<13)) THEN PROCgamewindow UNTIL R2=0 Amnesia_SelectTable is called to tell Amnesia which table you wish to processand what you want to do with that table. Read its entry in the SWI docs for a full explanation. With the parameters above it selects table 1 for a standard process. The values R0, R1 and R2 from Amnesia_SelectTable are passed straight to Amnesia_ProcessTable. Amnesia_ProcessTable may return either An object for you to do something with. R2=0, indicating that it has finished processing this table. Heres how it works. When you call Amnesia_ProcessTable Amnesia looks through the table until it finds an object. Then, it does all the work which you specified in the flags when you created the object. This includes moving the object, running timers etc. If there is nothing interesting happening with the object then Amnesia plots it if necessary and starts on the next object. On the other hand, if there is something interesting happening, like a timer expiring or the object has moved outside of a certain area, Amnesia_ProcessTable will return the object 'For Attention'. This means that the SWI returns to your program, with R1 pointing to the object which you have to deal with, and R2 containing a 'Reason Code'. The value in R2 has a direct relation with the value in the objects flags. For example, if the timer bit of the object is set (bit 8) and the timer expires, R2 will return with bit 8 set. If the kill window bit is set (bit 16) and the object is outside of the kill window, then the SWI will return with bit 16 of R2 set, and so on. When you have dealt with the object, you probably want to carry on processing the rest of the table by calling Amnesia_ProcessTable again. However, so that Amnesia knows that youre restarting from part-way through the table you dont give it the R0, R1 and R2 from Amnesia_SelectTable. Instead you give it the R0, R1 and R2 which it gave to you. The ProcessTable SWI will then plot the object that youve just dealt with, work out how far it had got through the table, and carry on from there. *** NOTE *** If you call the ProcessTable SWI more than once you must pass the same R0, R1 and R2 which it generated, back to it. Use the code above and make sure that things like PROCtimer and PROCgamewindow do not alter the variables R0, R1 or R2. This is important. To illustrate, this code would not work: SYS "Amnesia_SelectTable",1,0,0 TO R0,R1,R2 REPEAT SYS "Amnesia_ProcessTable",R0,R1,R2 TO a,b,c IF (c AND (1<<8)) THEN PROCtimer IF (c AND (1<<13)) THEN PROCgamewindow UNTIL c=0 ------------------------------------------- Scanning a Table ================ The may be times when you wish to scan a table for a specified object without applying all of the effects of a process pass. This can be achieved through a modified sort of process pass. SYS "Amnesia_SelectTable",1,1,8,&1000 TO R0,R1,R2,R3 REPEAT SYS "Amnesia_ProcessTable",R0,R1,R2,R3 TO R0,R1,R2,R3 PROCscanfound UNTIL R2=0 This will return all the objects with the value &1000 at offset +8. The value passed in R1 to Amnesia_SelectTable determines what sort of test is used for the scan. The SWI docs have full infomation. **************************************************** This document is copyright A.Southgate 1994. It may be freely distibuted and copied but should not be modified, otherwise things will get very confusing. **************************************************** FileDataStartHeref Ef7[Start Here - Amnesia - Version 1.00 =================================== This file contains information for the inexperienced programmer about entering numbers in binary and hexadecimal. If you already know how to do this, move to the Basics document. One thing I will say to experienced users is BE CAREFUL WHEN USING << IN BASIC. It has a low priority, so 1 + 1 << 5 is evaluated as (1+1)<<5, and worse still X AND 1<<3 is evaluted as (X AND 1) << 3. Use brackets like X AND (1<<3). Binary ------ Computers work with binary numbers - zeroes and ones. To use Amnesia you need to know a bit about how binary numbers work. As we move from right to left in a binary number, each figure is worth double the one to the right of it, so Binary | Decimal equivalent 1 1 10 2 100 4 1000 8 10000 16 100000 32 and so on.... Each of the zeroes or ones in a binary number is a 'bit'. The bit on the far right is called the least significant bit, bit zero, or the LSB, and the bit on the far left is the most significant bit (MSB). Just about all numbers youll encounter when programming your Acorn computer are 32 bits long, so the MSB is bit 31. In BASIC we can enter numbers in various ways. %100000 : direct binary 1<<5 : a number and a shift value 32 : the decimal equivalent &20 : the hexadecimal equivalent Shift values are useful when using Amnesia. The << symbol shifts a number a certain number of binary places to the left. So %11011 << 3 = %11011000 Equivalent to 27 << 3 = 216 in decimal BASIC will convert between binary and other forms for you. Try PRINT %11011 PRINT %11011 << 3 You may have noticed that <<3 is equivalent to multiplying by 8, just as <<4 is equivalent to multiplying by 16, and <<5 multiplying by 32 etc. Hexadecimal is useful as it's easy to convert to and from binary. All you need to know are the 16 numbers and letters in binary. 0000 = &0, 0001 = &1, 0010 = &2, 0011 = &3, 0100 = &4, 0101 = &5, 0110 = &6, 0111 = &7, 1000 = &8, 1001 = &9, 1010 = &A, 1011 = &B, 1100 = &C, 1101 = &D, 1110 = &E, 1111 = &F. Then you can chop up a binary number like this. %01100100011101010110001101010001 splits up as %0110 0100 0111 0101 0110 0011 0101 0001 whis equals &64756351 by exchanging each four binary digits for one hexadecimal digit. So, when the Amnesia help files talk about using bit 11, youll know that you can enter that as any of %100000000000, 1<<11, &800, or 2048. Try experimenting in BASIC. Here are some type of commands to use. A=%11010101 let A= a number in binary A=&FC0 let A= a number in hexadecimal PRINT ~A Print out A in hexadecimal and the exotic *Eval 16_FC0 *Eval 36_ANDY *Eval will convert any base up to base 36 into decimal! Use 16_ for hex and 2_ for binary. FileDataSWIDocscE6< SWI Documentation for the Amnesia module version 1.10 ===================================================== Amnesia is a module which provides support for memory allocation and an 'object handler' primarily for use in video games. The Amnesia module has many facilities and you are unlikely to need all of them. This document contains full information regarding the SWIs so may look a bit daunting. Dont worry - its not half as complicated as it looks! ======================================= Amnesia_Init ------------ Initialises the Amnesia module On Entry R0 = Area start R1 = Area length R2 = Area type On Exit R0 preserved R1 preserved R2 preserved Interrupt status not altered. Executes in SVC mode. SWI is not re-entrant. Use This SWI must be issued before using any other Amnesia facilities. R0 should be word aligned (multiple of 4). The register meanings are as follows: R0 = 0 : Claim from RMA. R2 = 0 : Tidy mode - compact heap on each release of memory R2 = 1 : Messy mode - compact heap when out of space R2 = 2 : Static mode - compact heap only when instructed to do so In tidy mode the module will shift the heap and gather all of the free space together when blocks or tables are deallocated, so the heap is always tidy and not fragmented. In messy mode the heap will be shifted if there is not enough space for a requested allocation. Therefore the heap is usually in a mess and fragmented. This mode tends to give you occasional big tidy-ups instead of regular small ones. In static mode the heap is not shifted until you specifically request it. This is so that BASIC programs have a chance to re-read all of the pointers that they use. To release the Amnesia block, call this SWI with R1=0. The module can only support one heap at a time, although this heap can be split up into blocks as you please. The SWI may return errors as the memory block is checked for validity. All of the following SWIs will return errors if called before a successful Amnesia_Init. ======================================= Amnesia_ClaimBlock ------------------ Claim a block of memory from the Amnesia heap. On Entry R0 = Address of pointer which will be used to reference the block. R1 = Length required in bytes R2 = Zero, or pointer to name string R3 = Flags On Exit Pointer at R0 set to point to block, or [R0] = zero if allocation failed. R1 = length allocated Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI attempts to claim a block of memory within the Amnesia heap if available. It may shift the heap in messy mode. R1 is rounded up to be a multiple of 4. If the call is successful the block is then yours to do what you like with. Always use the pointer at [R0] to access the block, as it may change when the heap is tidied. You may supply R0 = 0, but Amnesia will no longer be able to tidy the heap below the block. The name pointed to by R2 may be up to 8 characters long and is for your use only. Amnesia will take a copy. The flags in R3 are as follows: Bit 0 : If this bit is set, the block is static - it will not be moved by heap tidying. Avoid static blocks if possible as they may cause Amnesia to waste memory. Ideally all of your static blocks should be claimed before your moveable ones. Bit 1 : If set, the block claimed will be quad-word aligned +4 like blocks returned by OS_Module. The address will end in 4 (so look like &xxxxxxx4). Bit 2 : If this bit is set, the block is assumed to be accessed by an interrupt routine (because its a sound sample, for example). If so, interrupts are disabled when the block is moved during a heap tidy to prevent problems. Errors will be returned if there is no room. ======================================= Amnesia_ReleaseBlock -------------------- Release a previously claimed block of memory. On Entry R0 = Address of pointer (as above) or zero On Exit The call zeroes pointer at [R0] if release is valid ie [R0] is a pointer to an Amnesia block. Interrupt status unchanged. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI will release a block which has been previously claimed with Amnesia_ClaimBlock. If R0=0 then the whole Amnesia area is released. In tidy mode the heap will be shifted to release the free space for future allocations. The error Not a valid block may be returned. ======================================= Amnesia_ExtendBlock ------------------- Extends a block which has already been claimed On Entry R0 = Address of current pointer to block R1 = New length required in bytes On Exit Pointer at [R0] may be changed if block is moved R1 = new length allocated Interrupt status unchanged. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI tries to extend or shrink a previously claimed block. The heap may be shifted in tidy or messy modes. May return the errors No room or Not an allocated block. Its usual method is to claim another block, copy, and then release the block to be extended. ======================================= Amnesia_DescribeBlock --------------------- Returns information about a block. On Entry R0 = pointer to block or block number On Exit R0 = block address R1 = block size R2 = start of data area R3 = size of data area R4 = pointer to name R5 = pointer to block pointer (as passed in R0 to ClaimBlock) R6 = block flags Interrupt status unchanged. Executes in SVC mode. SWI is re-entrant. Use This SWI returns information on a specified block. ======================================= Amnesia_ClaimTable ------------------ Claims space for a table of objects and creates a header for that table On Entry R0 = Your handle for the table (0-31) R1 = Flags R2 = Zero or pointer to name R3 = Number of objects R4 = Size of a single object (bytes) On Exit R0-R3 Preserved Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI sets up a table for subsequent use. A table is a list of objects which usually represent sprites on the screen (aliens, missiles etc) but can be used for other purposes. All objects in the new table are marked as inactive. Returns an error if the allocation fails. R1 contains information as follows: bit | meaning if set 0 - objects require collision checking facilities. The processing of tables is detailed with the SWI Amnesia_ProcessTable. If the collision checking bit is set a collison checking table of a default length will be claimed. The possible errors are No room, not initialised, bad table type, bad handle. ======================================= Amnesia_ReleaseTable -------------------- Releases a previously claimed table On Entry R0 = Your handle for the table (0-31) On Exit R0 preserved Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI must not be called from an interrupt routine. Use Releases the space used by a table and its collision checking area if present. May return errors if the table is corrupted. ======================================= Amnesia_ExtendTable ------------------- *** This SWI is not implemented *** *** Please contact the author if you _really_ need it! *** On Entry R0 = Your handle for the table (0-31) R2 = New number of objects On Exit R0, R2 Preserved Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI extends or shrinks a current table if possible. Shrinking it may delete objects. All new objects in the table are marked as inactive. Errors are generated if the extend fails. ======================================= Amnesia_WipeTable ------------------- On Entry R0 = Your handle for the table (0-31) On Exit R0 corrupted, others preserved. Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI marks all objects in the specified table as inactive. ======================================= Amnesia_Tidy ------------ Tidies the heap and makes all of the free space available. On Entry No parameters On exit No results Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI must not be called from an interrupt routine. Use This SWI will tidy the Amnesia heap and collect all of the free space together. In messy or tidy modes this will be performed automatically and this SWI need not be used. In static mode you can call this SWI in response to the error No room in amnesia heap, and then update your pointers before resuming. This SWI may return errors such as overwritten/nonsensical blocks in area. ======================================= Amnesia_MakeObject ------------------ Creates an object in a table. On Entry R0 = Table handle R1 = Object type/sprite (non-zero) R2 = Object flags R3 = x coord R4 = y coord R5 = x velocity R6 = y velocity R7 = Timer value R8 = Object size On Exit R1 = address of object allocated, for you to fill in the rest if you need to. R1 = Zero, and carry set if no object could be created. Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI is not re-entrant. Use This SWI creates an object (an entry in the table) with the given parameters if there is room. No error will be returned if the object cannot be created because there is no room in the table, but R1 will be zero on exit. The SWI tries to create an object as quickly as possible, but will scan the whole table for a free space if necessary. When a space is found the module stores all passed registers using the form STMIA R10,{R1-R8} where R10 = the address of the new object, returned to you in R1. The coordinates in R3,R4 are FastSpr style, shifted left twelve places. The top left of the screen in (0,0) and the bottom right in, say, mode 13, is (320<<12, 256<<12). The values in R5,R6 are added directly to these. The flags in R2 have the following meaning: bit | meaning if set 0 - object needs plotting by the module 1 - object needs plotting by the user 2 - object has a velocity (R5,R6) 3 - object responds to gravity 4 - object should use the plot offsets for plotting 5 - object has a FastSpr animation 6 - make up the object size (R8 invalid) 7 - object has no timer (R7 invalid - use 0) 8 - object needs attention when timer expires 9 - object should be destroyed when timer expires 10 - reserved 11 - object should be collison-checked 12 - reserved 13 - velocity entries should be used and then zeroed (used by solid objects) 14 - object uses the game window 15 - object uses the plot window 16 - object uses the kill window 17 - object should be saved by Amnesia_SaveTable 24 - call for attention if trigger 1 set 25 - call for attention if trigger 2 set 26 - call for attention if trigger 3 set 27 - call for attention if trigger 4 set 28 - call for attention if trigger 5 set 29 - call for attention if trigger 6 set 30 - call for attention if trigger 7 set 31 - call for attention if trigger 8 set If both the 'need attention when time expires' and 'destroy when timer expires' bits are set, you will get an attention request before the object is deleted. If you reset the timer the deletion will not happen. The timer in R7 has the following structure: | timer value timer decrement Upon each process pass (each time Amnesia_Process is used on the object) the action SUB R7,R7,R7,LSL #16 is performed. When this causes the timer to cross zero the timer is said to have expired and the action specified by the flags in R1 is taken. The size should be specified in PIXELS in R8, in the following format: | x size y size If the 'make up the object size' bit is set the module attempts to read the object size from the FastSpr file. If that fails the size is set to zero. Object size is used for collison checking only. Note that R8 cannot be passed from the BASIC SYS command and should be filled in using the returned address in R1 if necessary. If the FastSpr animation bit is set, the word after the object timer is used to control the FastSpr animation. Bits 31-24 are passed as the animation frame. This SWI may return the error Table does not exist. ======================================= Amnesia_MakeObjectSpace ----------------------- Finds a space for you to make an object yourself On Entry R0 = Table handle On Exit R0 preserved R1 = Address of available object, or zero if unable to allocate. Interrupts disabled in critical stages otherwise unaltered. Executes in SVC mode. SWI is not re-entrant. Use This SWI finds a free object space in the given table if possible. You must then fill in all of the parameters yourself if you wish to create an object. The object data is undefined on return so must be overwritten. May return a table does not exist error. ======================================= Amnesia_SelectTable ------------------- Selects a table for subsequent processing. On Entry R0 = Table handle [+ user attn bits] R1 = Process type (0 -> normal, 1 -> scan (CMP), 2 -> scan (TST)) If R1=0 R2 = Plot action (0 -> plot, 1 -> don't) If R1=1 or 2 R2 = offset in object R3 = CMP or TST value R4 = BIC value On Exit R0-R2 altered, ready to pass to Amnesia_ProcessTable R0 = table number + internal flags + user attn flags R1 = pointer to first object R2 = internal flags R3,R4 preserved Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use This SWI selects the table to be processed next. Subsequent calls to Amnesia_ProcessTable will update objects, plot them if necessary, and may ask the user to process objects. If a normal process is selected this SWI will also wipe the collision checking table if present. If you wish to return objects with user attention bits (bits 24-31) in their flags, set the relevant bit or bits in R0. If R1 = 0 the table is processed fully. If R1 = 1 the table is scanned using a CMP instruction. The value at offset R2 in each object is BICed with R4 and compared with the value of R3, and the object returned if identical. If R1 = 2 the table is scanned using a TST instruction. The value at offset R2 in each object is BICed with R4 and TSTed with the value of R3, and the object returned if any bit set in R3 is also set in the value at the selected offset. If R3 = 0 all objects are returned. ======================================= Amnesia_ProcessTable -------------------- Processes one or more objects from a table. On Entry At the start of a process these registers should be those generated by Amnesia_SelectTable. R0 = Table Handle plus flag bits R1 = Value from Amnesia_SelectTable or the previous Amnesia_ProcessTable R2 = Reason code/flags R3 = Scan value, if a scan is selected On Exit R0 = Table handle plus flag bits R1 = Updated pointer to current object which needs attention, or zero if end of table R2 = Reason code/flags R3 = Preserved Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant (!). Use Amnesia_ProcessTable should be called repeatedly after a single Amnesia_SelectTable to process the table. The SWI will process the object as necessary, and it will return control to you if the object needs attention. If R2 = 0 the end of the table has been reached and processing has finished. You should not call this SWI again before selecting another table. The module keeps no internal records of which table you are processing, so you may process objects/tables in any order. The three or four parameters passed to Amnesia_ProcessTable fully define what is going on. This SWI may return errors. R0 will point to an error block as usual. ======================================= Amnesia_DeleteObject -------------------- Deletes an object in a table On Entry R1 = Object address On Exit All registers preserved Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use Simply STRs zero at address R1. Use to make your code look tidier if you like. ======================================= Amnesia_CountObjects -------------------- Counts the number of objects in a table On Entry R0 = table number On Exit R0 = number of objects Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use Returns the number of active objects in the specified table. ======================================= Amnesia_SetWindow ----------------- Sets an Amnesia window. On Entry R0 = window to set R1 = minimum x coordinate R2 = minimum y coordinate R3 = maximum x coordinate R4 = maximum y coordinate On Exit R0-R4 preserved Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use This SWI sets one of the windows held by Amnesia. The window set is governed by R0. R0 = 0 : Set the game window. This window is provided purely for the user, and will return for attention if an object is outside of this window. It could be used, for example, to bounce a ball on the edge of the screen. The plot offset is not added before this comparison. R0 = 1 : Set the plot window. If any part of an object is within this window the module will attempt to plot it. The plot offset is added before the comparison. R0 = 2 : Sets the kill window. If a object wanders completely outside of this window it will be deleted if the relevant flag is set. The plot offset is not added before comparison. ======================================= Amnesia_ReadWindow --------------------- Sets the game window. On Entry R0 = window to read On Exit R0 altered R1 = minimum x coordinate R2 = minimum y coordinate R3 = maximum x coordinate R4 = maximum y coordinate Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use Reads the settings of a window. ======================================= Amnesia_SetPlotOffset --------------------- Sets the plot offset. On Entry R0 = x offset R1 = y offset On Exit R0, R1 = Previous values Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use The plot offset is added to an objects coordinates before passing them to FastSpr, if the relevant bit is set. The coordinates are in pixels<<12. ======================================= Amnesia_ReadPlotOffset ---------------------- Reads the plot offset. On Entry No parameters On exit R0 = x offset R1 = y offset Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use Returns the plot offset, for use by your own plotting code, for example. ======================================= Amnesia_SetGravity ------------------ Sets the plot offset. On Entry R0 = x gravity R1 = y gravity On Exit R1 preserved Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use Gravity is added to an objects velocity on each process pass if bit 3 is set in the flags. Any value, positive or negative, is permitted for R0 and R1. ======================================= Amnesia_ReadGravity ------------------- Reads the gravity setting On Entry No parameters On exit R0 = x gravity R1 = y gravity Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use Returns the gravity setting. ======================================= Amnesia_CollisionCheck ---------------------- Performs collision checking between two tables On Entry R0 = First table number (0-31) R1 = Second table number (0-31) On Exit R0 = Address of colliding object in the first table, or 0 if no collision. R1 = Address of colliding object in second table. R2 = offset of object in first table. Don't bother with these. R3 = offset of object in second table Interrupt status unaltered. Executes in SVC mode. SWI is re-entrant. Use This SWI performs a fast collision check between two tables, or between a table and itself. The addresses of the objects are returned. Collision checking can then be continued by calling the SWI again, until R2 returns zero. An example coding is: .collisioncheck STMFD R13!,{R14} MOV R0,#1 MOV R1,#2 .loop SWI "Amnesia_CollisionCheck" CMP R2,#0 BEQ done STMFD R13!,{R0-R1} MOV R0,#0 STR R0,[R0]; delete both colliding objects STR R0,[R1]; LDMFD R13!,{R0-R1} B loop .done LDMFD R13!,{PC} For collision checking to work, the following must be true: Both tables must have been claimed with collision checking enabled The objects in question must have the collision checking bit set in their flags Collision checking between a table and itself is a special case. Amnesia deals with the anomalies for you, to ensure that are not told about an object colliding with itself. Half the number of checks are required. The algorithm used is moderately fast. Tables of bounding boxes are built up as objects are processed. Subsequently each check between two objects takes six instructions to complete. If two tables of 50 objects are checked against each other this takes 2500 checks (5050) so thats 15000 instructions. Obviously the amount collision checking should be minimised to reduce the processor time required. With this in mind, if any object does not need a collision check, then do not set the collision check bit in the objects flags. This SWI will return errors if the tables do not exist, or were not claimed with collision checking specified. ======================================= Amnesia_LoadFile ---------------- Creates an Amnesia block and loads a file into it On Entry R0 = address of block pointer R1 = filename R2 = pathname On Exit [R0] = address of allocated block R1-R2 unchanged, R0 corrupted Interrupt status unaltered. Executes in SVC mode. SWI should not be called from an interrupt routine. Use This SWI loads a file into the Amnesia area, creating a block to do so. R0 is the address of the pointer which you wish to use for the block. The block will be quad word aligned plus 4 bytes, like an OS_Module block. The string pointed to by R1 is added after that pointed to by R2 to produce the complete filename. ================================== Amnesia_LoadHammered -------------------- Creates an Amnesia block and loads a file into it On Entry R0 = address of block pointer R1 = filename R2 = pathname On Exit [R0] = address of allocated block R1-R2 unchanged, R0 corrupted Interrupt status unaltered. Executes in SVC mode. SWI should not be called from an interrupt routine. Use Identical to Amnesia_LoadFile but decompresses the file if it is a Hammered file. ================================== Amnesia_SaveFile ---------------- Saves an Amnesia block On Entry R0 = address of block R1 = filename R2 = filetype On Exit R1-R2 unchanged, R0 corrupted Interrupt status unaltered. Executes in SVC mode. SWI should not be called from an interrupt routine. Use This SWI saves an Amnesia block as a file. ======================================= Amnesia_LoadTable ----------------- Saves the objects in an Amnesia table On Entry R0 = table number R1 = filename R2 = pathname On Exit R1-R2 unchanged, R0 corrupted Interrupt status unaltered. Executes in SVC mode. SWI should not be called from an interrupt routine. Use This SWI loads objects from a file into an Amnesia table. The object length and table name should match. Objects already in the table are preserved. ======================================= Amnesia_SaveTable ----------------- Saves the objects in an Amnesia table On Entry R0 = table number R1 = filename On Exit R1-R2 unchanged, R0 corrupted Interrupt status unaltered. Executes in SVC mode. SWI should not be called from an interrupt routine. Use This SWI saves the objects in an Amnesia table which have bit 17 set in their flags. ======================================= Amnesia_GetTableAddr -------------------- Gets the address of a table. On Entry R0 = table number On exit R0 = table address Interrupt status unaltered. Executes in SVC mode. SWI is re entrant. Use This SWI returns the address of a table should you wish to manipulate it yourself. A brief idea of the table structure can be gleaned fron the Headers document in the Technical directory. ======================================= Amnesia_Blocks -------------- Prints a diagnostic report. On Entry No parameters On exit No results. Interrupt status unaltered. Executes in SVC mode. SWI should not be called from an interrupt routine. Use Prints a diagnostic report listing the current block allocations, showing if the area is sound or not. If an Amnesia has just returned an error the report will tell you in which block the error occured. This SWI is intended for use from the command line during software development. It can be invoked by the command *Amnesia Blocks (or *Amn.B.). Amnesia keeps a guard word at the start of each block, so this command will you if you have written to memory past the end of a block and corrupted the header of the next. ======================================= **************************************************** This document is copyright A.Southgate 1995. It may be freely distibuted and copied but should not be modified, otherwise things will get very confusing. **************************************************** FileDataHeader;E| ; Amnesia module header ; This header was part of the module code which was assembled using !ExtAsm. ; Copyright A.Southgate 1994 but may be freely distributed and used in the ; creation of other code. #set Service_Amnesia=&80320; issued when the Amnesia area is discarded. ; used by Stasis to kill sound voices. #set errorlim = 100 #set def_tables = 32 ; coordinate shift value #set coordshift = 12 ; block flags #set BF_static = 1 #set BF_qwa = 1<<1 #set BF_intoff = 1<<2 ; area types #set A_type_tidy = 0 #set A_type_messy = 1 #set A_type_static = 2 ; flags used is R2 during table processing/scanning #set R_skip_advance = 1 #set R_tst = 1<<1 #set R_alive = 1<<31 ; flags used in R0 during table processing/scanning #set PF_advance = 1<<23 #set PF_plot = 1<<22 #set PF_process = 1<<21 ; the Amnesia object flags #set Amf_plot = 1<<0 #set Amf_user_plot = 1<<1 #set Amf_velocity = 1<<2 #set Amf_gravity = 1<<3 #set Amf_use_plot_ofs = 1<<4 #set Amf_anim = 1<<5 #set Amf_make_objsize = 1<<6 #set Amf_colch = 1<<7 #set Amf_attn_timer = 1<<8 #set Amf_dest_timer = 1<<9 #set Amf_attn = 1<<10 #set Amf_timer2 = 1<<11 #set Amf_zero_vec = 1<<12 #set Amf_game_horiz = 1<<13 #set Amf_game_vert = 1<<14 #set Amf_plot_window = 1<<15 #set Amf_kill_window = 1<<16 #set Amf_colch_window = 1<<17 #set Amf_save = 1<<18 #set Amf_reserved = 1<<19 #set Amf_noleft = 1<<20 #set Amf_noright = 1<<21 #set Amf_noup = 1<<22 #set Amf_nodown = 1<<23 #set Amf_attn_mask = &FF<<24 ;imask are the events which are never returned to the user #set Amf_imask = Amf_plot + Amf_velocity + Amf_gravity + Amf_use_plot_ofs + Amf_anim + Amf_make_objsize + Amf_colch + Amf_dest_timer + Amf_zero_vec + Amf_plot_window + Amf_save + Amf_colch_window + Amf_timer2 ; the variable block at R12 struct Amn_v { .areastart DCD 0 .areatype DCD 0 .areasize DCD 0 .gamewindow DBD 4; 4 words .plotwindow DBD 4; 4 words .killwindow DBD 4; 4 words .plotxofs DCD 0 .plotyofs DCD 0 .gravx DCD 0 .gravy DCD 0 .colch0 DCD 0 .colch1 DCD 0 .colch3 DCD 0 .colchsave DBD 4; 4 words - save area for colch regs .colchboxes DBD 8; 8 words - store area for bounding boxes .errorctr DCD 0 .errorblock DCD 0 .errortable DCD 0 .buffer DBD 16 ; 16 words .temp0 DCD 0 .temp1 DCD 0 .temp2 DCD 0 .sizeof } ; the block header structure struct Amn_b { .id DCD 0 .ptr DCD 0 .name DBB 8 ; 8 bytes .size DCD 0 .flags DCD 0 .sizeof } ; the table header structure struct Amn_t { .id DCD 0 .ptr DCD 0 .name DBB 8 ; 8 bytes .size DCD 0 .flags DCD 0 .objsize DCD 0 .number DCD 0 .tabflags DCD 0 .next DCD 0 .sizeof } ; the saved table file header struct Amn_save { .id DCD 0 .name DBB 8 ; 8 bytes .objsize DCD 0 .number DCD 0 .gap DCD 0 .sizeof } ; the area header (block 0) struct Amn_h { .id DCD 0 .ptr DCD 0 .name DBB 8 ; 8 bytes .size DCD 0 .flags DCD 0 .type DCD 0 .areasize DCD 0 .tlist DCD 0 .sizeof } ; the object structure struct Amn_o { .type DCD 0 .flags DCD 0 .x DCD 0 .y DCD 0 .xvec DCD 0 .yvec DCD 0 .timer DCD 0 .size DCD 0 .timer2 DCD 0 .sizeof } ; the collision checking table header struct Amn_c { .id DCD 0 .ptr DCD 0 .name DBB 8 ; 8 bytes .size DCD 0 .flags DCD 0 .writeofs DCD 0 .sizeof } ; a collision checking table entry struct Amn_cent { .ofs DCD 0 .minx DCD 0 .miny DCD 0 .maxx DCD 0 .maxy DCD 0 .sizeof } ;the table list header struct Amn_tlist { .number DCD 0 .sizeof } FileDataObjFoundEk ; Amnesia module object handling code ; This code was part of the module code which was assembled using !ExtAsm. ; Copyright A.Southgate 1994 but may be freely distributed and used in the ; creation of other code. ; This is the code used my Amnesia when is finds an object during table ; processing. ; On entry, R10 points to the found object. ; R11 is the R0 value passed to ProcessTable. .objfound SUB R10,R10,R9; R10 now points to the found object STMFD R13!,{R7-R9} ; we need for later ; R7 as pointer to t struct ; R8 as end address ; R9 as object length LDMIA R10,{R1-R8} BIC R2,R2,#%1111<<20 STR R2,[R10,#o.flags] AND R9,R11,#&FF<<24; R9 = the trigger mask ORR R9,R9,#Amf_colch+Amf_attn+Amf_anim TST R11,#PF_plot ORRNE R9,R9,#Amf_plot+Amf_user_plot; request user plot if plots requested TST R2,#Amf_use_plot_ofs ORRNE R9,R9,#Amf_use_plot_ofs TST R2,#Amf_velocity + Amf_attn_timer + Amf_dest_timer + Amf_anim TSTEQ R2,#Amf_zero_vec + Amf_timer2 BEQ skipvelocity TST R2,#Amf_velocity ADDNE R3,R3,R5 ADDNE R4,R4,R6 TST R2,#Amf_zero_vec MOVNE R5,#0 MOVNE R6,#0 TST R2,#Amf_gravity BLNE addgravity TST R2,#Amf_attn_timer + Amf_dest_timer + Amf_anim SUBNE R7,R7,R7,LSL #16 CMP R7,#0; test for timer expiry ORRLT R9,R9,#Amf_attn_timer + Amf_dest_timer STMIA R10,{R1-R7} TST R2,#Amf_timer2 BLNE runtimer2 .skipvelocity TST R2,#Amf_game_horiz + Amf_game_vert + Amf_plot_window + Amf_kill_window BEQ nowindows STMFD R13!,{R2,R7} MOV R14,R2 ;NOTE MOV R5,R8,LSR #16 MOV R6,R8,LSL #16; R1 is <<16 its real value ; and don't forget the <<12 from pixels to coords MOV R5,R5,LSL #16 SUB R1,R3,R5,LSR #17-coordshift ADD R3,R3,R5,LSR #17-coordshift SUB R2,R4,R6,LSR #17-coordshift ADD R4,R4,R6,LSR #17-coordshift TST R14,#Amf_game_horiz + Amf_game_vert BEQ nogamewindow ADD R0,R12,#v.gamewindow ;the game window triggers when any part of the ; object is outside of it LDMIA R0,{R5-R8} CMP R1,R5 CMPGE R7,R3 ORRLT R9,R9,#Amf_game_horiz CMP R2,R6 CMPGE R8,R4 ORRLT R9,R9,#Amf_game_vert .nogamewindow TST R14,#Amf_kill_window BEQ nokillwindow ADD R0,R12,#v.killwindow LDMIA R0,{R5-R8} ;the kill window triggers if an object is entirely ; outside of it. CMP R1,R7 CMPLE R5,R3 CMPLE R2,R8 CMPLE R6,R4 ORRGT R9,R9,#Amf_kill_window .nokillwindow TST R14,#Amf_plot_window BEQ noplotwindow TST R9,#Amf_use_plot_ofs LDRNE R5,[R12,#v.plotxofs] LDRNE R6,[R12,#v.plotyofs] ADDNE R1,R1,R5 ADDNE R3,R3,R5 ADDNE R2,R2,R6 ADDNE R4,R4,R6 ADD R0,R12,#v.plotwindow LDMIA R0,{R5-R8} ;the plot window triggers if an object is entirely ; outside of it. CMP R1,R7 CMPLT R5,R3 CMPLT R2,R8 CMPLT R6,R4 ORRGE R9,R9,#Amf_plot_window TST R9,#Amf_plot_window TSTNE R2,#Amf_colch_window ORRNE R9,R9,#Amf_colch_window .noplotwindow LDMFD R13!,{R2,R7} .nowindows ; reset regs to return BIC R0,R11,#PF_advance; signal that we haven't finished MOV R1,R10 AND R2,R9,R2 TST R2,#Amf_plot_window BICNE R2,R2,#Amf_plot + Amf_user_plot BICS R9,R2,#Amf_imask LDMFD R13!,{R7-R9} LDMNEFD R13!,{R3-R9,PC}^ ; return if attention required .noadvance MOV R0,#0 TST R2,#Amf_kill_window STRNE R0,[R10,#o.type] TST R2,#Amf_dest_timer BEQ nodesttimer LDR R1,[R10,#o.timer] CMP R1,#0 STRLT R0,[R10,#o.type] .nodesttimer LDR R0,[R10,#o.type] CMP R0,#0 BEQ objectdead TST R2,#Amf_plot BLNE plotobj ;uses previous R0 TST R2,#Amf_colch BEQ objectskip TST R2,#Amf_colch_window BNE objectskip BL colchadd LDMVSFD R13!,{R3-R9,PC} .objectskip .objectdead ;SWI OS_ReadEscapeState ;BCC lookforobj B lookforobj LDMFD R13!,{R3-R9,PC} .runtimer2 STMFD R13!,{R0} LDR R0,[R10,#o.timer2] SUBS R0,R0,R0,LSL #16 STR R0,[R10,#o.timer2] BICGT R9,R9,#Amf_timer2 LDMFD R13!,{R0} MOV PC,R14 .addgravity LDR R0,[R12,#v.gravx] ADD R5,R5,R0 LDR R0,[R12,#v.gravy] ADD R6,R6,R0 MOV PC,R14 .plotobj STMFD R13!,{R0-R3,R14} TST R2,#Amf_anim BLNE fastspranim TST R2,#Amf_use_plot_ofs LDRNE R3,[R12,#v.plotxofs] LDR R1,[R10,#o.x] ADDNE R1,R1,R3 LDRNE R3,[R12,#v.plotyofs] LDR R2,[R10,#o.y] ADDNE R2,R2,R3 MOV R1,R1,ASR #coordshift MOV R2,R2,ASR #coordshift SWI FastSpr_Plot LDMFD R13!,{R0-R3,PC} .fastspranim TST R2,#Amf_timer2 LDREQ R1,[R10,#o.timer] LDRNE R1,[R10,#o.timer2] AND R1,R1,#&FF<<24 ORR R0,R0,R1,LSR #8 MOV PC,R14 .colchadd STMFD R13!,{R1-R9,R14} LDR R0,[R12,#v.temp0] LDR R9,[R0,#4]; get colchtab addr CMP R9,#0 BEQ colchnotable SUB R9,R9,#b.sizeof LDR R1,[R9,#c.writeofs] LDR R2,[R9,#c.size] CMP R1,R2 BGE colchnoroom SUB R0,R10,R7;offset within table ADD R7,R9,R1; position to write to LDR R3,[R10,#o.x] LDR R4,[R10,#o.y] LDR R8,[R10,#o.size] MOV R5,R8,LSR #16 MOV R6,R8,LSL #16; R6 is <<16 its real value MOV R5,R5,LSL #16; now so is R5 SUB R1,R3,R5,LSR #17-coordshift ADD R3,R3,R5,LSR #17-coordshift SUB R2,R4,R6,LSR #17-coordshift ADD R4,R4,R6,LSR #17-coordshift STMIA R7!,{R0-R4} SUB R1,R7,R9; restore writeofs STR R1,[R9,#c.writeofs] LDMFD R13!,{R1-R9,PC}^ .colchnotable LDMFD R13!,{R1-R9,R14} B colchnotableerr .colchnoroom LDMFD R13!,{R1-R9,R14} B colchnoroomerr ; Don't worry - I can't understand it either! ; Andy. 8-)FileDataPlotCodeE?- ; Amnesia module plot code ; This header was part of the module code which was assembled using !ExtAsm. ; Copyright A.Southgate 1994 but may be freely distributed and used in the ; creation of other code. ; Before calling the module has performed the equivalent of a ; LDMIA R10,{R0,R2-R4}, where R10 is the address of the object .plotobj STMFD R13!,{R0-R3,R14} TST R2,#Amf_anim BLNE fastspranim TST R2,#Amf_use_plot_ofs LDRNE R3,[R12,#v.plotxofs] LDR R1,[R10,#o.x] ADDNE R1,R1,R3 LDRNE R3,[R12,#v.plotyofs] LDR R2,[R10,#o.y] ADDNE R2,R2,R3 MOV R1,R1,ASR #coordshift MOV R2,R2,ASR #coordshift SWI FastSpr_Plot LDMFD R13!,{R0-R3,PC} .fastspranim TST R2,#Amf_timer2 LDREQ R1,[R10,#o.timer] LDRNE R1,[R10,#o.timer2] AND R1,R1,#&FF<<24 ORR R0,R0,R1,LSR #8 MOV PC,R14 FileDataReadMeEs9Amnesia Technical Details - Version 1.10 ======================================== This directory contains the nasty technical details about Amnesia, and includes assembler headers for the object structures etc. There are also some code fragments which might be useful. FileDataWindowsy Ef]hAmnesia Windows - for Amnesia 1.00 =================================== This file describes the use of windows within Amnesia. Overview -------- Amnesia can control graphical objects within a large area - much larger than the screen. When an object, say a bullet or a bomb, moves off the screen you might be tempted to forget about it. However, this would be a bad idea, as you would build up a surplus of objects which were off the screen, taking no part in the game, but still consuming processor time to move them etc. So that you can just forget about objects as they move off the screen, Amnesia provides three 'windows' - rectangular areas which may be smaller or larger than the screen. Amnesia then takes action depending on whether the objects are inside or outside of these windows. Ill deal with each window in turn. (1) The game window ------------------- This window is provided purely for the user. It is intended to form some part of the game. The game window is useful for bouncing objects off the edges of the screen. If any part of an object is outside of the game window that object will be returned for attention, providing that the game window bits are set in its flags. To help with bouncing objects the game window tells you whether the object is outside of the window in a horizontal or vertical direction (or both). (2) The plot window ------------------- This window is used to make sure that a game runs at the highest speed it can. It is used to make sure that no attempt will be made to plot an object if it is fully off the screen. Unlike the game window, the plot window only prevents the plot if the WHOLE of the object is outside of the window. As a rule of thumb, you should use this window if a lot of your objects spend most of their time off the screen, and you should set the window to the size of the screen. (3) The kill window ------------------- This window is really useful to tidy up all those stray objects that wander off the screen. If the kill window bit is set (bit 16) in the object flags, and the object wanders outside of the window, it is automatically deleted. Setting Windows --------------- Amnesia provides an SWI to set windows: SYS "Amnesia_SetWindow",window,min x,min y,max x,max y window is the window number. 0 -> the game window, 1 -> the plot window, and 2 -> the kill window. min x is the minimum x value - the left hand edge of the window. min y is the minimum y value - the top edge. max x is the maximum x value - the right hand edge. max y is the maximum y value - the bottom edge. The full plot window for a MODE 13 screen is set by SYS "Amnesia_SetWindow",1,0,0,320<<12,256<<12 FileDataHelpTextEO`Amnesia Version 1.10 ==================== This application contains a game engine module. Please refer to the help files within this directory. A. Southgate 1994 but use and distribute freely. FileData!BootEJI|!Boot file for !FastSpr IconSprites .!Sprites Set FastSpr$Path . Set File$Type_113 FastSpr Set Alias$@RunType_113 FastSprLoad %*0 wimpslot -min 16k -max 16k FileData!HelpD|beN| !Help file for !FastSpr Run .!Boot Set FastSpr$Temp Yes RMEnsure UtilityModule 3.00 Set FastSpr$Temp No If FastSpr$Temp = "Yes" Then Filer_OpenDir FastSpr:FSprHelp If FastSpr$Temp = "Yes" Then Filer_Run FastSpr:HelpText Else Type HelpText Unset FastSpr$Temp FileData!RunrD0T3|!Run file for !FastSpr Set FastSpr$Path . Run !Boot RMLoad FastSpr FileData!SpritesD(5E!fastspr,, qygguwwydwGqgydqfuywdwVE'dwVtwydwVGdwfuwwDdwgUyDDeqgVwGTfqwvyevwgygfuwvgwwgwwwfile_113,, wwwwwwww '"uy vw'bybuywGfU'@fuwy gGguwwDgUyDUrVwWUrfye wyg&"w'"'wwwwwwwwFileData!Sprites22\ D/i` !fastspr!TwwwwwwUUUUUU333333DDUUTUE4www7DDDdyD3D@DT'23@E4Dty"3DT434312C5CtwwwyB3@4C1CDDCty3CDD4C13@DC44swwww"C@DCDC4y$"C@CCCD4s7"""2C@DDC4T4y#2223T44D4wwwG3234DED3DtyC"3C4DDD4D733CCTDDCSty434DEDDD44www7333DTD4DC3sy#3CC33D`TD3DCE7#232C`ETDDswwy333DC`TDDC743CCPFETDuy4C3DeTD4Cyww7444EdD5EDtG4D443C`EFTDDyD3434FEE5DtG33D4eVDT4DFC4CD@EEEEDt6CSC@eTDEE7SDTEEVTSU5DTTdVVUDTUETfile_113!wwwwwwUUUUUU333333DDUUwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww@twwwwTDGDww@E3syDww@DDDC7TwwdEtwwwyCEwwUE7Sww@VDty3wwdU5DywwwGDDwweUDCtG42cwwUEUCCy$"BUww@EDEDCtG"4UwwPUTED4Cy$33EwwPUEDDwwwG4CCww`UDEty4CSww`UTCCwwwGDCDww`VDECtyDDDD3Dww`UU45CG443CDww@UVE54ty4CDDDwwfEEDDDG3DDdwwVEEDtwwyDDDewwTVVDGETFww@VUEtwwwDDUwwVUUDyDDDDfwwdeVFtGDDUEww@VVVDyDUeww@ffUtyGTwwdUUewdFww@feEwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwFileDataFastSpr4 BWYi}( ,4P}$FastSprFastSpr 3.01 (16 Oct 1994)FastSprFastSprPlot FastSprLoadmFastSprWipeFastSprBackdrop iFastSprFlash 8uFastSprSWIsD issues a plot command via FastSpr_Plot. Use this command for testing only please (very slow).   is an optimised sprite plotter, using a special sprite format. A.Southgate 1994 - may be freely included in commercial or non-commercial software. The flash facility is not active in this release.  loads a FastSpr file into the RMA.  [pool]  removes one or more FastSpr files from memory.  [pool] sets the colour used to fill the clip window, used by the SWI "FastSpr_ClearWindow". Colours are numbered 0-255 as in !Paint.   sets the colour used to paint a sprite when flash is specified by setting bit 30 in the sprite number. Colours are numbered 0-255 as in !Paint. *** SetFlash is inactive in this release ***  The module supports the following SWIs, based at &47D00. &47D00 "FastSpr_Plot",spritenum,x,y &47D01 "FastSpr_ClearWindow" &47D02 "FastSpr_SetClipWindow",xmix,ymin,xmax,ymax &47D03 "FastSpr_Load",filename$,pool &47D04 "FastSpr_GetAddress" TO PlotsAdr,ClearsAdr,BanksAdr,,VarsAdr &47D05 "FastSpr_SetBackdrop",colour &47D06 "FastSpr_ScreenBank",bank &47D07 "FastSpr_SpritesAreAt",address &47D08 "FastSpr_ReadSize",number TO xsize,ysize &47D09 "FastSpr_GetPointer",pool TO address &47D0A "FastSpr_SetFlash",colour PlotsAdr, ClearsAdr and BanksAdr are call addresses for the three routines, to bypass the SWI system. VarsAdr is the address of FastSprs variables. *** SetFlash is inactive in this release *** FastSprPlotClearWindowSetClipWindowLoadGetAddressSetBackdropScreenBankSpritesAreAtReadSizeGetPointerSetFlashFQ@-[ [ 4,(@-PQ @R@SPQPQR $ (0@- R@-?P4@-Q  !kQ @- !C-`  QPCT`0Chfj  0PPCH@- !{@- !x@- !0!@!LO- @\M? dM Q0@-  4@?P  PUO-Z @-p0T1p  Q Z  $(#@- $ @\-$\-\- @-,@-0@- P PC- P$Pa $! -( $,JJJ Z ( @$Q(@$A XC hB, 0@P`p>  [(, 0@P`p JP, JP$P J$P ZFSP1FSP2C2C@CO-@ xP OQ Q8Qs01S @ H6#D$  Qp P !OO C-?d4&VpKoOWO W8Ysï01S @ H6#D$DIA I(B5#4#A0 (xPE `FQRUVpx0C @DQRUV FRFREDQpEQCxPV PjP: YpbP`  A ,B ) xPE `FQRUVpx0C @DQRUV FRFREDQpEQCxW8 W: Y  IX\Q !"$#4$D%T&d't(,.Q !"$#4$D%T&d't(,. IX\,\A(l .('t&d%T$D#4"$! WJ AWK Pqp`qp XV䎠G0P?^ ˧^!˧^"$˧^#4˧^$D˧^%T˧!?^ ˧^!˧^"$˧^#4˧^$D˧^%T˧G0PPPGPu^$D˧^#4˧^"$˧^!˧^ ˧  K A H 'xPa`qp XV䎠G0P?7^ ^!^"$^#4^$D^%T!?7^ ^!^"$^#4^$D^%TG0PPPG7Pu^ ^!^"$^#4^$D A 'htxPPTqp`qp XV䎠TG(P$^P ˧^Q!˧^R"$˧^S#4˧^T$D˧'^P ˧^Q!˧^R"$˧^S#4˧^T$D˧G(PP@GT^S#4˧ T^R"$˧T^Q!˧T^P ˧ TO- W3 Y  IP "4$T&t "4$T&t "4$T&t "4$T&t IP@P P "4$T&t IY Y"4Y$T Y&tW? qp`qp XV䎠G`P?P R"4T$T?P R"4T$T?P R"4T$T?P R"4T$TG`P0PPP` UP UR"4  ? 'xa`qp XV䎠G`P?7^ ^"4^$T?7^ ^"4^$T?7^ ^"4^$T?7^ ^"4^$TG`P0PPP`7 U^"4U^  'htx PTqp`qp XV䎠TWP PU RU"4GPPPU  TO- WN Y  IP  ^  ^  ^  ^ IP@P Z  ^ Z  ^ Z  ^ Z  ^WJ PPqp`qp XVGP4 P @^JU TTTT@@@@t````  ? Gxpqp`qp XVGP) PU  PPNP0PNP PPNP0PNP   PNP @PNP0PNP P 'htx PPPPEPPqp`qp XVPGP! @ PUPU PU0TPUPU PU0PU@ P FastSpr : File not found!FastSpr : File not suitable for this module"FastSpr : No room in RMA for file#FastSpr : Attempt to plot with no valid spritefile$FastSpr : Sprite number out of range%FastSpr : Clip window too wide&FastSpr : Bad clipping window'FastSpr : Unknown FastSpr SWIFileDataHistory[EgHistory ======= FastSpr 2.00 was released in 1993. It also formed part of the game Asylum. Version 2.00 could only use FSP1 type files. Version 3.00 can plot both FSP1 and FSP2 format file. The extended features of FSP2 format are: Pre shifting for higher speed animation frames Version 3.00 also supports multiple sprite pools. FileDataManualEFastSpr Documentation - version 3.00 ===================== FastSpr is a module occupying about 8K, designed to offer high speed sprite plotting to the games writer. Typically it is at least twice as fast as OS routines, whilst providing full masking and a variable clipping window. The routines may be accessed via SWIs or direct calls. Using FastSpr ============= FastSpr uses a special sprite format, which provides high speed plotting. Sprite files are most easily produced using the application FSPConv, with which instructions are provided. Basically, you need to do the following: o Make a SpriteFile (using !Paint) with sprites called 0,1,2,3,4...etc o Drag this to the FSPConv icon o Click convert. The FastSpr files are usually about twice the size of the originating sprite file, but may be up to six times as large, or smaller, depending on the amount of transparent area of the sprites. See the help files with FSPConv for full details. Loading the Module ================== You can load the module by either double clicking the application, or using the command *RMLoad FastSpr:FastSpr, or whatever you can engineer for yourself. Loading your sprites ==================== The FastSpr file may be loaded in either of two ways: (i) Into the RMA : Using *FastSprLoad or the SWI "FastSpr_Load" (ii) Into user memory. There is a simple way to load the file into an Amnesia area. See the entry on FastSpr_GetPointer in the SWIDocs file. Typical BASIC coding: 10 *FastSprLoad 1 Filename or 10 SYS "FastSpr_Load","Filename",1 Plotting ======== Before any FastSpr operation, select the correct MODE for the sprites you are using. The SWI used to plot sprite is "FastSpr_Plot", number &47D00. Remeber that for speed, the SWIs should be referred to by number, not name. Typical BASIC coding: 10 SYS &47D00,&02000003,160,128 - Plots sprite 3 from pool 2 at coordinates 160,128. Coordinates =========== FastSpr uses memory coordinates. The top left of the screen is (0,0), and the bottom right is (x-1,y-1) where x is the number of bytes in one line, and y is the number of lines. For example, in MODE 13 (256 colour,320 by 256 pixels), (319,255) is the bottom right corner of the screen. The application !FSPConv produces sprites for which the middle of the sprite is plotted at the coordinates given. Negative coords and those off the screen are acceptable. Clipping Window =============== The sprites are clipped (ie parts outside of the window are not plotted) according to the window set by SWI "FastSpr_SetClipWindow". Typical BASIC coding: 10 SYS "FastSpr_SetClipWindow",xmin,ymin,xmax,ymax Xmin and ymin are inclusive, whereas xmax and ymax are exclusive, so the correct window for the whole of a MODE 13 screen is 0,0,320,256. The SWI "FastSpr_ClearWindow" fills the clip window with the current backdrop colour, set by SWI "FastSpr_SetBackdrop" or *FastSprBackdrop. ScreenBanks =========== FastSpr supports switching of screen banks to provide flicker free updates. SWI "FastSpr_Screenbank" does the job. A value of 1 supplied switches all subsequent operations to the shadow bank (the OS bank 2), any other value to the main bank (OS bank 1). Typical BASIC coding: 10 b%=1 20 REPEAT loop starts Do plotting, etc, here 30 WAIT 40 SYS &47D06,b% sets FastSpr's bank to one bank 50 SYS &6,&71,b% sets the displayed bank to the other (SWI is OS_Byte) (55 SYS &6,&70,2-b%) only if you're using normal plotting routines as well 60 SYS &47D01 clears FastSpr's window 70 bank%=3-b% switches the banks for next time 80 UNTIL FALSE loop ends Note : The most common problem with switching banks is neglecting to allocate enough screen memory. No errors are produced - it just doesnt work. Other Features ============== For ultimate speed, you can call some routines directly to save time decoding the SWI issued. The SWI "FastSpr_GetAddress" returns the addresses of the useful routines. Typical BASIC coding: 10 SYS "FastSpr_GetAddress",plotadr,clearadr,bankadr ... 20 A%=0 30 B%=160 40 C%=128 50 CALL plotadr is equivalent to 10 SYS "FastSpr_Plot",0,160,128 Remember that these routines are in the RMA, so the desktop and RMTidy commands may move the module and your addresses will no longer be valid. Speed Considerations ==================== The following guidelines should provide maximum speed. (1) Use sprites with as many transparent pixels as possible. A sprite with twice as many solid pixels takes almost twice as long to plot in most cases. (2) If you're using SWI FastSpr_ClearWindow, choose a clip window which (best) includes the whole width of the screen, or (next best) where xmin and xmax are multiples of 4. (3) In BASIC refer to all SWIs by number if they need to be fast. (4) Avoid horizontal clipping if you can. Clipping the top or bottom of a sprite carries no time penalty, but clipping the sides may increase plotting time to up to twice. When clipping both sides, plotting time may be x3. What it can't cope with ======================= (1) Sprites bigger than 255 pixels along either axis in FSP1 format. (2) Screen modes wider than 640 pixels, or narrower than 4 (window clearing only). To avoid problems, the following may be helpful. (1) Make sure you are in the right mode for your sprite. (2) Don't set clip windows and then change mode (which resets them). (3) Don't chop up your machine with an axe. (4) Don't forget that the module uses non-standard coordinates. Conditions ========== This version of FastSpr may be freely used and distributed for commercial or non-commercial applications. If you can distribute the whole application and the application !FSPConv with your software then so much the better, but otherwise just include whatever you need. You must not remove my copyright notice from the module. This software is supplied as is, and no liability will be accepted for loss or damage of any kind arising from its use or misuse. Andy Southgate, 5th Nov 1993. Updated 16th October 1994. FileDataSWIDocsEFastSpr Version 3.01 ==================== SWI Documentation ================= FastSpr supports an SWI block based at &47D00. -------------------------------- FastSpr_Plot ============ Plots a sprite On Entry R0 = sprite number R1 = x coordinate R2 = y coordinate On exit R0 corrupted R1, R2 preserved Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI plots a sprite to the current screen bank (see the SWI FastSpr_ScreenBank). The sprite number is made up as follow. MSB /--byte 3 --\ /-- byte 2 -- \ /-- bytes 1 and 0 --\ [sprite pool] [animation frame] [sprite number] So animation frame 4 of sprite 7 from pool 2 would have the number &02040007. The coordinates are in pixels from the top left. Note that this is different from OS cooridinate, which begin at the bottom left. For a MODE 13 screen the bottom right hand pixel is (319,255). The sprite will be plotted so that its centre is at the coordinates given (unless you choose differently with FSPConv). ================================== FastSpr_ClearWindow =================== Clears the current graphics window On Entry No parameters On exit No results Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI fills the current graphics window with the current backdrop colour. The action is similar to BASICs CLS, but only the FastSpr window, as set by FastSpr_SetClipWindow, is cleared. ================================== FastSpr_SetClipWindow ===================== Sets the graphics window On Entry R0 = minimum x coord (inclusive) R1 = minimum y coord (inclusive) R2 = maximum x coord (exclusive) R3 = maximum y coord (exclusive) On exit Registers preserved Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI sets the current clipping window. If you wish to use FSP2 type files the minimum and maximum x coordinates must be multiples of 4. For FSP1 files they may assume any value. The clipping window must be within the screen boundaries. When a screen mode is selected the clip window is set to the whole screen. For MODE 13 this means R0=0, R1=0, R2=320, R3=256. ================================== FastSpr_Load ============ Loads a sprite file On Entry R0 = filename R1 = pool number On Exit R0 corrupted R1 preserved Executes in SVC mode. Interrupt status may be altered. SWI is not re-entrant. Use This command loads a sprite file into the RMA. The pool number is in the range 0-&3E. ================================== FastSpr_GetAddress ================== Returns addresses of certain routines within FastSpr. On Entry No parameters On Exit R0 = address of Plot routine R1 = address of ClearWindow routine R2 = address of ScreenBank routine R4 = address of FastSprs variable. Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI returns addresses of useful routines within FastSpr. You may set up registers as for the relevant SWI and call these routines directly. This will save a bit of time by bypassing the operating systems SWI handler, but will lead to problems if the RMA is tidied or FastSpr is RMKilled etc. ================================== FastSpr_SetBackdrop =================== Sets the backdrop colour On Entry R0 = colour 0-&FF On Exit Registers preserved Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI sets the backdrop colour as used by FastSpr_ClearWindow. R0 is the byte value written to the screen, so the colours are identical to those shown in the palette of Paint. ================================== FastSpr_ScreenBank ================== Selects the current screen bank On Entry R0 = bank number or address On Exit R0 preserved Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI sets the screen bank. R0=0 selects bank 1, R0=1 selects bank 2 (yes, Im sorry...). A value greater than &8000 is taken to be the address of an area of memory to be used as a screen. ================================== FastSpr_SpritesAreAt ==================== The old form of implementing sprite pools On Entry R0 = address of sprite files On Exit R0 preserved Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI sets the address of the sprite file in pool 0. It should not be used for new programs and is retained for past comptibility. ================================== FastSpr_ReadSize ================ Return the size of a sprite On Entry R0 = sprite number On Exit R0 = x size R1 = y size Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI returns the size of a sprite in pixels. The sprite number is in the same format as used by FastSpr_Plot. ================================== FastSpr_GetPointer ================== Get the address of a sprite pool pointer On Entry R0 = pool number On Exit R0 = address of pointer Executes in SVC mode. Interrupt status unaltered. SWI is re-entrant. Use This SWI returns the address of FastSprs pointer to the sprite file in the specified pool. If you wish to tell FastSpr you have loaded a sprite file into user memory you would store its address at the address returned in R0. Example ...load file into memory block at R1... MOV R0,#1 SWI FastSpr_GetPointer STR R1,[R0] This is very easily interfaced with Amnesia. MOV R0,#1 SWI FastSpr_GetPointer ADR R1,filename MOV R2,#0 SWI Amnesia_LoadFile ... .filename DCB "FSPSprites",0 or identically SYS "FastSpr_GetPointer",1 TO adr SYS "Amnesia_LoadFile",adr,"FSPSprites",0 ================================== FastSpr_SetFlash ================ SetFlash was inactive in this version. ======================================== This file last updated 16/10/94 by A.Southgate. FileDataHelpTextEf"?FastSpr version 3.00 (16 Oct 94) ================================ This application provides a high speed sprite plotting module. For full information, refer to the documents inside its directory. A. Southgate 1994 - use and distribute freely FileData!FSPConvy$Eo9<h7SK @0SKR'TF'0qv0g _#8]4iTf\Ol!]ns),Ist\##ҟKzbN(lȓKspn g*#ҟK,{c_Ц"ۗdȅ(s$2vJf nYP׃՜8Q4}Ek nZ KuG+kfٙKeEc:4i#Ѵ $UUy5oȘnd`U_oD63q( Nq3!3q\q&#N_8+#όџKջ$,Ut&u =0" =$Ƨr*OaC#\gўKkU%O]0|ڈD~ Dd\Ycu˥߷Sp,xKfFK|-xJpfFND븥@po$ oozF"FxΈ4 u'p.#p/p0p1 p2p3!o*%եo+)եo-o,1եo-5z.kBrTC #ϟKLV)Kw{aK+WLnqdihU 8dWHU֫~~tKvCq֏ C~ͥ_;t: #͟K;._mJtޓ#Ϟ(ʹ,&\BȂA8Dv}(f,/v/vՂ(lT֮Ar'cr6s#̴aiՐAL⻵hWA@oj~ Sv# ̟Kʐ/Bk6~TAͷZ~9GX`a:ǡZϥ &)/R aXbS[~Uv# φ̟Kj.Bk6T~AͷZޖ~8FXtTppa|tzkw轹Z(T aXbS[~]za-eCl*hrv{,ѷ{8mٓ$9̴nQ%M-R}>`WB!εpa䛃!FfKYidd2QK0#N\[r~eYfD$g\~k"= LR,l,^bbNH4?ռ~̻fm삿gZ}H3{|r~bˉ"avZ{P{-ό![taddW)8rٓ#Ϟ˟K$kQ%M,u[V,B!δpaP!F\KdYidd2QA0H3{|r~eYflg{~A2 =N H4?ռ~̻fm삾gZ}þH3!|[{wbˉ"avZ|{-ό![dtad`Wlra3#˴Tk!rUK8+Tf|ΐ,-v~h4{{紀個u~AŐ,|}e}WqɎ!7ӃTu!UB\US #ʟKkGFmx2|powa{ϦhAiRHiNJ[}ŋDΉ⩻Ьƻ^fUg:_$$}ʴBx6|ϥdžwk d\ȲPѳүQϳЯwپƳ{Ư{HپƳ{Ư{,}H|Bye 슓Є*R̙̿Ȼ n yB^œЬuـ!R$nۉЬـ!R(n۵Χ|wuf}ތA }: |NUcj_4##ɟKٻ-|}2MVU#wd/^\U0/^\S+`w0"pW/4,y u P^}tp{9xj|0P ዐa v*\),Y"[mncft: ax#dFs* O̔S i{ \dHK݃#/f\ uyT^Vɜ^d׉~^0kkР[w{"e~(~lКz΢wtJm{}޵e{tG|!wpْKU #ɴڻ,ƴԻ%Vݝ XԻI? m:soC 2c3 OKat#Dt2[t>=# ȟKջdo`f/He[tbo񹥽o񹥽x,ҡВFti:##ȲȟKٻpklCM7 m{xŦ  @n-[`,Z =e;n? detC?o:o^eDo@eCeU: mݒ O̵Sܽ@cڋ[] #bȟKBHք>fPdFuF}{ P/pf\|#=A=kM̗X%]#,ȟKC bFmz᰼t{4.o J|p 44cDtHCnY}罀z{|W{s Dq3L{h=s|x՜ snomˆ]#ǟKBPG8ioJj,xƒjCxeF|VslkCGWU_oۥ'lGoJAlL0אKρR)bxj)aZxSyxj)ϙvo}:md:eubJo Jf"e*rdPo1:K֢ IJrcP㓪uL9agtfClˣudk9rJ#hgԘ #dBE.T,)TqhǔSCF\fY!mq;[)%[xՋE~qFCf>>E^Eq#φğK`^crYŋ$Ӷ>u#tğK^QrYŋ#ⶪZ#aĴ$9˽ 7œ&\a{ѡ0+Xa{ǡȶ&`a!La{dklJcl#*ğKٻ,^_0"YVӹZ󍛦NKdXdXBddIkhlJ_nm,4d5#ôڻ,_^̴ܬ0{VXZә qi~,q|iFr`VcX`qִܓxqaDrF`VcWIL_Jr3uDa#,Ăe~i(c% n$c=IfzfffP? ?X 23a^t,3Orn?g: #|ßK,CVeͼihezc fQfch˯A0g2f>s s(JceBhu@4ndW# f#5t#_Ѷ:oed##FßKCI",le؎pvCcphefgchcchk˰Afeyw f>:e |3ozrg# 04Šdb>;yh\"7˶X{€NɉOAwX?4V.Šud3$r# Ϟ´If;lpW˻"X׋pUhBnC 2w ̶|ɷɸM*duX*Vb/.3>yVbIVrd3#Ϟ+լ´:i͆pE˻d4U kvȶ|(D<bh#D ЖXVm.X3$e;diC$}#|ŸKK6/|#!{/!t?F\lV&igǥ෴'T[I1.62;8?<@LVX.:>ľ!Υ6W1pľ%ľ'#^.8-vv@d\sW6caF&HҷdUJy<#´|xvfxʀɦu3N65LM6%C:J3HIFG?E>0N&>򣐣`;8TDHb,"-5:ǏH"/``%"ΣXN_&#߿4o dBH*Pum UƋc!ib@Cް#ſd̜sΜϜDDghbJjL"{b)o))ZbU'ɜ\HuDdQ3| #ΒK@g,elz{U ֢|tˤ3.:2n3;ii\4s #`qdBGݦL\@mh>Qhn|nc8q@a;@ചy_ŋmش_ŋbm02o8n*p3r:l3.3uA.$e3 {y:s'eCd331 #jr.:RQ:p J,!tC gp3o-:Qi[o4Cr*,2R:2TNA 3t ,N4dt0Cͤ ߣhZŤpDVfb\Kw[v4륾ϻO#)ֻ=kc# Kw 3LeʒWUۜ$t04w(,w $ww3} }} %$w՜L9ʒW,#ĽKͣ"޾M#3Ľ޾p/˴...#ΚK3o#֏3Fδݸ ۵orm"M#xKٻ\\wANHmsHy5iEȥ s Ȼs'/'(",-pFayv [p pٻȪrpxo 5ٴxAClfl1hllXљ#,K-6l]# KC r ƭbƭbƭb jvW#C4̵Yݶݣb\̭bGۛb\̭bGRmo ))mvml))mvnlz!z` )nv(l" JPK1( (#ɼK`k&\8B mpr趨Rt:d_۪CߪrTJ%y##mcaBt:am3#ϘK{n,v rضrضr˱qضqض {PO0)"o`b#gvڜ 0ov"ۥR#Ϟ)XB8oɴ8Kp[vcTcq趦yRqt:d_۪Cߪr:nsG3e]uBeS 3to\#&K3νL:yn#3RLkn# a3ܽL\nRa[#e3ʸݽͽLC6DnRa[#Ỵa3ܽL<2nPa[#ϻb3ܽ߾L nRa[#ؽb3ܽ߾LF6nRa[#֫a3ܽLG6mRa[#ؙe3ʸݽͽLm-UUսȽLͳm#ֳ3mL#ΤK3˽L6Ʋl#3ĵ!6klL#ΈK5췬6flL#zK3ێL#nK!3̽L#a36kL#RK3˽L6Ʋ#C36kL#4Kw3ܽȽL6#3'ĽL6#8T L6# PUP彬6(fL Ako#K@[ {6lLٻAko#⹟K36kLL6ƴWL6V#ιK36k{L#¹K36kzL#ζK36kyL#ΪK3ȷ6kxL#ΘK3U6kuLL6U#ΆK36ktL#zK3L6r6kTL6kJL#3gqL#\K3!]U-ULp#3KĽLn#3?ĽL6m#33ĽL6l#3'ĽL6k#36kjLFVuYXfAZF^uẠ#K36kiL#K36kFkL#渟K3L6Ơ;k#ڸK3ܵ޶޷޸6k$kLûN6;JûN5J#θKûN4#3ĽL6j#ֻٟlŻ0=IL6ƙblՋ#336kjL#23ܽɽLj,Lͻ6"mIN#31s(QCSi##o S}L6j#30˵`ͶyɷyɸyU_" ϽL6jmI~,#3/˶A𡬋#.=3lǶ䡬)]n9"t#-3ۋގޏސ#,3С׋#+3˴˻آ#*3˴˻ߒ#)3˴˻ԡ؂# (3˴˻ݏط ިm[c#'ڻ3X# &3˴˻eبݽE[b#%⻖뙘3,̴˻ݬ'$$ڻ w3,̴˻/}׬b]##ۻ3!ק#"ۻ,3Ѝݬ彵^bM_ # M)#巴3û 㡸ϵ鶍#3˷Ի#ϼK3Իb[#3Ի6kХ#ϚK3Ի6k܋ս#׉3û6V#xK3Իv܋E #g3û"6c0#RK㻘3Ի46kL܋ݦ# #93Իݹ# K3û#3Իܟ# K3Ի26k܋ݦ!#3R3lʵ׬#3ٶԻؠ؋ĥ#ʶK3û6ɠ#׻3ûչؽ#ϪK3Ի ۨ܋ս#י3û-6ߵ#ψK3Իۆ܋ս#3wԻ!6kv؋#hK3û/6Ͽ#Y3û Wﶍ #A3û)6=ئ޽Ϸ鸨 #'3û #hi #3û+6 ئ޽^n# K3Ի ܋ݹhޠ#ⵟKj3la`_ݬ#ѵ3Իܽϲ鳍#۵3Իܽϲ鳍#֙<=3l"ɷݛގޏސ#πK3ԻۺNc[#m3ͬ[c#\K3û66GJ[J[ xIxI #8Kջ ط!ط"߷## Kջ ߷!ԡط"߷##Kջ ߷!#Kջ ߷!A}B~ CG5"STQ[!RQ%kB N"NG7W7}GeE7W \kN z QE DyKD)U\S 60@K : 19/KK F#wĴrg?$e13y+J:#fK浜]g*$)e33TC#LK-˵Uݴ ,¬^ #5@gjq-@tҡg) xNц#ydOIաWl# KٻHڼߡEﵜﶜo~E[pm]# 䳟KջJfRi^ ]ÏZҲw*!` #˳FP ^iT h?"@NgLۑ#ϨK 88#"9#ՙ (]Nb#ϊK,hPҎQK[֌KڥQ+]QHBQպ reGwg=^QMjmg]|nQ>X UQQKQBM[K|VgM@nި!ȌNKIgL!#$pdCYm:à虔ݬ,ֶfUo:J i :td#w;E#Kջ8;<9:%b$\yL*\+\)L%\WfxLbaVsUu_ tYq}{{s-zE:qEH^oraolr +pv# ϞQ(ֱd\F G؞I vRwW ;J JG >C}>LǕ>z\ "8\7Q6UVJTά[ŻvީѻŻKϩʵC?oAܰ{ K[ũ𵜸[׏5朵AܐD[Ż y[ũܩ\؆Ma6zn A?nZ-do+Tvs(TPۋ l{O,hb}Ȝf񹻠!A">Z"vuًK#KFE\,ឿa@PLkae3ou_3c< xiEx]@Wmn]7}xUP(:oD0f<@f8QDTڽŧ|Qn^^UX ֧$,/#X{#p|Ν+X}*Q/!Z\{"z훵]Ȇ2ν,QLO{[۶PndLW%xz\J`ǩ`OO`0G{4}lS0wpS}U@Džuד!#!4(wN"N##E#FnZ 憰!n*͒$پRՑ ZQr#(K(3ҵD#;©L#Ϟ[KTfK[(Qe9$ $!gǥ^X f$Sߊ]@Nm,^Ozw UOh 5_Oo_!w Φ|EHD,)7?C7A?@=>=>;#K3̽LlZQ# K3̽L^ZQ#K"3:kNZL#K3̽L@ZQ#3ߨĴUQL̟1Z#ШK3QL#Z#3èĴQL̟Z#δK3QLZ#3Ľ޾LYQ#ΚKm^]"mU g[3[ }y0ͽL"QVLYQ#zKk6f"l,"˵7si(_jճ\,""_#\Kջ-ܵLۉ˄6şY)= WX$+,*#=K8$l@0ZvՌ#\-KIjB8t%p<$=8#[,ߝXkej`,R(sܪdN1I3mf r:%a22 ?l#ً 8ɵ8=ݹ ׺<8~ 9~v׻v$8|<\\˴L, /L+Bȼus.0ì w,U[x #kl7t \ ZS ?:H{ g ~v 蒵; AյLx~ˀRY٪$U}0ޖt"(QXȧ2K:犯fe2#>K黜kBT׶ x w Rx> wΪw k"/(qvd;Ig#KF۵ N’"IYn#Iۀ9^g;YW;Wo`-Y鵜WH펿LF< ڪȯFL :<Ț#<99=eIX ;b"~MFX،!ptn8!{ٌKcU"p06mt#ֻً롸!aWmn#w!Bn2^NR=m{Cwkt ּ ~T dW|  #;!MD@k?Sp{]sؿU8m1Ռ$ =V*֡Ʃ:K AK L@#^ e!⠸6htn[Ud6f#n,ƻ XXB]tnΨ,=nmo"5W5 n(W5 n"W δxnxќԜҜМn#pxn,"uisɴ,xm#ΚK ۥ"]n}wœ}>8!i,xi(zĜ~ܝ&!ܻ!#kɡXљ#`K1٬ṡޜ!l*Ӝ*IάnᣡPMG  Φu͢nu wn3^v2mnmzހ0s$ĜnjN# Ϟ'K۬9^ًڋ1WU跘hϬLF< ڪȯ#΢K zG5f,l͗ #桷`'#̳Kջ9⥻٧A'#ϞKۻnȜ۸gH"X""xWo""n#ہ{oȜpĴVx x5F `X#dKnwWm24f nmPhl#ϞJ˥9I¶ť`]VDΡF֚tb{n͚¬b: #ChJQa"hۆ̄yȜƻhh㖸hDۜ'pipYq0.B6:#͟ɴT.G(5H4aꔪ#ԡK@$iVJDr#ϞKk3Hsյ@LmJǬݏX鏦 Ns^& ǵݷ9RwsT[@ܵs+2:loaM3o 9$ *ϴ^T,۵Rȵ'ʡ+t3L#ip+ OC:#HKpkHQ3IjhR˟ɴ0T@4:ra#r*hzRwYTnkhgRwT&Җܵhk^TR m, K"KkmBN19wޠ.,#ᠴ(xk T</.?D&##\ѠK[="B 6kٰT Ut%?UB8NO#\K]WuY,‚cQ VCaPJaGeCAِK\xdNׄrRpRso#8'Ğ˵c "#,WW7# Kl.#K$nwBYF=fL= f(1e Rh,jf lc5ؓŹ@VAT /..".#̝KܐkB,l(bQxлUAhh ew*,wB*1l㴜6#0tgnɥvQY3ڬ./#3}۵ϟɴrP@(m9:nڣdaJnn$tALO#XKջvs]t!OQAPxcmܜ_m0:no~3mshCsE*m:npy"iW)ԙ#Ko`ۢzPQxnM{yZ MWu/ʙf"ch"0 # 윟Khkh;pTO~Q%8QqO)۬zoyȜ K#}CQM1լ#{]Ы8sǬw9#ٻ{]Е6sNj7w"5 B 0#\"\.Y#Ϟn;KE*ui*iB#iQi '=o tk T6/o%R4io2ge[#| vÜ{\|'$P(F |Uŧ[ھ Ph-t{@% #ʨ [ePbP녹7p$BP>Pԃm.%/ݜtۜۑ@MMin#n a~Cf3e#Mll5"P.P| #PًȦP pjs۹ PD"#Ξ*8Λk֋P{ML#OaE#G P5#ƯƜf./# ldƜfh{BZ[mHM|xDQDe4f:U)53D+(WתifDd7"WתioH*5orB[ͼ T""8cdfg ue 户|{HD֘˚L҅Հ=HۡTO,h:*)1.*1+2+%2,2,SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS%T!""*)"""&'&(  A T BTZT)qT)dTdTB[dT ss"dT vu"dT )dT )dT )dT )dT )(E @@p@) F)Q %   "(    \dJh]\J] \gD\^2]D^dNjgH cc\  ^ ^ k T  r`o\x`hj|{**_<*J\_T      - .-  }. k  ` o` |q@?*J\]^T       @# 2    (\M--O4I g F_.*`ft  h K O?{|. &e2*e C)i1*^ ֯7dca Ad* maf_ֲ`Ik* `&*aY?e>*_aȩA*|?b= SE D,_*QT`wE]`d ^\a  ڎta]\P =V1D *  Dث]5[\m0V  :[W  y")& "#!*,!}Ar   ` tl { l k ~@Pu> \\z]i\]k] j]l]j `g~i߯_`?     \_@](]Jc  _^*e  ]5j kk k \k: k k { kό `ä.\ϼHa]`h"`f\g @lgծ(\]1 \Zgu^\ ?ܭB"b]]C]]]^@ kl{|kkpk &g` l 2k2k\X_o&*g_P\i].\.g^^͛`g~   )k4|  $L\_fw 'H   h       KD! \ecb   k  \g_\g_b` ak kkk \ j||lku(rd`2|Hv`\x_g{|lk{\j_hh_l_|_hhoxkl_h^ ]Tܿ\kkkkkk:kkk@] \i\t_ \gkl"kkk]8zЮ]@j]0jm8^4pl*]j\d"kxl쏛\`\^6hl] j],^*"\xg\lJ\^@j]`k],^(h{\\`2] ](h_`h^]X] ]]%b-\d&   _( ]]^{f,#&       SZ&,*  )%    &A| 09  #$ E% dyEb@ax'o\J\^`` ^Q\`] b{\a ]y*::|] y%]ub\J]_^^@]_]_]`]_]oR_KDR`  f h #7Я Zo@`_d)] y*Я]]CcZ:^ '\ \^]]*\\a:]Jlp@kge      / cE]_]^e7\\  ]]_]\^ ]\F\H ]]4b]n3]]=^ @a^a ShTl l;lAƲ@]EƠ3^y!t9gFǮ<2*ٮ󜣮_ 8)\]e]]]] F}]]^u6`]H\O]]`\^S]0*]\] ^ ^hAad*]_`G_b^*L``]]g+^]Y^\I^\N\I \^]]]`\d* k]^__`IgO\_`ba{ iiD`O]]E]_\a\\^Fa*^ f` w/\ ^ ]_^>_^]\]eA`^ ^^* ]M_1_ a*}]zA\^_S^L\]]4*`I]i_SaL^\L \]Oc\]] `Ea_d]]-cE]]_]]`\*_\]cLf]Eb_^]p *\*ﻎ@:P]*\*lb{}\]i`,(W  AX^ ]\py(^X]]]]e^ J\\\\`^J\]]`@*]\pqa^ u *WK *ZJ\H\IJ\K:\+\\`\\Z^\,]`\~( ]]]]]]\]]_^~]] e_]]i :*_\6.]^@c_@]]f@:*\ *\] ]]Z]]^u]Y\]0] P\^yg`J\v   JZ *:\*\ \:\*Z\p::\J**\a\` \\p]\p\:\**   \p] "^i=\]\]]]^]an]c]_`]]y   :{ J\_w***e_abPg_            / & -`  ::** &:\)\ \***\  7 ':\p  7 '\ :  )\ F,\m *^ *\:*\`]  ::**   \**\&** \J\`*  \   7 \`**  G\    7& \m   G]:*\`\m***\:\*Zl l0\*_ ]_@`K9^^^]c]*[Z*I\\]f!*\:\pIZ\`]Pf}\]p\J*] \p]]\`a]\:\**\*\]0]d` ]^]]]\ab] _] } G\(^_`ce                  qB Bk*l^``h?,O? @ JoV` q P@ 0[) QQ T 00K00Q\Q00Q00\Q00T  @POo@U H Z7`z0 SzASzzD S@ zzzzL&2 SzQ0(SzzT0(SP0( zzzz\0(] `I ]ʻ|Hrcc 3.00 FileData!HelpObey$EJFSPConv ======= This application produces sprite files for the FastSpr module. Please load it and choose Help from the menu for full info. Andy Southgate. FileData!Run"="" Then Error Open a directory with !System in it first RMEnsure SharedCLibrary 3.50 RMLoad System:Modules.Clib RMEnsure SharedCLibrary 3.50 Error Your version of the Shared C Library is too old. You need version 3.50 or greater RMEnsure ColourTrans 0.52 If ""="" Then Error Open a directory with !System in it first RMEnsure ColourTrans 0.52 RMLoad System:Modules.Colours RMEnsure ColourTrans 0.52 Error Your version of the Colourtrans module is too old. You need version 0.52 or greater |Increase wimpslot to 128K if you have memory problems Wimpslot 112K 112K Set FSPConv$Dir Set FSPConv$Path . Run FSPConv:!FSPConv FileData!Spritesy$Ew!fspconv, wwwwqgydGydqwd'dydGdqwDdqDteGgwwwwwwpwwwwwgwpwwwwwqpfile_113,, wwwwwwww '"uy vw'bybuywGfU'@fuwy gGguwwDgUyDUrVwWUrfye wyg&"w'"'wwwwwwwwptr_menu ,,@UUUUUjUYUUU@iYUUUVPZiYUUUUYUUUUUYUUUUUUUgright ,, ADEDDDTD%""RDEDDDTD%""RD%"QD%!RDEDDDTDD@DDDDDDDDDDFileData!Sprites22, Ev*0 !fspconv!TwwwwwwUUUUUU333333DDUUwwwwwwwwE7DDyD3D'23y3D12CyA31Cy1C3wwww"Cy$!C7"#2Cy#2223G3234DyC"3C4733CCy434Dwww7333Dy#3CC33D7#232Cy333DC743CCy4C3Dww7DD7EG4DDtpCyD34twwwwwwwwwwwwpzzwwwwwwwwwwwwpSE3Dp EDDppwwwwwwwwETfile_113!wwwwwwUUUUUU333333DDUUwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww@twwwwTDGDww@E3syDww@DDDC7TwwdEtwwwyCEwwUE7Sww@VDty3wwdU5DywwwGDDwweUDCtG42cwwUEUCCy$"BUww@EDEDCtG"4UwwPUTED4Cy$33EwwPUEDDwwwG4CCww`UDEty4CSww`UTCCwwwGDCDww`VDECtyDDDD3Dww`UU45CG443CDww@UVE54ty4CDDDwwfEEDDDG3DDdwwVEEDtwwyDDDewwTVVDGETFww@VUEtwwwDDUwwVUUDyDDDDfwwdeVFtGDDUEww@VVVDyDUeww@ffUtyGTwwdUUewdFww@feEwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwptr_menu ,,@UUUUUjUYUUU@iYUUUVPZiYUUUUYUUUUUYUUUUUUU4gright,,@DDDUUUUUDQD#""QDQDUUUUUDQD%!!QDQD%!QDQD%QD%QD%!QDUUUUUDDDDDDDDDDDDD@DDDDDDDDDDFileDataCentreMenuEMCentre Menu Help ================ FastSpr usually plots a sprite so that the centre of the sprite at the coordinates given. You may, if you wish, have FastSpr plot the sprite so that its top left corner is at the coordinates given, for example. Any offset 0-255 is acceptable.FileDataFrameMenu E[)The Frame Menu ============== Frames refer to the animation frames which are available when using FSP2 format files. The frame sprites are named by following the sprite number with an underscore and the frame number (starting a 0). So, if sprite number 7 has 4 frames, the sprite file which you load should contain sprites called: 7_0 7_1 7_2 7_3 In general you should not have missing frames eg just 7_0, 7_1 and 7_3 say. To use the animation, you should pass a frame number in bits 23-16 of the sprite number which you pass to FastSpr in R0. To plot frame 3 of sprite 7 in pool 4 you would pass R0 = &04030007 to FastSpr. Remember that animation frames are ONLY available in FSP2 format files, and therefore only with FastSpr version 3.00 or greater. Animation Sequences =================== FastSpr animation can usually be carried out using a steadily incrementing number. The table shows which frame will be plotted, depending on the frame number which is passed to FastSpr and the number of frames in the sprite file for the sprite in question. Frame number passed to FastSpr in bits 23-16 Number | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15| of frames | | | | | | | | | | | | | | | | | =========================================================================== 2 | 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 3 | 0 1 2 1 0 1 2 1 0 1 2 1 0 1 2 1 4 | 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 5 | 0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 6 | 0 1 2 3 4 5 5 5 0 1 2 3 4 5 5 5 7 | 0 1 2 3 4 5 6 6 0 1 2 3 4 5 6 6 8 | 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 9 | 0 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 10 | 0 1 2 3 4 5 6 7 8 9 9 9 9 9 9 9 11 | 0 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 12 | 0 1 2 3 4 5 6 7 8 9 10 11 11 11 11 11 13 | 0 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 14 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 13 13 15 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 16 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Note that 3, 5 and 9 are special cases. The patterns wrap around after 15, ie 16 is the same as zero, 17 the same as 1 etc. It is possible to use more than 16 frames but you will need a special version of FSPConv - please apply to the author stating your requirements.FileDataGeneralEY&Help For FSPConv ================ FSPConv prepares sprite files for use by the module FastSpr. The FastSpr module provides high speed sprite plotting with clipping and masking, and has proven reliable in the commercial field. FastSpr version 2.00 may be used with no royalty payments for both commercial and non-commercial applications. FastSpr can be obtained from most PD libraries. Using FSPConv ============= FSPConv converts a normal sprite file into a FastSpr file. A typical FastSprfile would be created like this: Create a sprite file using paint, with sprites named 0,1,2,3,4,5 etc... Drag this file to the FSPConv icon. A sprite window and a conversion window should appear. The conversion window has a save destination filename, which by default is the sprite filename with FSP inserted before the final name (the 'leafname'). If you want to, drag the FastSpr file icon to a filer window to change the save destination, in the usual way. You may now click the 'Convert' button the begin conversion. Bazaam!!! FSPConv should do the business. You may close the conversion window if you want to mess about with your sprites before converting them. As you might guess, telling FastSpr to plot sprite 0 will plot the sprite which was originally called '0'. BIG NOTE: FSPConv cannot convert a FastSpr file BACK into a normal sprite file, so keep a copy of your normal sprite file to edit your sprites. Transparency ============ Sprite masks are ignored, as they double the size of your sprite files. Instead, one colour, usually colour 0, is taken to be transparent. This may be altered on the icon bar menu if you wish. Limitations =========== Both FSPConv and FastSpr were designed with 256 colour sprites in mind. They both 'should' cope with 2,4 and 16 colour modes but the horizontal position resolution is reduced (FastSpr takes coordinates of the form lines down, BYTES across). You cant yet drag a file from a !Paint save window straight to FSPConv. Sprite palletes are ignored. This makes the 16 colour ones look a bit bizarre in the sprite window, but the still convert OK. FSPConv will run out of memory if you have sprites numbered over 1000 or so. The best cure is to have lower sprite numbers as excessively large numbers waste memory and disc space, but if you must, change the WimpSlot in FSPConvs !Run file. The Quick Test ============== Try this: Use !Paint to make a sprite file with a sprite named 0 which is, say width 16, height 16, in mode 13. Be artistic! Save it with the name 'Sprites' in the root directory of your disc (the one that opens when you click on the disc icon). Drag this file to the FSPConv icon. Click convert. Double click on the !FastSpr icon. Press F12. Type 'FastSprLoad FSPSprites' (without the quotes). Get an error message? Type 'Mount' and try again. Type 'BASIC' Type 'MODE 13' (capitals). Type 'SYS "FastSpr_Plot",0,150,150' with all the capitals in the right places. If all is well, your sprite should the appear on the screen. Status ====== FSPConv is public domain and may be freely distributed. The program was written in C and compiled with Acorn C version 3.00, so it should work with RISC OS 2 provided you have a copy of the Shared C Library 3.50 or greater and Colourtrans. Bugs ==== I dont know of any serious ones, but Id like to know if you find any. FastSpr is known to have problems (address exceptions etc) in the following situations: If the screen is scrolled. If you try to use two screen banks but dont have sufficient memory allocated. Please send your bug reports, both for FastSpr and FSPConv, to: Andy Southgate 14 Madingley Road Cambridge CB3 0EE or Email as142@cam.ac.uk If you could send me the sprite file which causes the problem, so much the better. Good luck! Andy. FileDataNumberMenu Et/The Number Menu =============== To produce a FastSpr file you start with a normal sprite file, as produced by !Paint. The sprites names should be numbers, starting at zero. To spell it out, you need sprites called 0, 1, 2, 3 etc etc. You may have gaps - your file may contain only sprites called 2, 5, 7, 67 for example. Your sprites may appear in any order - they will be sorted into numerical order. You may include other sprites which don't have numbers as names - these will be ignored. For example, you load a sprite file (by dragging it to the FSPConv window or icon) which has sprites named: 57 test 34 12 pattern FSPConv will ignore the sprites called pattern and test (as they are not numbers) and produce a FastSpr file with sprites numbered 12, 34 and 57. FileDataPreMenu E/*Preshift Menu Help ================== Preshifting is a technique used to increase the speed of sprite plotting. A preshifted sprite can be written to the screen 4 pixels at a time instead of one. **NOTE** : PRESHIFTING IS ONLY AVILABLE IN FSP2 FORMAT FILES. Up to four copies of the sprite may need to be stored - if you want to plot a sprite at ANY horizontal position you will need all four. Let's say that n is an integer. If you want to plot your sprite at x coordinates which are 4n+0 (eg 0,4,8,12,16...) you must switch on the toggle icon marked '0' for that sprite. If you want to plot the sprite at x coordinates of 4n+1 (1,5,9,13,17...) you must switch on the toggle marked '1' and so on. Using preshifting with all toggles 0-3 on will mean a lot of memory is used for the sprite file, but the sprite can be plotted in any position. If the sprite isn't going to move horizontally, you can save memory by just setting the '0' toggle. Note that the settings of the preshifting controls will affect every FRAME of the sprite that is showing, but the controls must be set individually for each separate sprite. Advanced Use ============ To get the best from FastSpr you'll have to know a bit about how it works. A sprite can be plotted using up to three techniques. (1) The STRB block ================== This moves pixels to the screen one pixel at a time. It can write any shape of sprite, but only manages one pixel every 6 cycles (ARM 2). This is the method used exclusively in FSP1 format files. This technique can also clip a sprite to any horizontal position. Stores 4 bytes in the file per pixel. (2) The STR block ================= This moves pixels to the screen four at a time. It can only write a horizontal line of four pixels which start where the x coordinate is a multiple of 4. It can only clip to windows where the horizontal coordinates are multiples of 4. Speed is roughly one pixel every two cycles. Stores 2 bytes in the file per pixel. (3 The STM block ================= This moves pixels to the screen 12 or 28 at a time. It can only write a horizontal line of 12 or 28 pixels which start where the x coordinate is a multiple of 4. It can only clip to windows where the horizontal coordinates are multiples of 4. Speed is about 1 pixel per cycle. Stores just over one byte in the file per pixel. Note that there are a lot of other overheads such as clipping tables, which increase the size of the file further. FSPConv compiles files which will plot as much of the sprite as possible using (3), plot as much of the rest as possible with (2), and plot what's left with (1). You may permit or forbid FSPConv to use (2) and (3) for a particular sprite with the toggles at the bottom of the sprite window. Points to note: If you switch off the STR and STM block you are no longer using preshifting at all. The sprite will be plotted as if it were from an FSP1 format file and the settings of the toggles 0-3 are ignored. Solid sprites of 15 (or just over) or 31 (or just over) pixels in width can be plotted very quickly using STM blocks. Transparent areas may reduce the plotting speed as STR or STM blocks are more difficult to produce (as there are fewer continuous horizontal lines of pixels) and the rest will need to be plotted using an STRB block. You can make a big difference to the size of your sprite file with the pre- shifting controls. Experiment to find the ideal set for your application. FileDataSpriteHelpKEHuSprite Window Help ================== The sprite window allows you to Load a sprite file by dragging to the window. Review the contents of your sprite file. Move the centre positions around. Start the conversion. Try selecting help from the menus on the icons to the right for help on individual aspects of the process. FileDataTypeMenuE)uType Menu Help ============== FSPConv 3.00 can generate files of two type: (1) FSP1 : This was the first FastSpr file type used by FastSpr version 2.00. (2) FSP 2: This is the filetype supported by the second generation FastSpr module (version 3.00). It allows the use of preshifting and animation frames. If you don't want to use preshifting or animation frames then use type FSP1 as the output file will be a bit shorter.FileDataSpritesey$dEv5h,up,$$AA$$AA$$AA0CCCCCC#0444444$,down, AAA44AAD4AAD4FileDataTemplates$EDcVProginfo tSprite Conv Transp oimp !Convert onvFakeMode impz` p=0x 2`Title: "T~`Author: `Purpose: B`Version: P=aLP=aP=aPD=a Pa&About this program ... R2 Andy Southgate R2 Makes FastSpr files R2 ... R2 This application is Public Domain. R2   =8/CD *GH KL OP @bSa2:Vf down 4*p=bd X:|f up :f1rs 2V" down **= X|" up "1Ǘ H=H>l= = 0T down (= Vz up `1 0@Tl down :(v= V@zl up HSize  Mode  Centre "Bx: "JBjy: BFrame =FastSpr Typez*= ~1 53 68 TJL j^` rt 1dž h8=1 Bh0=18h=1(T (NT * Name5No Sprites R3 R3 R3 R3 Sprite Number 0 R7;Pptr_write pptr_menu;Sgright ... R7;Pptr_write pptr_menu;Sgright ... R2 ... R2 ... R2 ... R7;Pptr_write pptr_menu;Sgright ... R7;Pptr_write ... R2 ... R2 pptr_menu;Sgright Preshifting for this Sprite R3 0 Sradiooff,radioon 1 Sradiooff,radioon 2 Sradiooff,radioon 3 Sradiooff,radioon pptr_menu;Sgright Full R5,3 Horiz. Locked R5,3 None R5,3 STR block Soptoff,opton STM block Soptoff,opton Current Sprite Conversion Control R3 H  = x@ d=:~Transparent Colour R1 ... Pptr_write;R7;a0-9,\- (-1 for none) tJJ  =xZ~tNd`"r aZ td8=& J=1r N=1zj jSource Size>jpj4  \@ ^N=1Convert Sprites R1 R1 R2 R1 Sfile_113 Output file R1 ... R7;Pptr_write FastSpr R2 Convert R6,3 .... R2 Cancel R5,3 ... R2 Output Size R2 ... R2 ... R2;L Size? R5,3 l  =  x@ =$&"bMode Fake Mode R1 ... Pptr_write;R7;a0-9,\- Use fake mode Soptoff,opton FileData!BootallacAE_EH|!Boot file for Stasis Set Stasis$Path . Iconsprites !Sprites Set Alias$@RunType_112 RMEnsure Stasis 0.41 Run Stasis:Stasis|mStasisLoad 1 %%0|mStasisSound 1 1 &7f &4555 Set Alias$@LoadType_112 RMEnsure Stasis 0.41 Run Stasis:Stasis|mStasisLoad 1 %%0|m Set File$Type_112 Stasis FX 212 128 FX 213 68 FileData!HelpallacDN| !Help file for !Stasis Set Stasis$Temp Yes RMEnsure UtilityModule 3.00 Set Stasis$Temp No If Stasis$Temp = "Yes" Then Filer_OpenDir .StasisHelp If Stasis$Temp = "Yes" Then Filer_Run .HelpText Else Type .HelpText Unset Stasis$Temp FileData!RunWallacdD.kN|!Run file for Stasis Set Stasis$Path . Run !Boot RMLoad Stasis FileData!SpritesacDKqx]L!stasis,<  CuwwwW4BuwW4 CuwW$ W$ CuwW4BuBuwW4"CuwG4rW$Cu'2TwwwwwErwE#2Tw'swwwwwwwwwwwww tGDt7333s'"BW tGDw333w"BW tGt73s'BW tDw3wBW@wwwwwwwtD433""CG@wwwwwwwfile_112,, wwwwwwwwwwwwwwwwww333333333333333ww###############ww"""""""""""""""wwwwww!twwwwwwwwwwwGwwCWUuGDDDt7"B5ww2WUwDDDw#BEwwBWuGDt7BEwwBWwDwCEww1wwwwwwwwwrD433""C'!!!ww"""2wwwwwww#"""ww###############ww333333333333333wwwwwwwwwwwwwwwwwwFileData!Sprites22\ DW` !stasis!TwwwwwwUUUUUU333333DDUU "2TwwwE# CwwE3Tww40tw4""CwGtG#2tG@G 3330ts CuwwwW4@700twW43CuwG0tG# 2tGsG0t702DDD#02TwwwwwE#@wwE333Twws4""C7 pwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwDDDT7333s#"""wpGDDDG333t"""rwDDDu3337"""wpGDDt43C'""rwDDT63s#""wpGDD73t""rwDDG3E""wpwwwwwwwpwwwwwwwwfUD433DuwfUDC3CCuwfUD433DupwwwwwwwTfile_112!wwwwwwUUUUUU333333DDUUwwwwwwwwwwwwwwwwwDDwwwwwwwwwwwwwwwwwDDw333333333333333wDDw333333333333333wDDw222222222222222wDDw###############wDDw"""""""""""""""wDDw"""""""""""""""wDDw"!!!!!!!!!!!!!!wDDwwDDwwDDwwDDw1wwwwwwwwwwwwwwDDw!wwwwwwwwwwwwwwDDwtGDt7333s'"rGwDDwBwDT7333s%"w$wDDwtGDW333u"rGwDDw@wDu333W"w$wDDwtGt53S'rGwDDw@wT73s%w$wDDwtWW3urGwDDwBww3ww$wDDw1wwwwwwwwDDwqVUD3"2TwDDwrVUD3"2T'!!!wDDw!!!qVUD3"2TwDDw"""2wwwwwww#"""wDDw"""""""""""""""wDDw###############wDDw222222222222222wDDw333333333333333wDDw333333333333333wDDwwwwwwwwwwwwwwwwwDDwwwwwwwwwwwwwwwwwDDFileDataAlSourceacE)p#type &ffa #name StasisDVox #base 0 #include ASMLib:Standard #set Service_PsychoStarting=&80300 #set Service_PsychoDying =&80301 #set Service_UKStasisFormat=&80310 #set Service_StasisSave =&80311 #set Service_StasisIdentify=&80312 #set stasis_alien =1 #set dvox_filetype =&108 struct dvox { .type DCB 0 .flags DCB 0 .pitch DBB 2 .dataofs DCD 0 .repstart DCD 0 .repend DCD 0 .id DCD 0 .version DCD 0 .upcall DCD 0 .len DCD 0 .sizeof } .ModuleHeader .start DCD 0 DCD init DCD final DCD service DCD title DCD help DCD helptable DCD 0 DCD 0 DCD 0 DCD 0 .title DCB "StasisDVox" DCB 0 ALIGN .help DCB "Stasis Alien",9,"1.00 (24 Jul 1994) - For DataVox format samples" DCB 0 ALIGN .helptable DCB "StasisDVox" DCB 0 ALIGN DCD 0 DCD 0 DCD 0 DCD dvoxhelp DCD 0;End Marker .dvoxhelp DCB "This module allows Stasis to handle DataVox type 3 files. The samples can be replayed, and saved by the *StasisSave DataVox command.",0 ALIGN .dvoxid DCB "DVOX" .service ;R12 is the only register we may corrupt in a service call SUBS R12,R1,#&80000 MOVMI PC,R14 SUB R12,R12,#&300 TEQ R12,#Service_UKStasisFormat-&80300 TEQNE R12,#Service_StasisIdentify-&80300 TEQNE R12,#Service_StasisSave-&80300 MOVNE PC,R14 TEQ R12,#Service_StasisIdentify-&80300 BEQ identify TEQ R12,#Service_StasisSave-&80300 BEQ save .ukformat STMFD R13!,{R3-R4,R14} LDR R3,[R0,#dvox.id] LDR R4,dvoxid CMP R3,R4 LDMNEFD R13!,{R3-R4,PC}^ ;identified a DataVox sample. ;we could also check R2 = &108 (the filetype) ;Not all datavox samples are in logarithmic format. ;This module must convert it if it isn't. ;That's what typeconv does. BL typeconv ADR R0,alienblock MOV R1,#0; claim service call LDMFD R13!,{R3-R4,PC} .typeconv STMFD R13!,{R0-R5,R14} LDRB R1,[R0,#dvox.type]; note byte load MOV R2,#0 CMP R1,#1;datavox linear unsigned type ADREQ R2,convtab1 CMP R1,#2;datavox linear signed type ADREQ R2,convtab2 CMP R1,#3;datavox Ulaw type ADREQ R2,convtab3 CMP R2,#0 LDMEQFD R13!,{R0-R5,PC} LDR R3,[R0,#dvox.dataofs] ADD R3,R3,R0 LDR R4,[R0,#dvox.len] ADD R4,R4,R0 .loop LDRB R5,[R3] ;get data from dvox sample LDRB R5,[R2,R5] ;look it up in the table STRB R5,[R3],#1 ;store it back, add 1 to R3 CMP R3,R4 BLT loop LDMFD R13!,{R0-R5,PC} .convtab1 INCBIN Alien:convtab1 .convtab2 INCBIN Alien:convtab2 .convtab3 INCBIN Alien:convtab3 ALIGN .alienblock DCB "StAl"; ID Word - required - used to check if the block is valid. DCD getinfo-alienblock;get info routine DCD putinfo-alienblock;put info routine DCD 0 ;release routine (we don't have one) DCD 0 ;must be zero DCD 0 ;for future use DCD 0 ;for future use DCD name1-alienblock DCD formatname-alienblock DCD dvox_filetype DCD title-alienblock DCD 0 ALIGN ;The info routine is entered with ;R0 points to the stasis slot decription block ;R1 points to your sample ;The file length as loaded may be accessed by LDR R0,[R10,#4] ;The info entry should return: ;R1=name * ;R2=length ;R3=finetune * &4000=default, &2000=1 octave lower, &8000=1 octave higher etc ;R4=repofs * ;R5=replen * ;R6=datastart ;R7=volume * ;R8=special (return R8=0) ; *= may return zero if not supported ;Most of this routine deals with the DVox format's idiosyncrasies .getinfo MOV R11,R1;our sample address MOV R1,#0; sample name - not supported by DVOX samples LDR R2,[R11,#dvox.len]; file length MOV R3,#0;finetune/volume value - not supported MOV R4,#0 MOV R5,#0 LDRB R7,[R11,#dvox.flags] ;ignore repeat offset unless timed play is set TST R7,#0 LDRNE R4,[R11,#dvox.repstart] ;we need the repeat offset LDRNE R5,[R11,#dvox.repend] ;we need the repeat length SUBNE R5,R5,R4 ; that's the repeat length sorted out LDR R6,[R11,#dvox.dataofs] SUB R2,R2,R6 ; convert file length to sample length SUBNE R4,R4,R6 ; that's the repeat offset ADD R6,R6,R11 ; R6 is the address of the sample data MOV R7,#0 MOV R8,#0 MOV PC,R14 .putinfo MOV R11,R1 ;LDMFD R13,{R1} ;no writeback LDR R6,[R11,#dvox.dataofs] ADD R2,R2,R6 ;put the values into datavox style ADD R4,R4,R6 ADD R5,R5,R4 TST R8,#1<<2 STRNE R2,[R11,#dvox.len] TST R8,#1<<4 STRNE R4,[R11,#dvox.repstart] TST R8,#1<<5 STRNE R5,[R11,#dvox.repend] TST R8,#1<<6 SUBNE R6,R6,R11 STRNE R6,[R11,#dvox.dataofs] AND R0,R8,#%10001010 ;what we don't support MOV PC,R14 .identify ADD R0,R0,#1 CMP R2,#0 MOVEQ PC,R14 ADR R12,alienblock STR R12,[R2],#4 MOV PC,R14 ;On entry to a save routine, R0 is the slot number (for us to pass ;to Stasis_GetSlotInfo. ;R2 points to the filename ;R3 points to the namecheck routine in Stasis which compares the name ;pointed to by R1 to that entered at the command line ;We pass on the Service call if we don't recognise the save type ;ie return with MOV PC,R14 with registers unchanged. ;If we want to save in our format we return with ;R0 preserved. ;R1=0 to claim the service call ;R2 points to a filled-in header block ;R3 is the length of the header block ;R4 is the filetype ;Stasis will add the sample data in logarithmic format after the header ; ;Otherwise return with R2=0 after carrying out the whole save process ;yourself. ;To return an error, return with R2=1 and R0 pointing to an error block. .dvoxformat ;read with reference to the dvox struct at the start of this file DCB 0 DCB 0 DCB &17 DCB &7E DCD &20 DCD 0 DCD 0 DCB "DVOX" DCD 3 DCD 0 DCD 0 .save STMFD R13!,{R1,R14} ADR R1,name1 MOV R14,PC MOV PC,R3 ;BL to R3 ADRNE R1,name2 MOVNE R14,PC MOVNE PC,R3 LDMFD R13!,{R1,R14} MOVNES PC,R14;return if no match STMFD R13!,{R0,R5-R10,R14} SWI Stasis_GetSlotInfo ADR R10,dvoxformat ADD R2,R2,#dvox.sizeof ;fill in our header STR R2,[R10,#dvox.len] ADD R5,R5,R4 ;R5 is now the repeat end ADD R4,R4,#dvox.sizeof STR R4,[R10,#dvox.repstart] ADD R5,R5,#dvox.sizeof STR R5,[R10,#dvox.repend] MOV R6,#dvox.sizeof STR R6,[R10,#dvox.dataofs] MOV R1,#0 MOV R2,R10 MOV R3,#dvox.sizeof MOV R4,#dvox_filetype LDMFD R13!,{R0,R5-R10,PC} ;return and let Stasis do the rest .init ;My standard init/final service calls. STMFD R13!,{R0-R3,R14} ADR R0,start MOV R1,#Service_PsychoStarting MOV R2,#0; the R12 value MOV R3,stasis_alien ADR R4,alienblock SWI OS_ServiceCall CMP R1,#0 LDMFD R13!,{R0-R3,R14} ADREQ R0,initerrtext ORRVS R14,R14,#1<<28 MOVS PC,R14 .final STMFD R13!,{R0-R3,R14} ADR R0,start MOV R1,#Service_PsychoDying MOV R2,#0 MOV R3,stasis_alien ADR R4,alienblock SWI OS_ServiceCall CMP R1,#0 LDMFD R13!,{R0-R3,R14} ADREQ R0,finalerrtext ORRVS R14,R14,#1<<28 MOVS PC,R14 .initerrtext DCD &809DFE DCB "StasisDVox : Initialisation veto",0 ALIGN .finalerrtext DCD &809DFF DCB "StasisDVox : RMKill veto",0 .name1 DCB "DataVox",0 .name2 DCB "DVox",0 .formatname DCB "DataVox format 3",0 ALIGN FileDataConvTab1acE|}umeYI10HXdlt|FileDataConvTab2acE#|z0HXdlt|}umeYI1FileDataConvTab3acEE|}{ywusqomkigeca_][YWUSQOMKIGECA?=;97531/-+)'%#! ~|zxvtrpnljhfdb`^\ZXVTRPNLJHFDB@><:86420.,*(&$"  FileDataReadMellacnEgA%:StasisDvox ========== This alien format handler illustrates most of the features of an alien format handler. FileDataSetupallacE|Set Alien$Path .FileDataStasisDVoxEʹ(`$,8xStasisDVoxStasis Alien 1.00 (24 Jul 1994) - For DataVox format samplesStasisDVoxThis module allows Stasis to handle DataVox type 3 files. The samples can be replayed, and saved by the *StasisSave DataVox command.DVOXQAL<<<<  < @-0@@S?@- Q< QM/Q/R?00@@PPPS?}umeYI10HXdlt|0HXdlt|}umeYI1}{ywusqomkigeca_][YWUSQOMKIGECA?=;97531/-+)'%#! ~|zxvtrpnljhfdb`^\ZXVTRPNLJHFDB@><:86420.,*(&$"  StAl0x&d 0@Pp@ PPE` B@D `p` @P @  P@ `F`RO~ DVOX@-GE@G-L}\O  P @@ P P `` 0BOᇽ@-cO@ 0aOO0Q@@c@-fO @ 0MO0Q@,cStasisDVox : Initialisation vetotasStasisDVox : RMKill vetoDataVoxDVoxDataVox format 3FileDataAlSourceacEjE{1#type &ffa #name StasisRaw #base 0 #set Service_PsychoStarting=&80300 #set Service_PsychoDying =&80301 #set Service_UKStasisFormat=&80310 #set Service_StasisSave =&80311 #set Service_StasisIdentify=&80312 #set stasis_alien =1 #set raw_filetype =&FFD .ModuleHeader .start DCD 0 DCD init DCD final DCD service DCD title DCD help DCD helptable DCD 0 DCD 0 DCD 0 DCD 0 .title DCB "StasisRaw" DCB 0 ALIGN .help DCB "Stasis Alien",9,"1.00 (24 Jan 1995) - For raw data samples" DCB 0 ALIGN .helptable DCB "StasisRaw" DCB 0 ALIGN DCD 0 DCD 0 DCD 0 DCD rawhelp DCD 0;End Marker .rawhelp DCB "This module allows Stasis to handle raw data. The samples can be replayed, and saved by the *StasisSave Raw command.",0 ALIGN .service ;R12 is the only register we may corrupt in a service call SUBS R12,R1,#&80000 MOVMI PC,R14 ;for a quick return SUB R12,R12,#&300 TEQ R12,#Service_UKStasisFormat-&80300 TEQNE R12,#Service_StasisIdentify-&80300 TEQNE R12,#Service_StasisSave-&80300 MOVNE PC,R14 TEQ R12,#Service_StasisIdentify-&80300 BEQ identify TEQ R12,#Service_StasisSave-&80300 BEQ save .ukformat STMFD R13!,{R3-R4,R14} MOV R3,#&FFD CMP R2,R3 LDMNEFD R13!,{R3-R4,PC}^ ;identified a raw sample by its filetype. ADR R0,alienblock MOV R1,#0; claim service call LDMFD R13!,{R3-R4,PC} .alienblock DCB "StAl"; ID Word - required - used to check if the block is valid. DCD getinfo-alienblock;get info routine DCD putinfo-alienblock;put info routine DCD 0 ;release routine (we don't have one) DCD 0 ;must be zero DCD 0 ;for future use DCD 0 ;for future use DCD name1-alienblock DCD formatname-alienblock DCD raw_filetype DCD title-alienblock DCD 0 ALIGN ;The info routine is entered with ;R0 points to the stasis slot decription block ;R1 points to your sample ;The file length as loaded may be accessed by LDR R0,[R10,#4] ;The info entry should return: ;R1=name * ;R2=length ;R3=finetune * &4000=default, &2000=1 octave lower, &8000=1 octave higher etc ;R4=repofs * ;R5=replen * ;R6=datastart ;R7=volume * ;R8=special (return R8=0) ; *= may return zero if not supported .getinfo MOV R11,R1;our sample address MOV R1,#0; sample name - not supported by raw samples LDR R2,[R10,#4]; file length MOV R3,#0 MOV R4,#0 MOV R5,#0 MOV R7,#0 MOV R6,R11 MOV R7,#0 MOV R8,#0 MOV PC,R14 .putinfo AND R0,R8,#%111111111 ;what we don't support ie everything MOV PC,R14 ; This service call is used to build a list of recognised filetypes .identify ADD R0,R0,#1 CMP R2,#0 MOVEQ PC,R14 ADR R12,alienblock STR R12,[R2],#4 MOV PC,R14 ;On entry to a save routine, R0 is the slot number (for us to pass ;to Stasis_GetSlotInfo. ;R2 points to the filename ;R3 points to the namecheck routine in Stasis which compares the name ;pointed to by R1 to that entered at the command line ;We pass on the Service call if we don't recognise the save type ;ie return with MOV PC,R14 with registers unchanged. ;If we want to save in our format we return with ;R0 preserved. ;R1=0 to claim the service call ;R2 points to a filled-in header block ;R3 is the length of the header block ;R4 is the filetype ;Stasis will add the sample data in logarithmic format after the header ; ;Otherwise return with R2=0 after carrying out the whole save process ;yourself. ;To return an error, return with R2=1 and R0 pointing to an error block. .rawformat .save STMFD R13!,{R1,R14} ADR R1,name1 MOV R14,PC MOV PC,R3 ;BL to R3 LDMFD R13!,{R1,R14} MOVNES PC,R14;return if no match STMFD R13!,{R0,R5-R10,R14} MOV R1,#0 ADR R2,rawformat MOV R3,#0 MOV R4,#raw_filetype LDMFD R13!,{R0,R5-R10,PC} ;return and let Stasis do the rest .init ;My standard init/final service calls. STMFD R13!,{R0-R4,R14} ADR R0,start MOV R1,#Service_PsychoStarting MOV R2,#0; the R12 value MOV R3,stasis_alien ADR R4,alienblock SWI OS_ServiceCall CMP R1,#0 LDMFD R13!,{R0-R4,R14} ADREQ R0,initerrtext ORRVS R14,R14,#1<<28 MOVS PC,R14 .final STMFD R13!,{R0-R4,R14} ADR R0,start MOV R1,#Service_PsychoDying MOV R2,#0 MOV R3,stasis_alien ADR R4,alienblock SWI OS_ServiceCall CMP R1,#0 LDMFD R13!,{R0-R4,R14} ADREQ R0,finalerrtext ORRVS R14,R14,#1<<28 MOVS PC,R14 .initerrtext DCD &809DFE DCB "StasisRaw : Initialisation veto",0 ALIGN .finalerrtext DCD &809DFF DCB "StasisRaw : RMKill veto",0 .name1 DCB "Raw",0 .name2 DCB "Raw",0 .formatname DCB "Raw Data",0 ALIGN FileDataReadMellacE{AStasisRaw ========= This is about the most simple Stasis Alien format handler you can have. It supports raw data as a sample type, recognising it by the filetype FFD. It might form a good basis if yuore writing an alien format handler. FileDataStasisRawcE@, @,8pStasisRawStasis Alien 1.00 (24 Jan 1995) - For raw data samplesStasisRawThis module allows Stasis to handle raw data. The samples can be replayed, and saved by the *StasisSave Raw command.QAL<<<<$ <( @-> 0RStAl0\dl 0@Pp `p RO@-@G-( O0N @ᇽ@-O 0@O0Q@<c@-O 0NO0Q@(cStasisRaw : Initialisation vetoStasisRaw : RMKill vetoRawRawRaw DataFileDataHelpTextacEStasis - version 1.00 (16 Oct 94) ================================= This application provides sound handling routines. For full information read the files inside this directory. This application is Andy Southgate 1993-95, but may be used freely. FileDataStasisllacDEcA01X/,4X@}l StasisStasis Voices 1.10 (20 Jan 1994)StasisStasisSamplep-StasisLoad:StasisSavex StasisLink.StasisTune /%StasisCatx)}0StasisStateStasisInfoH"+StasisFineTune:StasisNameX StasisRepeat StasisLength6StasisVolume0StasisVolSlided StasisPitchSlidee=StasisOverdrive StasisSound2StasisSWIs A voice generator using samples. Andy Southgate but use freely. sets details of a user defined sample.  [ ] loads a sample into memory, in the specified slot. The native file format is a compact header block, followed by 8 bit log scaled data.   saves a sample. Either Stasis or Tracker format can be specified by using StasisSave S (or just StasisSave ) or StasisSave T. Stasis format is a little shorter.  [format]  attaches a channel to a sample slot.   sets the master tuning of the sounds. The default value is &4000.   displays information about the samples present. Default is samples 0-15.  [ []] displays information about the state of the sound playing on a channel.  [] displays information the sample in the specified slot.  [] sets the fine tune value for a sample. The normal value is &4000.   sets the name of a sample to a string of up to 20 characters.   sets the repeat loop of a sample.   sets the length of the sample. Simply rewrites the length - doesnt change the memory allocation.   sets the volume of a sample in the range 0-&ff.   sets the volume slide for a channel.   sets the pitch slide for a channel.   is no longer available on this module. makes a sound, in a similar way to the *Sound command.  []Stasis supports the following SWIs: "Stasis_Sample",slot,start,length,repofs,replen "Stasis_Load",slot,filename,storage_type "Stasis_Save",slot,filename,save_type_string "Stasis_Link",channel,slot "Stasis_Name",slot,name "Stasis_FineTune",slot,finetune "Stasis_Volume",slot,volume "Stasis_Sound",channel,slot,volume,pitch,ignore "Stasis_GetSlotInfo",slot TO slot,name,pitch,finetune,repofs,replen, datastart,volume,formatstring "Stasis_PutSlotInfo",slot,name,pitch,finetune,repofs,replen, datastart,volume,bitfield "Stasis_VolSlide",channel,rate,target_volume "Stasis_PitchSlide",channel,rate,target_pitch "Stasis_Slide",channel,type,target,time StasisGetAddressSampleLoadSaveLinkNameVolSlidePitchSlideControlFineTuneVolumeSoundGetSlotInfoPutSlotInfoSlideMakeLinkTuneAttachBaseRateGetControlAddressGetSlotAddress[  `!@|"  l TT`&  !"T"('(Sta1Name of the voice SAMPSNAMName of the voice SVOLSLENROFSRLENSDATUser@-Q@0 S @0 S ! O-,hVO -  Aj[" 0-JNK -EAB , 010Q^O# R  sOO0~- ~~-  @ ~j 0 j;-8 Stasis : Save failed - O SStasisTTracker@- 0 0 0R RS PO-⊢ YO Y Y YF Y8 `O  -P  $0@  P@ `F(`O  - P   9C<2p @UP ,P@O   @ P@`O GOP L-⊢ pW X X X, X `` 0@P $0@ P(``p  0p#<9 @,P8` 0 @P`pStAl- c`c@--8P@< ^ - @-0 R@* @-0 R@! PxD-Q  -PI  $0@ P,`(`,. xxD-QKp -P6 $ 4 8  B  00 @UP,P\. xSta1SAMPUserA-@O@P@P@P@T @@-( 10Q@@@-@ ! T O-@P 0P 0S@-TU 8NC--hhF$JPC{ (@-aah⊢ 2U h2Zh?-acP?qacG-⊢ P Q P P P PP& GF >@-0PSLP$Q0S>O- 냏 P- aa@-  c @--?-acP? qa c!j  -00aq a qaj- 0aa z--aa RR qah   @- -00aq a q@h j  EO@ @- Q ?@-@ R @T?  @T?@- !A-@- !!0@- !!@!P0@- !!@- !!pက@- !0!@!@-0 @- !0!@!@-0 @-@  ⋳LQm Q~ T⁡ 5 0;@-Q(QB-P`-S0c-P  SS101 1:P@  00c`-a0@-Q(QRXS0c@- @@-Overdrive is no longer supported by this module @-0 S !PG-0PKZ@-State of module Workspace address & ' Sample rate &$ Master tuning &  Real tuning & 100Hz timer &  Rate change callbacks sent &4 Rate change callbacks received &8@-⋳LState of channel  Last played slot $ Control block address &  Sample address & Sample length &  Repeat offset &  Repeat length & Pitch (internal) & Raw pitch &4 Volume (internal) &( Log amp table at &8 Phase accumulator &~ State changes &h{ Current state &pl Previous state &lc Auto rate changes &d` Buffer 1 address &Q Buffer 2 address &H Last buffer filled = 0` Flash buffer fills &D< Fast buffer fills &@3 Slow buffer fills &<* Fixed pitch fills &H! Buffer flushes &L Kicks &P Channel status :  T I \ Ett{@     OGated off Buffer 1 flushed Buffer 2 flushed Silenced by escape Live Kick active Off Fresh Volume slide,Pitch slide, Safe Attached @- target &, rate &. @-0 S !G-@-⊢ Information held by Stasis on slot P  ======================================= Address of sample &g Length of file at that address &[ Storage type u :  Sample format : Pq  Information held by sample data =============================== Bh Sample name : Pk Sample format : p Sample data address & Sample length & Sample repeat offset & Sample repeat length & Sample finetune & Sample volume & There is no sample in this slot. @- Alien format description routines at &(5h in module Sample has no name Sample has no format description-@- P $ PPQ  (filetype &) j, savename j$j@-P0P^PmPsPQUnknown - checked but not matched to any known formatStasis - native formatTracker - TFFUser - pointers to user specified memoryAlien - supported by an external moduleUnidentified - no attempt has been made@-P<PSPwPPPQEmpty - no sample in this slotRMA - stored in the relocatable module areaAmnesia - stored in the current Amnesia areaUser - a block of pointers in the RMA point to user memoryLink - a link to a sample in user memorySafe Link - a link to a sample in the RMAUnidentified - storage type is not known - indicates an error@-0 S !@S !@- Channel Slot Sample Name Where Address Length Repeat Repeat Offset Length =========|====|======================|=======|==========|======|======|====== pqP@-P@0P1 0S |  P <  | pr} pp-nh-F | WWWWWF@- |P< 00S F@- | P < F --  ---- mptEmpty RMA User Link SLinkAmsia@- R  P P?Q@-< @-< 0Q0Q0Q0Q@-< 0Q@-< @- !P!`!pZ!! 0 @C-Q ⊢ Y -aah⊢ Shqr s 0t@C-⊢ R   <^- !@!^j@-h 0@@-@ @-!@-P  [FQ NQ -2QS@-%@-O- 0@@P0@@ 0@@O-PQ= 0 -00aq a qOhj Q QŏL   Q GQ 0-  0SL ;0SEOhRj 0@-0 0@@@-A0 @-A O- 0boZO-boQZ- aa3 Z Stasis-ßL  0@@ $-ßL^- !@!P!`!p 0@PG-@⊣L  @+- 1   Y P Y APY[[P Pt$8B-Q$$_ ,0 @P`B @c@-@-$( $@-4 ,Q @- ,Q  A-*0s,0L -88@- 0@@PPPP  0 -P`-R b-P 0RR1 101:P@  0  b`-a1 0@- L R-TY PPPG@-  00_-$p 0 0_0P-tp  0BAR @P0@-ps N~\\P0S (8 !$ b V @@ J[[![(%PcRY @@X X' %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC %(VPC \IDDX4 X] %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V %(V \HHZ%(U    %(U    %(U    %(U    \HHZ%T    %T    \HHZ%(UrC !rC !rC !rC %(UrC !rC !rC !rC %(UrC !rC !rC !rC %(UrC !rC !rC !rC  \tHHZ%TrC  !rC  !rC  !rC  %TrC  !rC  !rC  !rC   \A<<V%(VPC U5%(VPC U.%(VPC U'%(VPC U \%(VPC UVE%(VPC UVE%(VPC UVE%(VPC UVE \  PU@0V 0偑 \ ̶ \ ̶ \ ̶ \ ̶LL \QR R  Q \    (TX 0AR0cSC((\` 0AR0cSpk_-plphh  PO( X ⊣Lt X dd \ \`  `t[442 O@ T-Qa-Yi-Q  YY11 1: Q A  ᩐia-`O-  p sLp j[ Stasis : No sample in that slotStasis : Voice attach/detach failureStasis : No room in RMAStasis : Unknown SWI@- @Stasis : Release of block of unknown typeStasis : Unknown sample formatStasis : Alien format handler guard word corrupttas@-Stasis : With reference to ,,,, ,@,,;@uStasis : Cannot make requested alteration - sample format does not allow itnamelengthfinetunerepeat offsetrepeat lengthsample data addressvolumeFileDataManualE#qStasis 1.10 Manual ================== Stasis is a module occupying about 11K which provides an easy to use sound system for games programmers. Stasis plays samples, which it can load and save in various ways. Sound commands are issued in the normal way. There are facilities to retune samples to a different pitch if necessary. Primitive pitch/volume slides are included. Loading the Module ================== There are many ways - double clicking the application, *Run the application, *RMLoad Stasis:Stasis once the filer has seen the application, or whatever you can engineer for yourself. Using Stasis ============ The simplest (and probably the best) way to use Stasis is to load samples using the *StasisLoad command, choose which channel plays which sample with *StasisLink, and the play them with SOUND command (from BASIC) or Sound SWIs. Loading Your Sounds =================== Stasis can load samples in either its native format (which will be extended in the future) or Tracker format (provided so that samples can be exchanged with other packages). The command is *StasisLoad . Stasis currently provides 64 slots, each of which can contain one sample. The parameter is a decimal number 0-63. Stasis now supports alien file format modules. If StasisDvox is loaded then Stasis will be able to load DataVox format samples. Checking that Youve Loaded Your Samples ======================================== The command *StasisCat will list details of the first 16 sample slots. *StasisCat 0 63 lists them all. Playing your Samples ==================== To get a sound from the module, you need to tell it which sample to play on which channel. The command is *StasisLink . The channel is the conventional 1-8 as used by the RISC OS sound system. The slot should be the same number that you told *StasisLoad when you loaded your sample. Note that you dont need to attach channels (using *ChannelVoice etc) as Stasis claims the channel when you issue a *StasisLink command. If you need things to happen a bit more quickly, use the Stasis_Link SWI. R0,R1 hold the parameters channel,slot. The SWI doesnt attach the voice - make sure you use a *StasisLink command or the Stasis_Attach SWI at least once for each channel to do this. Once a sample is linked to a channel, it can be played using conventional sound commands. The duration of the sound (the fourth number in a SOUND command) is ignored, and should be zero for future compatibility. Theres also the Stasis_Sound SWI which has the advantage that it can be called from an interrupt routine. Examples ======== If a Stasis sample is double clicked on the Desktop, it will be loaded into slot 1 and you should hear it. You can also try the following, using slot 2 as an example, from the command line (press F12): *StasisLoad 2 *StasisLink 1 2 and then press ctrl-G. Providing the file exists and the sound system is working, you should hear a sound. If not, try the commands *Audio On, *Speaker On or *Volume 127 to see if that helps. In BASIC, you could try: *StasisLoad 1 *StasisLink 1 1 and whenever you need to make a sound SOUND 1,-15,40,0 - for a pitch of 40. Entering the command *StasisCat should show whether you have loaded any samples. Slides ====== Stasis supports both volume and pitch slides. The command is of the form *StasisSlide