summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drawbob.i659
-rw-r--r--drawbob.s1965
2 files changed, 2624 insertions, 0 deletions
diff --git a/drawbob.i b/drawbob.i
new file mode 100644
index 0000000..dd550d7
--- /dev/null
+++ b/drawbob.i
@@ -0,0 +1,659 @@
+*
+* DrawBob.i (zu BOBOL V3.16 23-Aug-91)
+*
+
+ *********** BOBOL Kommandos *************
+
+
+DO MACRO ; LoopBeginn setzen
+dovar set *
+ ENDM
+
+REPEAT MACRO ; LoopBeginn setzen
+repeatvar set *
+ ENDM
+
+FOR MACRO
+forvar set *
+ dc.w BOBFOR
+ dc.w \1 ; Anzahl Durchläufe
+ ENDM
+
+LOOP MACRO ; Prg von vorne starten
+ dc.w BOBLOOP
+ ENDM
+
+ENDE MACRO ; Prg beenden
+ dc.w BOBENDE
+ ENDM
+
+REMOVE MACRO ; Bob entfernen
+ dc.w BOBREMOVE
+ ENDM
+
+SETPRI MACRO ; Bob-Priorität ändern
+ dc.w BOBSETPRI
+ dc.w \1
+ ENDM
+
+SIGNAL MACRO ; SignalMaske senden
+ dc.w BOBSIGNAL
+ dc.w \1
+ ENDM
+
+WAIT MACRO ; auf SignalMaske warten
+ dc.w BOBWAIT
+ dc.w \1
+ ENDM
+
+BBEQ MACRO ; Springen wenn Maske falsch
+scavar set *
+ dc.w BOBUNTIL
+ dc.w \1 ; Maske
+ dc.w scavar-\2 ; Zieladresse
+ ENDM
+
+BBNE MACRO ; Springen wenn Maske richtig
+scavar set *
+ dc.w BOBWHILE
+ dc.w \1 ; Maske
+ dc.w scavar-\2 ; Zieladresse
+ ENDM
+
+UNTIL MACRO ; zum REPEAT springen bis Bedingung stimmt
+scavar set *
+ dc.w BOBUNTIL
+ dc.w \1
+ dc.w scavar-repeatvar
+ ENDM
+
+WHILE MACRO ; zum DO springen bis Bedingung nicht mehr stimmt
+scavar set *
+ dc.w BOBWHILE
+ dc.w \1
+ dc.w scavar-dovar
+ ENDM
+
+NEXT MACRO
+forvar2 set *
+ dc.w BOBNEXT
+ dc.w forvar2-forvar-4
+ ENDM
+
+CPUJUMP MACRO
+ dc.w BOBCPUJUMP
+ dc.l \1
+ dc.l \2
+ ENDM
+
+LEFT MACRO
+ dc.w BOBLEFT
+ dc.w \1
+ ENDM
+
+RIGHT MACRO
+ dc.w BOBRIGHT
+ dc.w \1
+ ENDM
+
+UP MACRO
+ dc.w BOBUP
+ dc.w \1
+ ENDM
+
+DOWN MACRO
+ dc.w BOBDOWN
+ dc.w \1
+ ENDM
+
+LEFTUP: MACRO
+ dc.w BOBLEFT+BOBUP
+ dc.w \1
+ ENDM
+
+RIGHTUP: MACRO
+ dc.w BOBRIGHT+BOBUP
+ dc.w \1
+ ENDM
+
+LEFTDOWN: MACRO
+ dc.w BOBLEFT+BOBDOWN
+ dc.w \1
+ ENDM
+
+RIGHTDOWN: MACRO
+ dc.w BOBRIGHT+BOBDOWN
+ dc.w \1
+ ENDM
+
+DELAY MACRO
+ dc.w BOBDELAY
+ dc.w \1
+ ENDM
+
+RNDDELAY MACRO
+ dc.w BOBRNDDELAY
+ dc.w \1
+ dc.w \2
+ ENDM
+
+POKEB: MACRO
+ dc.w BOBPOKEB
+ dc.l \1
+ dc.w \2
+ ENDM
+
+POKEW MACRO
+ dc.w BOBPOKEW
+ dc.l \1
+ dc.w \2
+ ENDM
+
+POKEL MACRO
+ dc.w BOBPOKEL
+ dc.l \1
+ dc.l \2
+ ENDM
+
+RELMOVE: MACRO
+ dc.w BOBRELMOVE
+ dc.w \1
+ ENDM
+
+SETANIM: MACRO
+ dc.w BOBSETANIM
+ dc.l \1
+ ENDM
+
+SETMOVE: MACRO
+ dc.w BOBSETMOVE
+ dc.l \1
+ ENDM
+
+SETCLIP: MACRO
+ dc.w BOBSETCLIP
+ dc.w \1
+ dc.w \2
+ dc.w \3
+ dc.w \4
+ dc.w \5
+ ENDM
+
+SETORGTAB: MACRO
+ dc.b bob_OrgTab
+ dc.b BOBSETLONG
+ dc.l \1
+ ENDM
+
+
+SETX: MACRO
+ dc.b bob_X
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+
+SETY: MACRO
+ dc.b bob_Y
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+SETDATA: MACRO
+ IFEQ NARG-1 ; 1 Argument
+ DC.W BOBSETDATA ; Normales AddBob
+ DC.L \1
+ ENDC
+ IFEQ NARG-2 ; 2 Argumente
+ DC.W BOBSETRELDATA ; Relatives AddBob
+ DC.L \1 ; Offset im Bobifile
+ DC.L \2 ; Zeiger auf Zeiger auf File
+ ENDC
+ ENDM
+
+SETMOVESPEED: MACRO
+ DC.W BOBSETMOVESPEED
+ DC.W \1
+ ENDM
+
+SETMOVESTEP: MACRO
+ dc.b bob_MoveStep
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+SETANIMSPEED: MACRO
+ DC.W BOBSETANIMSPEED
+ DC.W \1
+ ENDM
+
+SETID: MACRO
+ DC.W BOBSETID
+ DC.W \1
+ ENDM
+
+SETUSERDATA: MACRO
+ dc.b bob_UserData
+ dc.b BOBSETLONG
+ DC.L \1
+ ENDM
+
+SETUSERDATAPTR: MACRO
+ dc.b bob_UserDataPtr
+ dc.b BOBSETLONG
+ DC.L \1
+ ENDM
+
+
+
+SETFLAGS: MACRO
+ dc.b bob_Flags
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+SETUSERFLAGS: MACRO
+ dc.b bob_UserFlags
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+
+LSIGNAL: MACRO
+ dc.w BOBLSIGNAL
+ dc.w \1
+ ENDM
+
+LWAIT: MACRO
+ dc.w BOBLWAIT
+ dc.w \1
+ ENDM
+
+ADDBOB: MACRO
+ dc.w BOBADDBOB
+ dc.l \1
+ ENDM
+
+ADDRELBOB: MACRO
+ dc.w BOBADDRELBOB
+ dc.l \1 ; Bob
+ dc.w \2,\3 ; X/Y-Offsets
+ ENDM
+
+SETCOLLHANDLER: MACRO
+ dc.b bob_CollHandler
+ dc.b BOBSETLONG
+ dc.l \1
+ ENDM
+
+SETMEMASK: MACRO
+ dc.b bob_MeMask
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+SETHITMASK: MACRO
+ dc.b bob_HitMask
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+RNDANIM: MACRO
+ dc.w BOBRNDANIM
+ dc.w \1 ; 1. Bildchen (-1 ?)
+ dc.w \2 ; Letztes Bildchen
+ ENDM
+
+SETHANDLER: MACRO
+ dc.b bob_Handler
+ dc.b BOBSETLONG
+ dc.l \1
+ IFEQ NARG-2
+ dc.b bob_HandlerD0
+ dc.b BOBSETLONG
+ dc.l \2
+ ENDC
+ ENDM
+
+
+REMHANDLER: MACRO
+ SETHANDLER 0
+ ENDM
+
+
+MOVETO: MACRO
+ dc.w BOBMOVETO
+ dc.w \1,\2 ; X/Y
+ dc.w \3 ; Anzahl Schritte bis dahin
+ ENDM
+
+FLASH: MACRO
+ dc.w BOBFLASH
+ dc.w \1 ; Zeit in DrawBob()s oder so
+ dc.w \2 ; Farbnummer
+ ENDM
+
+SETCONVERT: MACRO
+ dc.w BOBSETCONVERT
+ dc.l \1 ; Tabelle
+ dc.w \2 ; EintragsGrösse
+ dc.w \3 ; EintragsOffset
+ ENDM
+
+ANIMTO: MACRO
+ dc.w BOBANIMTO
+ dc.w \1 ; 1. Bobnummer
+ dc.w \2 ; Letzte Bobnummer
+ ENDM
+
+GOTO: MACRO
+ dc.w BOBGOTO
+ dc.l \1 ; Label
+ ENDM
+
+ADDDAUGHTER: MACRO
+ dc.w BOBADDDAUGHTERBOB
+ dc.l \1 ; Daughter-Bob
+ dc.w \2,\3 ; X-Versatz,Y-Versatz
+ ENDM
+
+SETIMAGE: MACRO
+ dc.b bob_Image
+ dc.b BOBSETWORD
+ dc.w \1
+ ENDM
+
+
+TESTJOY: MACRO
+ dc.w BOBTESTJOY
+ dc.w \1 ; Joystick-Maske
+ IFEQ NARG-1
+ dc.l 0
+ ELSE
+ dc.l \2 ; Zeiger auf FlipFlag
+ ENDC
+ ENDM
+
+
+BITTEST: MACRO ; BitTest BitNr,Adr
+ dc.w BOBBITTEST
+ dc.w \1
+ dc.l \2
+ ENDM
+
+JEQ: MACRO
+mvar: SET *
+ dc.w BOBJEQ
+ dc.w \1-mvar
+ ENDM
+
+JNE: MACRO
+mvar: SET *
+ dc.w BOBJNE
+ dc.w \1-mvar
+ ENDM
+
+
+FOREVERMAGIC: EQU -1
+
+FOREVER: MACRO
+ FOR FOREVERMAGIC
+ ENDM
+
+
+
+
+
+ *********** BOBKOMMANDOS *************
+
+
+COMVAL: SET -2
+
+SETCOM: MACRO
+BOB\1: EQU COMVAL
+COMVAL: SET COMVAL-2
+ ENDM
+
+
+ SETCOM SETWORD
+ SETCOM SETLONG
+ SETCOM LOOP
+ SETCOM ENDE
+ SETCOM REMOVE
+ SETCOM SETPRI
+
+ SETCOM SIGNAL
+ SETCOM WAIT
+ SETCOM CPUJUMP
+ SETCOM UNTIL
+ SETCOM WHILE
+
+ SETCOM POKEB
+ SETCOM POKEW
+ SETCOM POKEL
+ SETCOM RELMOVE
+ SETCOM SETANIM
+
+ SETCOM SETMOVE
+ SETCOM SETCLIP
+ SETCOM SETDATA
+ SETCOM SETMOVESPEED
+
+ SETCOM SETANIMSPEED
+ SETCOM SETID
+ SETCOM FOR
+ SETCOM NEXT
+
+ SETCOM LSIGNAL
+ SETCOM LWAIT
+ SETCOM DELAY
+ SETCOM RNDDELAY
+ SETCOM ADDBOB
+
+ SETCOM RNDANIM
+ SETCOM MOVETO
+
+ SETCOM FLASH
+ SETCOM SETCONVERT
+ SETCOM ANIMTO
+ SETCOM GOTO
+ SETCOM ADDRELBOB
+
+ SETCOM SETRELDATA
+ SETCOM ADDDAUGHTERBOB
+ SETCOM TESTJOY
+ SETCOM BITTEST
+ SETCOM JEQ
+
+ SETCOM JNE
+
+
+BOBLEFT: EQU 1
+BOBRIGHT: EQU 2
+BOBUP: EQU 4
+BOBDOWN: EQU 8
+
+;-----------------------------------------------------------------------
+
+ *********** BOBSTRUKTUREN *************
+
+ STRUCTURE BobData,0
+ WORD bod_Width ; Breite des Bobs in Pixel
+ WORD bod_Height ; Höhe des Bobs in Zeilen
+ WORD bod_X0 ; X-Offset des Bob-Nullpunkts
+ WORD bod_Y0 ; Y-Offset des Bob-Nullpunkts
+ WORD bod_CollX0
+ WORD bod_CollY0
+ WORD bod_CollX1
+ WORD bod_CollY1
+ BYTE bod_PlanePick ; Für welche Planes sind Daten vorhanden
+ BYTE bod_PlaneOnOff ; Was tun mit den restlichen Planes
+ WORD bod_Flags ; Siehe BODF_ Definitionen
+ WORD bod_WordSize ; Bob-Breite in WORDs +1
+ WORD bod_PlaneSize ; Anzahl Bytes einer Plane
+ WORD bod_TotalSize ; Länge des Bobs+Header
+ LABEL bod_SIZEOF ; Grösse dieses Bob-Headers
+ LABEL bod_Images ; Bob Images
+
+ BITDEF BOD,ANIMKEY,8 ; Bit 8 / erstes Bob einer Anim
+
+;-----------------------------------------------------------------------
+
+ *** Flags für bob_Flags
+
+ BITDEF BOB,NORESTORE,0 ; Bit 0 / Bob nicht restoren
+ BITDEF BOB,NODRAW,1 ; Bit 1 / Bob nicht zeichnen
+ BITDEF BOB,BACKCLEAR,2 ; Bit 2 / Hintergrund löschen
+ BITDEF BOB,NOLIST,3 ; Bit 3 / Bob nicht in Liste einfügen
+ BITDEF BOB,NOCUT,4 ; Bit 4 / nicht Cookie Cut
+ BITDEF BOB,NODOUBLE,5 ; Bit 5 / nicht double buffern
+ BITDEF BOB,SPECIALDRAW,6 ; Bit 6 / nur zeichnen wenn ein anderes bob dahinter liegt
+ BITDEF BOB,NOCOLLISION,7 ; Bit 7 / keine Kollision ausloesen
+ BITDEF BOB,FLIPXMOVE,8 ; Bit 8 / X-Move-Koordinaten spiegeln
+ BITDEF BOB,FLIPYMOVE,9 ; Bit 9 / Y-Move-Koordinaten spiegeln
+ BITDEF BOB,NEWIMAGE,10 ; Bit 10 / Bob nur zeichnen wenn sich Image geändert hat
+ BITDEF BOB,NOMOVE,11 ; Bit 11 / MovePrg anhalten
+ BITDEF BOB,NOANIM,12 ; Bit 12 / Bob in Liste eintragen aber nicht handeln
+ BITDEF BOB,ONLYANIM,13 ; Bit 13 / nur Anims ausführen
+ BITDEF BOB,HIDDEN,14 ; Bit 14 / wird gesetzt wenn bob nicht gezeichnet wird (SPECIAL-DRAW)
+
+ **** Flags für bob_ClipFlags
+
+ BITDEF CLIP,DOWN,0 ; Bit 0 / gegen unten clippen
+ BITDEF CLIP,UP,1 ; Bit 1 / gegen oben clippen
+ BITDEF CLIP,LEFT,2 ; Bit 2 / gegen links clippen
+ BITDEF CLIP,RIGHT,3 ; Bit 3 / gegen rechts clippen
+ BITDEF CLIP,GLOBAL,4 ; Bit 4 / Globale Klipkoordinate mitrechnen
+
+CLIPF_X: EQU CLIPF_RIGHT|CLIPF_LEFT
+CLIPF_Y: EQU CLIPF_UP|CLIPF_DOWN
+CLIPF_ALL: EQU CLIPF_X|CLIPF_Y
+CLIPF_GLOBALL: EQU CLIPF_ALL|CLIPF_GLOBAL
+
+
+ **** Bits für Status-Register
+
+ BITDEF SR,ZEROFLAG,0 ; Bit 0 / ZeroBit (Anwendung wie CPU-SR)
+
+
+;-------------------------------------------------------------------------
+
+ STRUCTURE Bob,0
+
+ APTR bob_NextBob ; nachfolgendes Bob in der Liste
+ APTR bob_LastBob ; vorhergehendes Bob in der Liste
+ BYTE bob_Id ; BobKennung
+ BYTE bob_Priority ; Priorität
+
+ APTR bob_BobData ; Zeiger auf BobData Struktur
+ WORD bob_X ; aktuelle X Koordinate (ohne Offset)
+ WORD bob_Y ; aktuelle Y Koordinate (ohne Offset)
+
+ WORD bob_AbsX ; korrigierte X Koordinate (ohne Offset)
+ WORD bob_AbsY ; korrigierte Y Koordinate (ohne Offset)
+
+ WORD bob_X0 ; Kopie aus bod_X0
+ WORD bob_Y0 ; Kopie aus bod_Y0
+
+ LONG bob_LastLastOffset ; vorletzte X+Y Koordinate (mit Offset)
+ WORD bob_LastLastBltSize ; vorletzte Breite+Höhe
+
+ LONG bob_LastOffset ; letzte X+Y Koordinate (mit Offset)
+ WORD bob_LastBltSize ; letzte Breite+Höhe
+
+ WORD bob_Image ; aktuelles Bob
+ WORD bob_LastImage ; letztes Bob
+ WORD bob_LastLastImage ; vorletztes Bob
+
+ APTR bob_AnimPrg ; Zeiger auf aktuelles AnimKommando
+ WORD bob_AnimOffset ; Offset ins AnimPrg
+ BYTE bob_AnimSpeed ; AnimationsGeschwindigkeit
+ BYTE bob_AnimSpeedCounter ; Speed-Zähler
+ WORD bob_AnimTo ; Ziel von ANIMTO
+
+ APTR bob_MovePrg ; Zeiger auf aktuelles MoveProgram
+ WORD bob_MoveOffset ; Offsets ins MovePrg
+ BYTE bob_MoveSpeed ; Bewegungsgeschwindigkeit
+ BYTE bob_MoveSpeedCounter ; Speed-Zähler
+ WORD bob_MoveCounter ; Kommando Zähler
+ WORD bob_MoveCommand ; aktuelles Kommando
+ WORD bob_MoveStep ; Geschwindigkeit
+ WORD bob_RelMoveCounter ; Anzahl RelMoves (in Bytes)
+
+ WORD bob_AnimDelayCounter
+ WORD bob_MoveDelayCounter
+
+ WORD bob_LSignalSet ; gesetzte lokale symbols
+ WORD bob_Flags ; diverse Flags (siehe NewBob Struktur)
+ BYTE bob_RemFlag ; Wenn dieses Flag nicht 0 ist, wird Bob entfernt sobald es wieder 0 ist
+ BYTE bob_NewPri
+
+ APTR bob_LastLastSaveBuffer ; HintergrundBuffer für vorletztes Bob
+ APTR bob_LastSaveBuffer ; HintergrundBuffer für letztes Bob
+
+ WORD bob_ClipX ; linke obere X Clip-Koordinate
+ WORD bob_ClipY ; linke obere Y Clip-Koordinate
+ WORD bob_ClipX2 ; rechte untere X Clip-Koordinate
+ WORD bob_ClipY2 ; rechte untere Y Clip-Koordinate
+ WORD bob_ClipFlags ; diverse Flags fürs Cliing
+
+ WORD bob_CollX0
+ WORD bob_CollY0
+ WORD bob_CollX1
+ WORD bob_CollY1
+
+ WORD bob_AnimForCounter ; für AnimPrg-For-Next
+ WORD bob_MoveForCounter ; für MovePrg-For-Next
+
+ APTR bob_OrgTab ; Zeiger auf ersetzende OriginTabelle
+
+ APTR bob_CollHandler ; Wird angesprungen bei MeMask-Koll.
+ WORD bob_MeMask ; which types can collide with this bob
+ WORD bob_HitMask ; which types this bob can collide with
+
+ LONG bob_Handler ; CPU-Prg welches vor dem Zeichnen aufgerufen wird
+ LONG bob_HandlerD0 ; Diesen Wert bekommt man im D0
+
+ WORD bob_MoveToSteps ; Anzahl der noch zu machenden Steps
+ WORD bob_MoveToX ; X Koordinate mit 16 multipliziert
+ WORD bob_MoveToY ; Y Koordinate mit 16 multipliziert
+ WORD bob_MoveToXStep ; X Verschiebung
+ WORD bob_MoveToYStep ; Y Verschiebung
+
+ APTR bob_ConvertTab
+ WORD bob_ConvertSize
+ WORD bob_ConvertOffset
+
+ BYTE bob_TraceMode
+ BYTE bob_TraceLock
+
+ BYTE bob_FlashTime
+ BYTE bob_FlashColor
+
+ LONG bob_UserData ; Frei benutzbar vom User
+ APTR bob_UserDataPtr ; noch mal was für Straub's Ronny
+ WORD bob_UserFlags
+
+ APTR bob_ParentBob
+
+ BYTE bob_sr ; Status-register
+ BYTE bob_Pad1
+
+ LABEL bob_SIZEOF ; Länge der Bob Struktur
+
+ LABEL bob_AnimPtrs ; Array auf die einzelnen Bobs der Animation
+
+bob_Test: EQU 18504
+
+
+ BITDEF JOY,DOWN,0
+ BITDEF JOY,RIGHT,1
+ BITDEF JOY,UP,2
+ BITDEF JOY,LEFT,3
+ BITDEF JOY,FIRE,7
diff --git a/drawbob.s b/drawbob.s
new file mode 100644
index 0000000..1631f4f
--- /dev/null
+++ b/drawbob.s
@@ -0,0 +1,1965 @@
+****************************************************************************
+** **
+** B O B O L - The Amiga High Speed Bob Animation System **
+** **
+****************************************************************************
+** **
+** Modification History **
+** -------------------- **
+** **
+** 04-Apr-89 CHH Created this file from CHW's DrawBob.s **
+** 07-Apr-89 CHH NORESTORE NODRAW + BACKCLEAR Flags **
+** 07-Apr-89 CHH NOLIST **
+** 08-Apr-89 CHH Added BobControlSystem "BOBOL" **
+** 08-Apr-89 CHH RemBob Bug fixed **
+** 14-Apr-89 CHH RemBob Bug 2 fixed **
+** 21-Apr-89 CHH BOBPOKEL Bug fixed **
+** 22-May-89 CHW Bit definitions cleaned up **
+** 04-Jun-89 CHH DownClipping **
+** 06-Jun-89 CHH UpClipping LeftClipping RightClipping **
+** 06-Jun-89 CHW Converted to conform the Exec rules **
+** 07-Jun-89 CHH RemAllBobs added **
+** 15-Jun-89 CHH SETCLIPFLAGS+SETORGTAB added **
+** 19-Jun-89 CHH CMP/BNE-BOBOL-Wüste durch Tabelle ersetzt. **
+** SetMovePrg,SetAnimPrg extern gemacht. **
+** 20-Jun-89 CHH NewBobStructure durch NewBobPrg ersetzt **
+** 26-Jun-89 CHH FOR/NEXT added **
+** 27-Jun-89 CHH GlobalClipping added **
+** 19-Jul-89 CHH Local Signals added **
+** 27-Jul-89 CHH KollisionsRectangle added **
+** 13-Sep-89 CHH GetBobData extern definiert **
+** 29-Oct-89 CHH ADDBOB added **
+** 22-Nov-89 CHH NEWIMAGE added **
+** 27-Nov-89 CHH TestPoint() Collision-Rectangle added **
+** 15-Dec-89 CHH RNDANIM added **
+** 27-Jan-90 CHH GlobalX added **
+** 25-Mar-90 CHH SETHANDLER added **
+** 02-Apr-90 CHH rechtes Clipping korrigiert **
+** 02-Apr-90 CHH Straubs Kollisions-Routine eingebaut **
+** 02-Apr-90 CHH WaitBlit() will nun Custom im A5 **
+** 02-Apr-90 CHW Code gekürzt, verschnellert und aufgeräumt **
+** 29-May-90 CHH MOVETO eingebaut, MOVESPEED und MOVESTEP sind auf **
+** 1 initialisiert, Reihenfolge-Bug von SETMOVE und **
+** SETMOVESTEP entfernt -> ist jetzt egal **
+** FLASH eingebaut **
+** 16-Jun-90 CHH X0 und Y0 in BobStruktur eingebaut, damit alles **
+** pure ist **
+** 20-Jun-90 RS TestBehind durch TestBobOverlay ersetzt -> **
+** SPECIALDRAW läuft wieder **
+** 25-Jul-90 CHH ANIMSPEED werden auf 1 initialisiert **
+** 31-Jul-90 CHH TripleScreen halb eingebaut **
+** 2-Aug-90 CHH SETCONVERT eingebaut **
+** 6-Aug-90 CHH NOANIM eingebaut **
+** 8-Aug-90 CHH ANIMTO "" **
+** 13-Aug-90 CHH GOTO fuer AddBobPrg eingebaut **
+** 14-Aug-90 CHH MAXANIM entfernt -> beliebige Anzahl Bobs **
+** 15-Aug-90 RS RTS in Function's optimiert **
+** 18-Aug-90 RS MAXANIM bug fixed -> clr.l (A3) **
+** 09-Sep-90 RS ADDRELBOB added **
+** 15-Sep-90 RS ADDDAUGHTERBOB added **
+** 15-Sep-90 CHH SETIMAGE added **
+** 16-Sep-90 CHW Code cleaned up and optimized, Kollision repariert **
+** 19-Sep-90 RS Kollision fuer DaughterBobs angepasst **
+** 19-Oct-90 CHH Joystick-Kommandos eingebaut **
+** 23-Oct-90 CHH StatusRegister added **
+** 25-Oct-90 CHH BITTEST/JEQ/JNE/FOREVER eingebaut **
+** 28-Oct-90 C+R SETWORD/SETLONG eingebaut. Makros geändert -> **
+** alles kürzer,besser,schneller,genialer. **
+** 1-Nov-90 CHH Joystick-Routine geändert auf JoyBuf **
+** 2-Nov-90 CHH SETHANDLER-Funktion durch doppeltes SETLONG-MACRO **
+** ersetzt,UserFlags added,ONLYANIM-Flag added ** **
+** 21-Nov-90 CHH RemBob/SpecialDraw-Bug behoben **
+** 24-Feb-91 CHW An neues Library-Konzept angepasst **
+** 28-Feb-91 CHW Blitter-Arbitration eingebaut **
+** 10-Apr-91 CHH SaveMask eingebaut **
+** 10-Apr-91 CHH SaveMask wird jetzt im BitmStr übergeben / JNE und **
+** JEQ Sprünge relativ gemacht **
+** 23-Aug-91 CHH FlipFlag für AskJoy added **
+** **
+** Benutzung: Einmal 'InitDrawBob' aufrufen | Parameter: A0=BitMap **
+** Resultat : Nix **
+** **
+** 'AddBob' ein Bob addieren | Parameter: A1=InitPrg **
+** Resultat : D0=Bob **
+** **
+** 'RemBob' ein Bob entfernen | Parameter: A0=Bob **
+** Resultat : Nix **
+** **
+** MainLoop: 'RestoreBobList' | Parameter: A1=BitMap **
+** Resultat : Nix **
+** **
+** 'DrawBobList' | Parameter: A1=BitMap **
+** Resultat : Nix **
+** **
+****************************************************************************
+
+
+BOBVERSION: EQU 3
+BOBREVISION: EQU 16
+
+ OPT O+,OW-,O5-,OW6+
+
+ IDNT Bobol
+ SECTION text,CODE
+
+ INCLUDE "MyExec.i"
+ INCLUDE "exec/macros.i"
+ INCLUDE "hardware/custom.i"
+ INCLUDE "DrawBob.i"
+
+ XREF _custom,__MyExecBase
+
+ XDEF InitDrawBob,AddBob,RemBob,RestoreBobList
+ XDEF DrawBobList,RestoreOneBob,DrawOneBob
+ XDEF AnimateOneBob,MoveOneBob,TestPoint
+ XDEF WaitBlit,RemAllBobs,SetAnimPrg,SetMovePrg
+ XDEF SetGlobalClip,GetBobData,GlobalX
+ XDEF HandleCollision,CollOneBob,FlashBob
+
+
+ STRUCTURE DrawOneBobStackFrame,0
+
+ WORD sf_Temp1
+ WORD sf_Temp2
+ WORD sf_TempX ; X und Y müssen hintereinander sein!
+ WORD sf_TempY
+ WORD sf_BobOffset
+ WORD sf_BobModulo
+ UWORD sf_FirstMask
+ UWORD sf_LastMask
+
+ LABEL sf_SIZEOF
+
+;-----------------------------------------------------------------------
+; Achtung: Die Befehlstabelle ist rückwärts organisiert, also neue
+; Kommandos hier am Anfang anfügen und nicht beim Label, gell!
+; Die Kommando-Konstanten (BOBLOOP, ...) müssen GERADE sein!
+
+ dc.w JneFunc-BobolTab
+
+ dc.w JeqFunc-BobolTab
+ dc.w BitTestFunc-BobolTab
+ dc.w TestJoyFunc-BobolTab
+ dc.w AddDaughterFunc-BobolTab
+ dc.w SetRelDataFunc-BobolTab
+
+ dc.w AddRelBobFunc-BobolTab
+ dc.w GotoFunc-BobolTab
+ dc.w AnimToFunc-BobolTab
+ dc.w SetConvertFunc-BobolTab
+ dc.w FlashFunc-BobolTab
+
+ dc.w MoveToFunc-BobolTab
+ dc.w RndAnimFunc-BobolTab
+
+ dc.w AddBobFunc-BobolTab
+ dc.w RndDelayFunc-BobolTab
+ dc.w DelayFunc-BobolTab
+ dc.w LWaitFunc-BobolTab
+ dc.w LSignalFunc-BobolTab
+
+ dc.w NextFunc-BobolTab
+ dc.w ForFunc-BobolTab
+ dc.w SetIdFunc-BobolTab
+ dc.w SetAnimSpeedFunc-BobolTab
+
+ dc.w SetMoveSpeedFunc-BobolTab
+ dc.w SetDataFunc-BobolTab
+ dc.w SetClipFunc-BobolTab
+ dc.w SetMoveFunc-BobolTab
+
+ dc.w SetAnimFunc-BobolTab
+ dc.w RelMoveFunc-BobolTab
+ dc.w PokeLFunc-BobolTab
+ dc.w PokeWFunc-BobolTab
+ dc.w PokeBFunc-BobolTab
+
+ dc.w WhileFunc-BobolTab
+ dc.w UntilFunc-BobolTab
+ dc.w CpuJumpFunc-BobolTab
+ dc.w WaitFunc-BobolTab
+ dc.w SignalFunc-BobolTab
+
+ dc.w SetPriFunc-BobolTab
+ dc.w RemoveFunc-BobolTab
+ dc.w EndeFunc-BobolTab
+ dc.w LoopFunc-BobolTab
+ dc.w SetLongFunc-BobolTab
+ dc.w SetWordFunc-BobolTab
+
+BobolTab: dc.w 0
+
+;-----------------------------------------------------------------------
+
+ *** A0 : BitMap
+
+InitDrawBob: movem.l d0/a0,-(SP)
+ move.w bm_Pad(a0),d0
+ not.w d0
+ move.b d0,SaveMask
+ moveq #0,d0
+ move.b bm_Depth(a0),d0
+ move.w d0,NumPlanes
+ lea meb_BobList(a6),a0
+ jsr meb_NewList(a6)
+ movem.l (SP)+,d0/a0
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** D0: GlobalXClip / D1: GlobalYClip
+
+SetGlobalClip: movem.w d0/d1,GlobalXClip
+ rts
+
+
+;-----------------------------------------------------------------------
+
+
+ *** D0: Länge des Flashes / D1: Farbe des Flashes
+
+FlashBob: move.b d0,bob_FlashTime(a0)
+ move.b d1,bob_FlashColor(a0)
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob / A1: AnimPrg / D0: Speed
+
+SetAnimPrg: move.l a1,bob_AnimPrg(a0)
+ clr.w bob_AnimOffset(a0)
+ move.b d0,bob_AnimSpeed(a0)
+ move.b d0,bob_AnimSpeedCounter(a0)
+ subq.b #1,bob_AnimSpeedCounter(a0)
+ clr.w bob_AnimDelayCounter(a0)
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob / A1: MovePrg / D0: Speed / D1: MoveStep
+
+SetMovePrg: move.l a1,bob_MovePrg(a0)
+ move.b d0,bob_MoveSpeed(a0)
+ move.w d1,bob_MoveStep(a0)
+ clr.w bob_MoveOffset(a0)
+ clr.b bob_MoveSpeedCounter(a0)
+ clr.w bob_MoveCounter(a0)
+ clr.w bob_MoveCommand(a0)
+ clr.w bob_RelMoveCounter(a0)
+ clr.w bob_MoveDelayCounter(a0)
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A1: NewBob-Programm
+
+AddBob: movem.l d1-d7/a0-a6,-(SP)
+
+ cmp.w #BOBSETDATA,(a1) ; SetData am Anfang ?
+ beq.s 1$ ; ja --->
+ cmp.w #BOBSETRELDATA,(a1) ; SetRelocData
+ beq.s 1$ ; ja --->
+
+.Endlos: move.w #$f00,$dff180 ; ROT
+ move.w #$ff0,$dff180 ; GELB
+ MSG <"BadBob (A1)">
+ bra.s .Endlos ; Flacker
+
+1$: suba.l a0,a0 ; Reloc = 0;
+
+ cmp.w #BOBSETDATA,(a1) ; Reloc
+ beq.s .NormalAdd ; no -->
+
+ move.l 6(a1),a0 ; GetRelocBase
+ move.l (a0),a0 ; GetReloc
+
+.NormalAdd: add.l 2(a1),a0
+
+ move.l #bob_SIZEOF+8,d0 ; jaja
+11$: addq.l #4,d0
+ add.w bod_TotalSize(a0),a0
+ tst.w bod_Width(A0)
+ bmi.s 12$
+ btst #BODB_ANIMKEY,bod_Flags(a0)
+ beq.s 11$
+
+12$: SYSCALL AllocFastClearMem ; BobStruktur reservieren
+ move.l d0,a0
+ moveq.l #1,d0
+ move.b d0,bob_AnimSpeed(a0)
+ move.b d0,bob_MoveSpeed(a0)
+ move.w d0,bob_MoveStep(a0)
+ move.w #-1,bob_AnimTo(A0)
+
+ move.l a1,a2 ; Zeiger auf NewBobPrg
+ moveq.l #0,d1 ; Bobol-PC
+
+2$: lea BobolTab(PC),a3 ; NewBob-Programm ausführen
+ move.w 0(a2,d1.w),d0 ; Nächstes Kommando
+ or.w #$ff00,d0
+ cmp.w #BOBENDE,d0 ; Ende ?
+ beq.s 3$ ; ja --->
+ adda.w 0(a3,d0.w),a3 ; Routinen-Offset dazu
+
+ jsr (a3)
+ bra.s 2$
+3$:
+
+gugugu move.b bob_NewPri(a0),bob_Priority(a0)
+ move.b #$80,bob_NewPri(a0)
+
+ move.w bob_Flags(a0),d4
+
+ moveq.l #-1,d0
+ move.l d0,bob_LastLastOffset(a0)
+ move.l d0,bob_LastOffset(a0)
+
+ move.l d0,bob_LastImage(a0)
+
+ lea bob_AnimPtrs(a0),a3 ; Animations Array
+ move.l bob_BobData(a0),a2 ; Größtes Bob suchen
+ moveq #0,d0
+ moveq #0,d1
+ moveq #0,d2
+.Loop: addq.w #1,d2
+ move.l a2,(a3)+ ; Bob ins AnimArray eintragen
+ move.w bod_Width(a2),d0 ; Breite des Bobs in Pixel
+ bmi.s .EndLoop ; End-Markierung --->
+ addi.w #15,d0 ; aufrunden auf WORD
+ lsr.w #3,d0 ; Breite in Bytes
+ addq.w #2,d0 ; Breite + 2
+ mulu.w bod_Height(a2),d0 ; mal Höhe
+ cmp.l d1,d0 ; Ist Bob das grösste ?
+ blo.s 6$ ; nein --->
+ move.l d0,d1 ; sonst übernehmen
+6$: add.w bod_TotalSize(a2),a2
+ btst.b #BODB_ANIMKEY,bod_Flags(a2) ; Anim fertig ?
+ beq.s .Loop ; nein ---> Loop
+.EndLoop:
+ clr.l (a3) ; Endmarkierung im AnimArray
+
+ btst #BOBB_NORESTORE,d4 ; Speicher reservieren ?
+ bne.s 2$ ; nein --->
+
+ SYSTST.l TripleScreen
+ bne.s 2$
+
+
+ move.w NumPlanes,d2
+ move.w d2,d3
+
+
+ subq.w #1,d3
+ move.b SaveMask,d0
+.CLoop: ror.b #1,d0
+ bcs .PlaneExists
+ subq.w #1,d2
+.PlaneExists: dbf d3,.CLoop
+
+
+
+ mulu.w d2,d1 ; Länge einer BobPlane*Anzahl Bitmaps des Bildes
+ move.l d1,d0
+ add.l d0,d0 ; 2* wegen Double-Buffer
+ SYSCALL AllocMem ; reservieren
+
+ move.l d0,bob_LastSaveBuffer(a0)
+ add.l d1,d0
+ move.l d0,bob_LastLastSaveBuffer(a0)
+2$:
+ btst #BOBB_NOLIST,d4 ; Bob in Liste eintragen ?
+ bne.s 3$ ; nein --->
+ movea.l a0,a1 ; Bob
+ move.l a6,-(SP)
+ lea __MyExecBase(PC),a6
+ lea meb_BobList(a6),a0
+ jsr meb_Enqueue(a6)
+ movea.l (SP)+,a6
+ movea.l a1,a0
+3$:
+ move.l a0,d0
+ movem.l (SP)+,d1-d7/a0-a6
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob to remove
+
+RemBob: movem.l d0/a0-a1,-(SP)
+ move.l a0,d0 ; Bob gültig ?
+ beq.s 4$ ; nein --->
+
+ tst.b bob_RemFlag(a0)
+ bne.s 4$
+
+ move.b #1,bob_RemFlag(a0)
+ clr.l bob_MovePrg(a0)
+ clr.l bob_AnimPrg(a0)
+ clr.l bob_CollHandler(a0)
+ clr.w bob_HitMask(a0)
+
+ move.l a0,a1 ; A1=Bob
+1$: lea __MyExecBase(PC),a0 ; SHIIIT!! 3 TAGE DEBUG...
+ lea meb_BobList(a0),a0
+3$: move.l bob_NextBob(a0),a0
+ tst.l bob_NextBob(a0)
+ beq.s 4$
+ ; Ist Bob ParentBob des eben
+ cmp.l bob_ParentBob(A0),a1 ; gelöschten ? nein -->
+ bne.s 3$
+
+ bsr.s RemBob
+ bra.s 3$
+
+4$: movem.l (SP)+,d0/a0-a1
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** void
+
+RemAllBobs: move.l a0,-(SP)
+ lea meb_BobList(a6),a0
+1$: move.l bob_NextBob(a0),a0
+ tst.l bob_NextBob(a0)
+ beq.s 2$
+ tst.l bob_ParentBob(A0)
+ bne 1$
+ bsr RemBob
+ bra.s 1$
+2$: movea.l (SP)+,a0
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A1: BitMap, Zeichnet alle Bobs der Liste (rückwärts)
+
+DrawBobList: movem.l d0-d7/a0-a6,-(SP)
+ lea _custom,a5
+ bsr AskJoy
+ move.w d0,JoyBuf
+
+.Loop: lea __MyExecBase(PC),a0
+ lea meb_BobList(a0),a0 ; Zeiger auf erstes Bob
+
+3$: movea.l bob_NextBob(a0),a0 ; nächstes Bob
+ tst.l bob_NextBob(a0) ; kein Bob mehr ?
+ beq.s TestNewPri
+ cmp.b #3,bob_RemFlag(a0) ; muss Bob enfernt werden
+ blt.s 3$ ; nein --->
+ move.l a1,-(SP) ; jaja :-( !!
+ movea.l a0,a1 ; BobNode
+ SYSCALL Remove ; entfernen
+ move.l bob_LastSaveBuffer(a0),d0
+ move.l bob_LastLastSaveBuffer(a0),d1
+ cmp.l d0,d1
+ bhi.s 6$
+ move.l d1,d0
+6$:
+ move.l d0,a1 ; Save-Buffer
+ SYSCALL FreeMem ; freigeben
+ move.l a0,a1 ; Bob
+ SYSCALL FreeMem ; freigeben
+ movea.l (SP)+,a1
+ bra.s .Loop ; Nochmal von vorn
+
+
+TestNewPri: tst.b NewPri
+ beq.s .End
+ lea __MyExecBase(PC),a0
+ lea meb_BobList(a0),a0 ; erstes Bob in der Liste
+ moveq.l #0,d7
+1$: movea.l bob_NextBob(a0),a0 ; Zeiger auf nächstes Bob
+ tst.l bob_NextBob(a0) ; Noch ein Bob ?
+ beq.s .End ; nein ---> Ende
+ move.b bob_NewPri(a0),d0
+ cmpi.b #$80,d0 ; neue Priorität ?
+ beq.s 1$ ; nein --->
+ move.b #$80,bob_NewPri(a0)
+ move.b d0,bob_Priority(a0)
+ movem.l a1/a6,-(SP)
+ movea.l a0,a1 ; Bob
+ lea __MyExecBase(PC),a6
+ jsr meb_Remove(a6) ; entfernen
+ lea meb_BobList(a6),a0
+ jsr meb_Enqueue(a6) ; und wieder rein
+ movem.l (SP)+,a1/a6
+ bra.s TestNewPri ; ---> Loop
+.End:
+ clr.b NewPri
+
+DrawBobs: lea __MyExecBase(PC),a0
+ lea meb_BobList+lh_Tail(a0),a0 ; letztes Bob der Liste
+
+1$: movea.l bob_LastBob(a0),a0 ; Zeiger auf nächstes Bob
+ tst.l bob_LastBob(a0) ; kein Bob mehr ?
+ beq.s EndDrawBobList ; wenn ja ---> Ende
+ move.w bob_Flags(A0),d0
+ btst #BOBB_NOANIM,d0
+ bne.s 2$
+ bsr AnimateOneBob ; sonst Bob animieren
+2$: move.w bob_Flags(A0),d0
+ btst #BOBB_NOMOVE,d0
+ bne.s 3$
+ bsr MoveOneBob ; bewegen
+3$: bsr DrawOneBob ; und zeichnen
+ bra.s 1$ ; ---> Loop
+EndDrawBobList:
+ movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A1: BitMap, restauriert alle BobHintergründe
+
+RestoreBobList: movem.l a0/a5,-(SP)
+ lea _custom,a5
+ lea __MyExecBase(PC),a0
+ lea meb_BobList(a0),a0 ; erstes Bob in der Liste
+1$: movea.l bob_NextBob(a0),a0 ; Zeiger auf nächstes Bob
+ tst.l bob_NextBob(a0) ; kein Bob mehr ?
+ beq.s .End ; wenn ja ---> Ende
+ bsr.s RestoreOneBob ; sonst Hintergrund zeichnen
+ bra 1$ ; ---> Loop
+.End: movem.l (SP)+,a0/a5
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob, A5: custom
+
+RestoreOneBob: movem.l d0-d7/a0-a6,-(SP)
+
+ move.w bob_Flags(a0),d4
+ btst #BOBB_BACKCLEAR,d4 ; BOBF_BACKCLEAR ?
+ bne.s 5$ ; ja --->
+ btst #BOBB_NORESTORE,d4 ; BOBF_NORESTORE ?
+ bne 3$ ; ja ---> kein Hintergrund restoren
+5$:
+ btst #BOBB_NODOUBLE,d4 ; BOBF_NODOUBLE ?
+ beq.s 6$ ; nein --->
+
+ move.w bob_LastBltSize(a0),bob_LastLastBltSize(a0) ; nicht double-buffern
+ move.l bob_LastOffset(a0),bob_LastLastOffset(a0)
+ move.l bob_LastSaveBuffer(a0),bob_LastLastSaveBuffer(a0)
+
+6$: move.l bob_LastLastSaveBuffer(a0),a3 ; A3 : HintergrundBuffer
+ move.w bob_LastLastBltSize(a0),d0 ; D0 : BltSize
+ beq.s 2$
+ move.w d0,d1
+ and.w #%111111,d1 ; Breite des Blits in Words
+ add.w d1,d1 ; D1 : jetzt in Bytes
+ move.w bm_BytesPerRow(a1),d2 ; Breite des Bildes
+ sub.w d1,d2 ; D2 : BildBreite - BlitBreite = Modulo
+
+ moveq #0,d3
+ move.w d0,d3 ; BltSize
+ lsr.w #6,d3 ; Höhe des Blits
+ mulu d1,d3 ; D3 : PlaneLänge
+
+ move.b SaveMask,d7
+ moveq #0,d4
+ move.b bm_Depth(a1),d4 ; D4 : Anzahl Planes
+ subq #1,d4 ; für dbf
+
+ move.l bob_LastLastOffset(a0),d5 ; D5 : XY Offset
+ cmp.l #-1,d5
+ beq.s 2$ ; negativ? -> nicht restoren
+
+ lea bm_Planes(a1),a6 ; A6 : Zeiger auf Planes
+
+
+ SYSGET.l TripleScreen,d1
+ beq.s .Normal
+ move.l d1,a3
+ add.w #bm_Planes,a3
+
+ bsr TripleRestore
+ bra 2$
+
+
+.Normal: bsr RestoreItNormal
+
+2$: move.w bob_LastBltSize(a0),bob_LastLastBltSize(a0)
+ move.l bob_LastOffset(a0),bob_LastLastOffset(a0)
+ move.l bob_LastLastSaveBuffer(a0),d0
+ move.l bob_LastSaveBuffer(a0),bob_LastLastSaveBuffer(a0)
+ move.l d0,bob_LastSaveBuffer(a0)
+
+3$: movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+
+
+RestoreItNormal:
+ SYSCALL OwnBlitter
+1$: bsr WaitBlit
+ move.l a3,bltapt(a5) ; Source A
+ move.l (a6)+,d6 ; Ziel
+ ror.b d7
+ bcc.s .NextPlane
+
+ add.l d5,d6 ; + Offset
+ move.l d6,bltdpt(a5) ; Dest D
+ move.l #-1,bltafwm(a5) ; First+LastWordMask
+ moveq #0,d6
+ move.w d6,bltcon1(a5) ; BltCon1
+ move.w d6,bltamod(a5) ; QuellModulo
+ move.w #$09f0,bltcon0(a5) ; D = A
+
+ move.w bob_Flags(a0),d6
+ btst #BOBB_BACKCLEAR,d6 ; BOBF_BACKCLEAR ?
+ beq.s 4$ ; nein ->
+ move.w #$0100,bltcon0(a5) ; sonst Hintergrund nur löschen
+4$: move.w d2,bltdmod(a5) ; ZielModulo
+
+ move.w d0,bltsize(a5) ; Blit starten!
+ add.w d3,a3 ; PlaneLänge zum Source addieren
+.NextPlane: dbf d4,1$
+ SYSCALL DisownBlitter
+ rts
+
+
+
+
+TripleRestore:
+ SYSCALL OwnBlitter
+1$: bsr WaitBlit
+ move.l (A3)+,d6 ; Hintergrund
+ add.l d5,d6 ; + Offset =
+ move.l d6,bltapt(a5) ; Source A
+ move.l (a6)+,d6 ; Ziel
+ add.l d5,d6 ; + Offset
+ move.l d6,bltdpt(a5) ; Dest D
+ move.l #-1,bltafwm(a5) ; First+LastWordMask
+ moveq #0,d6
+ move.w d6,bltcon1(a5) ; BltCon1
+ move.w #$09f0,bltcon0(a5) ; D = A
+
+ move.w bob_Flags(a0),d7
+ btst #BOBB_BACKCLEAR,d7 ; BOBF_BACKCLEAR ?
+ beq.s 4$ ; nein ->
+ move.w #$0100,bltcon0(a5) ; sonst Hintergrund nur löschen
+4$: move.w d2,bltdmod(a5) ; ZielModulo
+ move.w d2,bltamod(A5)
+
+ move.w d0,bltsize(a5) ; Blit starten!
+ dbf d4,1$
+ SYSCALL DisownBlitter
+ rts
+
+
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob
+
+AnimateOneBob: bsr GetBobData
+ move.l bod_CollX0(a2),bob_CollX0(a0) ; X0.W und Y0.W
+ move.l bod_CollX1(a2),bob_CollX1(a0) ; X1.W und Y1.W
+
+ movea.l bob_AnimPrg(a0),a2 ; Animationsprogram
+ move.l a2,d0 ; vorhanden ?
+ beq .End ; nein ---> Exit
+ addq.b #1,bob_AnimSpeedCounter(a0) ; Zähler erhöhen
+ move.b bob_AnimSpeedCounter(a0),d0 ; Limit
+ cmp.b bob_AnimSpeed(a0),d0 ; erreicht ?
+ bne .End ; nein ---> exit
+
+; tst.b bob_TraceMode(A0)
+; beq.s .AnimRepeat
+
+; clr.b bob_AnimSpeedCounter(a0) ; Zähler löschen
+
+; tst.b bob_TraceLock(A0)
+; bne.s .End
+; st.b bob_TraceLock(A0)
+
+.AnimRepeat: clr.b bob_AnimSpeedCounter(a0) ; Zähler löschen
+ tst.w bob_AnimDelayCounter(a0)
+ beq.s 1$
+ subq.w #1,bob_AnimDelayCounter(a0)
+ bra .End
+
+1$: move.w bob_AnimTo(a0),d1
+ bmi.s 11$
+
+ move.w bob_Image(a0),d2
+ cmp.w d1,d2
+ beq.s 12$ ; ende ? -> nein
+
+ blt.s 13$
+
+
+ subq.w #1,bob_Image(a0)
+ bra.s .End
+
+
+13$: addq.w #1,bob_Image(a0)
+ bra.s .End
+
+
+12$: move.w #-1,bob_AnimTo(a0)
+
+
+11$: move.w bob_AnimOffset(a0),d1 ; Offset ins Prg
+ move.l bob_AnimPrg(a0),a2
+ move.w 0(a2,d1.w),d0 ; Kommando holen
+ bmi.s .AnimCommand ; wenn negativ -> Kommando
+ cmp.b #BOBSETWORD,d0
+ beq.s .AnimCommand
+ cmp.b #BOBSETLONG,d0
+ beq.s .AnimCommand
+
+
+ move.l bob_ConvertTab(a0),d4
+ beq.s 2$
+ move.l d4,a3
+ mulu bob_ConvertSize(a0),d0
+ add.w bob_ConvertOffset(a0),d0
+ move.w (a3,d0.w),d0
+
+
+2$: move.w d0,bob_Image(a0) ; sonst als BobNummer eintragen
+ addq.w #2,bob_AnimOffset(a0) ; Offset erhöhen
+ bra.s .End
+
+.AnimCommand:
+ or.w #$ff00,d0
+ lea BobolTab(PC),a3
+ adda.w 0(a3,d0.w),a3
+ lea bob_AnimForCounter(a0),a4
+ lea bob_AnimDelayCounter(a0),a6
+
+ jsr (a3) ; Ausführen MARSCH!
+
+ move.w d1,bob_AnimOffset(a0) ; Neuer 'PC'
+ tst.b d0 ; Weitermachen ?
+ beq .AnimRepeat ; ja ---> Loop
+.End: rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob
+
+MoveOneBob: move.l bob_MovePrg(a0),a2 ; MovePrg
+ move.l a2,d0 ; vorhanden ?
+ beq EndMoveOneBob ; nein ->
+
+ move.w bob_Flags(a0),d0
+ addq.b #1,bob_MoveSpeedCounter(a0) ; SpeedZähler erhöhen
+ move.b bob_MoveSpeedCounter(a0),d0 ; auslesen
+ cmp.b bob_MoveSpeed(a0),d0 ; Limit erreicht
+ bne EndMoveOneBob ; nein ->
+MoveRepeat: clr.b bob_MoveSpeedCounter(a0) ; Counter löschen
+ tst.w bob_MoveDelayCounter(a0)
+ beq.s 0$
+ subq.w #1,bob_MoveDelayCounter(a0)
+ bra EndMoveOneBob
+
+0$: move.w bob_MoveStep(a0),d2
+ bra.s 2$
+1$: tst.w bob_RelMoveCounter(a0)
+ beq.s NoRelMove
+
+ move.w bob_MoveOffset(a0),d1
+ movem.w 0(a2,d1.w),d0/d1 ; X/Y-Move-Deltas
+ move.w bob_Flags(a0),d3
+ btst #BOBB_FLIPXMOVE,d3 ; BOBF_FLIPXMOVE
+ beq.s 11$
+ neg.w d0
+11$: btst #BOBB_FLIPYMOVE,d3 ; BOBF_FLIPYMOVE
+ beq.s 22$
+ neg.w d1
+22$:
+ add.w d0,bob_X(a0)
+ add.w d1,bob_Y(a0)
+
+ addq.w #4,bob_MoveOffset(a0)
+ subq.w #4,bob_RelMoveCounter(a0)
+2$: dbf d2,1$
+ bra EndMoveOneBob
+
+
+NoRelMove: tst.w bob_MoveToSteps(A0)
+ beq.s .NoMoveToMoves
+
+ subq.w #1,bob_MoveToSteps(a0)
+ move.w bob_MoveToX(A0),d0
+ add.w bob_MoveToXStep(a0),d0
+ move.w d0,bob_MoveToX(a0)
+ asr.w #4,d0
+ move.w d0,bob_X(a0)
+
+ move.w bob_MoveToY(A0),d0
+ add.w bob_MoveToYStep(a0),d0
+ move.w d0,bob_MoveToY(a0)
+ asr.w #4,d0
+ move.w d0,bob_Y(a0)
+ bra EndMoveOneBob
+
+.NoMoveToMoves:
+ tst.w bob_MoveCounter(a0) ; neues Kommando holen
+ beq.s GetNewMoveCommand ; ja ->
+ subq.w #1,bob_MoveCounter(a0) ; KommandoZähler subtrahieren
+ move.w bob_MoveCommand(a0),d1 ; aktuelles Kommando holen
+ move.w bob_MoveStep(a0),d2 ; Geschwindigkeit
+ move.w bob_Flags(a0),d3
+ btst #BOBB_FLIPXMOVE,d3 ; BOBF_FLIPXMOVE
+ beq.s 5$
+ neg.w d2
+5$: btst #BOBB_FLIPYMOVE,d3 ; BOBF_FLIPYMOVE
+ beq.s 6$
+ neg.w d2
+6$:
+ btst #0,d1 ; BOBLEFT ?
+ beq.s 1$
+ sub.w d2,bob_X(a0)
+1$:
+ btst #1,d1 ; BOBRIGHT ?
+ beq.s 2$
+ add.w d2,bob_X(a0)
+2$:
+ btst #2,d1 ; BOBUP ?
+ beq.s 3$
+ sub.w d2,bob_Y(a0)
+3$:
+ btst #3,d1 ; BOBDOWN ?
+ beq.s 4$
+ add.w d2,bob_Y(a0)
+4$:
+ bra.s EndMoveOneBob
+
+GetNewMoveCommand:
+ move.w bob_MoveOffset(a0),d1
+ move.w 0(a2,d1.w),d0
+ bmi.s 1$
+ cmp.b #BOBSETWORD,d0
+ beq.s 1$
+ cmp.b #BOBSETLONG,d0
+ beq.s 1$
+
+ addq.w #4,bob_MoveOffset(a0)
+ move.w d0,bob_MoveCommand(a0) ; aktuelles Kommando setzen
+ move.w 2(a2,d1.w),bob_MoveCounter(a0) ; WiederholungsZähler setzen
+ bra MoveRepeat
+
+1$:
+ or.w #$ff00,d0
+ lea BobolTab(PC),a3
+ adda.w 0(a3,d0.w),a3
+ lea bob_MoveForCounter(a0),a4
+ lea bob_MoveDelayCounter(a0),a6
+
+ jsr (a3) ; Bobol-Kommando aufrufen
+
+ move.w d1,bob_MoveOffset(a0)
+ tst.w d0
+ beq MoveRepeat
+EndMoveOneBob:
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** D0: X, D1: Y -> D0: Bob das hier liegt oder 0
+
+TestPoint: movem.l d1-d7/a0-a6,-(SP)
+ lea __MyExecBase(PC),a0
+ lea meb_BobList(a0),a0 ; erstes Bob in der Liste
+ moveq #0,d7
+1$: move.l bob_NextBob(a0),a0 ; Zeiger auf nächstes Bob
+ tst.l bob_NextBob(a0) ; kein Bob mehr ?
+ beq.s EndTestPoint ; wenn ja -> Ende
+ move.w bob_Flags(a0),d6
+ tst.b bob_RemFlag(a0)
+ bne.s 1$
+
+ btst #BOBB_NOCOLLISION,d6 ; BOBF_NOCOLLISION ?
+ bne.s 1$ ; nein ->
+
+ bsr.s TestOneBobPoint ; sonst Bob testen
+ beq.s 1$ ; Loop ->
+EndTestPoint:
+ move.l d7,d0
+ movem.l (SP)+,d1-d7/a0-a6
+ rts
+
+TestOneBobPoint:
+ movem.l d0-d6/a0-a6,-(SP)
+ moveq.l #0,d7
+ bsr.s GetBobData
+
+ move.w bob_AbsX(a0),d2
+ move.w d2,d3
+ add.w bod_CollX0(a2),d2
+ add.w bod_CollX1(a2),d3
+ cmp.w d0,d2 ; ist Test X kleiner Bob X1 ?
+ bgt.s 9$ ; nein -> Ende
+ cmp.w d0,d3 ; ist Test X grösser Bob X2 ?
+ blt.s 9$ ; nein -> Ende
+
+78$: move.w bob_AbsY(a0),d2
+ move.w d2,d3
+ add.w bod_CollY0(a2),d2
+ add.w bod_CollY1(a2),d3
+ cmp.w d1,d2 ; ist Test Y kleines Bob Y1 ?
+ bgt.s 9$ ; Nein -> Ende
+ cmp.w d1,d3 ; ist Test Y grösser Bob Y2
+ blt.s 9$ ; nein -> Ende
+ move.l a0,d7
+9$:
+ movem.l (SP)+,d0-d6/a0-a6
+ tst.l d7
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob -> A2: BobData
+
+GetBobData: movem.l d0/d1/a1,-(SP)
+ move.w bob_Image(a0),d0
+ lsl.w #2,d0
+ lea bob_AnimPtrs(a0),a2
+ movea.l 0(a2,d0.w),a2
+ move.l bod_X0(a2),bob_X0(a0) ; X0.W und Y0.W
+ movea.l bob_OrgTab(a0),a1
+ move.l a1,d1 ; Keine OrgTab --->
+ beq.s 1$
+ move.l 0(a1,d0.w),bob_X0(a0) ; X0.W und Y0.W
+1$:
+ movem.l (SP)+,d0/d1/a1
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob -> bob_AbsX & bob_AbsY berechnen aus ParentBobs
+
+GetAbsKoords: movem.l d2/a1-a2,-(SP)
+ movem.w bob_X(a0),d0/d1 ; X und Y holen
+ movea.l a0,a1 ; a1=Bob
+
+.NextParentBob: move.l bob_ParentBob(a1),d2 ; Existiert ein ParentBob ?
+ beq.s 1$ ; nein ---> Fertig
+ movea.l d2,a1 ; a2=ParentBob
+ add.w bob_X(a1),d0 ; add XPos
+ add.w bob_Y(a1),d1 ; add YPos
+ bra.s .NextParentBob ; ---> Loop
+1$:
+ movem.w d0/d1,bob_AbsX(a0) ; AbsX und AbsY
+ movem.l (SP)+,d2/a1-a2
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob, Hintergrund retten und Bob in die BitMap zeichnen
+
+DrawOneBob: movem.l d0-d7/a0-a6,-(SP)
+
+ SYSCALL OwnBlitter
+
+ lea -sf_SIZEOF(SP),SP ; StackFrame erstellen
+ lea _custom,a5
+
+ clr.w sf_LastMask(SP)
+ bsr GetAbsKoords ; Koordinaten umrechnen
+ bsr GetBobData ; BobDaten ins A2 holen
+
+ move.w bob_Flags(a0),d7
+
+ move.l bob_Handler(a0),d0
+ beq.s .NoHandler
+ movea.l d0,a3
+ move.l bob_HandlerD0(a0),d0
+ movem.l d0-d7/a0-a6,-(SP)
+ jsr (a3) ; Handler aufrufen
+ movem.l (SP)+,d0-d7/a0-a6
+.NoHandler:
+ move.w bob_Flags(a0),d7
+
+
+ tst.b bob_RemFlag(a0) ; muss Bob entfernt werden
+ beq.s 5$ ; nein ->
+ addq.b #1,bob_RemFlag(a0) ; Zähler addieren
+5$: btst #BOBB_SPECIALDRAW,d7 ; BOBF_SPECIALDRAW ?
+ beq.s 1$ ; nein --->
+ bsr TestBobOverlay ; liegt ein Bob hinter akt Bob ?
+ or.w #BOBF_HIDDEN,bob_Flags(a0)
+ tst.l d7
+ beq EndDrawOneBob ; nein -> akt Bob nicht zeichnen
+1$:
+ and.w #~BOBF_HIDDEN,bob_Flags(a0)
+ move.w bob_Flags(a0),d7
+ btst #BOBB_NEWIMAGE,d7
+ beq.s 0$
+ move.w bob_LastLastImage(a0),d7
+ cmp.w bob_Image(a0),d7
+ beq EndDrawOneBob
+ move.w bob_LastImage(a0),bob_LastLastImage(a0)
+ move.w bob_Image(a0),bob_LastImage(a0)
+0$:
+ movem.w bob_AbsX(a0),d0/d1 ; AbsX und AbsY holen
+ add.w GlobalX,d0
+
+ sub.w bob_X0(a0),d0 ; X -= Nullpunkt
+ sub.w bob_Y0(a0),d1 ; Y -= Nullpunkt
+
+ movem.w d0/d1,sf_TempX(SP) ; TempX & TempY
+
+ move.w d0,d4 ; XPos nach D4 für Feinbest.
+ ror.w #4,d4 ; in Bits 12-15 schieben
+ andi.w #$f000,d4 ; D4 : Shift-Value
+ asr.w #4,d0 ; XPos / 8 -> Bytes
+ add.w d0,d0 ; Nur gerade Adressen
+ ext.l d0
+
+ muls.w bm_BytesPerRow(a1),d1 ; aus YPos wird Y-Offset
+ add.l d0,d1 ; Plus XPos = Dest.-Offset
+
+ move.w bod_WordSize(a2),d3 ; Bob-Breite+1 in Words
+ move.w bod_Height(a2),d2 ; Bob-Höhe in Lines
+ lsl.w #6,d2 ; Höhe nach Bits 15-6
+ or.w d3,d2 ; D2 : BltSize
+
+ move.w d2,sf_Temp1(SP)
+ move.w d3,sf_Temp2(SP)
+
+ clr.w sf_BobOffset(SP)
+ clr.w sf_BobModulo(SP)
+ move.w #-1,sf_FirstMask(SP)
+
+ move.w bob_ClipFlags(a0),d7
+ btst #CLIPB_DOWN,d7
+ beq.s 11$
+
+ move.w sf_TempY(SP),d6
+ move.w bob_ClipY2(a0),d3 ; untere Grenze
+ btst #CLIPB_GLOBAL,d7
+ beq.s 55$
+ add.w GlobalYClip(PC),d3
+55$:
+ lsr.w #6,d2 ; Höhe des Bobs
+ add.w d2,d6 ; untere Grenze des Bobs
+ sub.w d3,d6 ; BobUnten - UnterGrenze
+ bmi.s 11$ ; wenn minus -> nicht clippen
+ clr.w sf_Temp1(SP)
+ move.w bod_Height(a2),d2
+ sub.w d6,d2
+ beq.s 11$
+ bmi.s 11$
+ lsl.w #6,d2
+ move.w bod_WordSize(a2),d3
+ or.w d3,d2
+ move.w d2,sf_Temp1(SP)
+11$:
+ btst #CLIPB_UP,d7
+ beq.s 2$
+
+ move.w sf_Temp1(SP),d2 ; BltSize
+ beq.s 2$ ; wenn NULL ->
+ move.w sf_TempY(SP),d6 ; Bob Y
+ move.w bob_ClipY(a0),d3 ; Obere ClipGrenze
+ btst #CLIPB_GLOBAL,d7
+ beq.s 66$
+ add.w GlobalYClip(PC),d3
+66$:
+ sub.w d6,d3 ; um wieviel muss geklipt werden
+ bmi.s 2$ ; um nichts ->
+ clr.w sf_Temp1(SP) ; altes bltsize loeschen
+ move.w d2,d6
+ lsr.w #6,d6 ; D6 : alte Hoehe
+ sub.w d3,d6 ; Anzahl Linien die nicht gezeichnet werden
+ bmi.s 2$
+ beq.s 2$
+ lsl.w #6,d6
+ move.w bod_WordSize(a2),d2
+ or.w d6,d2 ; D2 : neues BltSize
+ move.w d2,sf_Temp1(SP)
+ move.w d3,d5 ; ClipLinien
+ muls.w bm_BytesPerRow(a1),d5 ; * Breite
+ add.l d5,d1 ; D1 : neuer ZielOffset
+
+ move.w bod_WordSize(a2),d5
+ subq.w #1,d5
+ add.w d5,d5 ; D5 : breite des Bobs in Bytes
+ mulu d3,d5
+ add.w d5,sf_BobOffset(SP)
+2$:
+ btst #CLIPB_LEFT,d7
+ beq.s 3$
+
+ move.w sf_Temp1(SP),d2 ; D2 : BltSize
+ beq.s 3$
+
+ move.w sf_TempX(SP),d5
+ asr.w #3,d5
+ and.w #~1,d5 ; D5 : X Position in geraden bytes
+
+ move.w bob_ClipX(a0),d6
+ btst #CLIPB_GLOBAL,d7
+ beq.s 33$
+ add.w GlobalXClip(PC),d6
+33$:
+ asr.w #3,d6
+ and.w #~1,d6 ; D6 : ClipX Position in geraden bytes
+
+ sub.w d5,d6 ; D6 : Anzahl der zu clipenden Bytes
+ bmi.s 3$ ; wenn kein ->
+ clr.w sf_Temp1(SP) ; altes BltSize loeschen
+
+ move.w d2,d3
+ and.w #%111111,d3
+ add.w d3,d3 ; D3 : Breite des Blits in Bytes
+ sub.w d6,d3 ; Breite - ClipSize
+ ble.s 3$ ; bob ganz weg
+
+ ext.l d6
+ add.w d6,sf_BobModulo(SP)
+ add.l d6,d1
+ add.w d6,sf_BobOffset(SP)
+
+ lsr.w #1,d3
+ move.w d3,sf_Temp2(SP)
+
+ and.w #~%111111,d2
+ or.w d3,d2
+ move.w d2,sf_Temp1(SP)
+
+ move.w sf_TempX(SP),d3
+ and.w #$f,d3
+ eor.w #$f,d3
+ add.w d3,d3
+ lea ClipMasks(PC),a3
+ move.w 0(a3,d3.w),sf_FirstMask(SP)
+
+
+3$: btst #CLIPB_RIGHT,d7
+ beq 4$
+
+ move.w bob_ClipX2(a0),d5
+ btst #CLIPB_GLOBAL,d7
+ beq.s 44$
+ add.w GlobalXClip(PC),d5
+44$:
+ asr.w #3,d5
+ and.w #~1,d5 ; D5 : ClipX2 in bytes
+
+ move.w sf_TempX(SP),d6
+ and.w #~15,d6
+
+ move.w bod_Width(a2),d0
+ add.w #15,d0
+ and.w #~15,d0
+ add.w d0,d6
+
+ asr.w #3,d6 ; D6 : BobX2 in Bytes
+
+ sub.w d5,d6 ; D6 : Anzahl zu clippende Bytes
+ bmi.s 4$
+
+ move.w sf_Temp1(SP),d2 ; D2 : letztes BltSize
+ clr.w sf_Temp1(SP)
+ move.w d2,d3
+ and.w #%111111,d3
+ add.w d3,d3
+ sub.w d6,d3
+ ble.s 4$
+
+
+ lsr.w #1,d3 ; D3 : zu clippende Words
+ move.w d3,sf_Temp2(SP) ; retten
+ and.w #~%111111,d2 ; D2 : BltSize-Höhe
+ or.w d3,d2 ; D2 : neues BltSize
+ move.w d2,sf_Temp1(SP) ; retten
+ add.w sf_BobModulo(SP),d6
+ addq.w #2,d6
+ move.w d6,sf_BobModulo(SP)
+ subq.w #1,d3
+ move.w d3,sf_Temp2(SP)
+
+ move.w d2,d6
+ and.w #%111111,d6
+ subq.w #1,d6
+ bne.s 100$
+101$: clr.w d2
+ bra.s 102$
+100$: bmi 101$
+
+ and.w #~%111111,d2
+ or.w d6,d2
+
+102$: move.w d2,sf_Temp1(SP)
+
+
+ move.w sf_TempX(SP),d3
+ and.w #$f,d3
+ eor.w #$f,d3
+ add.w d3,d3
+ lea ClipMasks(PC),a3
+ move.w 0(a3,d3.w),d3
+ not.w d3
+ move.w d3,sf_LastMask(SP)
+
+
+4$: movem.w sf_Temp1(SP),d2/d3 ; Temp1 und Temp2
+
+ move.w d2,bob_LastBltSize(a0) ; BltSize für Restore retten
+ move.l d1,bob_LastOffset(a0) ; ZielOffset für Restore retten
+
+
+ move.w bm_BytesPerRow(a1),d0 ; Bildbreite in Bytes, even!
+ add.w d3,d3 ; Bob-Breite+1 (Bytes, even)
+ sub.w d3,d0 ; Bildbreite - Bobbreite = Modulo
+
+
+
+
+DrawIt: move.w bob_Flags(a0),d7
+ btst #BOBB_NORESTORE,d7 ; BOBF_NORESTORE ?
+ bne.s 9$ ; wenn ja -> kein Hintergrund speichern
+
+ SYSTST.l TripleScreen ; Wenn TrippleScreen gestetzt
+ bne.s 9$ ; kein Hintergrund rettten
+
+
+ ******* Jetzt Hintergrund retten ******
+
+ tst.w d2 ; BltSize = NULL ?
+ beq.s 11$ ; wenn ja -> nichts retten
+
+ move.b SaveMask,d3
+ moveq #0,d5
+ move.b bm_Depth(a1),d5 ; Anzahl Planes
+ subq #1,d5 ; für dbf
+ move.l bob_LastSaveBuffer(a0),a3 ; SaveBuffer
+
+ bsr WaitBlit
+ move.l a3,bltdpt(a5) ; Ziel setzen
+ lea bm_Planes(a1),a3
+
+0$: move.l (a3)+,a6 ; Zeiger auf BildBitMaps
+ ror.b d3
+ bcc.s .NextPlane
+ add.l d1,a6 ; + Offset
+ move.l a6,bltapt(a5) ; Quelle A setzen
+ clr.w bltcon1(a5) ; BltCon1
+ move.w #$09f0,bltcon0(a5) ; BltCon0 D = A
+ move.l #-1,bltafwm(a5) ; First+LastWordMask
+ move.w d0,bltamod(a5) ; Modulo A
+ clr.w bltdmod(a5) ; Modulo D
+ move.w d2,bltsize(a5) ; Blit starten
+ bsr WaitBlit ; auf Blitter warten
+.NextPlane: dbf d5,0$ ; nächste Plane
+
+
+9$:
+ bsr WaitBlit ; Jetzt Bob ins Bild zeichnen
+
+11$: tst.b bob_RemFlag(a0)
+ bne EndDrawOneBob
+
+ btst #BOBB_NODRAW,d7 ; BOBF_NODRAW ?
+ bne EndDrawOneBob ; ja ->
+
+
+
+ tst.w d2
+ beq EndDrawOneBob
+ move.w bob_Flags(a0),d7
+
+ move.w d0,bltcmod(a5) ; Source C (=Bild) Modulo
+ move.w d0,bltdmod(a5) ; Destination Modulo
+ move.w sf_BobModulo(SP),d0
+ subq.w #2,d0
+ move.w d0,bltamod(a5) ; Masken-Modulo := -2
+ move.w d0,bltbmod(a5) ; Bob-Data-Modulo := -2
+ move.w sf_FirstMask(SP),bltafwm(a5)
+ move.w sf_LastMask(SP),bltalwm(a5)
+
+ moveq #0,d5
+ moveq #0,d6
+ move.b bod_PlanePick(a2),d5 ; D5 : PlanePick
+ move.b bod_PlaneOnOff(a2),d6 ; D6 : PlaneOnOff
+
+ tst.b bob_FlashTime(a0)
+ beq.s .NoFlash
+ subq.b #1,bob_FlashTime(a0)
+ moveq.l #0,d5
+ move.b bob_FlashColor(a0),d6
+.NoFlash:
+
+
+ move.w bod_PlaneSize(a2),d0 ; D0 : Bob-PlaneSize
+ lea bod_Images(a2),a0 ; A0 : Maske
+ lea 0(a0,d0.w),a6 ; A6 : 1. Bob-Plane
+ move.w d0,sf_Temp1(SP)
+ add.w sf_BobOffset(SP),a6
+ add.w sf_BobOffset(SP),a0
+ lea bm_Planes(a1),a2 ; A2 : Dest. Planes-Base
+
+ *** Vorhandene Bob-Planes ins Bild hineinkopieren
+
+ move.w d4,bltcon1(a5) ; Source B Shift value
+
+
+ moveq #0,d0 ; Plane-Counter
+1$: movea.l (a2)+,a3 ; nächste Destination-Plane
+ adda.l d1,a3 ; += Bob-Position
+ move.w d4,d3 ; Shift-value für bltcon0
+ btst d0,d5 ; Gibt's Daten für diese Plane?
+ bne.s 3$ ; ja --->
+ btst d0,d6 ; Plane setzen oder löschen?
+ bne.s 2$ ; setzen ---> _
+ ori.w #$b0a,d3 ; Minterm: D := AC
+ bra.s 4$ ; --->
+2$: ori.w #$bfa,d3 ; Minterm: D := A+C
+ bra.s 4$ ; --->
+3$: ori.w #$fca,d3 ; Minterm: cookie-cut
+4$: bsr.s WaitBlit
+ move.l a6,bltbpt(a5) ; Source B: Bob-Planes
+ btst #4,d7 ; BOBF_NOCUT in bob_Flags ?
+ beq.s 6$
+ move.w #-1,bltadat(a5) ; Maske setzen
+ and.w #~$800,d3 ; Source A auschalten
+6$:
+ move.l a0,bltapt(a5) ; Blitter Source A : Maske
+ move.l a3,bltcpt(a5) ; = Source C (Hintergrund)
+ move.l a3,bltdpt(a5) ; = Destination
+ move.w d3,bltcon0(a5)
+ move.w d2,bltsize(a5) ; Blit starten !!!
+
+ btst d0,d5
+ beq.s 7$
+ adda.w sf_Temp1(SP),a6
+7$: addq.w #1,d0
+ cmp.b bm_Depth(a1),d0
+ blt 1$
+
+EndDrawOneBob: lea sf_SIZEOF(SP),SP ; StackFrame aufräumen
+
+ SYSCALL DisownBlitter
+
+ movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A5: custom
+
+WaitBlit: btst #6,dmaconr(a5)
+1$: btst #6,dmaconr(a5)
+ bne.s 1$
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** void
+
+HandleCollision:
+ movem.l d0-d7/a0-a6,-(SP)
+ lea meb_BobList(a6),a0
+.MainBobLoop: move.l bob_NextBob(a0),a0
+ tst.l bob_NextBob(a0) ; A0=Kollision
+ beq.s .EndMainLoop ; auslösendes Bob
+
+ bsr GetAbsKoords
+ bsr.s CollOneBob
+ bra.s .MainBobLoop
+
+.EndMainLoop: movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** A0: Bob
+
+CollOneBob: movem.l d0-d7/a0-a6,-(SP)
+ move.w bob_HitMask(a0),d0 ; Bob löst keine
+ beq.s .EndMainLoop ; Kollision aus
+
+ movem.w bob_CollX0(a0),d0-d3 ; Koordinaten
+ add.w bob_AbsX(a0),d0
+ add.w bob_AbsY(a0),d1
+ add.w bob_AbsX(a0),d2
+ add.w bob_AbsY(a0),d3 ; SourceBob
+
+ lea __MyExecBase(PC),a1
+ lea meb_BobList(a1),a1
+
+.BobLoop: move.l bob_NextBob(a1),a1
+ tst.l bob_NextBob(a1) ; A1=Kollision
+ beq.s .EndMainLoop ; einfangendes Bob
+
+ cmp.l a0,a1 ; Keine Kollision
+ beq.s .BobLoop ; mit sich selber
+
+ move.w bob_HitMask(a0),d4 ; HitMask
+ move.w bob_MeMask(a1),d5 ; MeMask
+ and.w d4,d5 ; nicht über-
+ beq.s .BobLoop ; einstimmend -->
+
+ movem.w bob_CollX0(a1),d4-d7
+ add.w bob_AbsX(a1),d4
+ add.w bob_AbsY(a1),d5
+ add.w bob_AbsX(a1),d6 ; Koordinaten
+ add.w bob_AbsY(a1),d7 ; ZielBob
+
+ cmp.w d2,d4
+ bgt.s .BobLoop
+ cmp.w d0,d6
+ blt.s .BobLoop
+ cmp.w d3,d5
+ bgt.s .BobLoop
+ cmp.w d1,d7
+ blt.s .BobLoop
+
+.Coll: move.l bob_CollHandler(a1),d4 ; KollisionsHandler
+ beq.s .BobLoop ; nicht vorhanden -->
+
+ movem.l d0-d7/a0-a6,-(SP) ; Zur Sicherheit
+ move.l d4,a2
+ jsr (a2) ; Handler Starten
+ movem.l (SP)+,d0-d7/a0-a6 ; Zur Sicherheit
+ bra.s .BobLoop
+
+.EndMainLoop: movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+;-----------------------------------------------------------------------
+
+ *** Kollisionstest ohne CollisionRectangle
+
+TestBobOverlay: movem.l d0-d6/a0-a2,-(SP)
+
+ bsr GetBobData
+ movem.w bob_AbsX(a0),d0/d1 ; AbsX und AbsY
+ sub.w bob_X0(a0),d0
+ sub.w bob_Y0(a0),d1
+ move.w d0,d2
+ move.w d1,d3
+ add.w bod_Width(a2),d2
+ add.w bod_Height(a2),d3
+
+ lea __MyExecBase(PC),a1
+ lea meb_BobList(a1),a1
+
+.BobLoop: move.l bob_NextBob(a1),a1
+ tst.l bob_NextBob(a1) ; A1=Kollision
+ beq.s .EndMainLoop ; einfangendes Bob
+
+ cmp.l a0,a1 ; Keine Kollision
+ beq.s .BobLoop ; mit sich selber
+
+ move.l a0,-(SP)
+ move.l a1,a0
+ bsr GetBobData
+ movem.w bob_AbsX(a0),d4/d5 ; AbsX und AbsY
+ sub.w bob_X0(a0),d4
+ sub.w bob_Y0(a0),d5
+ move.w d4,d6
+ move.w d5,d7
+ add.w bod_Width(a2),d6
+ add.w bod_Height(a2),d7
+ move.l (SP)+,a0
+
+ cmp.w d2,d4
+ bhi.s .BobLoop
+ cmp.w d0,d6
+ blt.s .BobLoop
+ cmp.w d3,d5
+ bhi.s .BobLoop
+ cmp.w d1,d7
+ blt.s .BobLoop
+
+ move.l a1,d7
+ bra.s .End
+
+.EndMainLoop: moveq #0,d7
+.End:
+ movem.l (SP)+,d0-d6/a0-a2
+ rts
+
+
+
+
+******************************************************************************
+
+AskJoy: ; 1=down transform
+ ; 2=right joycode
+ ; 4=up into
+ ; 8=left c-64 joycode
+ ; 128=Fire (1 aktiv)
+
+
+ movem.l d1,-(SP)
+
+ move.w joy1dat(a5),d0
+
+ move.w d0,d1
+ and.w #$101,d1 ;seperate bits
+ and.w #$202,d0
+
+ lsr.w #1,d0 ;shift one group
+ eor.w d0,d1 ;eor
+ lsl.w #1,d0 ;shift back
+
+ or.w d1,d0 ;or together
+
+ move.w d0,d1
+ lsr.w #6,d1 ;crunch bits
+ and.w #$ff,d0
+ or.w d1,d0
+
+ move.b $bfe001,d1 ;get both firebuttons
+ not.w d1
+
+ and.w #$80,d1 ;isolate fire
+ or.w d1,d0 ;Joy-Code finished
+ movem.l (SP)+,d1
+ rts
+
+
+******************************************************************************
+
+;-----------------------------------------------------------------------
+; BOBOL-KOMMANDOS, Offset D1 wird upgedatet
+;-----------------------------------------------------------------------
+
+
+SetWordFunc: moveq.l #0,d0
+ move.b 0(a2,d1.w),d0 ; Offset in BobStrukt
+ move.w 2(A2,d1.w),d2 ; zu setzender Wert
+ move.w d2,0(a0,d0.w) ; in BobStrukt eintragen
+ moveq.l #0,d0
+ addq.l #4,d1
+ rts
+
+
+SetLongFunc: moveq.l #0,d0
+ move.b 0(a2,d1.w),d0 ; Offset in BobStrukt
+ move.l 2(A2,d1.w),d2 ; zu setzender Wert
+ move.l d2,0(a0,d0.w) ; in BobStrukt eintragen
+ moveq.l #0,d0
+ addq.l #6,d1
+ rts
+
+
+
+
+LoopFunc: moveq #0,d1 ; 'PC' zurücksetzen
+ bra.s ReturnNull
+
+RemoveFunc: bsr RemBob
+EndeFunc: st.b d0 ; Nicht weitermachen
+ rts
+
+
+SignalFunc: move.w 2(a2,d1.w),d2 ; zu setzende Signals holen
+ move.l a6,-(SP)
+ lea __MyExecBase(PC),a6
+ or.w d2,meb_SignalSet(a6) ; und setzen
+ movea.l (SP)+,a6
+ addq.w #4,d1 ; Offset erhöhen
+ bra.s ReturnNull
+
+WaitFunc: move.w 2(a2,d1.w),d2 ; WaitMaske holen
+ move.l a6,-(SP)
+ lea __MyExecBase(PC),a6
+ move.w meb_SignalSet(a6),d3 ; getzte Signals holen
+ and.w d2,d3 ; ist ein Signal gesetzt ?
+ beq.s 1$ ; nein --->
+ not.w d2
+ and.w d2,meb_SignalSet(a6) ; Signals löschen
+ movea.l (SP)+,a6
+ addq.w #4,d1 ; Offset erhöhen
+ bra.s ReturnNull
+1$: movea.l (SP)+,a6
+ st.b d0 ; Nicht weitermachen
+ rts
+
+
+SetPriFunc: move.w 2(a2,d1.w),d2 ; neue Priorität holen
+ move.b d2,bob_NewPri(a0) ; und setzen
+ addq.w #4,d1 ; Offset erhöhen
+ st.b NewPri
+ bra.s ReturnNull
+
+CpuJumpFunc: move.l 2(a2,d1.w),a3 ; SprungAdresse
+ move.l 6(a2,d1.w),d0 ; Parameter ins D0
+ movem.l d0-d7/a0-a6,-(SP)
+ move.w bob_Flags(A0),d1
+ lea __MyExecBase(PC),a6 ; Für User
+ jsr (a3) ; Routine anspringen
+ movem.l (SP)+,d0-d7/a0-a6
+ add.w #10,d1 ; nächstes Kommando
+ReturnNull: moveq #0,d0
+ rts
+
+UntilFunc: move.w 2(a2,d1.w),d2 ; Signals die abgfragt werden sollen
+ move.w 4(a2,d1.w),d4 ; Offset
+ move.l a6,-(SP)
+ lea __MyExecBase(PC),a6
+ move.w meb_SignalSet(a6),d3 ; gesetzte Signals
+ and.w d2,d3
+ bne.s 1$ ; Signal gesetzt -> Loop beenden
+ sub.w d4,d1 ; SchleifenAnfang PC setzen
+ not.w d2
+ and.w d2,meb_SignalSet(a6) ; Signal löschen
+ bra.s 2$
+1$: addq.w #6,d1 ; Signal gesetzt
+2$: movea.l (SP)+,a6
+ bra.s ReturnNull
+
+WhileFunc: move.w 2(a2,d1.w),d2 ; Signal
+ move.w 4(a2,d1.w),d4 ; Offset
+ SYSGET.W SignalSet,d3 ; gesetzte
+ and.w d2,d3
+ beq.s 1$ ; Signal nicht gesetzt -> Loop beenden
+ sub.w d4,d1 ; SchleifenAnfang PC setzen
+ bra.s 2$
+1$: addq.w #6,d1 ; Signal gesetzt
+2$: bra.s ReturnNull
+
+PokeBFunc: move.l 2(a2,d1.w),a3 ; Adresse
+ move.w 6(a2,d1.w),d2 ; Wert
+ move.b d2,(a3)
+ addq.w #8,d1
+ bra.s ReturnNull
+
+PokeWFunc: move.l 2(a2,d1.w),a3
+ move.w 6(a2,d1.w),d2
+ move.w d2,(a3)
+ addq.w #8,d1
+ bra.s ReturnNull
+
+PokeLFunc: move.l 2(a2,d1.w),a3
+ move.l 6(a2,d1.w),d2
+ move.l d2,(a3)
+ add.w #10,d1 ; nächstes Kommando
+ bra.s ReturnNull
+
+SetClipFunc: move.w 2(a2,d1.w),bob_ClipX(a0)
+ move.w 4(a2,d1.w),bob_ClipY(a0)
+ move.w 6(a2,d1.w),bob_ClipX2(a0)
+ move.w 8(a2,d1.w),bob_ClipY2(a0)
+ move.w 10(a2,d1.w),bob_ClipFlags(a0)
+ add.w #12,d1 ; nächstes Kommando
+ bra.s ReturnNull1
+
+RelMoveFunc: move.w 2(a2,d1.w),d2
+ move.w d2,bob_RelMoveCounter(a0)
+ addq.w #4,d1
+ bra.s ReturnNull1
+
+SetAnimFunc: move.l a1,-(SP)
+ move.l 2(a2,d1.w),a1
+ moveq #0,d0
+ move.b bob_AnimSpeed(a0),d0
+ bsr SetAnimPrg
+ move.l (SP)+,a1
+ addq.w #6,d1
+ bra.s ReturnNull1
+
+SetMoveFunc: movem.l d1/a1,-(SP)
+ move.l 2(a2,d1.w),a1
+ moveq #0,d0
+ move.b bob_MoveSpeed(a0),d0
+ moveq #0,d1
+ move.w bob_MoveStep(a0),d1
+ bsr SetMovePrg
+ movem.l (SP)+,d1/a1
+ addq.w #6,d1
+ bra.s ReturnNull1
+
+
+SetDataFunc: move.l 2(a2,d1.w),bob_BobData(a0)
+ addq.w #6,d1
+ReturnNull1: moveq #0,d0
+ rts
+
+SetMoveSpeedFunc:
+ move.w 2(a2,d1.w),d0
+ move.b d0,bob_MoveSpeed(a0)
+ clr.b bob_MoveSpeedCounter(a0)
+ addq.w #4,d1
+ bra.s ReturnNull1
+
+SetAnimSpeedFunc:
+ move.w 2(a2,d1.w),d0
+ move.b d0,bob_AnimSpeed(a0)
+ clr.b bob_AnimSpeedCounter(a0)
+ addq.w #4,d1
+ bra.s ReturnNull1
+
+SetIdFunc: move.w 2(a2,d1.w),d0
+ move.b d0,bob_Id(a0)
+ addq.w #4,d1
+ bra.s ReturnNull1
+
+
+ForFunc: move.w 2(a2,d1.w),(a4) ; Zähler setzen
+ addq.w #4,d1
+ bra.s ReturnNull1
+
+NextFunc: moveq #0,d0
+ move.w 2(a2,d1.w),d2
+ cmp.w #FOREVERMAGIC,(A4)
+ beq.s 1$
+ subq.w #1,(a4) ; Zähler erniedrigen
+ bne.s 1$
+ addq #4,d1
+ rts
+1$: sub.w d2,d1
+ rts
+
+
+LSignalFunc: move.w 2(a2,d1.w),d2 ; zu setzende Signals holen
+ or.w d2,bob_LSignalSet(a0) ; und setzen
+ addq.w #4,d1 ; Offset erhöhen
+ bra.s ReturnNull1
+
+LWaitFunc: move.w 2(a2,d1.w),d2 ; WaitMaske holen
+ move.w bob_LSignalSet(a0),d3 ; getzte Signals holen
+ and.w d2,d3 ; ist ein Signal gesetzt ?
+ beq.s 1$ ; nein ->
+ not.w d2
+ and.w d2,bob_LSignalSet(a0) ; Signals löschen
+ addq.w #4,d1 ; Offset erhöhen
+ moveq #0,d0
+ rts
+1$: st.b d0
+ rts
+
+
+DelayFunc: move.w 2(A2,d1.w),(a6) ; DelayZeit eintragen
+ addq.w #4,d1
+ bra ReturnNull2
+
+RndDelayFunc: bsr.s GetLimitRandom
+ move.w d0,(A6)
+ addq.w #6,d1
+ bra ReturnNull2
+
+RndAnimFunc: bsr.s GetLimitRandom
+ move.w d0,bob_Image(a0)
+ addq.w #6,d1
+ st.b d0
+ rts
+
+GetLimitRandom: move.w 4(A2,d1.w),d0 ; oberes Limit
+ sub.w 2(a2,d1.w),d0 ; - unteres Limit
+ ext.l d0
+ SYSCALL Random
+ add.w 2(a2,d1.w),d0 ; + unteres Limit
+ rts
+
+AddBobFunc: move.l a1,-(SP)
+ move.w bob_Flags(A0),d0
+ btst #BOBB_ONLYANIM,d0
+ bne.s 1$
+ move.l 2(a2,d1.w),a1
+ bsr AddBob
+1$: addq.w #6,d1
+ moveq.l #0,d0
+ move.l (SP)+,a1
+ rts
+
+AddRelBobFunc: move.l a1,-(SP)
+ move.l 2(a2,d1.w),a1 ; Bob
+ bsr AddBob ; adden
+ move.l d0,a1 ; NewBob
+
+ move.w bob_X(A0),d0 ; BobX
+ add.w 6(A2,d1.w),d0 ; X-Versatz
+ add.w d0,bob_X(A1)
+ move.w bob_Y(A0),d0 ; BobY
+ add.w 8(A2,d1.w),d0 ; Y-Versatz
+ add.w d0,bob_Y(A1) ; relativ zu Bob
+
+ add.w #10,d1
+ moveq.l #0,d0
+ move.l (SP)+,a1
+ rts
+
+
+ReturnNull2: moveq #0,d0
+ rts
+
+
+MoveToFunc: movem.l d0-d7,-(SP)
+ move.l d1,d7 ; D7 : PrgOffset
+ moveq.l #0,d0
+ moveq.l #0,d1
+ moveq.l #0,d2
+ moveq.l #0,d3
+ movem.w bob_X(a0),d0/d1 ; X & Y
+ movem.w 2(a2,d7.w),d2-d3
+ asl.l #4,d0 ; X1 Koordinate * 16
+ asl.l #4,d1 ; Y1 Koordinate * 16
+ asl.l #4,d2 ; X2 Koordinate * 16
+ asl.l #4,d3 ; Y2 Koordinate * 16
+
+ move.w 6(a2,d7.w),d4 ; Anzahl der Steps
+ move.l d2,d5
+ sub.l d0,d5
+ divs.w d4,d5
+ move.w d5,bob_MoveToXStep(A0)
+
+ move.l d3,d5
+ sub.l d1,d5
+ divs.w d4,d5
+ move.w d5,bob_MoveToYStep(a0)
+
+ move.w d0,bob_MoveToX(a0)
+ move.w d1,bob_MoveToY(a0)
+ move.w d4,bob_MoveToSteps(a0)
+
+ movem.l (SP)+,d0-d7
+ addq.w #8,d1 ; Nächstes Kommando
+ReturnNull3: moveq #0,d0
+ rts
+
+FlashFunc: movem.l d0-d1,-(SP)
+ move.w 2(a2,d1.w),d0
+ move.w 4(a2,d1.w),d1
+ bsr FlashBob
+ movem.l (SP)+,d0-d1
+ addq.l #6,d1
+ bra.s ReturnNull3
+
+SetConvertFunc: move.l 2(a2,d1.w),bob_ConvertTab(a0)
+ move.w 6(a2,d1.w),bob_ConvertSize(a0)
+ move.w 8(a2,d1.w),bob_ConvertOffset(a0)
+ add.w #10,d1
+ bra.s ReturnNull3
+
+AnimToFunc: move.w 2(a2,d1.w),bob_Image(a0)
+ move.w 4(a2,d1.w),bob_AnimTo(a0)
+ addq.w #6,d1
+ bra.s ReturnNull3
+
+GotoFunc: move.l 2(a2,d1.w),a2
+ moveq.l #0,d1
+ bra.s ReturnNull3
+
+SetRelDataFunc: move.l 6(a2,d1.w),a1 ; BobBase
+ move.l (a1),d0 ; Address
+ add.l 2(a2,d1.w),d0 ; + Offset
+ move.l d0,bob_BobData(a0)
+ add.w #10,d1
+ bra.s ReturnNull3
+
+AddDaughterFunc:
+ movem.l a0-a3,-(SP)
+ move.l a0,a3 ; aktives Bob
+ move.l 2(a2,d1.w),a1 ; NewBob
+ bsr AddBob ; adden
+ move.l d0,a1 ; a0=NewBob
+
+ move.w 6(a2,d1.w),d0 ; X-Offset
+ add.w d0,bob_X(a1) ; addieren
+ move.w 8(a2,d1.w),d0 ; Y-Offset
+ add.w d0,bob_Y(a1) ; addieren
+
+ move.l a3,bob_ParentBob(a1) ; Aktuelles Bob = ParentBob
+
+ add.w #10,d1
+ movem.l (SP)+,a0-a3
+
+ReturnNull4: moveq.l #0,d0
+ rts
+
+
+
+TestJoyFunc: movem.l d2/a3,-(SP)
+ bclr #SRB_ZEROFLAG,bob_sr(A0) ; ZeroFlag löschen
+ move.w JoyBuf,d0 ; Joystick abfragen
+ move.l 4(a2,d1.w),d2
+ beq.s .NoFlip
+ move.l d2,a3
+ btst #0,(a3)
+ beq.s .NoFlip
+ move.w d0,d2
+ bclr #JOYB_LEFT,d2
+ bclr #JOYB_RIGHT,d2
+ btst #JOYB_LEFT,d0
+ beq.s 2$
+ bset #JOYB_RIGHT,d2
+2$: btst #JOYB_RIGHT,d0
+ beq.s 3$
+ bset #JOYB_LEFT,d2
+3$: move.w d2,d0
+.NoFlip: cmp.w 2(a2,d1.w),d0 ; Ergebnis mit Maske vergleichen
+ bne.s 1$ ; wenn nicht gleich -> Ende
+ bset #SRB_ZEROFLAG,bob_sr(A0) ; ZeroFlag setzen
+1$: addq.w #8,d1
+ movem.l (SP)+,d2/a3
+ bra ReturnNull4
+
+
+
+BitTestFunc: bclr #SRB_ZEROFLAG,bob_sr(A0) ; ZeroFlag löschen
+ move.w 2(A2,d1.w),d0 ; zu testendes bit
+ move.l 4(a2,d1.w),a3 ; zu testende Adr
+ btst d0,(A3) ; bit testen
+ bne.s 1$ ; wenn bit 0 ist
+ bset #SRB_ZEROFLAG,bob_sr(A0) ; ZeroFlag setzen
+1$: addq.w #8,d1
+ bra ReturnNull4
+
+
+
+JeqFunc: btst #SRB_ZEROFLAG,bob_sr(A0)
+ beq.s 1$
+ ;sub.l a2,a3
+ ;move.w a3,d1
+ add.w 2(a2,d1.w),d1
+ bra ReturnNull4
+
+1$: addq.w #4,d1
+ bra ReturnNull4
+
+JneFunc: btst #SRB_ZEROFLAG,bob_sr(A0)
+ bne.s 1$
+ ;sub.l a2,a3
+ ;move.w a3,d1
+ add.w 2(a2,d1.w),d1
+ bra ReturnNull4
+
+1$: addq.w #4,d1
+ bra ReturnNull4
+
+
+
+
+;-----------------------------------------------------------------------
+; Daten
+;-----------------------------------------------------------------------
+
+ClipMasks: dc.w %1111111111111111
+ dc.w %0111111111111111
+ dc.w %0011111111111111
+ dc.w %0001111111111111
+ dc.w %0000111111111111
+ dc.w %0000011111111111
+ dc.w %0000001111111111
+ dc.w %0000000111111111
+ dc.w %0000000011111111
+ dc.w %0000000001111111
+ dc.w %0000000000111111
+ dc.w %0000000000011111
+ dc.w %0000000000001111
+ dc.w %0000000000000111
+ dc.w %0000000000000011
+ dc.w %0000000000000001
+
+
+NumPlanes: ds.w 1
+GlobalXClip: ds.w 1 ; GlobalXClip und GlobalYClip müssen
+GlobalYClip: ds.w 1 ; hintereinander stehen!
+NewPri: ds.w 1
+GlobalX: ds.w 1
+JoyBuf: ds.w 1
+SaveMask: ds.b 1
+ ds.b 1
+
+ END