header
lorom

; NOTE: $1600+ is used for various cutscene controls.
; $1700+ is used for the individual actors and the RAM they need.

; Exceptions follow:
!inCutscene = $0F6E		; True if we're in a cutscene.
!skipCutsceneOnLoad = $0F6F	; Set to true after finishing a cutscene.
				; Because cutscenes play automatically when the level starts,
				; We need to disable them after playing them once.
				; Otherwise we end up in an infinite loop of loading a level,
				; Redirecting to a cutscene,
				; Loading the level,
				; Redirecting to the cutscene,
				; etc...
				
!cutsceneFadeStatus = $0F6F	; Highest bit indicates whether or not we're fading (0 = not fading)
				; Lowest bit indicates the direction (0 = fading from 0 to F)
				
!cutsceneFadeValue = $0DAE	; The current fade value (0 to F)
;!cutsceneFadeTimer = $0F71	; 
				
				
!currentFontPointer = $45	; The pointer to the current font (updated automatically)
!currentWidthsPointer = $47	; The pointer to the current widths (updated automatically)
!trackingWidth = $49		; How wide the space between each character is.  Should not be larger than 8 - the widest character.


;!buffer = $000000		; 
!messagePtr = $16A0		; 
!timeToNextLetter = $16A3	; 
!messagePos = $16A4		; 
!waitingForButton = $16A6	; 
!noWaitOn = $16A7		; 
!letterX = $16A8		; 
!letterY = $16A9		; 
!VRAMUploadAddr = $16AA		; Current VRAM address to upload current tile(s) to.
!doMAIN = $16AC			;
!cutsceneNumber = $16AD		;
!textNumber = $16AE		;
!uploadTwo = $16AF		; If this value is below 2, then this is the number of tiles to upload - 1.  Otherwise, it's 1 tile.
				; It is also used to determine if the contents of tile2 should be copied to tile1 at the code's start.
!VRAMX = $16B0			; The x position of the next empty tile.
!VRAMY = $16B1			; The y position of the next empty tile.
!currentLetter = $16B2		; Only used for adding delays to certain characters ("." "," "!" etc.)
!doNotUploadTiles = $16B3	; Set if the tiles should not be updated.
!checkForWordWrap = $16B4	; Set after every space.
!textYPos = $16B5		; Current position of the layer 3 text
!scrollTextUp = $16B6		; Timer for scrolling the text up.  While !0, the text will scroll.
!fadeTextOut = $16B7		; Serves two purposes.  If >= 1, sets the text darkness to this - 1.  If 1, clear out all text graphics.
!clearTextPosition = $16B8	; Used to clear the text, in conjunction with !fadeTextOut.
!textSpeed = $16B9		; The speed at which the text scrolls.
!textIsAppearing = $16BA	; Set if the text is appearing, clear otherwise.
!NMIUploadFlag = $16BB		; Set if, during NMI, we should upload what's in the buffer at $7EAD00
!NMIUploadDest = $16BC		; The upload destination of buffer uploads.
!NMIUploadSize = $16BE		; The upload size of buffer uploads.

!currentFont = $16C0		; The current font to use.

!tile1 = $7EC810		; Address of the first tile
!tile2 = $7EC830		; Address of the second tile.
!textTilemapExGFX = $0A00	; The ExGFX number of the layer 3 tilemap used for the text
!borderExGFX = $0A01		; The ExGFX number of the border graphics
!buttonSpriteExGFX = $0A02	; The ExGFX number of the button press and Mario graphics.
!textTilemapSize = $1000
!borderExGFXSize = $0060
!letterHeight = $10		; How high each letter's graphic is.
!backgroundColor = $16C1	; 3 bytes; sets the background color to R G B (5 bits for each)

!layer1MapAddr = $5000		; Note: This is enough to store two tilemaps.  Since it's only possible to upload one tilemap at a time,
!layer2MapAddr = $6000		; Alternate between which tilemap to use for each scene (upload one, upload the other, switch to them both).
!layer3MapAddr = $4000		; Covers both the top (window) and bottom (text) portions (top is right and bottom is left).
	
!layer1ChrAddr = $8000
!layer2ChrAddr = $8000
!layer12ChrAddr = !layer2ChrAddr<<4|!layer2ChrAddr
!layer34ChrAddr = $0000		;

!spaceWidth = $07		; The width of a space.

!forcePause = $16C5		; If set, no "press A to continue" prompts will appear until cleared.

!inManualWait = $16C6		; Set if we used a "wait" command ($F0+)

!currentSpeaker = $16C7		; Set to the index of the current speaker.  If negative, then anyone can speak.




		
macro VWFASM(label)
	db $E9
	dl <label>
endmacro
	
macro VWFASMArg(label, arg)

	db $E8
	dl <label>
	db <arg>
	
endmacro




; Overwrite the "load Yoshi's house during the ending" game state (21).
org $0095BC
autoclean 	JSL Main
RTS

org $00A59C
autoclean	JSL LevelStartHijack
NOP
NOP

org $008176
		JML NMIHijack
		NOP #2	

org $008385
		JML IRQHijack
		NOP

freecode
prot AllCutsceneData1, AllCutsceneData2, AllCutsceneData3

CutsceneLevels:
;Intro,W1Intro,Truntec, Driad,Tanuki,   Mau,Barker, Blimp, Frank,            DocCroc,Norveg Bowser
dw $00C5, $0009, $01D2, $0049, $00F2, $01A8, $00DD, $006E, $00D6, $012B, $012C, $0186, $0143, $001E, $FFFF

CutsceneLevelValues:
;Intro,W1Intro,Truntec, Driad,Tanuki,   Mau,Barker, Blimp, Frank,            DocCroc,Norveg Bowser
db  $00, $01,   $02,   $03,   $04,   $06,   $07,   $08,   $09,   $0A,   $0B,   $0C,   $0E,   $0D

LevelStartHijack:
{
	
	PHB
	PHK
	PLB
	
	STA $7FFFFF
	
	; First, determine whether or not we should play a cutscene.
	; Amazingly, we can rely on $010B to contain the current level number.  Yay!
	LDA !skipCutsceneOnLoad
	BNE .noCutscene
	
	REP #$20
	LDX #$00
	
.loop
	LDA CutsceneLevels,x
	CMP #$FFFF
	BEQ .noCutscene
	CMP $010B
	BEQ .yesCutscene
	INX
	INX
	BRA .loop
	
.yesCutscene
	SEP #$20
	TXA
	LSR
	TAX
	LDA CutsceneLevelValues,x
	STA !cutsceneNumber

	PLB
	
;	LDA $0100
;	CMP #$0C
;	BCC +
	LDA #$21
	STA $0100
	
	; If we are going to run a cutscene, then we don't run the rest of the level loading code.
	; Instead we just set the new game mode and exit.
	; In order to exit from where we are now though we need some hackery.
	; First pull our return address off the stack.
	PLA : PLA : PLA
	; Now push the address of an RTS in bank one minus 1 onto the stack.
	; When we return from OUR RTL, we'll jump back to the RTS, thus ignoring the rest of the code that was going to run.
	LDA #$00
	PHA
	PEA $A60B
	
	; Now that we have our means of escape set up, we need to do some more magic.
	; When we leave this cutscene, we'll teleport to our level.
	; Thus we need to make sure that the level exits are set up properly.
	; And by that I mean destroy them all and force them to point to our level.
	LDX #$1F
	
-	LDA $010B
	STA $19B8,x
	LDA $010C
	AND #$01
	ORA #$04
	STA $19D8,x
	DEX
	BPL -
	
	; Also disable the "Mario Start!" bit
	LDA #$01
	STA $141D
	
	; Set fade status to fade in from 0 to F
	;LDA #%10000000
	;STA !cutsceneFadeStatus
	;LDA #$00
	;STA !cutsceneFadeValue
	; Above was moved to Init
	
	RTL
	
.noCutscene
	SEP #$20
	PLB
	STZ !skipCutsceneOnLoad
	JSR LevelStartHijackRestoreStuff
	
	RTL
}

