Add blinking "PRESS START" on the start screen [4.1.X Basic module]

dale_coop

Moderator
Staff member
Before the weekend starts... let's write a quick tutorial for adding a blinking PRESS START on our Start Screen.

StartScreen.gif


To do that, we will add a simple color palette cycling code (for the "Sub 3" palette, when the Start Screen is displayed).


1) Design your start screen and use the Sub 3 to write your PRESS START:

2020-05-01-18-09-39-NES-MAKER-4-1-5-Version-0x159-Basic-Adv-MST.png

(here I used the start screen graphics that come with the tutorial demos)


2) Go to the "Project Settings > User Variables" and create a new variable named "palettesCycleTimer" with an initial value "0":

2020-05-01-18-08-46-Project-Settings.png



3) Now, we will modify the script that is assigned to the "Handle Game Time" in your "Project Settings > Script Settings". I'd suggest to create a new script (or duplicate the ordinal), name it for example "HandleGameTimer_withColorsCycling.asm", with that code:
Code:
HandleGameTimer:
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; dale_coop : call of the palette cycling code (see the routine at the end of this script):
	JSR handlePaletteCycleTimer
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	DEC gameTimer
	BNE dontUpdateGameTimer
	LDA gameTimerLo
	CLC
	ADC #$01
	STA gameTimerLo
	LDA gameTimerHi
	ADC #$00
	STA gameTimerHi
;;;;;;;;;;;;;;;;;;;;;;;;;;; 
	;; DO WHATEVER READS OF THE GAMETIMER YOU MIGHT WANT HERE.
	JSR DoAlarm
;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDA #DayNightSpeed
	STA gameTimer
dontUpdateGameTimer:
	RTS
	
DoAlarm:
	
	;;; we're going to edge-load monsters one at a time if they are of edge type and are not active.
	LDX #$00
doLoadMonsterOnTimerLoop:

	LDA edgeLoaderInCue
	BEQ noEdgeMonstersInCue
	LDA currentBank
	STA prevBank
	LDY #$1C ;; data bank
	JSR bankswitchY
	JSR CreateTimedEdgeSpawner
	DEC edgeLoaderInCue
	LDY prevBank
	JSR bankswitchY

noEdgeMonstersInCue
	RTS
	
	
	
;;;;;;;;;;;;;;;;;;; PALETTES CYCLE  ;;;;;;;;;;;;;;;;;;;
handlePaletteCycleTimer:
    ;; On START SCREEN :
    LDA update_screen_details	;; special screen (start/win screens)?
    BNE endPaletteCycleTimer	;; if not skip the pal cycle code
    LDA currentScreen		;; screen 0 (the start one)?
    BNE endPaletteCycleTimer 	;; if not skip the pal cycle code 
  
  
    ;; from here, DO the palette cycle:
    LDA palettesCycleTimer
    BNE dontUpdatePaletteCycleTimer
    JSR pickPaletteToCycle
    LDA #$10  			;; HERE !!! the SPEED of the cycling
    STA palettesCycleTimer
dontUpdatePaletteCycleTimer:
    DEC palettesCycleTimer
endPaletteCycleTimer:
    RTS    
pickPaletteToCycle:
    LDA #$02    		;; HERE !!! the "Sub 3" palette
    ASL
    ASL 				;; these multiply your literal or variable with 4 so we can get the right offset for each palette in increments of 4.
    TAX
    LDY bckPal+1,x		;; pocket colour 1 in reg y
    LDA bckPal+2,x 
    STA bckPal+1,x		;; move colour 2 to 1
    LDA bckPal+3,x 
    STA bckPal+2,x		;; move colour 3 to 2
    TYA
    STA bckPal+3,x		;; move pocket (y) to 3
    LDA #$01
    STA updatePalettes	;; loading anything but zero into this value tells NESmaker it needs to update palettes.
    RTS


4) And assign that "HandleGameTimer_withColorsCycling.asm" script, to the Handle Game Timer:

2020-05-01-18-20-20-Project-Settings.png



VoilĂ , now you should have every tiles that use the Sub 3, having the colors cycling.

(Note: If you want something just like blinking... set just one color, and keep the other ones black)
 
