
; Listing11h3.s	- Coppereffekt vorberechnet !!! 50 vorberechnete Copperlisten
; werden nacheinander mit COP2LC ($dff084) angezeigt.

	SECTION	COPPERADVANCED,CODE

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

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

			;5432109876543210
DMASET	equ	%1000001010000000	; nur Copper DMA

WAITDISK	equ	30				; 50-150 zur Rettung (je nach Fall)

Start:
	bsr.w	PreCalCop			; Routine welche 50 Copperlisten kalkuliert
								; das macht eine vollständige "Schleife" des Effekts    
	lea	$dff000,a5
	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Copper
	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			; Bit zur Auswahl durch UND
	move.l	#$12000,d2			; warte auf Zeile $120
WarteY1:
	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 $120
	bne.s	WarteY1

	btst	#2,$dff016			; rechte Maustaste gedrückt?
	beq.w	Mouse2				; wenn ja SwapCop nicht ausführen

	bsr.w	SwapCop				; Zeigen Sie auf die nächste Copperliste für
								; die korrekte "Animation" des Effekts.
Mouse2:
	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$12000,d2			; warte auf Zeile $120
WarteY2:
	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 $120
	beq.s	WarteY2

	btst	#6,$bfe001			; Maus gedrückt?
	bne.s	Mouse

	rts


******************************************************************************
; Routine swap der vorberechneten Copperliste .. (eine Animation !!!)
******************************************************************************