LevelStartHijackRestoreStuff:
	; We need to do a JSL to 0085FA, but it's a JSR routine.
	PHK
	PEA.w .jslrtsreturna-1
	PEA $84CE
	JML $0085FA
.jslrtsreturna

	; Aaaaand again to NoButtons (F62D)
	PHK
	PEA.w .jslrtsreturnb-1
	PEA $84CE
	JML $00F62D
.jslrtsreturnb
RTS

reset bytes	

Main:
{
	JMP RealMain
	
incsrc cutsceneActor.asm

	RealMain:


	PHK				; Get the correct data bank.
	PLB				;
	
	JSL $7F8000			; Clear out all sprite tiles.
	
	LDX #$20
-	STZ $03FF,x
	DEX
	BNE -
	
	LDA !currentFont
	AND #$FF
	ASL
	TAX
	REP #$20
	LDA fonttable,x
	STA !currentFontPointer
	LDA widthstable,x
	STA !currentWidthsPointer
	SEP #$20
	
	
	LDA !waitingForButton		; \ If we're waiting on a button, we should basically be doing nothing.
	BNE +				; /
	LDA !scrollTextUp	
	BEQ +			
	INC !textYPos		
	DEC !scrollTextUp	
	+
	
	
	LDA #$01			; \ Never upload tiles unless specifically told to.
	STA !doNotUploadTiles		; /
	
	LDA !doMAIN
	BNE .continue
	JMP Init
.continue
	
	; Handle fading in and out.
	
	LDA !cutsceneFadeStatus
	BPL .doneWithFadeStuff
	
	AND #$01
	BNE .fadingOut
	
	; Fading in code here.
	LDA !cutsceneFadeValue
	INC
	STA !cutsceneFadeValue
	CMP #$0F
	BNE .doneWithFadeStuff
	STZ !cutsceneFadeStatus

.fadingOut
	LDA !cutsceneFadeValue
	DEC
	STA !cutsceneFadeValue
	;CMP #$00
	BNE .doneWithFadeStuff
	STZ !cutsceneFadeStatus
	
	
.doneWithFadeStuff
	
	
	
	LDA #$00
	JSL RunActorCode

	LDA !waitingForButton		;
	BNE VWFCheckButton		;
	LDA !timeToNextLetter		;
	BNE DecWaitTimer		;
	STZ !inManualWait
	LDA !fadeTextOut		;
	BEQ FetchCode			; Don't run any code if we're fading out.
	CMP #$01
	BNE +
	STZ !scrollTextUp
	STZ !textYPos
+
	JMP VWFFinish			;
FetchCode:
	REP #$20
	LDA !messagePtr
	STA $00
	SEP #$20
	LDA.w !messagePtr+2
	STA $02
	LDA [$00]
	CMP #$E0
	BCC NotControlCode
	SEC
	SBC #$E0
	STA $04
	PHA
	ASL
	CLC
	ADC $04
	TAX
	REP #$20
	LDA SpecialEffectTable,x
	STA $04
	SEP #$20
	LDA SpecialEffectTable+2,x
	STA $06
	PLA
	JML [$0004]
NotControlCode:
	JSR WordWrap
	LDY !waitingForButton
	BNE +
	JSR DecodeLetter

	LDA !noWaitOn
	BNE FetchCode
+
	JMP VWFFinish

SetButtonWait:
LDA #$01
STA !waitingForButton
RTS

VWFSpace:
	LDA #$51
	BRA NotControlCode
	
DecWaitTimer:
	DEC !timeToNextLetter
	JMP VWFFinish
	
VWFCheckButton:
	LDA !forcePause
	BNE .textIsPaused
	LDA #$02
	STA !textIsAppearing
	LDA #$D8
	STA $03FC
	LDA #$CA
	STA $03FD
	LDA $13
	AND #$10
	LSR #3
	CLC
	ADC #$EC
	STA $03FE
	LDA #$39
	STA $03FF
	LDA #$80
	STA $041F
	LDA $15
	CMP #$80
	BNE +
	LDA !waitingForButton		; This never set for user-induced button waits
	BNE ++
	JSR IncreaseMessagePosition
++
	STZ !waitingForButton
+
	JMP VWFFinish
	
.textIsPaused
	STZ !textIsAppearing
	RTL

VWFSetWait:
	AND #$0F			; Get the nibble of the byte
	ASL				; And multiply it by 2.
	STA $4202			; \
	LDA !textSpeed			; |
	INC				; | Multiply by the text speed
	STA $4203			; |
	LDA #$01			; |
	STA !inManualWait		; |
	NOP				; |
	;NOP #4				; |
	LDA $4216			; /
	STA !timeToNextLetter		;
	JSR IncreaseMessagePosition	;
	JMP VWFFinish				;
	

VWFWordBreak:
	JSR IncreaseMessagePosition
	JMP VWFFinish

VWFLineBreak:
	JSR InsertNewLine
	JSR IncreaseMessagePosition
	JMP VWFFinish
VWFClearText:
	LDA.b #$0E
	STA !clearTextPosition
	LDA #$10
	STA !fadeTextOut
	JSR IncreaseMessagePosition
	JSR InsertNewLine
	JMP VWFFinish
VWFSetTextSpeed:
	REP #$20
	INC $00
	SEP #$20
	LDA [$00]
	STA !textSpeed
	JSR IncreaseMessagePosition
	JSR IncreaseMessagePosition
	JMP VWFFinish
	
VWFSetFont:
	REP #$20
	INC $00
	SEP #$20
	LDA [$00]
	STA !currentFont
	JSR IncreaseMessagePosition
	JSR IncreaseMessagePosition
	JMP VWFFinish
	

VWFExecuteCodeArg:
	LDA #$01
	STA $0D
	BRA VWFExecuteCodeSkip
	
VWFExecuteCode:
	STZ $0D
VWFExecuteCodeSkip:
	PHP
	REP #$20
	INC $00
	LDA [$00]
	STA $04
	INC $00
	INC $00
	SEP #$20
	LDA [$00]
	STA $06
	PHB
	LDA $06
	PHA
	PLB
	PHK
	PEA.w .Ret1-1
	LDA $0D
	BEQ +
	REP #$20		; \
	INC $00			; |
	INC !messagePtr		; | Get the argument
	SEP #$20		; |
	LDA [$00]		; /
+
	JML [$0004]
.Ret1
	PLB
	
	PLP
	REP #$20
	INC !messagePtr
	INC !messagePtr
	INC !messagePtr
	INC !messagePtr
	SEP #$20
	JMP FetchCode

VWFEnd:

	LDA !cutsceneFadeValue
	BEQ .fadeOutComplete

	; Handle the actual fading out.
	; Note that since we never increase the message pointer we run this code "forever".
	LDA #%10000001
	STA !cutsceneFadeStatus
	JMP VWFFinish

	
.fadeOutComplete
	LDA #$00			; \ 
	PHA				; | Restore the data bank to bank 0.
	PLB				; /
	
	;LDA #$01
	;LDA $010B
	STZ $0109			; Level to go to after fade to overworld (none)
	
	;REP #$30			; \ 
	;LDA #$0028			; |
	;LDX #$4000			; |
	;LDY #!textTilemapSize		; |
	;JSL DecompressAndUploadGFXFile	; |
	;LDA #$0029			; |
	;LDX #$4400			; |
	;LDY #!textTilemapSize		; | Restore the layer 3 graphics
	;JSL DecompressAndUploadGFXFile	; |
	;LDA #$002A			; |
	;LDX #$4800			; | 
	;LDY #!textTilemapSize		; |
	;JSL DecompressAndUploadGFXFile	; |
	;LDA #$002B			; |
	;LDX #$4C00			; |
	;LDY #!textTilemapSize		; |
	;JSL DecompressAndUploadGFXFile	; /
	
	;SEP #$30
	
	;LDA.b #$3000>>11<<2		; \
	;STA $2107			; |
	;LDA.b #$3800>>11<<2		; | Restore tilemap addresses in VRAM
	;STA $2108			; |
	;LDA.b #$5000>>11<<2+1		; | 
	;STA $2109			; /
	
	;LDA.b #$0000>>13		; \ 
	;STA $210B			; | Restore CHR addresses in VRAM
	;LDA.b #$5000>>13		; | 
	;STA $210C			; / 
	
	STZ !inCutscene
	
	REP #$20
	LDA $010B
	CMP #$00C5
	SEP #$20
	BEQ .introCutsceneStuff
	
	LDA #$01
	STA !skipCutsceneOnLoad
	
	
	
	;LDA #$0F
	;STA $0DAE
	;LDA #$01
	;STA $0DAF

	INC $141A
	
	JSL $04DC09
	;LDA $0100
	LDA #$11
	STA $0100
	JMP VWFFinish
	
.introCutsceneStuff
	
	LDA #$0F
	STA $0DAE
	LDA #$01
	STA $0DAF

	INC $141A
	
	LDA #$00	; \ No clue what this does...!
	STA $7fc009	; / But it's necessary to get the graphics to load correctly.
	
	;LDA #$01
	;STA $1B9C
	LDA #$0B
	STA $0100
	;JMP VWFFinish

}

