Screen Fading

I know a few people have figured out how to get the partially existing screen fading code working, and I was wondering if anyone is willing to share now that the competition submissions are in.
(I know making a tutorial would have taken quite a bit of time away from working on submissions)

Since I am not using scrolling, I would like to implement a nice screen fade transition from one screen to another similar to the Troll Burner demo.
 

dale_coop

Moderator
Staff member
Personnaly, I made a AI script (monster action or End of action/animation), that will fade to black.
Here the script (thanks to drexegar for the first draft):
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for background pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDX #$00 
doFadeCurrentBckPal:
	LDA bckPal,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CMP #$10 ;; compares 10
	BCC + ;; if less than 10 skip to p1, if not continue below
	SEC ;; needs for subtraction
	SBC #$10 ;; subtract #$10
	STA bckPal,x ;; store it back into pallete
	JMP goNextBckPal;; jump to the next pal2
	+ 
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA bckPal,x ;; store it into pallete
goNextBckPal:
	INX	
	CPX #4
	BEQ goNextBckPal
	CPX #8
	BEQ goNextBckPal
	CPX #12
	BEQ goNextBckPal
	CPX #16
	BCC doFadeCurrentBckPal

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for sprite pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDX #$00 
doFadeCurrentSpritePal:
	LDA spritePalFade,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CMP #$10 ;; compares 10
	BCC + ;; if less than 10 skip to p1, if not continue below
	SEC ;; needs for subtraction
	SBC #$10 ;; subtract #$10
	STA spritePalFade,x ;; store it back into pallete
	JMP goNextSpritePal;; jump to the next pal2
	+ 
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA spritePalFade,x ;; store it into pallete
goNextSpritePal:
	INX	
	CPX #4
	BEQ goNextSpritePal
	CPX #8
	BEQ goNextSpritePal
	CPX #12
	BEQ goNextSpritePal
	CPX #16
	BCC doFadeCurrentSpritePal



	;; Important you need to load a non 0 number into updatePalettes and do a RTS so it can work.
	;; If you want to do palletes use "spritePalFade" instead of "bckPal"
	LDA #$01
	STA updatePalettes
RTS
 

drexegar

Member
dale_coop said:
Personnaly, I made a AI script (monster action or End of action/animation), that will fade to black.
Here the script (thanks to drexegar for the first draft):


I just realized that CPX means compare x right? And you did a INX increase X loop which I just learned a few days ago and use CPX to skip the other numbers.

I wanted to do a fade in but I dont want to have to store 20 palletes manually, no documentation so I do not know where the current pallete is stored in memory for backgrounds and sprites.

all I would have to do is just first grab the vaules(whereever they are stored), subtract 10, 20, and 30 depending on its 10 vaule so all the colors can be the darkest shade then add 10 to each color until it matches the stored pallete and then stops.

I cant do it cause I have no clue how to call up the pallet's STORED vaules for comparing.

Do you know where it is dale?
 

dale_coop

Moderator
Staff member
bckPal And spriteFadePal are the palettes currently loaded (bckPal the screen’s ones 4 palettes of 4 colors... and spriteFadePal are your gameobjects/monsters ones, 4 palettes of 4 colors too).
 

drexegar

Member
dale_coop said:
bckPal And spriteFadePal are the palettes currently loaded (bckPal the screen’s ones 4 palettes of 4 colors... and spriteFadePal are your gameobjects/monsters ones, 4 palettes of 4 colors too).

yeah but what happens when you change them, I can't get the originals screen colors, unless I store all 26 colors before I attempt a fade in.There is no way to tell the nes to stop raising the color, unless it knows when to stop, I wonder how fade in can work in dimension shift, thorugh nesmaker is must be reading from some sort of table data being stored.
 

Mugi

Member
drexegar said:
I wonder how fade in can work in dimension shift, thorugh nesmaker is must be reading from some sort of table data being stored.

the fade in dimension shift works basically just how it's laid out in the handlefade.asm that is present in the GameEngineData\Routines\Basic\System\HandleFades.asm
all i did to it was repair the missing pieces of this code and put it back in use.

using this file requires you to restore an include to the handlefades.asm into the bank data, restoring all the ZeroPage variables that are commented out (include the handlefades asm and compile the game to see all the errors it spits out, those will tell you which variables you need to enable for it.)

in addition to that, few changes had to be made to the handlefades code itself, and the "load new data" function of the code is commented out because it is non-functioning (i dont use it so dont ask.) in addition to that, handlepalettes needs some changes to accomondate to the working of the fades.

after that, using the macros for fade_darken and fade_lighten can be used to fade the screen in and out.

there is no dark sorcery involved in the way my game does fading. it's all the code joe wrote a long time ago for nesmaker, and in all likelihood, also the same code that was used for trollburner.


edit: i would like to point out that while i am using this code now since it works, it's terribly space-inefficient and a better way would propably just to write something more specific to one's own game, than to attempt to fix the handlefades.asm

for starters, this eats A LOT of zeropage (i literally have 2 bytes left because of this clusterf** of a code) and the whole deal with having to litter the macro to fade in and out everywhere eats tons and tons of space from bank14.
assuming you just want a fadeout/fadein for screen transitions, you're far better off writing something much more compact, and hooking it into handlescreenloads to make it play nice.

the way joe's code is designed, is the typical nesmaker code, as such, it is VERY versatile on how it can be used, but this always comes with the heavy price of extremely high resource usage. (also, it doesnt fade sprites, that's broken too, i didnt fix it since i dont want to fade sprites, so i just left it be.)
 