;	      \||||/
;	      (·)(·)
;	   ___\ \/ /___
;	  (_   \__/   _)
;	  /   .        \
;	 /    |Stz!\_   \
;	(_____| ___(_____)
;	 (___)      (___)
;	   ¡   \_    ¡
;	   |_   |   _|
;	   |    ;    |
;	   |    |    |
;	 __(____|____)__
;	(_______:_______)
 

SwapCop:
	move.l	CopBufPointer(pc),d0
	lea	CopJump,a0					; Adresszeiger auf cop2 in coplist
	move.w	d0,6(a0)				; Zeiger auf den aktuellen Frame
	swap	d0
	move.w	d0,2(a0)
	add.l	#(LINES*8)+ADDED,CopBufPointer	; zeigt auf weitere COP
	move.l	CopBufPointer(pc),d0
	cmp.l	#EndCopBuf,d0			; sind wir bei der letzten Copperliste?
	bne.w	NotEndBuf				; Wenn noch nicht, ok
	move.l	#CopBuf1,CopBufPointer	; sonst geh ab dem ersten!
NotEndBuf:
	rts

******************************************************************************
; 		Routine vorberrechneter Copper-Effekt
******************************************************************************

;	/\____/\
;	\(O..O)/
;	 (----)
;	  TTTT Mo!

LINES			equ	211
ADDED			equ	20			; LÄNGE DER HINZUGEFÜGTEN TEILE UNTEN...
NUMCOP			equ	50			; Anzahl frame/Copperlist!!!

PrecalCop:
; Jetzt erstellen wir die Copperlist.

	lea	CopBuf1,a0				; Adresse Puffer wo wir die Cops bearbeiten
	move.w	#NUMCOP-1,d7		; Anzahl der vorzuberechnenden Copperlisten
DoBuf:
	bsr.w	MakeCop				; Mach eine Copperlist
	add.w	#(LINES*8)+ADDED,a0	; zeige auf die nächste
	dbra	d7,DoBuf			; mache alle Copperlisten

; Jetzt "füllen" wir sie, als würden wir den Effekt in Echtzeit ausführen.
		
	lea	CopBuf1,a0				; Adresse der ersten vorberechneten Copperliste
	move.w	#NUMCOP-1,d7		; Anzahl cops zu "füllen" 
FillBuf:
 	bsr.s	ChangeCop			; Rufen Sie die Routine auf, die den Copper ändert 
	add.w	#(LINES*8)+ADDED,a0 ; springe zum nächsten, um ihn zu füllen
	dbra	d7,FillBuf			; Fülle alle copperlists
	
; Schließlich richten wir die Copperlisten Zeiger in der Copperlist!!!

	move.l	#CopBuf1,d0			; erstes "frame" copper2
	lea	CopJump,a0				; Zeiger auf das Ende copper1
	move.w	d0,6(a0)			; ...
	swap	d0
	move.w	d0,2(a0)

	move.l	#Copperlist,d0		; copper1 Anfang
	lea	CopJump2,a0				; Zeiger auf das Ende des "Partfinal"
	move.w	d0,6(a0)			; zu dem der copper2 springt
	swap	d0
	move.w	d0,2(a0)
	rts

******************************************************************************
; Routine die eine Copperlist erstellt
******************************************************************************

MakeCop:
	move.l	a0,-(sp)	
	move.l	#$2c07fffe,d1		; Copper wait Anweisung, beginnt mit
								; warten auf Zeile $2c
	move.l	#$1800000,d2		; $dff180 = color 0 für Copper
	move.w	#LINES-1,d0			; Anzahl der Zeilen der Schleife
	;moveq	#$000,d3			; Farbe setzen = schwarz
CopLoop:
	move.l	d1,(a0)+			; setzen des WAIT
	move.l	d2,(a0)+			; setzen des $180 (COLOR00) auf schwarz
	add.l	#$01000000,d1		; eine Zeile tiefer mit WAIT warten
	dbra	d0,CopLoop			; Wiederholen Sie diesen Vorgang bis zum Ende der Zeilen
	move.l	EndPointer(pc),d0	; PartFinale, zu dem alles copper2 springt
								; als frame verwendet.

	move.w	#$82,(a0)+			; TEILFINALE Zeiger - COP1LC
	move.w	d0,(a0)+
	swap	d0
	move.w	#$80,(a0)+
	move.w	d0,(a0)+
	move.l	#$880000,(a0)+		; COPJMP1 - springe zum letzten Stück, welches
								; dann copper1 wird als erster Copper wieder hergestellt!
	move.l	(sp)+,a0
	rts

CopBufPointer:
	dc.l	CopBuf1
EndPointer:
	dc.l	PartFinale

******************************************************************************
; Routine ändert die Farben in einer Copperlist
******************************************************************************

ChangeCop:
	move.l	a0,-(sp)			; a0 auf dem stack speichern
	move.w	#LINES-1,d0			; Anzahl der Zeilen der Schleife
	move.l	PointerTabCol(pc),a1	; Beginn der Farbtabelle in a1
	move.l	a1,PointerTemporary	; gespeichert in PuntatoreTemporaneo
	moveq	#0,d1				; d1 löschen
LineLoop:
	move.w	(a1)+,6(a0)			; Kopieren Sie die Farbe aus der Tabelle in die Copperlist
	addq.w	#8,a0				; nächste COLOR00 in Copperlist
	addq.b	#1,d1				; Ich notiere die Länge des Unterstrichs in d1
 	cmp.b	#9,d1				; Ende der Unterleiste?
	bne.s	WaitUnderBar

	move.l	PointerTemporary(pc),a1
	addq.w	#2,a1				; Punkt nach färben
	cmp.l	#EndTabColBar,PointerTemporary	; sind wir am Ende der Tabelle?
	bne.s	DoNotStartAgain		; wenn noch nicht, gehe zu DoNotStartAgain
	lea	TabColBar(pc),a1		; ansonsten ab dem ersten col!
DoNotStartAgain:
	move.l	a1,PointerTemporary	; und speichern Sie den Wert vorübergehend in Pun. temporaneo
	moveq	#0,d1				; d1 löschen
WaitUnderBar:
	dbra d0,LineLoop			; Mach alle Zeilen

	addq.l	#2,PointerTabCol	; nächste colore
	cmp.l	#EndTabColBar+2,PointerTabCol ; wir sind am ende der Farbtabelle?						 
	bne.s EndRoutine			 ; wenn nicht, raus, sonst...
	move.l #TabColBar,PointerTabCol	 ; ab dem ersten Wert von
								; TabColBar
EndRoutine:
	move.l	(sp)+,a0			; setze a0 vom Stapel fort
	rts

; Tabelle mit RGB-Farbwerten. In diesem Fall handelt es sich um Blautöne

TabColBar:
	dc.w	$000,$001,$002,$003,$004,$005,$006,$007
	dc.w	$008,$009,$00a,$00b,$00c,$00d,$00d,$00e
	dc.w	$00e,$00f,$00f,$00f,$00e,$00e,$00d,$00d
	dc.w	$00c,$00b,$00a,$009,$008,$007,$006,$005
	dc.w	$004,$003,$002,$001,$000,$000,$000,$000
	dcb.w	10,$000
EndTabColBar:
	dc.w	$000,$001,$002,$003,$004,$005,$006,$007	; diese Werte werden benötigt
	dc.w	$008,$009,$00a,$00b,$00c,$00d,$00d,$00e ; für die Nebenstangen
	dc.w	$00e,$00f,$00f,$00f,$00e,$00e,$00d,$00d
	dc.w	$00c,$00b,$00a,$009,$008,$007,$006,$005
	dc.w	$004,$003,$002,$001,$000,$000,$000,$000


PointerTemporary:
 	dc.l	TabColBar

PointerTabCol:
 	dc.l	TabColBar

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

	SECTION	GRAPHIC,DATA_C

Copperlist:
Copper2:
	dc.w	$180,$000			; COLOR00 - schwarz
	dc.w	$100,$200			; BPLCON0 - keine Bitplanes

; Hier können Sie Spritepointers, Colors, Bplpointers und so weiter setzen...

CopJump:
	dc.w	$84					; COP2LCH
	dc.w	0
	dc.w	$86					; COP2LCL
	dc.w	0
	dc.w	$8a,0				; COPJMP2 - starte den cop2 (frame)

* * * * * * 

PartFinale:						; zu diesem Stück springt das copper2 zu seinem
	dc.w	$ffdf,$fffe			; Ende, jedes Bild der Animation...
	dc.w	$0107,$fffe
	dc.w	$180,$010
	dc.w	$0207,$fffe
	dc.w	$180,$020
	dc.w	$0307,$fffe
	dc.w	$180,$030
	dc.w	$0507,$fffe
	dc.w	$180,$040
	dc.w	$0707,$fffe
	dc.w	$180,$050
	dc.w	$0907,$fffe
	dc.w	$180,$060
	dc.w	$0c07,$fffe
	dc.w	$180,$070
	dc.w	$0f07,$fffe
	dc.w	$180,$080
	dc.w	$1207,$fffe
	dc.w	$180,$090
	dc.w	$1607,$fffe
	dc.w	$180,$0a0
	dc.w	$1a07,$fffe
	dc.w	$180,$0b0
	dc.w	$1f07,$fffe
	dc.w	$180,$0c0
	dc.w	$2607,$fffe
	dc.w	$180,$0d0
	dc.w	$2c07,$fffe
	dc.w	$180,$0e0

CopJump2:
	dc.w	$80					; COP1LCH für Neustart der Copperlist von ourcopper
	dc.w	0
	dc.w	$82					; COP1LCL
	dc.w	0
	;dc.w	$88,0				; COPJMP1
	dc.w	$ffff,$fffe			; Ende Copperlist
EndPartFinale:

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

	SECTION	BUFFERCOPPER,BSS_C

CopCols:
CopBuf1:
	ds.b	((LINES*8)+ADDED)*NUMCOP	; 50 Copperlist!
EndCopBuf:

	end

Wenn Sie den Coppereffekt vorberechnen, werden die Multiplikationen, die
Koordinaten der 3D-Vektoren, Musik nicht beeinflusst ... Sie können eine Demo
erstellen, die den Prozessor frei lässt um einen nicht vorberechneten Effekt zu
machen !!!! HAHAHAHA!

Beachten Sie, wenn Sie von copper1 zu copper2 springen, das Sie an dessen Ende 
zum "PartFinale" Copper springen, so dass es copper1 als Ausgangscopper nimmt!
Lasst uns also das Copper zweimal aufbauen und nicht einmal wie in Listing11h.s                                                                                                                                                                                                                                                          