VWFFinish:
{
	
	LDA !textIsAppearing
	CMP #$02
	BNE +
	STZ !textIsAppearing		;
	BRA +++
+
	LDA !fadeTextOut		;
	BEQ +				;
.textIsNotAppearing			;
	STZ !textIsAppearing		;
	BRA ++				;
+					; Set the !textIsAppearing address.
	LDA !timeToNextLetter		;
	CMP !textSpeed			;
	BEQ .textIsAppearing		;
	BCS .textIsNotAppearing		;
.textIsAppearing			;
	LDA #$01			;
	STA !textIsAppearing		;
++					;

+++
	LDA !inManualWait
	BEQ +
	STZ !textIsAppearing
+
	RTL
}




InsertNewLine:
{
	LDA #$20			;
	STA !letterX			;
	STZ !VRAMX			;
	INC !VRAMY			;
	INC !VRAMY			;
	INC !VRAMY			;
	LDA !VRAMY
	CMP #$10
	BCC +
	LDA !textYPos
	BNE ++
	INC
	JSR SetButtonWait
	++
	LDA #$10
	CLC
	ADC !scrollTextUp
	STA !scrollTextUp
	+
	REP #$20			; \
	LDA.w #!tile2			; |
	STA $00				; | Clear out tile2.
	LDA.w #!tile2>>8		; |
	STA $01				; |
	JSR ClearTile			; /
	
	REP #$20			; \
	LDA.w #!tile1			; |
	STA $00				; |
	LDA.w #!tile1>>8		; | Clear out tile1.
	STA $01				; |
	JSR ClearTile			; /
	RTS
}

IncreaseMessagePosition:
	REP #$20
	INC !messagePtr
	SEP #$20
	RTS

; Checks for word wrap, and inserts new lines if necessary.
WordWrap:
{
	PHA			; Save the current letter
	LDA !letterX		; \ Save the current x position.
	PHA			; /
	LDY #$00		;
	
.loop
	LDA [$00],y		; Get the next letter in the word

	CMP #$E7
	BEQ .skipCode2
	CMP #$E8
	BEQ .skipCode5
	CMP #$E9		; \ If it's a JSL code, skip 4 bytes and continue
	BEQ .skipCode4		; /
	CMP #$EA
	BEQ .skipCode2
	CMP #$EB
	BEQ .exitLoop
	CMP #$EC		; \ If it's a new line... ... ...exit.
	BEQ .exitLoop		; /
	CMP #$ED		; \ If it's a clear, exit
	BEQ .exitLoop		; /
	CMP #$EE		; \ Not quite a space but exit anyway.
	BEQ .exitLoop		; /
	CMP #$EF		; \ If it's a button request, exit
	BEQ .exitLoop		; /
	CMP #$E0		; \ If it's an end code, exit.
	BEQ .exitLoop		; /
	BCS .notChar		; If it's any control code, skip it and go to the next character.
	TAX			; 
	
	PHY
	TXY
	LDA !letterX			; \
	CLC				; | Increase the current x position
	ADC (!currentWidthsPointer),y	; | by this letter
	PLY				; |
	;INC				; | plus 1 to account for tracking.
	CLC				; |
	ADC !trackingWidth		; |
	STA !letterX			; /
	CMP #$E0			; \ If we've passed #$E0, then exit.
	BCS .tooFar			; /
.notChar
	INY			; 
	BRA .loop		; 

.tooFar
	JSR InsertNewLine
	
	PLA
	PLA
	RTS
.exitLoop
	PLA
	STA !letterX
	PLA
	RTS
.skipCode5
	INY
.skipCode4
	INY			;
.skipCode3
	INY			;
.skipCode2
	INY			;
.skipCode1
	INY			; 
	BRA .loop		; 
}

	; Decodes the letter in A to the one or two (as needed) defined tiles.