Thank Dale ! I'm saving a link to this thread to come back to it when I'll need to start working on my start screen. and that tile palette cycling code might be useful in other context.
 

dale_coop

Moderator
Staff member
Yep, it could be use to do water/lava effect or rain... on normal screens.
(some NESmaker projects use that script for this purpose)
It requires a small modification on the code, but easy to do.
 

Jonny

Well-known member
Nice!!! Thank you. I was wondering how rain was done without having loads of animated sprites lol. This will come in very useful.
 

Atarath

Member
Dale, I was just about to dive into palette cycling and here you go posting a lovely tutorial. Thank you.
 

dale_coop

Moderator
Staff member
To illustrate another case scenario of palette cycle use...
For example, let's say I want to have it on certain screens (screens where I placed water tiles, or rain bg tiles, ... for example).

palCycling.gif


Just need a small modification in the code, the part where it checks when to do the palette cycle, around line 50.
There are a lot of possibilities for identifying which screens (all depends of your project).

You could test the screenType, for example, easy:
Code:
	LDA screenType
	CMP #255	;; screen type 255 ?
	BEQ doPaletteCycleTimer

Or, this time I will show you another way.... using the "Speed" screen property (property that is currently NOT used by the basic engine, so we're free to use it):
Code:
	LDA screenSpeed
	CMP #$01		;; "Medium" speed screens?
	BEQ doPaletteCycleTimer


2020-05-04-14-35-40-Screen-Details.png



The Handle Game Timer script would be:
Code:
HandleGameTimer:
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; dale_coop : call of the palette cycling code (see the routine at the end of this script):
	JSR handlePaletteCycleTimer
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	DEC gameTimer
	BNE dontUpdateGameTimer
	LDA gameTimerLo
	CLC
	ADC #$01
	STA gameTimerLo
	LDA gameTimerHi
	ADC #$00
	STA gameTimerHi
;;;;;;;;;;;;;;;;;;;;;;;;;;; 
	;; DO WHATEVER READS OF THE GAMETIMER YOU MIGHT WANT HERE.
	JSR DoAlarm
;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDA #DayNightSpeed
	STA gameTimer
dontUpdateGameTimer:
	RTS
	
DoAlarm:
	
	;;; we're going to edge-load monsters one at a time if they are of edge type and are not active.
	LDX #$00
doLoadMonsterOnTimerLoop:

	LDA edgeLoaderInCue
	BEQ noEdgeMonstersInCue
	LDA currentBank
	STA prevBank
	LDY #$1C ;; data bank
	JSR bankswitchY
	JSR CreateTimedEdgeSpawner
	DEC edgeLoaderInCue
	LDY prevBank
	JSR bankswitchY

noEdgeMonstersInCue
	RTS
	
	
	
;;;;;;;;;;;;;;;;;;; PALETTES CYCLE  ;;;;;;;;;;;;;;;;;;;
handlePaletteCycleTimer:
    ;; Pal cycling on START SCREEN :
    LDA update_screen_details	;; special screen (start/win screens)?
    BNE +						;; if not skip the pal cycle code
    LDA currentScreen		;; screen 0 (the start one)?
    BEQ doPaletteCycleTimer 	
	;; if not skip the pal cycle code
	+	
	
	;; Pal cycling on "Medium"-speed screens :
	LDA screenSpeed
	CMP #$01
	BEQ doPaletteCycleTimer

	;; another example, Pal cycling on screen type 255 screens :
	;LDA screenType
	;CMP #255
	;BEQ doPaletteCycleTimer

	
	JMP endPaletteCycleTimer
doPaletteCycleTimer: 
    ;; from here, DO the palette cycle:
    LDA palettesCycleTimer
    BNE dontUpdatePaletteCycleTimer
    JSR pickPaletteToCycle
    LDA #$10  			;; HERE !!! the SPEED of the cycling
    STA palettesCycleTimer
dontUpdatePaletteCycleTimer:
    DEC palettesCycleTimer
endPaletteCycleTimer:
    RTS    
pickPaletteToCycle:
    LDA #$02    		;; HERE !!! the "Sub 3" palette
    ASL
    ASL 				;; these multiply your literal or variable with 4 so we can get the right offset for each palette in increments of 4.
    TAX
    LDY bckPal+1,x		;; pocket colour 1 in reg y
    LDA bckPal+2,x 
    STA bckPal+1,x		;; move colour 2 to 1
    LDA bckPal+3,x 
    STA bckPal+2,x		;; move colour 3 to 2
    TYA
    STA bckPal+3,x		;; move pocket (y) to 3
    LDA #$01
    STA updatePalettes	;; loading anything but zero into this value tells NESmaker it needs to update palettes.
    RTS

EDITED: my bad, I pasted the not modified script... fixed! Now, it's the correct one.
 
I am trying to use both versions of this code in my game so I have the main start screen flashing and I have another game timer set up to use on whatever screen.
The game compiles just fine start screen flashes then I go to the main game and it doesn't Through the palate . Any thoughts
 

dale_coop

Moderator
Staff member
You could use a this code with multiple conditions.

What would be your condition for screens? screenType or screenSpeed?
 

dale_coop

Moderator
Staff member
If screen type... for example every screens that have a screen-type "42". The code would be:

Code:
	LDA screenType
	CMP #42
	BEQ doPaletteCycleTimer


The Handle Game Timer script would be:
Code:
HandleGameTimer:
	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;; dale_coop : call of the palette cycling code (see the routine at the end of this script):
	JSR handlePaletteCycleTimer
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	DEC gameTimer
	BNE dontUpdateGameTimer
	LDA gameTimerLo
	CLC
	ADC #$01
	STA gameTimerLo
	LDA gameTimerHi
	ADC #$00
	STA gameTimerHi
;;;;;;;;;;;;;;;;;;;;;;;;;;; 
	;; DO WHATEVER READS OF THE GAMETIMER YOU MIGHT WANT HERE.
	JSR DoAlarm
;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDA #DayNightSpeed
	STA gameTimer
dontUpdateGameTimer:
	RTS
	
DoAlarm:
	
	;;; we're going to edge-load monsters one at a time if they are of edge type and are not active.
	LDX #$00
doLoadMonsterOnTimerLoop:

	LDA edgeLoaderInCue
	BEQ noEdgeMonstersInCue
	LDA currentBank
	STA prevBank
	LDY #$1C ;; data bank
	JSR bankswitchY
	JSR CreateTimedEdgeSpawner
	DEC edgeLoaderInCue
	LDY prevBank
	JSR bankswitchY

noEdgeMonstersInCue
	RTS
	
	
	
;;;;;;;;;;;;;;;;;;; PALETTES CYCLE  ;;;;;;;;;;;;;;;;;;;
handlePaletteCycleTimer:
	;; Pal cycling on START SCREEN :
	LDA update_screen_details	;; special screen (start/win screens)?
	BNE +						;; if not skip the pal cycle code
	LDA currentScreen		;; screen 0 (the start one)?
	BEQ doPaletteCycleTimer 	
	;; if not skip the pal cycle code
	+	

	;; Pal cycling on "Medium"-speed screens :
	; LDA screenSpeed
	; CMP #$01
	; BEQ doPaletteCycleTimer

	;; another example, Pal cycling on specific screen type screens :
	LDA screenType
	CMP #42
	BEQ doPaletteCycleTimer


	JMP endPaletteCycleTimer
doPaletteCycleTimer: 
    ;; from here, DO the palette cycle:
    LDA palettesCycleTimer
    BNE dontUpdatePaletteCycleTimer
    JSR pickPaletteToCycle
    LDA #$10  			;; HERE !!! the SPEED of the cycling
    STA palettesCycleTimer
dontUpdatePaletteCycleTimer:
    DEC palettesCycleTimer
endPaletteCycleTimer:
    RTS    
pickPaletteToCycle:
    LDA #$02    		;; HERE !!! the "Sub 3" palette
    ASL
    ASL 				;; these multiply your literal or variable with 4 so we can get the right offset for each palette in increments of 4.
    TAX
    LDY bckPal+1,x		;; pocket colour 1 in reg y
    LDA bckPal+2,x 
    STA bckPal+1,x		;; move colour 2 to 1
    LDA bckPal+3,x 
    STA bckPal+2,x		;; move colour 3 to 2
    STY bckPal+3,x		;; move pocket (y) to 3
    LDA #$01
    STA updatePalettes	;; loading anything but zero into this value tells NESmaker it needs to update palettes.
    RTS
 
I do have one more question. I like to figure things out so maby just a hint. I fmade the start screen flash through all the pallets. lookd really cool. What want to do is have the dtart svreen cycle through all the pallets , and have a screen type code that only cycles one pallet .

I started doing a work around compiles fine but is frozen , when i try to dtart thd game. I fin sc it funny not the result i wanted but a redukt none the less.

So start the screen cycles all 4 pallets. $,00,$01,$02,$03
Screen Type $02
 

dale_coop

Moderator
Staff member
In that case, the easiest in your case would be to duplicate the "doPaletteCycleTimer" parts...
one for the start screen and one for the all the other screens.

OR
in the part of the code where you do the other palettes, add a code to skip that part if you are NOT on start screen.
 
Dale,

There is the code that im using for the screen only. Lable already defined, IM sure it is do to the other Special screen code. Would you take look at it and let me know what I should do different?
Line
1,23,26,30,43,49,70,77,79,81
thank you in Advance.
HandleGameTimer:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dale_coop : call of the palette cycling code (see the routine at the end of this script):
JSR handlePaletteCycleTimer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DEC gameTimer
BNE dontUpdateGameTimer
LDA gameTimerLo
CLC
ADC #$01
STA gameTimerLo
LDA gameTimerHi
ADC #$00
STA gameTimerHi
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DO WHATEVER READS OF THE GAMETIMER YOU MIGHT WANT HERE.
JSR DoAlarm
;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA #DayNightSpeed
STA gameTimer
DontUpdateGameTimer:
RTS

doAlarm:

;;; we're going to edge-load monsters one at a time if they are of edge type and are not active.
LDX #$00
DoLoadMonsterOnTimerLoop:

LDA edgeLoaderInCue
BEQ noEdgeMonstersInCue
LDA currentBank
STA prevBank
LDY #$1C ;; data bank
JSR bankswitchY
JSR CreateTimedEdgeSpawner
DEC edgeLoaderInCue
LDY prevBank
JSR bankswitchY

NoEdgeMonstersInCue
RTS



;;;;;;;;;;;;;;;;;;; PALETTES CYCLE ;;;;;;;;;;;;;;;;;;;
HandlePaletteCycleTimer: ;; another example, Pal cycling on specific screen type screens :
LDA screenType
CMP #113
BEQ doPaletteCycleTimer


JMP endPaletteCycleTimer
doPaletteCycleTimer:
;; from here, DO the palette cycle:
LDA palettesCycleTimer
BNE dontUpdatePaletteCycleTimer
JSR pickPaletteToCycle
LDA #$08 ;; HERE !!! the SPEED of the cycling
STA palettesCycleTimer
dontUpdatePaletteCycleTimer:
DEC palettesCycleTimer
endPaletteCycleTimer:

RTS
pickPaletteToCycle:
LDA #$02 ;; HERE !!! the "Sub 2" palette
ASL ;; these multiply your literal or variable with 4 so we can get the right offset for each palette in increments of 4.
TAX
LDY bckPal+1,x ;; pocket colour 1 in reg y
LDA bckPal+2,x
STA bckPal+1,x ;; move colour 2 to 1
LDA bckPal+3,x
STA bckPal+2,x ;; move colour 3 to 2
STY bckPal+3,x ;; move pocket (y) to 3
LDA #$01
STA updatePalettes ;; loading anything but zero into this value tells NESmaker it needs to update palettes.
RTS
 

dale_coop

Moderator
Staff member
Sorry I don't understand what is different in that script, then mine... (just you use 113 instead of my example "42")... but?
This is the script assigned to your Handle Game Timer?
 

dale_coop

Moderator
Staff member
Also, small suggestion....
when you share code on the forum, you should use the code </> tags button from the "Full Editor & Preview. It will make the code easier to read.
 
Thank you, i did not know how to set up the code like everyone else. Thank you.
The code is the same as your except it doesnt have the start screen in it. No it is not connected to handle game timer.
 
Top Bottom