
; Listing17e2.s = MStars.s
; Animation von Sprites, um "magische" Sterne zu machen
; Original version: Autor unbekannt
; Fixed version: Randy/Ram Jam

	SECTION	STARS,CODE

;	include	"DaWorkBench.s"	; entferne das; vor dem Speichern mit "wo"

*****************************************************************************
	include	"/Sources/startup2.s"	; speichern Copperlist etc.
*****************************************************************************

			;5432109876543210
DMASET	equ	%1000001110100000		; Copper,Bitplane,Sprites

WaitDisk	equ	10

Start:
	move.l	#Bitplane,d0
	lea	Bplpointers,a1
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	lea	$dff000,a5
	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Bitplane, Copper
								; und Sprites.
	move.l	#Copperlist,$80(a5)	; Zeiger Copperlist
	move.w	d0,$88(a5)			; Start Copperlist
	move.w	#0,$1fc(a5)			; AGA "deaktivieren"
	move.w	#$c00,$106(a5)		; AGA "deaktivieren"
	move.w	#$11,$10c(a5)		; AGA "deaktivieren"

Mouse:
	move.l	#$1ff00,d1			; Bits durch UND auswählen
	move.l	#$12c00,d2			; warte auf Zeile $12c
WaitY1:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l	d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmp.l	d2,d0				; warte auf Zeile $12c
	bne.s	WaitY1
WaitY2:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l	d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmp.l	d2,d0				; warte auf Zeile $12c
	beq.s	WaitY2

	btst	#2,$16(a5)			; rechte Maustaste gedrückt?
	beq.s	NoStellar

	bsr.s	Stellar

NoStellar:
	btst	#6,$bfe001			; linke Maustaste gedrückt?
	bne.s	Mouse
	rts

*****************************************************************************
; Routine, die die richtigen Sprites zeigt, um den "magischen Sterne"-Effekt
; zu erzielen
*****************************************************************************

WaitTime	=	2				; 0 = max Geschwindigkeit

Stellar:
	moveq	#8-1,d0				; Anzahl Sprites: 8
	lea	SpritePosXYTab(PC),A0	; seine Adresse wird für zwei 
								; Tabellen verwendet: mit positiven Offsets
								; greift es auf die Tabelle mit den XY Positionen
								; im "Kontrollwörter" Format zu,
								; während mit negativen Offsets der
								; Zugriff auf die Tabelle .b, für 
								; zufällige Animation verwendet wird

	lea	CopSpr,a1				; Zeiger Sprites in Copperlist

DoOneSpriteLoop:
; Lassen Sie uns die Ausführung etwas verlangsamen...

	subq.b	#1,-8(A0,d0.w)			; subtrahieren Sie 1 von der Wartezeit
	bpl.s	NoAnZero				; ist noch nicht = 0?
	move.b	#WaitTime,-8(A0,d0.w)	; Wartezeit zurückstellen

; Jetzt kümmern wir uns darum, die Werte und Frames aus dem AniTab zu durchlaufen

	moveq	#0,d1
	moveq	#0,d2
	move.b	-16(A0,d0.w),d1		; val1
	move.b	-24(A0,d0.w),d2		; val2
	addq.w	#1,d1				; val1+1
	cmp.b	#13,d1				; sind wir bei 13? (maximale frames)
	blt.s	NonMax1				; wenn noch nicht, ok
	moveq	#0,d1				; wenn ja, fangen Sie von vorne an
	addq.w	#1,d2
	cmp.b	#45,d2				; Wir sind bei 45? (maximale word
								; Steuerung SpritePosXYTab)
	blt.s	NonMax2				; wenn noch nicht, ok
	moveq	#0,d2				; ja?, fang von vorne an! (oder wir gehen von der Tabelle)
NonMax2:
	move.b	d2,-24(A0,d0.w)		; Wert speichern (pos XY aktuell der tab)
NonMax1:
	move.b	d1,-16(A0,d0.w)		; Wert speichern

; Jetzt müssen wir den richtigen Frame finden (Sprite)

	mulu.w	#68,d1				; aktuelle Frame * Länge 1 Rahmen,
								; und wir bekommen den Offset vom Anfang des
								; nur spriteanim
	move.w	d0,d3				; Nummer sprite aktuell in d3
	mulu.w	#13*68,d3			; * Länge 1 spriteanim = Offset für
								; nur spriteanim
	add.l	#AnimSprites-2,d1	; offset frames + Adresse AnimSprites
	add.l	d3,d1				; + offset sprite anim = richtige Adresse!!!

; Wir haben in d1 die Adresse des richtigen Sprites... wir müssen es aber 
; die X- und Y-Position (HSTART/VSTART) ändern, Nehmen Sie diese Werte von der Tabelle
; SpritePosXYTab, welches es bereits in Form von 2 schönen Kontrollwörtern
; bereithält. In d2 haben wir die Registerkarte ... d2 * 4 für den Offset!

	move.l	d1,a2				; die Adresse des Sprites direkt in a2 kopieren 
	add.w	d2,d2				;\ d2*4, in der Tat jedes Element der Tabelle
	add.w	d2,d2				;/       ist 2 words (4 bytes) lang
	move.l	0(A0,d2.w),(a2)		; SpritePosXYTab + Offset ok in den 2 Wörtern von
								; Überprüfen Sie das richtige Sprite.

