
; Listing7x2.s	- Kollision Sprite-Dual Playfield-Mode
; In diesem Beispiel zeigen wir die Kollision zwischen einem Sprite und
; den zwei Playfields. Der Sprite bewegt sich von oben nach unten. Wenn eine
; Kollision auftritt, verändert sich die Hintergrundfarbe (Rot oder Grün,
; je nach Art der Kollision).
; WinUAE: Chipset/Collision Level/Sprites and Sprites vs Playfields

	SECTION CipundCop,CODE

Anfang:
	move.l	4.w,a6			; Execbase
	jsr	-$78(a6)			; Disable
	lea	GfxName(pc),a1		; Name lib
	jsr	-$198(a6)			; OpenLibrary
	move.l	d0,GfxBase
	move.l	d0,a6
	move.l	$26(a6),OldCop	; speichern die alte COP

; wir verwenden 2 planes für jedes playfield

;	Pointen wie immer auf unser PIC

	move.l	#Pic1,d0
	lea	Bplpointers1,A1
	moveq	#2-1,d1
PointBp:
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	swap	d0
	add.l	#40*256,d0
	addq.w	#8,a1
	dbra	d1,PointBp


	move.l	#Pic2,d0		; point playfield 2
	lea	Bplpointers2,A1
	moveq	#2-1,d1
PointBp2:
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	swap	d0
	add.l	#40*256,d0
	addq.w	#8,a1
	dbra	d1,PointBp2

;	Pointen auf den Sprite

	lea	SpritePointers,a1		; Pointer in der Copperlist
	move.l	#MeinSprite0,d0		; Adresse des Sprite in d0
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)
	add.l	#16,a1

	move.l	#Copperlist,$dff080	; unsere COP
	move.w	d0,$dff088			; START COP
	move.w	#0,$dff1fc			; NO AGA!
	move.w	#$c00,$dff106		; NO AGA!


	move.w	#$0024,$dff104		; BPLCON2	%0100100
								; mit diesem Wert sind alle Sprites über
								; den Bitplanes

Warte1:
	cmp.b	#$ff,$dff006		; Zeile 255?
	bne.s	Warte1
Warte11:
	cmp.b	#$ff,$dff006		; immer noch Zeile 255?
	beq.s	Warte11

	btst	#6,$bfe001
	beq.s	Raus

	bsr.s	BewegeSprite		; Bewege den Sprite nach unten
	bsr.w	CheckColl			; Kontrolliert Kollision und greift ein

	bra.s	Warte1

Raus	move.l	OldCop(pc),$dff080	; Pointen auf die SystemCOP
	move.w	d0,$dff088			; Starten die alte SystemCOP

	move.l	4.w,a6
	jsr	-$7e(a6)				; Enable
	move.l	gfxbase(pc),a1
	jsr	-$19e(a6)				; Closelibrary
	rts

;	Daten

GfxName:
	dc.b	"graphics.library",0,0

GfxBase:
	dc.l	0

OldCop:
	dc.l	0

; Diese Routine bewegt den Sprite 0 nach unten, jeweils um 1 Pixel pro
; Frame. Es wird ein Flag verwendet.

BewegeSprite:
	not.w	Flag
	beq.s	EndeBewegeSprite

	addq.w	#1,Hoehe
	cmp.w	#300,Hoehe			; ist er am unteren Rand angekommen?
	blo.s	kein_Rand
	move.w	#$2c,Hoehe			; wenn ja, setz ihn wieder rauf
kein_Rand:
	move.w	Hoehe(pc),d0
	clr.b	VHBITS0	 			; lösche Bit 8 der vertikalen Position
	move.b	d0,Vstart0			; Kopiert die Bit von 0 bis 7 von Vstart
	btst.l	#8,d0				; ist die Position größer als 255 ?
	beq.s	NOBIGVSTART			; wenn nicht, geh weiter, das Bit wurde schon
								; vom clr.b VhBits gelöscht
	bset.b	#2,VHBITS0			; ansonsten setze Bit 8 auf 1 (Vertikale Start-
								; position)
