; "Base class" actor for SMWCP2 cutscenes.
; Actors have three routines associated with them:
; 1. A routine that runs on initialization.
; 2. A routine that runs every frame.
; 3. A routine that runs during NMI.
; It also has a byte detailing whether or not its slot is being used,
; as well as 6 misc bytes each actor can use for RAM (accessed by !actorRAM+10,x through !actorRAM+15,x or the !actorVar defines).

; To draw a tile, call DrawTile.  By default, each sprite has 8 tiles to it.
; More can be used, but they must be managed themselves.

!actorRAM = $7FA000		; Should be 0x100 bytes minimum.
!actorINIT1 = !actorRAM+$00
!actorINIT2 = !actorRAM+$10
!actorINIT3 = !actorRAM+$20

!actorMAIN1 = !actorRAM+$30
!actorMAIN2 = !actorRAM+$40
!actorMAIN3 = !actorRAM+$50

!actorNMI1 = !actorRAM+$60
!actorNMI2 = !actorRAM+$70
!actorNMI3 = !actorRAM+$80

!actorExists = !actorRAM+$90

!actorVar1 = !actorRAM+$A0
!actorVar2 = !actorRAM+$B0
!actorVar3 = !actorRAM+$C0
!actorVar4 = !actorRAM+$D0
!actorVar5 = !actorRAM+$E0
!actorVar6 = !actorRAM+$F0

; This macro creates a new actor and returns its ID in A (0 - 0xF)
; $00-02: Address of the actor's INIT routine.
; $03-05: Address of the actor's MAIN routine.
; $06-08: Address of the actor's NMI  routine.

NewActor:
{
	LDX #$0B
.loop	
	;TAX
	LDA !actorExists,x
	BEQ .endLoop
	;TXA
	;SEC
	;SBC #$10
	DEX
	BMI .noneFound
	BRA .loop
.endLoop
	;REP #$20
	LDA $00
	STA !actorINIT1,x
	LDA $01
	STA !actorINIT2,x
	LDA $02
	STA !actorINIT3,x
	LDA $03
	STA !actorMAIN1,x
	LDA $04
	STA !actorMAIN2,x
	LDA $05
	STA !actorMAIN3,x
	LDA $06
	STA !actorNMI1,x
	LDA $07
	STA !actorNMI2,x
	LDA $08
	STA !actorNMI3,x
	
	
	LDA #$01
	STA !actorExists,x
	LDA #$00
	STA !actorVar1,x
	STA !actorVar2,x
	STA !actorVar3,x
	STA !actorVar4,x
	STA !actorVar5,x
	STA !actorVar6,x
	TXA
	RTL
.noneFound
	LDA #$00
	RTL
}

DeleteActor:
{
	LDA #$00
	STA !actorExists,x
	RTL
}

; $00 = x pos
; $01 = y pos
; $02 = tile
; $03 = yxppccct
; $0E = index (shouldn't need to worry about normally; just don't let any actor code touch $0E and you'll be okay)
; A = size (0 = 8x8, 2 = 16x16)
DrawTile:
{
	PHY
	PHX
	PHA
	LDA $0E
	ASL #2
	TAY
	LDA $00
	STA $0200,y
	LDA $01
	CLC
	ADC $1888
	CMP #$F0
	BMI .prematureEnd			; Don't draw things that are above the screen.
	STA $0201,y
	LDA $02
	STA $0202,y
	LDA $03
	STA $0203,y

	LDA $0E		; Table index into Y
	LSR #2		;
	TAY		;

	LDA $0E		; Shift count into X
	AND #$03	;
	;EOR #$03
	TAX		;
			
	PLA		;
	AND #$02	;
	BEQ ++
-
	DEX		;
	BMI +		; Shift until the bit is in the correct place.
	ASL		;
	ASL		;
	BRA -		;
+
	ORA $0400,y	; OR it into the table.
	STA $0400,y	;
++
	PLX
	PLY
	INC $0E
	RTL		;
	
.prematureEnd
	PLA
	PLX
	PLY
	RTL
}

; Uploads an ExGFX file to VRAM.
; ExGFX is the number of the file.
; size is the size of the ExGFX file.
; VRAM is the address (byte, not word address)
; See also uploadExGFXW (which specifies a word address for VRAM).
macro UploadExGFXB(ExGFX, size, VRAM)
	REP #$30			; \
	LDA #!ExGFX			; |
	LDX #!VRAM>>1			; | Upload the layer 3 tilemap
	LDY #!size			; |
	JSR UploadGFXFile		; /
	SEP #$30
endmacro

; Exact same as uploadExGFXB, but VRAM is a word address.
; These are only differentiated for clarity.
macro UploadExGFXW(ExGFX, size, VRAM)
	REP #$30			; \
	LDA #!ExGFX			; |
	LDX #!VRAM			; | Upload the layer 3 tilemap
	LDY #!size			; |
	JSR UploadGFXFile		; /
	SEP #$30
endmacro

; Remember to set things like the VRAM address, CGRAM address, etc. before starting.
macro StandardDMA(register, source, size, transferMode)
	REP #$20
	LDX <transferMode>		; \ 2 registers write once.
	STX $4300			; /
	LDX.b <register>		; \ Write to $2118
	STX $4301			; / 
	LDA.w #<source>		; \
	STA $4302			; |
	LDX.b #<source>>>16		; | Source is the address of the first tile.
	STX $4304			; / 	
	LDA <size>			; \
	STA $4305			; /
	SEP #$20			; \		
	LDA #$01			; |	Begin DMA.
	STA $420B			; /
endmacro