dale_coop said:
Personnaly, I made a AI script (monster action or End of action/animation), that will fade to black.
Here the script (thanks to drexegar for the first draft):
---

Something strange, I cannot seem to use this script as an end of action/animation script.
From nothing, if I add the script exactly as it is and assign it to a blank end action, I get 'label already defined errors'

I looked it up in demo.txt and it seems to be throwing the error because it .includes the script twice, once for end actions and one for end animations.
That doesn't make sense though, because other end actions use labels and it doesn't cause an issue.

Edit: I got it working as a normal AI action, just wanted to mention that above ^^ Not sure why it causes that error.

I'm going to experiment with this and see if I can get similar code working for screen transitions.
 
Progress:

I wrote a script that just does fading in/out. Meant for transitioning between screens.
When assigned to a monster action, it works fine. (Change this script by removing the RTS at the end and setting the animation speed to 1 to get it to work as monster action)
It fades out perfectly, and I think it fades in too (it happens too fast to tell, still working on that.) How it works is it toggles
I am trying to make it a subroutine so I can make the fades happen whenever you touch a screen edge.
What happens though is that the emulator crashes :\

Here is my code so far:
Code:
;;Fade Screen and Sprites
;; Original Fade To Black Code by Dale_Coop
;; Modifications by ChroniclerOfLegends

;; Must Add two variables to ZP RAM and 1 user variable:
;fadeStep - user variable initialized to 3
;bckPalTmp - 16 bytes
;sprPalTmp - 16 bytes

Screen_Transition:

;; Check to see if we need to fade out or in
	LDA fadeStep
	CMP #$00 ;; Screen is not faded out
	BEQ FadeToBlack
	;; Backup palettes
	LDX #$00
	doPalBackup:
		LDA bckPal,x
		STA bckPalTmp,x
		LDA spritePalFade,x
		STA sprPalTmp,x
	getNextPalToBackup:
		INX	
		CPX #4
		BEQ getNextPalToBackup
		CPX #8
		BEQ getNextPalToBackup
		CPX #12
		BEQ getNextPalToBackup
		CPX #16
		BCC doPalBackup
	JMP FadeBackIn

;; The screen is not faded, so we need to fade it out.
FadeToBlack:
	LDA fadeStep
	CMP #$03
	BNE +
	JMP doneWithFades
  +:
	JSR FadeOutOneStep
	JMP FadeToBlack
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for background pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FadeOutOneStep:

	LDX #$00 
doFadeCurrentBckPal:
	LDA bckPal,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CMP #$10 ;; compares 10
	BCC + ;; if less than 10 skip to p1, if not continue below
	SEC ;; needs for subtraction
	SBC #$10 ;; subtract #$10
	STA bckPal,x ;; store it back into pallete
	JMP goNextBckPal;; jump to the next pal2
	+ 
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA bckPal,x ;; store it into pallete
goNextBckPal:
	INX	
	CPX #4
	BEQ goNextBckPal
	CPX #8
	BEQ goNextBckPal
	CPX #12
	BEQ goNextBckPal
	CPX #16
	BCC doFadeCurrentBckPal

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for sprite pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDX #$00 
doFadeCurrentSpritePal:
	LDA spritePalFade,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CMP #$10 ;; compares 10
	BCC + ;; if less than 10 skip to p1, if not continue below
	SEC ;; needs for subtraction
	SBC #$10 ;; subtract #$10
	STA spritePalFade,x ;; store it back into pallete
	JMP goNextSpritePal;; jump to the next pal2
	+ 
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA spritePalFade,x ;; store it into pallete
goNextSpritePal:
	INX	
	CPX #4
	BEQ goNextSpritePal
	CPX #8
	BEQ goNextSpritePal
	CPX #12
	BEQ goNextSpritePal
	CPX #16
	BCC doFadeCurrentSpritePal



	;; Important you need to load a non 0 number into updatePalettes and do a RTS so it can work.
	;; If you want to do palletes use "spritePalFade" instead of "bckPal"
	LDA #$01
	STA updatePalettes
	
	INC fadeStep
	
	RTS

;;---------------------------------------------------------------------------------------------------------;;

;;;; The Screen was already faded out, so we need to fade it back in now.
FadeBackIn:
	;;Set the screen and sprites to black
	JSR SetPaletteBlack
	
fadeBackInLoop:
	LDA fadeStep
	CMP #$00
	BNE +
	JMP doneWithFades
  +:
	JSR FadeInOneStep
	JMP fadeBackInLoop
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for background pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FadeInOneStep:

	LDX #$00 
doFadeCurrentBckPalIn:
	LDA bckPal,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CLC
	ADC #$10 ;; Add #$10
	CMP bckPalTmp,x
	BCC +
	LDA bckPalTmp,x
  +:
	STA bckPal,x ;; store it back into pallete
	JMP goNextBckPalIn;; jump to the next pal2
goNextBckPalIn:
	INX	
	CPX #4
	BEQ goNextBckPalIn
	CPX #8
	BEQ goNextBckPalIn
	CPX #12
	BEQ goNextBckPalIn
	CPX #16
	BCC doFadeCurrentBckPalIn

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for sprite pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDX #$00 
doFadeCurrentSpritePalIn:
	LDA spritePalFade,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CLC
	ADC #$10 ;; add #$10
	CMP sprPalTmp,x
	BCC +
	LDA sprPalTmp,x
  +:
	STA spritePalFade,x ;; store it back into pallete
	JMP goNextSpritePalIn;; jump to the next pal2