DecodeLetter:
{
	PHA			; Save the current letter.
	STZ !doNotUploadTiles	; We're decoding a letter, so upload stuff.
	
	LDA !textSpeed
	;INC
	STA !timeToNextLetter
	LDA !uploadTwo
	BEQ +			; If uploadTwo is set, then we need to copy the contents of tile2 to tile1 and clear tile2.
	REP #$20		; \
	LDA.w #!tile2		; |
	STA $00			; | 
	LDA.w #!tile2>>8	; |
	STA $01			; | Setup
	LDA.w #!tile1		; |
	STA $03			; |
	LDA.w #!tile1>>8	; |
	STA $04			; /
	JSR CopyTile		; Copy tile2 to tile1.
	REP #$20	
	JSR ClearTile		; Clear tile1 $00 still contains the address of tile2.
	STZ !uploadTwo		; Turn this off.
	+
	
	PLA
	STA $07			; Save the letter to $07.
	CMP #$ED
	BNE +
	LDA #$51		; If this is a space, pretend it's character #$51
	STA $07			; 
	+
	INC			; We decode backwards, so start at the next letter.
	STA $4202
	LDA #!letterHeight
	STA $4203
	NOP #3
	REP #$30
	LDA $4216
	DEC			; Last byte of the letter.
	TAY
	ASL
	TAX			; Y contains 1bpp index, X contains 2bpp index.

	LDA !currentFontPointer
	STA $00
	SEP #$20
	PHB
	PLA
	STA $02
	;LDA.w #font
	;STA $00
	;LDA.w #font>>8
	;STA $01
				; $00 contains the address of the current letter's 1bpp graphics.

	;SEP #$20
	LDX.w #!letterHeight<<1-2		; The number of bytes to decode
.loop				;
	XBA			; \
	LDA #$00		; | Clear out the high byte (I freaking love XBA).
	XBA			; /
	LDA [$00],y		; Get the byte.
	STA $04			; Store to temp.

	PHX			; But push X for now; we need it for a counter.
	
	LDA !letterX		; Get the current x position.
	AND #$07		; ...within the current tile.
	TAX			; Put it into X; we need to shift the new tile this many times.
	LDA $04			; Get the GFX byte back.
	REP #$20		;
	AND #$00FF		;
	XBA			; Put the GFX byte into the high byte of A.

.shiftLoop
	DEX
	BMI .shiftLoopExit
	LSR			; Shift it until it's out of the way of the first letter.
	BRA .shiftLoop
.shiftLoopExit
	PLX			; Get x back (the 2bpp index).
	XBA
	PHA			; Save both the left and right parts (but in reverse order).
	SEP #$20
	ORA !tile1,x		; \ Store the GFX byte to the GFX buffer.
	STA !tile1,x		; /
	PLA			;
	PLA			; Get the right part.
	STA !tile2,x		; And store it.
				; 
	LDA #$00		; 
	STA $7EC811,x		; Store 0 to the next byte of the GFX buffer (for 2bpp graphics).
	STA $7EC831,x		; 
	
	DEY
	DEX
	DEX
	BPL .loop		; 
				; We have the decoded letter in !tile1 / !tile2.
	SEP #$10
	LDX $07
	LDA !letterX
	AND #$07
	CLC
	PHY
	TXY
	ADC (!currentWidthsPointer),y
	PLY
	CMP #$07
	BCC .notNeedNewTile
	
	LDA #$01
	STA !uploadTwo

.notNeedNewTile
	LDA !letterX			; 
	;INC				;
	CLC
	ADC !trackingWidth
	CLC				; Increase the width.
	PHY
	TXY
	ADC (!currentWidthsPointer),y	; 
	PLY
	STA !letterX			; 
	JSR IncreaseMessagePosition
	
	CPX #$ED
	BNE +
	LDA #$01
	STA !checkForWordWrap
+
.space
	STX !currentLetter
	STZ !doNotUploadTiles
	RTS
}
	

	
TurnForcePauseOn:
	LDA #$01
	STA !forcePause
	RTL
	
TurnForcePauseOff:
	STZ !forcePause
	RTL
	
SetSpeakerToNull:
	STZ !currentSpeaker
	RTL	
	
	
	
	
	
	
	