NOBIGVSTART:
	addq.w	#8,d0				; Zähle die Länge des Sprite dazu, um die
								; Endposition (Vstop) zu ermitteln
	move.b	d0,Vstop0			; Gib die Bit von 0 bis 7 in Vstop
	btst.l	#8,d0				; ist die Position größer als 255 ?
	beq.s	NOBIGVSTOP			; wenn nicht, geh weiter, denn das Bit wurde
								; schon mit dem clr.b VhBits auf NULL gesetzt
	bset.b	#1,VHBITS0			; ansonsten setze Bit 8 auf 1 (Vertikale Start-
								; position)
NOBIGVSTOP:
EndeBewegeSprite:
	rts


; Diese Routine kontrolliert, ob es eine Kollision gibt.
; Wenn ja, verändert sie die Farbe des Hintergrundes, in dem sie in der
; Copperlist das Register COLOR0 verändert.

CheckColl:
	move.w	$dff00e,d0			; liest CLXDAT ($dff00e)
								; das Lesen dieses Registers bewirkt auch
								; seine sofortige Löschung, es ist also besser,
								; man kopiert es sich in d0 und macht dort dann
								; die Tests
	btst.l	#1,d0				; das Bit 1 meldet eine Kollision zwischen
								; Sprite 0 und Playfield 1
	beq.s	NoColl1			; wenn´s keine Kollision gab, überspringe

	move.w	#$f00,Kollisions_Sensor ; "anschalten" des Signales (COLOR0)
								; verändert die Copperlist (Rot)
	bra.s	exitColl			; Raus

NoColl1:
	btst.l	#5,d0				; Das Bit 5 meldet eine Kollision zwischen
								; Sprite 0 und Playfield 2
	beq.s	NoColl2			; wenn´s keine Kollision gab, überspringe
	move.w	#$0f0,Kollisions_Sensor ; "anschalten" des Signales (COLOR0)
								; verändert die Copperlist (Grün)
	bra.s	exitColl			; Raus

NoColl2:
	move.w	#$000,Kollisions_Sensor ; "ausschalten" des Signales (COLOR0)
								; verändert die Copperlist (Schwarz)
exitColl:
	rts

Flag:
	dc.w	0
Hoehe:
	dc.w	$2c


	SECTION GRAPHIC,DATA_C

Copperlist:
SpritePointers:
	dc.w	$120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
	dc.w	$12a,0,$12c,0,$12e,0,$130,0,$132,0
	dc.w	$134,0,$136,0,$138,0,$13a,0,$13c,0
	dc.w	$13e,0

	dc.w	$8e,$2c81		; DiwStrt
	dc.w	$90,$2cc1		; DiwStop
	dc.w	$92,$38			; DdfStart
	dc.w	$94,$d0			; DdfStop
	dc.w	$102,0			; BplCon1
	dc.w	$108,0			; Bpl1Mod
	dc.w	$10a,0			; Bpl2Mod

				; 5432109876543210
	dc.w	$100,%0100011000000000	; Bit 10 an = Dual Playfield
							; 4 Planes = 4 Farben pro Playfield

Bplpointers1:
	dc.w	$e0,0,$e2,0		; erste Bitplane Playfield 1 (BPLPT1)
	dc.w	$e8,0,$ea,0		; zweite Bitplane Playfield 1 (BPLPT3)


Bplpointers2:
	dc.w	$e4,0,$e6,0		; erste Bitplane Playfield 2 (BPLPT2)
	dc.w	$ec,0,$ee,0		; zweite Bitplane Playfield 2 (BPLPT4)

; Das ist das Register CLXCON (kontrolliert die Art der Registrierung)

; Die Bit von 0 bis 5 sind die Werte, die von den Planes eingenommen werden
; müssen
; Die Bit 6 bis 11 zeigen, welche Planes aktiv für Kollisionen sind
; Die Bit 12 bis 15 zeigen, welche ungeraden Sprites aktiviert werden sollen
; (für die Spriteregistrierung)

				;5432109876543210
	dc.w	$98,%0000001111001011	; CLXCON