goNextSpritePalIn:
	INX	
	CPX #4
	BEQ goNextSpritePalIn
	CPX #8
	BEQ goNextSpritePalIn
	CPX #12
	BEQ goNextSpritePalIn
	CPX #16
	BCC doFadeCurrentSpritePalIn


	;; Important you need to load a non 0 number into updatePalettes and do a RTS so it can work.
	;; If you want to do palletes use "spritePalFade" instead of "bckPal"
	LDA #$01
	STA updatePalettes
	
	DEC fadeStep
	
	RTS
	
	
; Set Palette Black Subroutine
SetPaletteBlack:
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA bckPal,x ;; store it into pallete
	STA spritePalFade,x ;; store it into pallete
	LDA #$01
	STA updatePalettes
	RTS
	
	
doneWithFades:
	RTS

Edit: I also don't know if there is a more resource-friendly way of getting your original palettes back when fading in.
I had to use 32 bytes for the temporary palette data :(
 

drexegar

Member
chronicleroflegends said:
Progress:

I wrote a script that just does fading in/out. Meant for transitioning between screens.
When assigned to a monster action, it works fine. (Change this script by removing the RTS at the end and setting the animation speed to 1 to get it to work as monster action)
It fades out perfectly, and I think it fades in too (it happens too fast to tell, still working on that.) How it works is it toggles
I am trying to make it a subroutine so I can make the fades happen whenever you touch a screen edge.
What happens though is that the emulator crashes :\

Here is my code so far:
Code:
;;Fade Screen and Sprites
;; Original Fade To Black Code by Dale_Coop
;; Modifications by ChroniclerOfLegends

;; Must Add two variables to ZP RAM and 1 user variable:
;fadeStep - user variable initialized to 3
;bckPalTmp - 16 bytes
;sprPalTmp - 16 bytes

Screen_Transition:

;; Check to see if we need to fade out or in
	LDA fadeStep
	CMP #$00 ;; Screen is not faded out
	BEQ FadeToBlack
	;; Backup palettes
	LDX #$00
	doPalBackup:
		LDA bckPal,x
		STA bckPalTmp,x
		LDA spritePalFade,x
		STA sprPalTmp,x
	getNextPalToBackup:
		INX	
		CPX #4
		BEQ getNextPalToBackup
		CPX #8
		BEQ getNextPalToBackup
		CPX #12
		BEQ getNextPalToBackup
		CPX #16
		BCC doPalBackup
	JMP FadeBackIn

;; The screen is not faded, so we need to fade it out.
FadeToBlack:
	LDA fadeStep
	CMP #$03
	BNE +
	JMP doneWithFades
  +:
	JSR FadeOutOneStep
	JMP FadeToBlack
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for background pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FadeOutOneStep:

	LDX #$00 
doFadeCurrentBckPal:
	LDA bckPal,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CMP #$10 ;; compares 10
	BCC + ;; if less than 10 skip to p1, if not continue below
	SEC ;; needs for subtraction
	SBC #$10 ;; subtract #$10
	STA bckPal,x ;; store it back into pallete
	JMP goNextBckPal;; jump to the next pal2
	+ 
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA bckPal,x ;; store it into pallete
goNextBckPal:
	INX	
	CPX #4
	BEQ goNextBckPal
	CPX #8
	BEQ goNextBckPal
	CPX #12
	BEQ goNextBckPal
	CPX #16
	BCC doFadeCurrentBckPal

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for sprite pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDX #$00 
doFadeCurrentSpritePal:
	LDA spritePalFade,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CMP #$10 ;; compares 10
	BCC + ;; if less than 10 skip to p1, if not continue below
	SEC ;; needs for subtraction
	SBC #$10 ;; subtract #$10
	STA spritePalFade,x ;; store it back into pallete
	JMP goNextSpritePal;; jump to the next pal2
	+ 
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA spritePalFade,x ;; store it into pallete
goNextSpritePal:
	INX	
	CPX #4
	BEQ goNextSpritePal
	CPX #8
	BEQ goNextSpritePal
	CPX #12
	BEQ goNextSpritePal
	CPX #16
	BCC doFadeCurrentSpritePal



	;; Important you need to load a non 0 number into updatePalettes and do a RTS so it can work.
	;; If you want to do palletes use "spritePalFade" instead of "bckPal"
	LDA #$01
	STA updatePalettes
	
	INC fadeStep
	
	RTS

;;---------------------------------------------------------------------------------------------------------;;

;;;; The Screen was already faded out, so we need to fade it back in now.
FadeBackIn:
	;;Set the screen and sprites to black
	JSR SetPaletteBlack
	
fadeBackInLoop:
	LDA fadeStep
	CMP #$00
	BNE +
	JMP doneWithFades
  +:
	JSR FadeInOneStep
	JMP fadeBackInLoop
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for background pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FadeInOneStep:

	LDX #$00 
doFadeCurrentBckPalIn:
	LDA bckPal,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CLC
	ADC #$10 ;; Add #$10
	CMP bckPalTmp,x
	BCC +
	LDA bckPalTmp,x
  +:
	STA bckPal,x ;; store it back into pallete
	JMP goNextBckPalIn;; jump to the next pal2
goNextBckPalIn:
	INX	
	CPX #4
	BEQ goNextBckPalIn
	CPX #8
	BEQ goNextBckPalIn
	CPX #12
	BEQ goNextBckPalIn
	CPX #16
	BCC doFadeCurrentBckPalIn

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do fading to black for sprite pals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDX #$00 
doFadeCurrentSpritePalIn:
	LDA spritePalFade,x ;; loads joes pallete for background (0-3) (4-7) (8-11) (12-15) 4,8,and 12 is not needed since its the same bgcolor as 0
	CLC
	ADC #$10 ;; add #$10
	CMP sprPalTmp,x
	BCC +
	LDA sprPalTmp,x
  +:
	STA spritePalFade,x ;; store it back into pallete
	JMP goNextSpritePalIn;; jump to the next pal2
goNextSpritePalIn:
	INX	
	CPX #4
	BEQ goNextSpritePalIn
	CPX #8
	BEQ goNextSpritePalIn
	CPX #12
	BEQ goNextSpritePalIn
	CPX #16
	BCC doFadeCurrentSpritePalIn


	;; Important you need to load a non 0 number into updatePalettes and do a RTS so it can work.
	;; If you want to do palletes use "spritePalFade" instead of "bckPal"
	LDA #$01
	STA updatePalettes
	
	DEC fadeStep
	
	RTS
	
	
; Set Palette Black Subroutine
SetPaletteBlack:
	LDA #$0F ;; set accumalator to 0F which is (black)
	STA bckPal,x ;; store it into pallete
	STA spritePalFade,x ;; store it into pallete
	LDA #$01
	STA updatePalettes
	RTS
	
	
doneWithFades:
	RTS

Edit: I also don't know if there is a more resource-friendly way of getting your original palettes back when fading in.
I had to use 32 bytes for the temporary palette data :(

My brain hurts trying to figure some of this stuff, but I see you still have to store temporary data, so the only work around, which only works for a few people, my game uses 3 equal brightness across every pallete, so I just use a formula that picks the correct brightness assuming brightness of the pallete matches, I only need 1 variable to control this, but then I have to work around any levels I use for pallete swapping so a good 2 more would work just for those.
 
Mugi said:
drexegar said:
I wonder how fade in can work in dimension shift, thorugh nesmaker is must be reading from some sort of table data being stored.

the fade in dimension shift works basically just how it's laid out in the handlefade.asm that is present in the GameEngineData\Routines\Basic\System\HandleFades.asm
all i did to it was repair the missing pieces of this code and put it back in use.

using this file requires you to restore an include to the handlefades.asm into the bank data, restoring all the ZeroPage variables that are commented out (include the handlefades asm and compile the game to see all the errors it spits out, those will tell you which variables you need to enable for it.)

in addition to that, few changes had to be made to the handlefades code itself, and the "load new data" function of the code is commented out because it is non-functioning (i dont use it so dont ask.) in addition to that, handlepalettes needs some changes to accomondate to the working of the fades.

after that, using the macros for fade_darken and fade_lighten can be used to fade the screen in and out.

there is no dark sorcery involved in the way my game does fading. it's all the code joe wrote a long time ago for nesmaker, and in all likelihood, also the same code that was used for trollburner.


edit: i would like to point out that while i am using this code now since it works, it's terribly space-inefficient and a better way would propably just to write something more specific to one's own game, than to attempt to fix the handlefades.asm

for starters, this eats A LOT of zeropage (i literally have 2 bytes left because of this clusterf** of a code) and the whole deal with having to litter the macro to fade in and out everywhere eats tons and tons of space from bank14.
assuming you just want a fadeout/fadein for screen transitions, you're far better off writing something much more compact, and hooking it into handlescreenloads to make it play nice.

the way joe's code is designed, is the typical nesmaker code, as such, it is VERY versatile on how it can be used, but this always comes with the heavy price of extremely high resource usage. (also, it doesnt fade sprites, that's broken too, i didnt fix it since i dont want to fade sprites, so i just left it be.)

Taking another shot at this, my custom script is not currently playing nice so I was taking another shot at fixing what was there. I managed to squeeze those variables into my zero page ram (with no room to spare), restore the.include for the fades, and place the macros. No errors, but no fades either. I saw that you said handlepalletes needs fixes too. Silly question but where is handlepalletes? I cannot find that script anywhere.
 

Mugi

Member
GameEngineData\Routines\Basic\DataLoadScripts\LoadPalettes.asm
needs some extra pokery for getting the fade to play nice. (im assuming this stuff was just modified after the fade stuff got disabled and somewhere down the line the script just would stop working.)

i can see why joe killed it off seeing the ridiculous amount of space it eats.
well oh well, here's the scripts i use for this. No idea how these will behave in games other than DS though (there's nothing left of the original load routines in DS anymore.)