Init:
{
	;LDA #$01
	;STA !cutsceneNumber
	
	
	STZ $4200			; Disable NMI for now.
	
	LDA #$80			; \ Force blank on.
	STA $2100			; /
	
	; Set fade status to fade in from 0 to F
	LDA #%10000000
	STA !cutsceneFadeStatus
	LDA #$00
	STA !cutsceneFadeValue

	LDA #$01
	STA !trackingWidth
	
	LDX #$00			; \
	TXA				; |
-	STA !actorRAM,x			; | Clear out all actor RAM
	DEX				; |
	BNE -				; /
	    
	LDA !cutsceneNumber		; \
	ASL				; |
	CLC				; |
	ADC !cutsceneNumber		; |
	TAY				; |
	LDA.b #cutsceneStrings		; |
	STA $00				; |
	LDA.b #cutsceneStrings>>8	; |
	STA $01				; |
	LDA.b #cutsceneStrings>>16	; |
	STA $02				; |
	LDA [$00],y			; |
	STA $03				; |
	INY				; |
	LDA [$00],y			; |
	STA $04				; |
	INY				; |
	LDA [$00],y			; |
	STA $05				; /
	
	LDA !textNumber			; \
	ASL				; |
	CLC				; |
	ADC !textNumber			; |
	TAY				; |
	LDA [$03],y			; |
	STA.w !messagePtr		; | Set the message pointer to the correct place.
	INY				; |
	LDA [$03],y			; |
	STA.w !messagePtr+1		; |
	INY				; |
	LDA [$03],y			; |
	STA.w !messagePtr+2		; /
	
	LDA #$01			; \
	STA !doMAIN			; |
	STA !inCutscene			; /
	
	
	
	;LDA #$13			; \
	;STZ $212E			; | Set window mask layer settings.
	;STZ $212F			; /
	
	LDA #$09			; \ Mode 1, 8x8 tiles, layer 3 has priority.
	STA $2105			; /
	
	LDA.b #!layer1MapAddr>>11<<2	; \
	STA $2107			; /
	LDA.b #!layer2MapAddr>>11<<2	; \
	STA $2108			; /
	LDA.b #!layer3MapAddr>>11<<2+1	; \ Layer 3 gets an "extra" tilemap to the right, which holds the top screen's border.
	STA $2109			; /
	
	LDA.b #!layer12ChrAddr>>13	; \ GFX index for BG1 and 2.
	STA $210B			; / 
	LDA.b #!layer34ChrAddr>>13	; \ GFX index for BG3 and 4.
	STA $210C			; / 
	
	STZ $210D			; \
	STZ $210D			; |
	STZ $210E			; |
	STZ $210E			; |
	STZ $210F			; | Zero out all scroll values.
	STZ $210F			; |
	STZ $2110			; |
	STZ $2110			; |
	STZ $2111			; |
	STZ $2111			; |
	STZ $2112			; |
	STZ $2112			; /
		
	REP #$20			; 209947
	LDA.w #!layer12ChrAddr>>1	; \ Dest. is the address of the graphics data.
	STA $2116			; / 
	LDX #$09			; \ 
	STX $4300			; / 
	LDX #$18			; \ Write to $2118
	STX $4301			; / 
	LDA.w #blankTileGFX		; \
	STA $4302			; |
	LDX.b #blankTileGFX>>16		; | Source is the address of the first tile.
	STX $4304			; / 	
	LDA #$0000			; \ Completely clear out VRAM.
	STA $4305			; / 		
	LDX #$01			; \ Begin DMA.
	STX $420B			; /
	
	REP #$30			; \
	LDA #!textTilemapExGFX		; |
	LDX #!layer3MapAddr>>1		; | Upload the layer 3 tilemap
	LDY #!textTilemapSize		; |
	JSL DecompressAndUploadGFXFile	; /
	SEP #$10

	
	REP #$10			; \
	LDX.w #$4000			; |
	LDA #$21FF			; |
-					; |
	STA $7EC800,x			; | Create an empty tilemap to DMA in a moment.
	DEX				; |
	DEX				; |
	BPL -				; /
	SEP #$10			; 209945
	
	LDA.w #!layer1MapAddr>>1	; \ Dest. is the address of the tilemap data.
	STA $2116			; / 
	LDX #$01			; \ 
	STX $4300			; / 
	LDX #$18			; \ Write to $2118
	STX $4301			; / 
	LDA.w #$7EC800			; \
	STA $4302			; |
	LDX.b #$7EC800>>16		; | Source is the address of the first tile.
	STX $4304			; / 	
	LDA.w #$4000			; \ 
	STA $4305			; / 	
	LDX #$01			; \ Begin DMA.
	STX $420B			; /
	
	LDA.w #!layer2MapAddr>>1	; \ Dest. is the address of the tilemap data.
	STA $2116			; / 
	LDX #$01			; \ 
	STX $4300			; / 
	LDX #$18			; \ Write to $2118
	STX $4301			; / 
	LDA.w #$7EC800			; \
	STA $4302			; |
	LDX.b #$7EC800>>16		; | Source is the address of the first tile.
	STX $4304			; / 	
	LDA.w #$4000			; \ 
	STA $4305			; / 	
	LDX #$01			; \ Begin DMA.
	STX $420B			; /
	
	
	
	REP #$30			; \
	LDA #!borderExGFX		; |
	LDX #!layer34ChrAddr>>1+$1F80	; | Upload the layer 3 border graphics.
	LDY #!borderExGFXSize		; |
	JSL DecompressAndUploadGFXFile	; /
	
	LDA #!buttonSpriteExGFX		; \
	LDX #$7800			; |
	LDY #$1000			; | Upload the button press graphics.
	JSL DecompressAndUploadGFXFile	; /
	
	SEP #$30
	
	LDA #$20			;
	STA !letterX			;
	
	LDX #$00			;
	LDA #$00			;
-					; Clear out the actor RAM
	STA !actorRAM,x			;
	DEX				;
	BNE -				;
	
	LDA !cutsceneNumber		; \
	ASL				; |
	CLC				; |
	ADC !cutsceneNumber		; |
	TAX				; |
	REP #$20 			; |
	LDA.l cutsceneInits,x		; | Jump to this cutscene's INIT routine.
	STA $00				; |
	SEP #$20			; |
	LDA.l cutsceneInits+2,x		; |
	STA $02				; |
	
	PHB
	LDA $02
	PHA
	PLB
	PHK				; |
	PEA.w .ret-1			; |
	
	JML [$0000]			; /
.ret
	PLB

	SEP #$30
	
	REP #$20			; \
	LDA.w #!tile2			; |
	STA $00				; | Clear out tile2.
	LDA.w #!tile2>>8		; |
	STA $01				; |
	JSR ClearTile			; /
	
	REP #$20			; \
	LDA.w #!tile1			; |
	STA $00				; |
	LDA.w #!tile1>>8		; | Clear out tile1.
	STA $01				; |
	JSR ClearTile			; /
	
	
	LDA #$A1			; \ Turn NMI and IRQ on.
	STA $4200			; /
	
	
	JMP Main
}
	; Codes:
	; $F0 - $FF: Wait for that many frames ($F0 = 1 frame, $FF = 16 frames).
	; $EF: wait for button press.
	; $EE: Possible break (use after dashes and such; indicates that a word can break here without a space).
	; $ED: Space.
	; $EC: New line
	; $EB: Clear all text.
	; $EA $XX: Set the text speed to $XX.
	; $E9 $XX $YY $ZZ: JSL to $ZZXXYY.
	; $E8 $XX $YY $ZZ $WW: JSL to $ZZXXYY with $WW in A.
	; $E7 $XX: Set font to XX
	; $E0: Stop.
	
!CCButton = $EF
!CCZeroSpace = $EE
!CCNewLine = $EC
!CCClearText = $EB
!CCTextSpeed = $EA
!CCSetFont = $E7
	
	
	
	
	
	; NOTE TO SELF: Do not put any code or data here! 
	; The INIT routine goes back into the MAIN routine
	; once it's finished.
	; I'm putting this here because I know you'll keep
	; sticking stuff here and waste time debugging
	; stupid crashes if I don't!
	
	
	
	
	
	
	
	
		
















	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

font1:
incbin vwffont.bin
font2:
incbin vwffonttruntec.bin
font3:
incbin vwffontitalic.bin

fonttable:
dw font1, font2, font3

widthstable:
dw widths1, widths2, widths1

widths1:
;   A    B    C    D    E    F    G    H
db $05, $05, $05, $05, $04, $04, $05, $05
;   I    J    K    L    M    N    O    P
db $01, $04, $05, $04, $07, $05, $05, $05
;   Q    R    S    T    U    V    W    X
db $05, $05, $05, $05, $05, $05, $07, $05
;   Y    Z    a    b    c    d    e    f
db $05, $05, $05, $05, $05, $05, $05, $03
;   g    h    i    j    k    l    m    n
db $05, $05, $01, $03, $05, $02, $07, $05
;   o    p    q    r    s    t    u    v
db $05, $05, $05, $04, $05, $04, $05, $05
;   w    x    y    z    0    1    2    3
db $07, $05, $05, $04, $05, $03, $05, $05
;   4    5    6    7    8    9    !    ?
db $07, $05, $05, $04, $03, $05, $01, $05
;   "<  >"    :    ;    ~    (    )    '
db $05, $05, $01, $02, $05, $03, $03, $02
;   .    ,    =    -    +    /    *    %
db $01, $02, $05, $05, $05, $03, $05, $08
;  ...   [ ]  [  TM ]  note
db $07, $07, $07, $07, $06, $07, $07, $07