; Jetzt haben wir in d1 die Adresse des richtigen Sprites zum Zeigen ...
; lasst es uns zeigen!

	move.w	d0,d3				; aktuelle Sprite-Nummer in d3...
	asl.w	#3,d3				; d3 * 8, um den Versatz vom ersten zu finden
								; Zeiger in copperliste, in der Tat jeder
								; Zeiger belegt 8 Bytes .....
	move.w	d1,6(a1,d3.w)		; Zeiger word hohe address sprite in cop,
								; tatsächlich: a1(erster Zeiger)+d3(Offset vom
	swap	d1					; (erster Zeiger)=Addresse Zeiger rechts!
	move.w	d1,2(a1,d3.w)		; Zeiger word unten
NoAnZero:
	dbra	d0,DoOneSpriteLoop
	rts



; 24 bytes (3*8)

AniTab:
	dc.b	34,8,28,41,19,16,42,26	; Tabelle mit nicht übereinstimmenden Werten für
	dc.b	0,7,7,1,6,7,11,4		; Erlaube "ähnliche" Animation
	dc.b	1,1,0,0,2,2,2,1			; zufällige Sterne.
SpritePosXYTab:
	dc.w	$2770,$3600,$434b,$5200,$7f43,$8e00	; Tabelle mit word
	dc.w	$874b,$9600,$8655,$9500,$6f62,$7e00	; Steuerung mit dem
	dc.w	$4362,$5200,$416c,$5000,$6060,$6f00	; verschiedenen x y Positionen
	dc.w	$6569,$7400,$6b66,$7a00,$4a70,$5900	; für die Sprites.
	dc.w	$646f,$7300,$3978,$4800,$577d,$6600	; Hinweis: 45 Kopien
	dc.w	$6078,$6f00,$3687,$4500,$3891,$4700
	dc.w	$438b,$5200,$538d,$6200,$5d87,$6c00
	dc.w	$2c91,$3b00,$2e96,$3d00,$4f92,$5e00
	dc.w	$5e96,$6d00,$3a9a,$4900,$39a1,$4800
	dc.w	$46a8,$5500,$599e,$6800,$61a2,$7000
	dc.w	$5aa5,$6900,$43ab,$5200,$44b3,$5300
	dc.w	$65b0,$7400,$4fb8,$5e00,$6dbc,$7c00
	dc.w	$28b8,$3700,$33be,$4200,$3ec4,$4d00
	dc.w	$49ca,$5800,$49bb,$5800,$72bf,$8100
	dc.w	$7cc5,$8b00,$82d5,$9100,$86ce,$9500

*****************************************************************************

	SECTION	Copper,DATA_C

Copperlist:
	dc.w	$8e,$2c81	; DIWSTRT
	dc.w	$90,$2cc1	; DIWSTOP
	dc.w	$92,$38		; DDFSTRT
	dc.w	$94,$d0		; DDFSTOP

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

	dc.w	$108,0		; BPL1MOD
	dc.w	$10a,0		; BPL2MOD
	dc.w	$102,0		; BPLCON1
	dc.w	$104,0		; BPLCON2

Bplpointers:
	dc.w	$e0,0,$e2,0	; plane 1

	dc.w	$100,$1200	; BPLCON0 - 1 plane lowres

	dc.w	$180,0		; COLOR00 - schwarz
	dc.w	$182,$fff	; COLOR01 - weiß

	dc.w	$180,$000,$182,$000

; Sprite-Farben - COLOR17 bis COLOR31

	dc.w	$1a2,$f00,$1a4,$a00,$1a6,$600
	dc.w	$1a8,$000,$1aa,$0f0,$1ac,$0a0
	dc.w	$1ae,$060,$1b0,$000,$1b2,$00f
	dc.w	$1b4,$00a,$1b6,$006,$1b8,$000
	dc.w	$1ba,$fff,$1bc,$aaa,$1be,$666

	dc.w	$ffff,$fffe	; Ende Copperlist

*****************************************************************************

; 68*13*8	dh 68 Bytes pro Frame * 13 Frames * 8 spriteanim

	dc.w	0	; wir schreiben auch hier! das hohe Wort ... das ist alles
				; um 1 Wort phasenverschoben .. frag mich nicht warum!
AnimSprites:
	incdir "/Sources/"
	incbin	"spranim1"	; 13 Frames
	incbin	"spranim2"	; 13 Frames
	incbin	"spranim3"	; 13 Frames
	incbin	"spranim4"	; 13 Frames
	incbin	"spranim5"	; 13 Frames
	incbin	"spranim6"	; 13 Frames
	incbin	"spranim7"	; 13 Frames
	incbin	"spranim8"	; 13 Frames

; ****************************************************************************

	SECTION	LEEREPLANE,BSS_C

Bitplane:
	ds.b	40*256	; 1 plane lowres "schwarz" wie Hintergrund.

	end