loadpalettes.asm
Code:
	LDA updatePalettes
	BEQ LoadPalettesEnd
	LDA #$3f
	STA $2006
	LDA #$10
	STA $2006
	LDX #$00
LoadSpritePal:
	LDA spritePalFade,x
	STA $2007
	INX
	CPX #$10
	BNE LoadSpritePal
	
;; load backgrounds last so that the *background* color gets overwritten correctly	
	
	LDA $2002
	LDA #$3F
	STA $2006
	LDA #$00
	STA $2006
	LDX #$00
LoadBackgroundPal:
	LDA updatePalettes
	CMP #$02
	BEQ ldFadePal
	LDA bckPal,x
	JMP doPalStore
ldFadePal:
	LDA bckPalFade,x
doPalStore:
	STA $2007
	INX
	CPX #$10
	BNE LoadBackgroundPal
	
	LDA #$00
	STA updatePalettes
LoadPalettesEnd:

handlefades.asm

Code:
;; prior to this routine being called, the macro
;; needs info on the timer, so that it can appropriately set it to start with.

HandleFadeLevels:
	LDA fadeByte
	BNE doHandleFadeLevels
	RTS

doHandleFadeLevels:
	LDX #$00 ; start loop

LoadBackgroundPal_FADES:
	CPX #$08
	BCC palValueIsLessThan8
	LDA bitwiseLut,x
	AND fadeSelect_bck+1
	JMP checkThisPalVal

