REM>.Src.Banner REM Display loading banner... REM Acorn Invaders (c) DynaByte Software 2007,10. ON ERROR OSCLI"Error 0 "+REPORT$+" at line "+STR$(ERL):END REM Initialise... PROCash_init :REM Kick LibASH. xpos%=0:ypos%=4:xsize%=8:ysize%=12 :REM Position & Size. x_eig%=16:y_eig%=20 :REM Screen object stuff. screen%=FNash_claim(24) :REM Claim for screen info. banner%=FNash_claim(16) :REM Claim for image co-ords. blk%=FNash_claim(20) :REM Claim for OS call block. REM Setup OS call block, call OS and setup screen info using REM returned values. blk%!0=4:blk%!4=5:blk%!8=11:blk%!12=12 :REM Setup OS call block. blk%!16=-1 SYS "OS_ReadVduVariables", blk%, blk% :REM Call OS. screen%!x_eig%=blk%!0 :REM Setup screen info. screen%!y_eig%=blk%!4 screen%!xsize%=(blk%!8)+1<.Resources.Graphics.Banner",1)<>1 THEN PRINT"Ouch! Cannot find banner Image.":PROCtidy_up(FALSE):END ENDIF REM Load banner image... REM This routine copes equally well with raw sprite data and files REM squashed with Acorn's Squash compressor. gfx_area%=FNgfx_load(".Resources.Graphics.Banner") REM Display our banner... PROCplot("banner",banner%!xpos%,banner%!ypos%) PROCtidy_up(TRUE) END REM Display a sprite at given co-ordinates. DEFPROCplot(sprite$,x%,y%) LOCAL address% SYS "OS_SpriteOp", 256+24, gfx_area%, sprite$ TO ,, address% SYS "OS_SpriteOp", 512+34, gfx_area%, address%, x%, y%, 0 ENDPROC REM Clean up after ourselves... REM Release all LibASH claims that haven't been released REM elsewhere and tear down LibASH subsystem ready to exit. DEFPROCtidy_up(loaded%) PROCash_free(screen%):PROCash_free(banner%) IF loaded% THEN PROCash_free(gfx_area%) PROCash_destroy ENDPROC REM ********************************************************************** REM Generic routines... (File System.) REM ********************************************************************** REM Check for the prescence of a filing system object at a given REM location or return object's size. I say object, as this can REM check for the existance of directories as well as files (with op%=1). REM Parameter block... REM filespec$ = Filespec to check for in current directory. REM op% = What to return. REM ...On Exit with op%=1 (Find.) REM rc% = 0 Object not found. REM = 1 Object is a file. REM = 2 Object is a directory. REM ...On Exit with op%=2 (Size.) REM rc% = Size of file. (In bytes.) DEFFNfs_fileop(filespec$,op%) LOCAL found%,size% SYS"XOS_File",17,filespec$ TO found%,,,,size% IF op%=1 THEN =found% =size% REM ********************************************************************** REM Generic routines... (Graphics Loader.) REM ********************************************************************** REM Load and Decompress GFX data... REM This uses a generic version of the routine used in the REM main Invaders code. Originally altered to remove dependancies REM on both LibASH and the obfuscation code, I've modified it REM again to use a generic silent version of the Squash handler REM routines currently used in the Invaders code. Minimum subset REM of LibASH calls put in place to enable the use of this REM handler (18/06/10). DEFFNgfx_load(filespec$) LOCAL size%,osize%,blk%,area% size%=FNfs_fileop(filespec$,2) :REM Input file size. blk% =FNash_claimfilled(size%,0) :REM Claim buffer. SYS "OS_File",16,filespec$,blk%,0 :REM Load file. osize%=FNsquash_init(blk%) :REM Init Squash. IF osize%>0 THEN area%=FNgfx_createdefaultarea(osize%+4) :REM Create a sprite area. PROCsquash_decompress(blk%,area%+4) :REM Decompress to memory. ELSE area%=FNgfx_createdefaultarea(size%+256) :REM Create a sprite area. SYS "OS_SpriteOp",256+10,area%,filespec$ :REM Load raw data. ENDIF SYS "OS_SpriteOp",256+17,area% :REM Verify data. =area% REM Create a default sprite area... REM This requires a few default parameters to be set up and is the same REM for both cases. Only the values differ. DEFFNgfx_createdefaultarea(size%) LOCAL area% area%=FNash_claimfilled(size%,0) area%!0=size%:area%!4=0:area%!8=16:area%!12=16 =area% REM ********************************************************************** REM Generic routines... (Squash Decompressor.) REM ********************************************************************** REM Return our output buffer size requirements... REM Returns either a positive value indicating the size of the REM output buffer we need to create, or zero if the data is not REM compressed. (We assume the data is compressed if we find REM "SQSH" as the first 4 bytes of the input buffer. No further REM checks as to the validity of the file are made by the this REM code. This routine would pass a file containing only this REM "SQSHed file NOT" string as valid when obviously it's not.) DEFFNsquash_init(in%) LOCAL size%,osize%,i%,magic$ size%=FNash_blocksize(in%) :REM Get size of input buffer. REM Quick sanity check here. We return zero if data not SQSHed. FOR i%=0 TO 3:magic$+=CHR$(in%?i%):NEXT i% IF magic$<>"SQSH" THEN =0 :REM Return 0 if not SQSHed. REM OK to continue... Buffer contains what appears to be squashed REM data. SYS"Squash_Decompress",1<<3,size% TO ,osize% :REM Init Squash. IF osize%=-1 THEN osize%=in%!4 :REM Squash bugfix. =osize% REM Decompress data... REM We are supplied with a full input buffer and an empty output REM buffer. It is assumed that we can obtain sizes for both using REM LibASH calls and that we have enough RAM to do the whole buffer REM in one chunk. NOTE:- Input buffer is clobbered on exit!! DEFPROCsquash_decompress(in%,out%) LOCAL size%,wksp%,wsize%,osize% size% =FNash_blocksize(in%) :REM Input buffer size. osize%=FNash_blocksize(out%) :REM Output buffer size. SYS"Squash_Decompress",1<<3,size% TO wsize% :REM Init Squash. wksp%=FNash_claimfilled(wsize%,0) :REM Claim workspace. SYS "Squash_Decompress",1<<2,wksp%,in%+20,size%-20,out%,osize% TO err% IF err%<>0 THEN ERROR 255,"Squash returned non-zero status : "+STR$(err%) PROCash_free(wksp%):PROCash_free(in%) :REM Free up memory. ENDPROC REM ********************************************************************** REM Generic routines... (Minimal LibASH support. v1.07) REM LibASH is partially based on ASH... REM Application Slot Heap for BASIC (c) Steve Rivell 7th Software 2004. REM ********************************************************************** REM Initialise ASH Subsystem... DEFPROCash_init LOCAL err% ash_heap%=0:ash_total%=0 SYS "Wimp_SlotSize", -1, -1 TO ash_slot% SYS "XOS_ReadMemMapInfo" TO ash_page% ; err% IF err% AND 1 THEN ash_page%=16384 PROCash_create(ash_page%) ENDPROC REM Release the memory used for our heap DEFPROCash_destroy IF ash_heap% THEN SYS "Wimp_SlotSize", ash_heap%-&8000,-1 TO ash_slot% ash_heap%=0:ash_total%=0 ENDIF ENDPROC REM Claim a block from the heap... REM Our block's size is now the requested size + 3 extra locations REM @ 4 bytes per location + 3 extra bytes. Changed behaviour... REM If we can't claim desired space then we return -1 in REM block%. This allows the caller to decide what to do. REM Offs | Significance. REM --------+--------------- REM 0 | Low marker. REM 4 | Block user area size in bytes. REM 8 | User area base address. (This is what is returned.) REM | High marker. DEFFNash_claim(bytes%) LOCAL size% size%=(bytes%+15) AND &FFFFFFFC block%=FNash_alloc(size%) IF block% THEN block%!0=&DEADDEAD :REM Store low marker... block%!4=bytes% :REM Store user area size... !(block%-8+(block%!-4))=&DEADDEAD :REM Store high marker... =block%+8 ENDIF =-1 REM Claim a block of memory, as above, but fill it with a REM specified value before returning. If we can't claim the space REM then we return -1. No need to change this back to restore REM behaviour. DEFFNash_claimfilled(bytes%,value%) LOCAL block% block%=FNash_claim(bytes%) :REM Claim requested space... IF block%=-1 THEN =block% PROCash_blockfill(block%,value%) :REM Fill with spec'd value... =block% REM Free a block into the heap DEFPROCash_free(RETURN block%) CASE FNash_blockintegrity(block%) OF WHEN 1 :ERROR 254, "Memory written below low block boundary!!" WHEN 2 :ERROR 254, "Memory written beyond high block boundary!!" WHEN 3 :ERROR 254, "Serious memory corruption has occured!!" ENDCASE block%-=8:ash_total%-=block%!-4 SYS "OS_Heap", 3, ash_heap%, block% block% = 0 ENDPROC REM Fill a block of memory with a specified value. (Word aligned.) DEFPROCash_blockfill(block%,value%) LOCAL offset%,size% size%=FNash_blocksize(block%) FOR offset%=0 TO size%-4 STEP 4 block%!offset%=value% NEXT offset% ENDPROC REM Returns integrity status of a given block... REM 0 -> No Errors REM 1 -> Low marker (Under-run) REM 2 -> High marker (Over-run) REM 3 -> Both markers!?! DEFFNash_blockintegrity(block%) LOCAL hi%,lo% hi%=FALSE:lo%=FALSE :REM Default. (No Errors) block%-=8 IF block%!0<>&DEADDEAD THEN lo%=TRUE IF !(block%-8+(block%!-4))<>&DEADDEAD THEN hi%=TRUE IF lo% AND hi% THEN =3 :REM Both markers trashed. IF hi% THEN =2 :REM High marker trashed. IF lo% THEN =1 :REM Low marker trashed. =0 :REM Integrity OK. REM Return the size (in bytes) of a specified block. DEFFNash_blocksize(block%) LOCAL blk% blk%=block%-4 =blk%!0 REM Create a heap in the memory above HIMEM DEFPROCash_create(size%) IF ash_heap% THEN ERROR 254, "You cannot have multiple heaps" size%=(size%+ash_page%-1) AND NOT (ash_page%-1) ash_heap%=HIMEM SYS "Wimp_SlotSize", ash_slot% + size%, -1 TO ash_slot% size%=ash_slot%+&8000-ash_heap% IF size%<1 THEN ash_heap%=0 ERROR 254, "Could not extend WimpSlot for heap" ELSE SYS "OS_Heap", 0, ash_heap%,, size% ENDIF ash_total%=0 ENDPROC REM Attempt to add some more memory into the end of our heap DEFPROCash_grow(bytes%) LOCAL prev% prev%=ash_slot% SYS "Wimp_SlotSize", ash_slot%+bytes%, -1 TO ash_slot% bytes%=ash_slot%-prev% IF bytes% THEN SYS "OS_Heap", 5, ash_heap%,, bytes% TO ,,, bytes% ENDPROC REM Claim a block from the heap (grow it if need be) - return REM zero if claim fails. DEFFNash_alloc(bytes%) LOCAL block%, err% SYS "XOS_Heap", 2, ash_heap%,, bytes% TO ,, block% ; err% IF err% AND 1 THEN PROCash_grow((bytes%+ash_page%) AND NOT (ash_page%-1)) SYS "XOS_Heap", 2, ash_heap%,, bytes% TO ,, block% ; err% IF err% AND 1 THEN =0 ENDIF ash_total% += block%!-4 =block%