; Diese Werte bedeuten, daß die Planes 1,2,3,4 für die Kollis. aktiviert sind.
; Es wird eine Kollision angezeigt, wenn der Sprite Playfield 1 überlagert, das
; die Pixel so hat:		Plane 1 = 1 (Bit 0)
;						Plane 3 = 0 (Bit 2)
; Also wird Color1 des Playfield 1 eine Kollision verursachen.

; Es wird eine Koll. mit Playf. 2 gemeldet, wenn der Sprite über der folgenden
; Pixelkombination ist: Plane 2 = 1 (Bit 1)
;						Plane 4 = 1 (Bit 3)
; Also Color3 des Playfield 2


	dc.w	$180			; COLOR00
Kollisions_Sensor:
	dc.w	0				; An DIESEM PUNKT schreibt die Routine CheckColl in
							; die Copperlist und verändert die Farben.

							; Palette Playfield 1
	dc.w	$182,$005		; Farben von 0 bis 7
	dc.w	$184,$a40
	dc.w	$186,$f80
	dc.w	$188,$f00
	dc.w	$18a,$0f0
	dc.w	$18c,$00f
	dc.w	$18e,$080


							; Palette Playfield 2
	dc.w	$192,$367		; Farben von 9 bis 15
	dc.w	$194,$0cc		; Die Farbe8 ist durchsichtig, sie wird nicht
	dc.w	$196,$a0a		; gesetzt.
	dc.w	$198,$242
	dc.w	$19a,$282
	dc.w	$19c,$861
	dc.w	$19e,$ff0


	dc.w	$1a2,$f00		; Palette der Sprites
	dc.w	$1a4,$0f0
	dc.w	$1a6,$ff0

	dc.w	$1aa,$fff
	dc.w	$1ac,$0bd
	dc.w	$1ae,$d50

	dc.w	$1B2,$00F
	dc.w	$1B4,$F0F
	dc.w	$1B6,$BBB

	dc.w	$1BA,$8E0
	dc.w	$1BC,$a70
	dc.w	$1BE,$d00

	dc.w	$ffff,$fffe		; Ende der Copperlist

;	Die zwei Playfields

Pic1:	incbin	"/Sources/colldual1.raw"
Pic2:	incbin	"/Sources/colldual2.raw"

; ********* Und hier der Sprite: KLARERWEISE in CHIP RAM!! *********

MeinSprite0:
Vstart0:
	dc.b $2c
Hstart0:
	dc.b $80
Vstop0:
	dc.b $2c+8
VHBITS0
	dc.b $00
 dc.w	%0000001111000000,%0111110000111110
 dc.w	%0000111111110000,%1111001110001111
 dc.w	%0011111111111100,%1100010001000011
 dc.w	%0111111111111110,%1000010001000001
 dc.w	%0111111111111110,%1000010001000001
 dc.w	%0011111111111100,%1100010001000011
 dc.w	%0000111111110000,%1111001110001111
 dc.w	%0000001111000000,%0111110000111110
 dc.w	0,0


	end

Dieses Beispiel  zeigt,  wie  die  Kollisionen  zwischen  Sprite  und  den
Playfields  (im Dual-Playfield-Mode) funktionieren. Die Kollisionen werden
unabhängig voneinander für  die  2  Playfields  kontrolliert,  indem  zwei
verschiedene  Bits  im  Register  CLXDAT  gelesen  werden. In unserem Fall
verwenden wir das Bit 1 für die Kollision mit  dem  Playfield  1  (geraden
Planes)  und  Bit  5  für  das  Playfield 2 (ungerade Planes). Im Reigster
CLXCON funktioniert alles wie im Falle eines normalen Bildschirmes:

Die Bit von 0 bis 5 sind die Werte, die die Planes einnehmen müssen.
Die Bit von 6 bis 11 geben an, welche Planes für die Kollisionen aktiviert sind
Die Bit von 12 bis 15 geben an, welche der ungeraden Sprites für die
Kollision aktiviert sind.

Es bleibt immer noch die Möglichkeit offen, einige Planes  nicht  für  die
Kollisionsdetektion  freizugeben,  sie  also  nicht  zu  aktivieren, um so
mehrere Farben nutzen zu können. Es wurde  in  Listing7w2.s  gezeigt.  Ihr
könnt versuchen, in der Copperlist den Wert des CLXCON zu verändern.

