******************************************************************************* * sprite.library.S Written by Readysoft. * Copyright 1993,1994 RS. All rights reserved. 1993.08.12.-1994.05.18. * v2.0. ******************************************************************************* ******************************************************************************* * Macros ******************************************************************************* ;------------------------------------------------------------------------------ ; SpriteName Macro ;------------------------------------------------------------------------------ SPR.NAM MACRO DC.B 'sprite.library',0 EVEN ENDM ******************************************************************************* * LIB Macro ******************************************************************************* SPR.LIB MACRO ******************************************************************************* * Constant Definitions ******************************************************************************* ;------------------------------------------------------------------------------ ; SpriteSetHeader Structure ;------------------------------------------------------------------------------ RSRESET spr_sh_Ident RS.L 1 identifier word 'SPRS' spr_sh_Version RS.L 1 version code spr_sh_Size RS.L 1 sprite set size spr_sh_SpriteDS RS.L 1 sprite data size spr_sh_AnSprDS RS.L 1 animsprite data size spr_sh_AnimDS RS.L 1 anim data size spr_sh_Sprites RS.B 1 number of sprites spr_sh_AnSprs RS.B 1 number of animsprites spr_sh_Anims RS.B 1 number of anims spr_sh_Inited RS.B 1 initialized spr_sh_SpriteDP RS.L 1 sprite data ptr spr_sh_AnSprDP RS.L 1 animsprite data ptr spr_sh_AnimDP RS.L 1 anim data ptr spr_sh_IndexT RS.B 256 index table spr_sh_SpriteT RS.B 256 sprite table spr_sh_AnSprT RS.B 256 animsprite table spr_sh_SizeOf RS.B 0 ;------------------------------------------------------------------------------ ; Sprite Structure ;------------------------------------------------------------------------------ RSRESET spr_sp_Code RS.B 1 identifier code spr_sp_NotUsed RS.B 9 not used area spr_sp_Height RS.W 1 height in pixel spr_sp_Data RS.L 1 ptr to DMA data spr_sp_SizeOf RS.B 0 IF spr_sp_SizeOf<>16 PRINTT '** Incorrect spr_sp_SizeOf !' ENDC ;------------------------------------------------------------------------------ ; SpriteAnim Structure ;------------------------------------------------------------------------------ RSRESET spr_an_Code RS.B 1 identifier code spr_an_Speed RS.B 1 speed (vblank/change) spr_an_SpeedCnt RS.B 1 speed counter spr_an_PhaseCnt RS.B 1 phase counter spr_an_Queue RS.L 1 ptr to sprite queue spr_an_SizeOf RS.B 0 IF spr_an_SizeOf<>8 PRINTT '** Incorrect spr_an_SizeOf !' ENDC ;------------------------------------------------------------------------------ ; SpriteInfo Structure ;------------------------------------------------------------------------------ RSRESET spr_si_XPos RS.W 1 sprite xpos spr_si_YPos RS.W 1 sprite ypos spr_si_Flags RS.W 1 flags spr_si_Height RS.W 1 height spr_si_Data RS.L 1 ptr to DMA data spr_si_Size RS.L 1 size of DMA data spr_si_SizeOf RS.B 0 ;------------------------------------------------------------------------------ ; Flag Bit Definitions ;------------------------------------------------------------------------------ spr_fl_b_Attach EQU 7 attach control ;------------------------------------------------------------------------------ ; Flag Bit-Value Definitions ;------------------------------------------------------------------------------ spr_fl_Attach EQU 1< Error(d0) ;------------------------------------------------------------------------------ spr.Init movem.l d1-d7/a0-a6,-(a7) lea sprite.lib(pc),a5 move.l a5,a0 clear varible area move.w #spr_SizeOf-1,d0 .Clear clr.b (a0)+ dbf d0,.Clear move.w #$80,d0 set border move.w #$2c,d1 move.w #$1c0,d2 move.w #$12c,d3 bsr spr.SetBorder moveq #7,d5 free all sprites .Free bsr spr.FreeSprite cmpi.l #spr_er_OK,d0 bne.s .Exit dbf d5,.Free .Exit movem.l (a7)+,d1-d7/a0-a6 rts ;------------------------------------------------------------------------------ ; InitSprS SprSCode,Data(d1,a0) --> Error(d0) ;------------------------------------------------------------------------------ spr.InitSprS movem.l d1-a6,-(a7) lea sprite.lib(pc),a5 tst.b d1 correct code ? beq .CodeErr moveq #0,d4 move.b d1,d4 lsl.w #2,d4 Code * 4 lea spr_SprSTable(a5),a4 tst.l 0(a4,d4.w) free code ? bne .CodeErr cmpi.l #'SPRS',spr_sh_Ident(a0) real sprs data ? bne .NoSprS cmpi.l #'v2.0',spr_sh_Version(a0) version OK ? bne .VersErr tst.b spr_sh_Inited(a0) already initialized ? bne .Inited move.b d1,spr_sh_Inited(a0) store SprSCode move.l a0,d0 adda.l #spr_sh_SizeOf,d0 move.l d0,spr_sh_SpriteDP(a0) --> SpriteDP adda.l spr_sh_SpriteDS(a0),d0 move.l d0,spr_sh_AnSprDP(a0) --> AnSprDP adda.l spr_sh_AnSprDS(a0),d0 move.l d0,spr_sh_AnimDP(a0) --> AnimDP .Sprites move.l spr_sh_SpriteDP(a0),a1 initializing sprites lea spr_sh_IndexT(a0),a2 lea spr_sh_SpriteT(a0),a3 move.l a0,d6 sprs address moveq #0,d7 .NextSpr cmpi.b spr_sh_Sprites(a0),d7 beq .AnSprs add.l d6,spr_sp_Data(a1) relocate data addr. moveq #0,d0 move.b spr_sp_Code(a1),d0 move.b #spr_in_Sprite,0(a2,d0.w) Type --> IndexTable move.b d7,0(a3,d0.w) Code --> SpriteTable lea spr_sp_SizeOf(a1),a1 next sprite addq.b #1,d7 bra .NextSpr .AnSprs move.l spr_sh_AnSprDP(a0),a1 initializing ansprs lea spr_sh_AnSprT(a0),a3 move.l a0,d6 sprs address moveq #0,d7 .NextASpr cmpi.b spr_sh_AnSprs(a0),d7 beq .Anims add.l d6,spr_sp_Data(a1) relocate data addr. moveq #0,d0 move.b spr_sp_Code(a1),d0 move.b d7,0(a3,d0.w) Code --> AnSprTable lea spr_sp_SizeOf(a1),a1 next animsprite addq.b #1,d7 bra .NextASpr .Anims move.l spr_sh_AnimDP(a0),a1 initializing anims lea spr_sh_IndexT(a0),a2 lea spr_sh_SpriteT(a0),a3 lea spr_sh_AnSprT(a0),a4 move.l a0,d6 sprs address moveq #0,d7 .NextAnim cmpi.b spr_sh_Anims(a0),d7 beq .OK add.l d6,spr_an_Queue(a1) relocate queue addr. moveq #0,d0 move.b spr_an_Code(a1),d0 move.b #spr_in_Anim,0(a2,d0.w) Type --> IndexTable move.l spr_an_Queue(a1),a6 moveq #0,d1 move.b (a6),d1 first item code move.b 0(a4,d1.w),0(a3,d0.w) Code --> SpriteTable lea spr_an_SizeOf(a1),a1 addq.b #1,d7 bra .NextAnim .OK moveq #0,d1 move.b spr_sh_Inited(a0),d1 restore SprSCode st spr_sh_Inited(a0) initialized .Inited lsl.w #2,d1 Code * 4 lea spr_SprSTable(a5),a1 insert sprs into move.l a0,0(a1,d1.w) SprSTable moveq #0,d0 all right .Exit movem.l (a7)+,d1-a6 rts .NoSprS move.l #spr_er_NoSprS,d0 not a sprs header bra.s .Exit .VersErr move.l #spr_er_Version,d0 different version bra.s .Exit .CodeErr move.l #spr_er_Code,d0 incorrect code bra.s .Exit ;------------------------------------------------------------------------------ ; SetSprite Sprite,SprS,XPos,YPos,F,SprN(d0,d1,d2,d3,d4,d5) --> Error(d0) ;------------------------------------------------------------------------------ spr.SetSprite movem.l d1-a6,-(a7) lea sprite.lib(pc),a5 lea spr_SprSTable(a5),a1 and.w #$ff,d1 lsl.w #2,d1 Code * 4 move.l 0(a1,d1.w),a0 SprS address in a0 cmpi.l #'SPRS',spr_sh_Ident(a0) real sprs data ? bne .NoSprS cmpi.l #'v2.0',spr_sh_Version(a0) version OK ? bne .VersErr tst.b spr_sh_Inited(a0) initialized ? beq .InitErr and.l #$ff,d0 lea spr_sh_IndexT(a0),a1 address of index table move.b 0(a1,d0.w),d1 index lea spr_sh_SpriteT(a0),a1 move.b 0(a1,d0.w),d0 code cmpi.b #spr_in_Sprite,d1 Sprite ? beq.s .Sprite cmpi.b #spr_in_Anim,d1 Anim ? beq.s .AnSpr bra .IndexErr .Sprite move.l spr_sh_SpriteDP(a0),a1 bra.s .DataOK .AnSpr move.l spr_sh_AnSprDP(a0),a1 .DataOK lsl.l #4,d0 ImageNum*spr_sp_SizeOf adda.l d0,a1 Sprite structure addr. bsr spr.GetSprite SpriteInfo addr. in a0 moveq #0,d5 move.w spr_sp_Height(a1),d5 move.l d5,d0 addq.l #2,d0 lsl.l #2,d0 size = 4*(height+2) bsr spr.MakeBuffer make DMA buffer cmpi.b #spr_er_OK,d0 error ? bne .NoMem bsr spr.CorrectPos correct position move.w d2,spr_si_XPos(a0) refresh SpriteInfo move.w d3,spr_si_YPos(a0) move.w d4,spr_si_Flags(a0) move.w d5,spr_si_Height(a0) bsr spr.CalcDef calc. SPRPOS, SPRCTL move.l spr_si_Data(a0),a2 addq.l #4,a2 destination move.l spr_sp_Data(a1),a3 source subq.w #1,d5 height-1 .Copy move.l (a3)+,(a2)+ copy gfx data dbf d5,.Copy clr.l (a2)+ moveq #0,d0 all right .Exit movem.l (a7)+,d1-a6 rts .NoSprS move.l #spr_er_NoSprS,d0 not a sprs header bra.s .Exit .VersErr move.l #spr_er_Version,d0 different version bra.s .Exit .InitErr move.l #spr_er_Inited,d0 not initialized bra.s .Exit .IndexErr move.l #spr_er_Index,d0 undefined index bra.s .Exit .NoMem move.l #spr_er_NoMem,d0 not enough memory bra.s .Exit ;------------------------------------------------------------------------------ ; GetSprite SprN(d5) --> SpriteInfo(a0) ;------------------------------------------------------------------------------ spr.GetSprite movem.l d5/a5,-(a7) lea sprite.lib(pc),a5 lea spr_SInfo0(a5),a0 mulu #spr_si_SizeOf,d5 lea 0(a0,d5.w),a0 SpriteInfo address movem.l (a7)+,d5/a5 rts ;------------------------------------------------------------------------------ ; FreeSprite SprN(d5) --> Error(d0) ;------------------------------------------------------------------------------ spr.FreeSprite movem.l a0-a1/a5,-(a7) lea sprite.lib(pc),a5 bsr spr.GetSprite SpriteInfo addr. in a0 moveq #72,d0 needs at least 72 bytes bsr spr.MakeBuffer make DMA buffer cmpi.l #spr_er_OK,d0 error ? bne.s .NoMem clr.w spr_si_XPos(a0) clr.w spr_si_YPos(a0) clr.w spr_si_Flags(a0) clr.w spr_si_Height(a0) move.l spr_si_Data(a0),a1 move.l #$feffff00,(a1) fill DMA buffer clr.l 4(a1) clr.l 8(a1) move.l #spr_er_OK,d0 all right .Exit movem.l (a7)+,a0-a1/a5 rts .NoMem move.l #spr_er_NoMem,d0 not enough memory bra.s .Exit ;------------------------------------------------------------------------------ ; MoveSprite dX,dY,SprN(d2,d3,d5) ;------------------------------------------------------------------------------ spr.MoveSprite movem.l d2-d3/a0/a5,-(a7) lea sprite.lib(pc),a5 bsr spr.GetSprite SpriteInfo addr. in a0 add.w spr_si_XPos(a0),d2 new coordinates add.w spr_si_YPos(a0),d3 bsr spr.SetSprPos set sprite position movem.l (a7)+,d2-d3/a0/a5 rts ;------------------------------------------------------------------------------ ; SetSprPos XPos,YPos,SprN(d2,d3,d5) ;------------------------------------------------------------------------------ spr.SetSprPos movem.l a0/a5,-(a7) lea sprite.lib(pc),a5 bsr spr.CorrectPos correct position bsr spr.GetSprite SpriteInfo addr. in a0 move.w d2,spr_si_XPos(a0) new coordinates move.w d3,spr_si_YPos(a0) bsr spr.CalcDef movem.l (a7)+,a0/a5 rts ;------------------------------------------------------------------------------ ; SetBorder MinX,MinY,MaxX,MaxY(d0,d1,d2,d3) ;------------------------------------------------------------------------------ spr.SetBorder move.l a5,-(a7) lea sprite.lib(pc),a5 move.w d0,spr_MinX(a5) move.w d1,spr_MinY(a5) move.w d2,spr_MaxX(a5) move.w d3,spr_MaxY(a5) move.l (a7)+,a5 rts ;------------------------------------------------------------------------------ ; AnimStep ;------------------------------------------------------------------------------ spr.AnimStep rts ;------------------------------------------------------------------------------ ; InsertCL NoOp --> Error(d0) ;------------------------------------------------------------------------------ spr.InsertCL movem.l a0/a5,-(a7) lea sprite.lib(pc),a5 bsr cop.AskAddress current address in d0 move.l d0,a1 move.l a1,spr_CListAddr(a5) store CList address lea spr.da.CList(pc),a0 add list moveq #64,d0 bsr cop.AddList bsr spr.RefreshCL refresh CList movem.l (a7)+,a0/a5 rts ;------------------------------------------------------------------------------ ; RefreshCL NoOp --> Error(d0) ;------------------------------------------------------------------------------ spr.RefreshCL movem.l d7/a0-a1/a5,-(a7) lea sprite.lib(pc),a5 lea spr_SInfo0(a5),a0 move.l spr_CListAddr(a5),d0 beq.s .NoCList move.l d0,a1 moveq #7,d7 .Loop move.l spr_si_Data(a0),d0 buffer address move.w d0,6(a1) swap d0 move.w d0,2(a1) lea spr_si_SizeOf(a0),a0 next sprite lea 8(a1),a1 dbf d7,.Loop move.l #spr_er_OK,d0 all right .Exit movem.l (a7)+,d7/a0-a1/a5 rts .NoCList move.l #spr_er_NoCList,d0 no CList bra.s .Exit ******************************************************************************* * Private Routines ******************************************************************************* ;------------------------------------------------------------------------------ ; MakeBuffer SpriteInfo,Size(a0,d0) --> Error(d0) ;------------------------------------------------------------------------------ spr.MakeBuffer movem.l d1-d2/a0-a2,-(a7) move.l a0,a2 store SpriteInfo addr. move.l d0,d2 store size cmp.l spr_si_Size(a2),d2 enough ? ble.s .Enough move.l spr_si_Data(a2),d1 is there memory beq.s .Free allocated ? move.l d1,a1 move.l spr_si_Size(a2),d0 size bsr mem.FreeMem free last buffer .Free move.l d2,d0 size move.l #mem_ty_Chip,d1 requirements bsr mem.AllocMem allocate new buffer tst.l d0 beq .NoMem move.l a0,spr_si_Data(a2) move.l d0,spr_si_Size(a2) .Enough move.l #spr_er_OK,d0 all right .Exit movem.l (a7)+,d1-d2/a0-a2 rts .NoMem move.l #spr_er_NoMem,d0 not enough memory bra.s .Exit ;------------------------------------------------------------------------------ ; CalcDef SpriteInfo(a0) ;------------------------------------------------------------------------------ spr.CalcDef movem.l d0-d7/a0-a1,-(a7) move.w spr_si_XPos(a0),d2 refresh SpriteInfo move.w spr_si_YPos(a0),d3 move.w spr_si_Flags(a0),d4 move.w spr_si_Height(a0),d5 move.b d3,d0 lsl.w #8,d0 SV7-SV0 in d0 move.w d3,d7 SV8-SV0 -> d7 add.w d5,d7 EV8-EV0 move.b d7,d6 lsl.w #8,d6 EV7-EV0 in d6 lsr.w #8,d3 SV8 in d3 move.b d3,d6 lsl.b #1,d6 lsr.w #8,d7 or.b d7,d6 move.w d2,d7 SH8-SH0 roxr.w #1,d7 roxl.b #1,d6 SV8,EV8,SH0 ok move.b d7,d0 SH8-SH1 ok swap d0 move.w d6,d0 btst #spr_fl_b_Attach,d4 attach ? beq.s .NoAtt bset #spr_fl_b_Attach,d0 .NoAtt move.l spr_si_Data(a0),d1 is there DMA buffer ? beq.s .Exit move.l d1,a1 move.l d0,(a1) insert SPRPOS, SPRCTL .Exit movem.l (a7)+,d0-d7/a0-a1 rts ;------------------------------------------------------------------------------ ; CorrectPos XPos,YPos(d2,d3) --> CorrectXPos,CorrectYPos(d2,d3) ;------------------------------------------------------------------------------ spr.CorrectPos move.l a5,-(a7) lea sprite.lib(pc),a5 cmp.w spr_MinX(a5),d2 bge.s .OkMinX move.w spr_MinX(a5),d2 .OkMinX cmp.w spr_MaxX(a5),d2 ble.s .OkMaxX move.w spr_MaxX(a5),d2 .OkMaxX cmp.w spr_MinY(a5),d3 bge.s .OkMinY move.w spr_MinY(a5),d3 .OkMinY cmp.w spr_MaxY(a5),d3 ble.s .OkMaxY move.w spr_MaxY(a5),d3 .OkMaxY move.l (a7)+,a5 rts ******************************************************************************* * DataArea ******************************************************************************* spr.da.CList DC.W $120,0,$122,0,$124,0,$126,0 DC.W $128,0,$12a,0,$12c,0,$12e,0 DC.W $130,0,$132,0,$134,0,$136,0 DC.W $138,0,$13a,0,$13c,0,$13e,0 ENDM