palValueIsLessThan8:
	LDA bitwiseLut,x
	AND fadeSelect_bck

checkThisPalVal:
	BNE getFadedAmountForThisValue 
	LDA bckPal,x
	JMP gotPalValue

getFadedAmountForThisValue:
	LDA fadeLevel
	ASL
	ASL
	ASL
	ASL
	CLC
	ADC bckPal,x
	BPL palValueIsGreaterThanZero
	;;pal value is less than zero.
	;;maintain the actual value for fades, but
	;;anything less than zero in a signed value
	;;draws #$0f (black).
	;; So actual buffer value is in tact for fade math,
	;; but keeps the appearance of fading to black.
	LDA #$0f
	JMP gotPalValue

palValueIsGreaterThanZero:
	CMP #$3c ;; is it as light as it can possibly be?  if so, make it white.
	BCC palValueIsLessThan3c
	LDA #$30

palValueIsLessThan3c:
	CMP #$0D
	BNE gotPalValue
	LDA #$0F

gotPalValue:
	STA bckPalFade,x
	INX
	CPX #$10
	BNE LoadBackgroundPal_FADES
	LDA #$02
	STA updatePalettes
	RTS


HandleFades:
	LDA fadeByte
	BNE doHandleFades
	RTS
doHandleFades:
	;uses fadeByte	
		; 7 = fade is active
		; 6 = fade darker / fade lighter ;; 0 = fade to dark color, 1 = fade to light color
		;_____________________________
		; 5 = LOOP
		; 4 = loading data
		; 3 = fade in
				;; now that we're doing this way, we can almost certainly
				;; combine this and just have one bit that determines if data is
				;; being loaded, to put fade on pause.
		;______________________________
		; 2 = "snap" fade out. Instant black or instant white, immediate to full step fade out.
			;whether black or white is determined by bit 6
		; 10 = how many steps to fade? - only 4 possible values - all the way out is 5.
		
		
	
	;uses fadeSpeed.
		;7 = load new data? 0=no, 1=yes
		;6 = does "fade out"? 0=no, 1=yes
			;; fade out in this case doesn't necessarily mean 'gets darker'.
			;; it just means ping pongs to the fade in script before
			;; returning to normal game.
		;5 = fade sprites? 0=no, 1=yes.
			;; if no, just the background will fade.
		;43210 = fade speed, *3 (asl x 3)
		
	;; checkFadeTimer
	DEC fadeTimer
	BEQ dontKeepRunningFadeTimer
	JMP keepRunningFadeTimer
dontKeepRunningFadeTimer:
	;;fade timer is up.  First thing to do is reset the timer.
	LDA fadeSpeed
	AND #%00011111
	ASL
	ASL
	STA fadeTimer
	LDA fadeByte
	AND #%01000000 ; is this fade to light or dark?
	BNE fadeToWhite
	;;; fade to black
	LDA fadeLevel
	sec
	sbc #$1
	JMP gotNewPalVal
fadeToWhite:
	LDA fadeLevel
	clc
	adc #$1
gotNewPalVal:
	STA fadeLevel
	BPL positiveValueForFadeLevel
	;; negative value for fade level
	EOR #$ff
	CLC
	ADC #$01

positiveValueForFadeLevel:
	STA temp
	;; first, check if this is looper.
	;; if it is not a looper (pulsing type of fade), then
	;; if this fade level is zero, it should *stop* fading. 
	;; this is the most standard type of fade...fade out, do things, fade back in to 0.
	LDA fadeLevel
	CLC
	ADC #$05
	BEQ stopFading 
	LDA fadeLevel
	SEC
	SBC #$05
	BEQ stopFading
	JMP nevermindCheckingForPalLoop
	
stopFading:	
	;; it is at zero
	LDA fadeByte
	AND #%00100000 ;; is it a looper?
	BEQ checkForPalLoop
	JMP nevermindCheckingForPalLoop ;; yes, it is a looper
checkForPalLoop:
	;;no, it is not a looper
	LDA #$00
	STA fadeByte

	;;;; check for load data first
	;;=================
	
	LDA fadeSpeed
	AND #%10000000 ;; this is the bit, in the byte, that sees if we need to load data
	BNE needToLoadData 
	JMP noNeedToLoadData
needToLoadData:
	;;; yes, we need to load new data.


	;LoadChrData #GraphicsBank01, #$10, #$40, #$0, BckChr00
	;LoadBackgroundPalette BckPal00
	
	;;load the pointer info
	;LDA currentBank
	;STA prevBank
	;LDY #$16
	;JSR bankswitchY
	;;; now we can get the offset from the screen tables.
	;;;;;;; if type is 0, check NameTablePointers
		;;; if type is 1, check NameTablePointers_Map1
		;;; if type is 2, check NameTablePointers_Map2
	;LDA newScreen	
	;ASL			
	;TAX
	;LDA NameTablePointers_Map1+0,X
	;STA temp16
	;LDA NameTablePointers_Map2+1,X
	;STA temp16+1
	
	;LoadNametableData #$01, NT_Rm50, #$01, #$80
	;LoadAttributeData #$01, AT_Rm50, #$38, #$08

	;LDY prevBank
	;JSR bankswitchY
	
	LDA #$00
	STA fadeLevel
	LDA #$00
	STA fadeByte
	