widths2:
;   A    B    C    D    E    F    G    H
db $07, $07, $07, $07, $07, $07, $07, $07	; 00
;   I    J    K    L    M    N    O    P
db $07, $07, $07, $07, $07, $07, $07, $07	; 08
;   Q    R    S    T    U    V    W    X	
db $07, $07, $07, $07, $07, $07, $07, $07	; 10
;   Y    Z    a    b    c    d    e    f
db $07, $07, $07, $07, $07, $07, $07, $07	; 18
;   g    h    i    j    k    l    m    n
db $07, $07, $07, $07, $07, $07, $07, $07	; 20
;   o    p    q    r    s    t    u    v
db $07, $07, $07, $07, $07, $07, $07, $07	; 28
;   w    x    y    z    0    1    2    3
db $07, $07, $07, $07, $07, $07, $07, $07	; 30
;   4    5    6    7    8    9    !    ?
db $07, $07, $07, $07, $07, $07, $07, $07	; 38
;   "<  >"    :    ;    ~    (    )    '
db $07, $07, $07, $07, $07, $07, $07, $07	; 40
;   .    ,    =    -    +    /    *    %
db $07, $07, $07, $07, $07, $07, $07, $07	; 48
;  ...   [ ]  [  TM ]  note
db $07, $07, $07, $07, $06, $07, $07, $07	; 50


blankTileData:
dw $21FF
blankTileGFX:
dw $0000

SpecialEffectTable:
dl VWFEnd, $000000, $000000, $000000, $000000, $000000, $000000, VWFSetFont
dl VWFExecuteCodeArg, VWFExecuteCode, VWFSetTextSpeed, VWFClearText, VWFLineBreak, VWFSpace, VWFWordBreak, VWFCheckButton
dl VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait
dl VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait, VWFSetWait

SpecialEffectWidths:
db $01, $01, $01, $01, $01, $01, $01, $01
db $05, $04, $02, $01, $01, $01, $01, $01
db $05, $04, $02, $01, $01, $01, $01, $01
db $05, $04, $02, $01, $01, $01, $01, $01


!GFXBuffer = $7EAD00
; Ripped from genericuploader.asm.  
; 16-bit A should be the ExGFX number to decompress.
; 16-bit X should be the VRAM address to upload to (divided by 2).
; 16-bit Y should be the size of the upload.
DecompressAndUploadGFXFile:
		REP #%00010000		; 16-bit X/Y
		PHY			; back up Y
		PHX			; back up X
		JSL DecompressGFXFile
		REP #%00010000		; 16-bit X/Y
		PLX
		PLY
		JSL UploadFromBuffer
		RTL
		
; Decompresses the GFX file in 16-bit A to $7EAD00
{
DecompressGFXFile:
		CMP.w #$0032		; \ < 32, use code
		BCC .GFX00to31		; / for GFX 00-31
		CMP.w #$0080		; \ still < 80,
		BCC .UploadReturn	; / return
		CMP.w #$0100		; \ > 100, use code
		BCS .ExGFX100toFFF	; / for 100-FFF
.GFX80toFF	AND.w #$007F		; reset most significant bit
		STA.b $8A		; \
		ASL A			;  | multiply by 3 using
		CLC			;  | shift-add method
		ADC.b $8A		; /
		TAY			; -> Y
		LDA.l $0FF94F		; \
		STA.b $06		;  | $0FF94F-$0FF950 contains the pointer
		LDA.l $0FF950		;  | for the ExGFX table for 80-FF
		STA.b $07		; /
		BRA .FinishDecomp	; branch to next step

.UploadReturn	;PLX
		;PLY
		RTL

.GFX00to31	TAX			; ExGFX file -> X
		LDA.l $00B992,x		; \
		STA $8A			;  | copy ExGFX
		LDA.l $00B9C4,x		;  | pointer to
		STA $8B			;  | $8A-$8C
		LDA.l $00B9F6,x		;  |
		STA $8C			; /
		BRA .FinishDecomp2	; branch to next step

.ExGFX100toFFF	;SEC			; \ subtract #$100
		SBC.w #$0100		; / SEC commented out because the BCS that branches here would only branch if the carry flag were already set
		STA.b $8A		; \
		ASL A			;  | multiply result
		CLC			;  | by 3 to get
		ADC.b $8A		;  | index
		TAY			; /
		LDA.l $0FF873		; \
		STA.b $06		;  | $0FF873-$0FF875 contans the pointer
		LDA.l $0FF874		;  | for the ExGFX table for 100-FFF
		STA.b $07		; /
.FinishDecomp	LDA.b [$06],y		; \ Get low byte.
		STA.b $8A		; / and high byte
		INC.b $06		; Increase pointer position by 1.
		BNE .NoCrossBank	; \
		SEP #%00100000		;  | allow bank crossing
		INC $08			;  | (not sure if this is necessary here)
		REP #%00100000		; /
.NoCrossBank	LDA.b [$06],y		; \ Get the high byte (again)
		STA.b $8B		; / and bank byte.
.FinishDecomp2	LDA.w #!GFXBuffer	; \ GFX buffer low
		STA.b $00		; / and high byte
		SEP #%00100000		; 8-bit A
		LDA.b #!GFXBuffer>>16	; \ GFX buffer
		STA.b $02		; / bank byte
		PHK			; \
		PEA.w .Ret1-1		;  | local JSL to LZ2 routine
		PEA $84CE		;  | (afterwards A/X/Y all 8-bit)
		JML $00B8DC		; /
.Ret1		
		RTL
	
; Uploads the graphics at $7EAD00 with the 16-bit address in X and the 16-bit size in Y.	
UploadFromBuffer:
		REP #%00010000		; 16-bit X/Y
		;PLX			; \ restore X, X is the
		STX.w $2116		; / VRAM destination
		LDA.b #%00000001	; \ control
		STA.w $4300		; / register
		LDA.b #$18		; \ dma to
		STA.w $4301		; / [21]18
		LDX.w #!GFXBuffer	; \
		STX.w $4302		;  | source
		LDA.b #!GFXBuffer>>16	;  | of data
		STA.w $4304		; /
		;PLY			; Restore Y, Y is the
		STY.w $4305		; / size of the upload
		LDA.b #%00000001	; \ start DMA
		STA.w $420B		; / transfer
		REP #%00100000		; 16-bit A
		RTL
}	

WaitAndUploadFromBuffer:
		STX !NMIUploadDest
		STY !NMIUploadSize
		SEP #$30
		LDA #$01
		STA !NMIUploadFlag
WaitForNMI:
-
		WAI			; \
		LDA $4212		; | Wait for NMI, when the graphics will be uploaded.
		BPL -			; /
		SEP #$30
		RTL

; Sets the current VRAM address to upload.
; A should be 8-bit. $00-$01 is destroyed.
CalculateVRAMAddress:
{
	LDA !VRAMY
	CMP #$30
	BCC +
	STZ !VRAMY
	+
	SEP #$20
	LDA !VRAMX
	REP #$20
	AND #$00FF
	ASL #3
	STA $00
	LDA !VRAMY
	AND #$00FF
	ASL #7
	CLC
	ADC $00
	;ORA #!layer34ChrAddr>>1
	AND #$3FF0
	
	STA !VRAMUploadAddr
	RTS
}