noNeedToLoadData:

	;; Check to see if we load data during fade
	;;====================
	
	JMP doneWithFade
nevermindCheckingForPalLoop:
	
	LDA fadeByte
	AND #%00000011
	CMP temp
	BNE doneWithFade ;; haven't reached the end yet.
	;;; we've reached the last step
	;;; we need to check to see if that's it, or if it should pingpong background

	;; now check to see if we're done or we're going to pingpong
	LDA fadeSpeed
	AND #%01000000 ;; does it pingpong?
	BNE doPingPongFade
	LDA #$00
	STA fadeByte
	LDA #$01
	STA updatePalettes
	JMP doneWithFade
doPingPongFade:
	LDA fadeLevel
	BMI changeToFadeIn
	;; change to fade out
	LDA fadeByte
	AND #%10111111
	JMP pingPongDone
changeToFadeIn:
	LDA fadeByte
	ORA #%01000000
pingPongDone:
	STA fadeByte
	
	
dontChangeThisValue:

	
keepRunningFadeTimer:

doneWithFade:
	RTS

after setting these up along with the required ZPvars, you may now call fade using beginfade macro.

now, some parts of this script were left broken, simply because of .....reasons. so not everything from it does work in this state.

you MUST NOT use modes other than what is stated below (they work but produce unwanted effects.)
you also MUST ALWAYS call FADE_LIGHTEN after using FADE_DARKEN to restore the screen, othervise you will eventually run into issues.

to fade out, use:
BeginFade FADE_DARKEN, #$03, #$00, #$00, FADE_AND_HOLD, FADE_ONCE, #%01110111, #%01110111

to fade in AFTER fading out, use:
BeginFade FADE_LIGHTEN, #$03, #$00, #$00, FADE_AND_HOLD, FADE_ONCE, #%01110111, #%01110111

you may toy with the speed and palette attributes, but changing the fade_and_hold or fade_once will propably break it at this state.
also, sprite fading doesnt work, i never looked into it since i didnt want to use it.

on a side note, i fixed the issue with fading out the "illegal" gray color that joe decided we cant use because it breaks fading, so now you can use the missing dark gray and it fades out and in just fine.

on another side note, it is possible to just throw this in handlescreenloads.asm and have it fade screen transitions all the time, but trust me, you dont really want to do that. Especially if you dont have scrolling,
waiting 4-5 seconds between every screen move is not fun after 5 minutes, as cool as it looks.

there is also the fact that these macros are not really small, so repeatedly littering them into every function eats tons of space from bank14 really fast.
the way i do this in DS, is that i have it set on warp tiles, and in addition to that, i have a custom handler that checks newscreen on screen transitions and hardcoded screen numbers (stage changes) are triggering it.
you might want to do something similar to your game to reduce using unnecessary copies of the macro.


just for a third side note, i didn't actually sit on this code just to be an asshat or whatever (im pretty sure people cursed me to hell for not sharing) i just really think this shouldn't be used, and it's bending a rewrite on my own project too
the way this fader works is just insane, you literally spend half of your ZP on this code alone. but since it looks like some people REALLY want to use it, here it is. Godspeed with resource management.
 
Thanks Mugi

No worries, I totally understand the reasons you were reluctant to release this. I can definitely see that its going to be a tough compromise between nice looking fades and the resource cost associated with it. I am more curious to learn how it works than to use it as is in my game. (Those variables literally take every last byte of my ZP ram)
Hoping to play around with it enough to learn how to do what you suggested: Make something much more game-specific and less resource heavy.
 

Mugi

Member
i will share mine once i get it rewritten assuming it does any better in the resource department too, but for now it's on low priority, for me the scroll is taking the attention until we get it just right.
that said, the amount of optimizing that needs might force me to actually abandon this code in order to get ZP back into usable state :p
 

DanielT1985

Member
Mugi said:
GameEngineData\Routines\Basic\DataLoadScripts\LoadPalettes.asm
needs some extra pokery for getting the fade to play nice. (im assuming this stuff was just modified after the fade stuff got disabled and somewhere down the line the script just would stop working.)

i can see why joe killed it off seeing the ridiculous amount of space it eats.
well oh well, here's the scripts i use for this. No idea how these will behave in games other than DS though (there's nothing left of the original load routines in DS anymore.)

loadpalettes.asm
Code:
	LDA updatePalettes
	BEQ LoadPalettesEnd
	LDA #$3f
	STA $2006
	LDA #$10
	STA $2006
	LDX #$00
LoadSpritePal:
	LDA spritePalFade,x
	STA $2007
	INX
	CPX #$10
	BNE LoadSpritePal
	
;; load backgrounds last so that the *background* color gets overwritten correctly	
	
	LDA $2002
	LDA #$3F
	STA $2006
	LDA #$00
	STA $2006
	LDX #$00
LoadBackgroundPal:
	LDA updatePalettes
	CMP #$02
	BEQ ldFadePal
	LDA bckPal,x
	JMP doPalStore
ldFadePal:
	LDA bckPalFade,x
doPalStore:
	STA $2007
	INX
	CPX #$10
	BNE LoadBackgroundPal
	
	LDA #$00
	STA updatePalettes
LoadPalettesEnd:

handlefades.asm

Code:
;; prior to this routine being called, the macro
;; needs info on the timer, so that it can appropriately set it to start with.

HandleFadeLevels:
	LDA fadeByte
	BNE doHandleFadeLevels
	RTS

doHandleFadeLevels:
	LDX #$00 ; start loop

LoadBackgroundPal_FADES:
	CPX #$08
	BCC palValueIsLessThan8
	LDA bitwiseLut,x
	AND fadeSelect_bck+1
	JMP checkThisPalVal

palValueIsLessThan8:
	LDA bitwiseLut,x
	AND fadeSelect_bck

checkThisPalVal:
	BNE getFadedAmountForThisValue 
	LDA bckPal,x
	JMP gotPalValue

getFadedAmountForThisValue:
	LDA fadeLevel
	ASL
	ASL
	ASL
	ASL
	CLC
	ADC bckPal,x
	BPL palValueIsGreaterThanZero
	;;pal value is less than zero.
	;;maintain the actual value for fades, but
	;;anything less than zero in a signed value
	;;draws #$0f (black).
	;; So actual buffer value is in tact for fade math,
	;; but keeps the appearance of fading to black.
	LDA #$0f
	JMP gotPalValue

palValueIsGreaterThanZero:
	CMP #$3c ;; is it as light as it can possibly be?  if so, make it white.
	BCC palValueIsLessThan3c
	LDA #$30

palValueIsLessThan3c:
	CMP #$0D
	BNE gotPalValue
	LDA #$0F

gotPalValue:
	STA bckPalFade,x
	INX
	CPX #$10
	BNE LoadBackgroundPal_FADES
	LDA #$02
	STA updatePalettes
	RTS


HandleFades:
	LDA fadeByte
	BNE doHandleFades
	RTS
doHandleFades:
	;uses fadeByte	
		; 7 = fade is active
		; 6 = fade darker / fade lighter ;; 0 = fade to dark color, 1 = fade to light color
		;_____________________________
		; 5 = LOOP
		; 4 = loading data
		; 3 = fade in
				;; now that we're doing this way, we can almost certainly
				;; combine this and just have one bit that determines if data is
				;; being loaded, to put fade on pause.
		;______________________________
		; 2 = "snap" fade out. Instant black or instant white, immediate to full step fade out.
			;whether black or white is determined by bit 6
		; 10 = how many steps to fade? - only 4 possible values - all the way out is 5.
		
		
	
	;uses fadeSpeed.
		;7 = load new data? 0=no, 1=yes
		;6 = does "fade out"? 0=no, 1=yes
			;; fade out in this case doesn't necessarily mean 'gets darker'.
			;; it just means ping pongs to the fade in script before
			;; returning to normal game.
		;5 = fade sprites? 0=no, 1=yes.
			;; if no, just the background will fade.
		;43210 = fade speed, *3 (asl x 3)
		
	;; checkFadeTimer
	DEC fadeTimer
	BEQ dontKeepRunningFadeTimer
	JMP keepRunningFadeTimer
dontKeepRunningFadeTimer:
	;;fade timer is up.  First thing to do is reset the timer.
	LDA fadeSpeed
	AND #%00011111
	ASL
	ASL
	STA fadeTimer
	LDA fadeByte
	AND #%01000000 ; is this fade to light or dark?
	BNE fadeToWhite
	;;; fade to black
	LDA fadeLevel
	sec
	sbc #$1
	JMP gotNewPalVal
fadeToWhite:
	LDA fadeLevel
	clc
	adc #$1
gotNewPalVal:
	STA fadeLevel
	BPL positiveValueForFadeLevel
	;; negative value for fade level
	EOR #$ff
	CLC
	ADC #$01

positiveValueForFadeLevel:
	STA temp
	;; first, check if this is looper.
	;; if it is not a looper (pulsing type of fade), then
	;; if this fade level is zero, it should *stop* fading. 
	;; this is the most standard type of fade...fade out, do things, fade back in to 0.
	LDA fadeLevel
	CLC
	ADC #$05
	BEQ stopFading 
	LDA fadeLevel
	SEC
	SBC #$05
	BEQ stopFading
	JMP nevermindCheckingForPalLoop
	
stopFading:	
	;; it is at zero
	LDA fadeByte
	AND #%00100000 ;; is it a looper?
	BEQ checkForPalLoop
	JMP nevermindCheckingForPalLoop ;; yes, it is a looper
checkForPalLoop:
	;;no, it is not a looper
	LDA #$00
	STA fadeByte

	;;;; check for load data first
	;;=================
	
	LDA fadeSpeed
	AND #%10000000 ;; this is the bit, in the byte, that sees if we need to load data
	BNE needToLoadData 
	JMP noNeedToLoadData
needToLoadData:
	;;; yes, we need to load new data.


	;LoadChrData #GraphicsBank01, #$10, #$40, #$0, BckChr00
	;LoadBackgroundPalette BckPal00
	
	;;load the pointer info
	;LDA currentBank
	;STA prevBank
	;LDY #$16
	;JSR bankswitchY
	;;; now we can get the offset from the screen tables.
	;;;;;;; if type is 0, check NameTablePointers
		;;; if type is 1, check NameTablePointers_Map1
		;;; if type is 2, check NameTablePointers_Map2
	;LDA newScreen	
	;ASL			
	;TAX
	;LDA NameTablePointers_Map1+0,X
	;STA temp16
	;LDA NameTablePointers_Map2+1,X
	;STA temp16+1
	
	;LoadNametableData #$01, NT_Rm50, #$01, #$80
	;LoadAttributeData #$01, AT_Rm50, #$38, #$08

	;LDY prevBank
	;JSR bankswitchY
	
	LDA #$00
	STA fadeLevel
	LDA #$00
	STA fadeByte
	