NMIHijack:
	LDA $4210
	JSR NMI
	LDA $1DFB
	JML $00817C
	
IRQHijack:
	JSR IRQ
	LDA.b #$81                
	LDY.w $0D9B
	JML $00838A

; In NMI, we set up things for the top screen.
NMI:
{
	LDA $0DAE			; \
	AND #$0F			; | Turn force blank off.
	STA $2100			; /
	

					;
	LDA !inCutscene			; \
	BNE +				; | If we're not in a cutscene, get out of here.
	RTS				; /
	+				;
	
	LDA !NMIUploadFlag
	BEQ +
	STZ !NMIUploadFlag
	REP #$10
	LDX !NMIUploadDest
	LDY !NMIUploadSize
	JSL UploadFromBuffer
	SEP #$30
	+
	
	LDA !backgroundColor
	ORA #$20
	STA $2132
	
	LDA !backgroundColor+1
	ORA #$40
	STA $2132
	
	LDA !backgroundColor+2
	ORA #$80
	STA $2132
		
	LDA #$01
	JSL RunActorCode
	
	LDA #$0A			; \
	STA $4209			; | Set an IRQ at scanline #$0A (which will modify the windowing).
	STZ $420A			; /
	
	LDA !doNotUploadTiles		; Only upload if the tiles have been updated.
	BNE .noUpload
	;LDA !timeToNextLetter
	;BNE .noUpload
	
	LDX !currentLetter		; \
	CPX #$48			; |
	BEQ .addWait			; |
	CPX #$49			; |
	BEQ .addWait			; |
	CPX #$3E			; | Add time to certain characters.
	BEQ .addWait			; |
	CPX #$3F			; |
	BNE .noWait			; |
.addWait				; |
	LDA #$08			;   \
	STA $4202			;   |
	LDA !textSpeed			;   |
	INC				;   |
	STA $4203			;   |
	INC !doNotUploadTiles		;   | Multiply by the text speed.
	NOP				;   |
	LDA $4216			;   |
	STA !timeToNextLetter		;   /
.noWait					; /
	
	JSR CalculateVRAMAddress	; Calculate the address to upload the tile(s) to.
	LDA !VRAMUploadAddr		; \ Store to the VRAM address.
	STA $2116			; /			
	LDX #$01			; \ 2 registers write once.
	STX $4300			; /
	LDX #$18			; \ Write to $2118
	STX $4301			; / 
	LDA.w #!tile1			; \
	STA $4302			; |
	LDX.b #!tile1>>16		; | Source is the address of the first tile.
	STX $4304			; / 	
	LDA #$0020			; \
	LDX !uploadTwo			; |
	BEQ +				; | Upload either 32 or 64 bytes, depending on need.
	ASL				; | Also increase the VRAM position if we're uploading two.
	INC !VRAMX			; |
	INC !VRAMX			; |
	+				; |
	STA $4305			; /
	SEP #$20			; \		
	LDA #$01			; |	Begin DMA.
	STA $420B			; /
.noUpload

	LDA !fadeTextOut
	BEQ .skipOverFadeStuff
	CMP #$01
	BEQ .doNotDecreaseFade
	DEC !fadeTextOut
	BRA .skipOverFadeStuff
	.doNotDecreaseFade
	
	LDA.w !clearTextPosition	; \
	REP #$20			; |
	AND #$00FF			; | Get the address to clear.
	ASL #9				; |
	STA $2116			; / 
	LDX #$09			; \ 
	STX $4300			; / 
	LDX #$18			; \ Write to $2118
	STX $4301			; / 
	LDA.w #blankTileGFX		; \
	STA $4302			; |
	LDX.b #blankTileGFX>>16		; | Source is the address of the first tile.
	STX $4304			; / 	
	LDA #$0400			; \ 
	STA $4305			; / 		
	LDX #$01			; \ Begin DMA.
	STX $420B			; /
	
	SEP #$10			; \
	LDA.w #!tile2			; |
	STA $00				; | Clear out tile2.
	LDA.w #!tile2>>8		; |
	STA $01				; |
	JSR ClearTile			; /
	
	REP #$20			; \
	LDA.w #!tile1			; |
	STA $00				; |
	LDA.w #!tile1>>8		; | Clear out tile1.
	STA $01				; |
	JSR ClearTile			; /
	
	SEP #$20			;
	DEC !clearTextPosition		;
	;LDA !clearTextPosition		;
	;CMP #!layer3MapAddr>>9-1	;
	BPL +				;
	STZ !fadeTextOut		;
	STZ !VRAMX			;
	STZ !VRAMY			;	
	LDA #$20			;
	STA !letterX			;
	STZ !textYPos			;
	
	
+
	
	.skipOverFadeStuff

	; Now we "switch" the screen.
	LDA $1A				; \
	STA $210D			; | Layer 1 X
	LDA $1B				; |
	STA $210D			; /
	LDA $1C				; \
	CLC				; |
	ADC $1888			; |
	STA $210E			; | Layer 1 Y
	LDA $1D				; |
	STA $210E			; /
	LDA $1E				; \
	STA $210F			; | Layer 2 X
	LDA $1F				; |
	STA $210F			; /
	LDA $20				; \
	STA $2110			; | Layer 2 Y 
	LDA $21				; |
	STA $2110			; /
	STZ $2111			; \
	LDA #$01			; | Layer 3 X
	STA $2111			; /
	LDA #$FB			; \
	STA $2112			; | Layer 3 Y
	STZ $2112			; /
	
	STZ $420C			; No HDMA
	
	LDA #$33			; \ Enable inversion window 1 for layers 1 and 2.
	STA $2123			; /
	STZ $2124			; Disable window 1 for layers 3 and 4.
	LDA #$33			; \
	STA $2125			; / Enable inversion window 1 for OBJ and Color Window
	
	LDA #$FF			;
	STA $2126			; Clip the entire screen
	STZ $2127			; (will be turned off a few scanlines later)
	
	LDA #$04			; \ Layer 3 on the main screen
	STA $212C			; /
	STZ $212E			; No windowing on the main screen.
	
	LDA #$13			; \ Layers 1, 2, and OBJ on the sub screen.
	STA $212D			; /
	STA $212F			; Clip them, too.
	    
	LDA #$22			; \ Prevent color math inside color windows
	STA $2130			; / and add the subscreen instead of fixed color.
	
	LDA #$20			; \ Enable color math on the backdrop.
	STA $2131			; / 
	

	
	STZ $11				; We have two IRQs, so $11 is used to distinguish whose code to run.
	
	LDA $10				; \
	BNE +				; | Stuff from the original NMI code that...is used to handle lag? 
	INC $10				; / Not sure, but if it's not here the game freezes up.
+
	
	PHK				; \
	PEA.w .spriteDMAReturn-1	; | Set up a "JSL"
	PEA $84CE			; | 
	JML $008449			; / Upload sprites.
.spriteDMAReturn

	PHK				; \
	PEA.w .controllerUpdateReturn-1	; | Set up a "JSL"
	PEA $84CE			; | 
	JML $008650			; / Update the controller.
.controllerUpdateReturn

	PLA				; \
	PLA				; / Not RTS
	
	JML $0083B2			; Jump straight to the NMI end.
}

IRQ:
{
	LDA !inCutscene			; \
	BNE +				; | If we're not in a cutscene, get out of here.
	RTS				; /
	+				;
					; We have two codes here.  The first deals with windowing and shows layer 1/2.  
					; The second turns on the text display.
	LDA $11
	CMP #$01
	BEQ .midScreen			; Between the border and the text.
	CMP #$02
	BEQ .enableSecondScreen
	CMP #$03
	BEQ .enableSprites
-	BIT $4212			; Wait until H-blank
	BVC -

	LDA #$27			; Set the window.
	STA $2126			; 
	LDA #$D8			; 
	STA $2127			; 
	
	LDA #$6D
	STA $4209			; \ Set an IRQ at scanline #$70
	STZ $420A			; /
	
	BRA .end
.midScreen
-	BIT $4212			; Wait until H-blank
	BVC -
	LDA #$FF
	STA $2126
	STZ $2127
	
	LDA #$74
	STA $4209			; \ Set an IRQ at scanline #$74 (it will switch from "picture" to "text" mode there)
	STZ $420A			; /
	BRA .end
.enableSprites	
	LDA #$14			; \ Layer 3 and OBJ on the main screen
	STA $212C			; /

	LDA #$03			; \ Layers 1, 2, and OBJ on the sub screen.
	STA $212D			; /
	STA $212F			; Clip them, too.
	BRA .end
.enableSecondScreen

-	BIT $4212			; Wait until H-blank
	BVC -
	
	LDA !cutsceneFadeStatus
	BMI .noBrightnessFoolery
	
	LDA !fadeTextOut
	BEQ +
	DEC
	STA $2100
	BRA ++
	+
	LDA #$0F
	STA $2100
	++
	
.noBrightnessFoolery

	LDA #$FF
	STA $2126
	STZ $2127
	
	STZ $2112
	LDA #$89
	CLC
	ADC !textYPos
	STA $2112
	STZ $2112
	STZ $2111
	STZ $2111
	
	LDA #$A0
	STA $4209			; \ Set an IRQ at scanline #$A0
	STZ $420A			; / It will turn off sprite clipping.

.end
	INC $11
	PLA				; \ 
	PLA				; / Skip out on the RTS
	
	JML $0083B2
	RTS
}

; $00 should contain the address of the tile to clear.
; A should be 16 bits wide (will be 8-bits on exit).
ClearTile:
{
	LDY #$1E
	LDA #$0000
.loop
	STA [$00],y
	DEY
	DEY
	BPL .loop
	SEP #$20
	RTS
}

; $00 should contain the source address.
; $03 should contain the target address.
; A should be 16 bits wide (will be 8-bits on exit).	
CopyTile:
{	
	LDY #$1E
.loop
	LDA [$00],y
	STA [$03],y
	DEY
	DEY
	BPL .loop
	SEP #$20
	RTS
}


QuickActorCodeRun:				; Call this from within scripts during certain circumstances.
	JSL $7F8000
	LDA !textIsAppearing
	PHA
	LDA #$00
	STA !textIsAppearing			; No, NOT STZ.  The LDA #$00 is important.
	JSL RunActorCode
	PLA
	STA !textIsAppearing
	RTL

; If A is 0, then we run INIT and MAIN.
; Otherwise, we run NMI.
; Note that no actor code should touch $0F.


RunActorCode:
{
	PHA
	CMP #$00
	BNE .skipGroundShake
	
				; ...while we're at it, zero out the APU ports too.
	STZ $2140
	STZ $2141
	STZ $2142
	STZ $2143
	
	LDA $1887		; \ If shake ground timer is set 
	BEQ .skipGroundShake	;  | 
	DEC $1887		;  | Decrement timer 
	AND #$03		;  | 
	TAX			;  | 
	LDA $00A1CE,x		;  | 
	STA $1888		;  | $1888-$1889 = Amount to shift level 
	LDA $00A1D2,x		;  | 
	STA $1889		;  /
.skipGroundShake
	PLA

	STZ $0E
	STA $0F
	LDX #$0B
.loop
	LDA !actorExists,x
	BNE .run
.back
	DEX
	;TXA
	;SEC
	;SBC #$10
	BMI .quitLongJump
	BRA .loop
.quitLongJump
	JMP .quit
.run
	STX $15E9
	;TXA
	;ASL
	;ASL
	;STA $0E					; $0E is the actor's dword index to the OAM (each actor gets 4 tiles).
	LDA $0F
	BNE .runNMI
	
	LDA !actorExists,x
	CMP #$02
	BEQ .noRunINIT
	PHP
	LDA !actorINIT1,x
	STA $00
	LDA !actorINIT2,x
	STA $01
	LDA !actorINIT3,x
	STA $02
	PHB
	LDA $02
	PHA
	PLB
	PHK
	PEA.w .ret1-1
	
	JML [$0000]
.ret1
	PLB
	PLP
	LDA #$02
	STA !actorExists,x
	
.noRunINIT
	LDA !textIsAppearing
	PHA
	LDA !currentSpeaker
	BMI +
	CPX !currentSpeaker
	BEQ +
	STZ !textIsAppearing
+
	PHP
	LDA !actorMAIN1,x
	STA $00
	LDA !actorMAIN2,x
	STA $01
	LDA !actorMAIN3,x
	STA $02
	
	PHB
	LDA $02
	PHA
	PLB
	PHK
	PEA.w .ret2-1
	JML [$0000]
.ret2
	PLB
	PLP
	PLA
	STA !textIsAppearing
	
	BRA .back
	
.runNMI	
	LDA !actorNMI1,x
	STA $00
	LDA !actorNMI2,x
	STA $01
	LDA !actorNMI3,x
	STA $02
	PHK
	PEA.w .ret3-1
	JML [$0000]
	JMP .back
.ret3

.quit
	RTL
}

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
print bytes," bytes of VWF rendering data."	
reset bytes	

freecode
AllCutsceneData1:

	
incsrc ActorIndices.asm


incsrc DocCroc.asm
incsrc MadamMau1.asm
incsrc MadamMau2.asm
incsrc Hindenbird.asm
incsrc Luigi.asm
incsrc Fish.asm
incsrc Toad.asm
incsrc Mario.asm
incsrc Truntec.asm
incsrc Dryad.asm
incsrc BarkerDuck.asm
incsrc Barrel.asm
incsrc Frank.asm
incsrc CutsceneBDoor.asm
incsrc DocCrocMonitor.asm
incsrc Intercom.asm
incsrc Bowser.asm
incsrc BowserChair.asm
incsrc Kamek.asm
incsrc Tanuki.asm
incsrc Norveg.asm

print bytes," bytes of actor data."
reset bytes	


incsrc CutsceneStrings.asm

print bytes," bytes of text/event data."
	
	
	
	
	
	