noNeedToLoadData:

	;; Check to see if we load data during fade
	;;====================
	
	JMP doneWithFade
nevermindCheckingForPalLoop:
	
	LDA fadeByte
	AND #%00000011
	CMP temp
	BNE doneWithFade ;; haven't reached the end yet.
	;;; we've reached the last step
	;;; we need to check to see if that's it, or if it should pingpong background

	;; now check to see if we're done or we're going to pingpong
	LDA fadeSpeed
	AND #%01000000 ;; does it pingpong?
	BNE doPingPongFade
	LDA #$00
	STA fadeByte
	LDA #$01
	STA updatePalettes
	JMP doneWithFade
doPingPongFade:
	LDA fadeLevel
	BMI changeToFadeIn
	;; change to fade out
	LDA fadeByte
	AND #%10111111
	JMP pingPongDone
changeToFadeIn:
	LDA fadeByte
	ORA #%01000000
pingPongDone:
	STA fadeByte
	
	
dontChangeThisValue:

	
keepRunningFadeTimer:

doneWithFade:
	RTS

after setting these up along with the required ZPvars, you may now call fade using beginfade macro.

now, some parts of this script were left broken, simply because of .....reasons. so not everything from it does work in this state.

you MUST NOT use modes other than what is stated below (they work but produce unwanted effects.)
you also MUST ALWAYS call FADE_LIGHTEN after using FADE_DARKEN to restore the screen, othervise you will eventually run into issues.

to fade out, use:
BeginFade FADE_DARKEN, #$03, #$00, #$00, FADE_AND_HOLD, FADE_ONCE, #%01110111, #%01110111

to fade in AFTER fading out, use:
BeginFade FADE_LIGHTEN, #$03, #$00, #$00, FADE_AND_HOLD, FADE_ONCE, #%01110111, #%01110111

you may toy with the speed and palette attributes, but changing the fade_and_hold or fade_once will propably break it at this state.
also, sprite fading doesnt work, i never looked into it since i didnt want to use it.

on a side note, i fixed the issue with fading out the "illegal" gray color that joe decided we cant use because it breaks fading, so now you can use the missing dark gray and it fades out and in just fine.

on another side note, it is possible to just throw this in handlescreenloads.asm and have it fade screen transitions all the time, but trust me, you dont really want to do that. Especially if you dont have scrolling,
waiting 4-5 seconds between every screen move is not fun after 5 minutes, as cool as it looks.

there is also the fact that these macros are not really small, so repeatedly littering them into every function eats tons of space from bank14 really fast.
the way i do this in DS, is that i have it set on warp tiles, and in addition to that, i have a custom handler that checks newscreen on screen transitions and hardcoded screen numbers (stage changes) are triggering it.
you might want to do something similar to your game to reduce using unnecessary copies of the macro.


just for a third side note, i didn't actually sit on this code just to be an asshat or whatever (im pretty sure people cursed me to hell for not sharing) i just really think this shouldn't be used, and it's bending a rewrite on my own project too
the way this fader works is just insane, you literally spend half of your ZP on this code alone. but since it looks like some people REALLY want to use it, here it is. Godspeed with resource management.

1. I'm having problems with the loadpalettes asm code. "Routines\Basic\\DataLoadScripts\LoadPalettes.asm(30): Unknown label." with that line 30 code, for me, being "LDA bckPalFade,x"

2. Can this be used for the title screen only? I'm assuming so.
 

Mugi

Member
bckPalFade is a variable you will have to set to ZP, if you get an error with it, you have it disabled there,

as far as using this for only to fade a title screen, yeah, it can be used for that, but enabling this code only to fade the title screen and nothing else makes even less sense than to use this code for fades in general.
i highly advice you not to.

at any rate, i did state it already that this is simply how i use this on my game, and since my engine is a mess, i have no idea if this even works in the vanilla engine or not.
if it doesnt, then it's out of my hands really. (by all means it should but i really have no time to test it for that.)
 

mouse spirit

Well-known member
I am trying dale_coop's method but so far i cant get it to do anything.
I copy and pasted directly, and have the script in my last action animation end.
I have a monster that at the end of its action state 0, this code executes.

Edit: Fixed. Nesmaker Project Settings has too many places for end actions.May be my fault.
Or maybe i had it in a wrong script place/dont have my stuff named correctly.
 

Jonny

Well-known member
I set up @dale_coop version for background. I can only seem to get it to change once to a darker shade. I used it as a normal action, not and end action and have messed about with various settings. Should I be getting a drop down in shade until at 0F (black). Can't figure out what I'm doing wrong :cry:

Edit: Think I've got it. Changed end animation to 'repeat' instead of 'loop'. Not sure if that should be necessary but it worked.
 
Last edited:

mouse spirit

Well-known member
I set up @dale_coop version for background. I can only seem to get it to change once to a darker shade. I used it as a normal action, not and end action and have messed about with various settings. Should I be getting a drop down in shade until at 0F (black). Can't figure out what I'm doing wrong :cry:

Edit: Think I've got it. Changed end animation to 'repeat' instead of 'loop'. Not sure if that should be necessary but it worked.
Yeah if I remember , I had that issue. Sounds like you've figured it out.
 
Top Bottom