Rotating Colors on a Sub Palette for NESMaker 4.5.6

vanderblade

Active member
Thanks, Cutter. One last question. Right now the palette cycling code doesn't play well with scrolling games. It leads to a lot of graphical glitches. Do you -- or anybody else reading this -- know of anyway to "stabilize" it for scrolling.
 

CutterCross

Active member
Thanks, Cutter. One last question. Right now the palette cycling code doesn't play well with scrolling games. It leads to a lot of graphical glitches. Do you -- or anybody else reading this -- know of anyway to "stabilize" it for scrolling.
Drexegar seemed to have made a stable version for Beach Master, but I don't remember if he made that public or not.

I don't use NESmaker's default scrolling engine, so I can't really vouch for a proper solution myself.
 

drexegar

Member
I wish @drexegar had shared his version...

OK dumb simple thing I found a few days ago when my fades corrupted scrolling, I have NOT done full testing with it but works so far.

The third bit of the screen updates is for the map so when you want to change just the bg color during scrolling, I use this...

LDA #%00000101
STA updateScreenData


If you doing both the pallete and sprite then you need to turn the second bit on:
LDA #%00000111
STA updateScreenData

OF course though, if your using to much code, this will definitely fall apart.

Let me know if this works.


The original thing I did was look for a spot in the NMI to control the palletes which I don't want to do anymore if I can avoid it.

oh yeah PRO TIP: Screen flags can only be read once during a screen load, so I just store my flag to another set of bits when I need to use the flag during gameplay.
 
Last edited:

Jonny

Well-known member
I'm looking for a little guidance please if anyone can help...

Using MetroVania Module, I get the following out of range error when I try to implement the above script for palette cycling.

The line where it stops seems to have something to do with Trampolines. I tried commenting out that section just to see what happened and I just got another out of range error in a different .asm

Thank you in advance.

***EDIT*** I've actualy solved this but I would like to learn how. I'd been playing about with a few input scripts, like wall grab, projectiles. When I removed them it compiled and the script for palette cycling works as it should. Curious to learn how the input scripts were causing the problem. Is it to so with whats being stored in RAM at the same time or something?

Ooopsie.png
 
Last edited:

Jonny

Well-known member
Pretty sure Bucket Mouse just made a custom variable for that, so that alone wouldn't help you.

ScreenFlags00 represents the first 8 screen flags in Screen Info (for 4.5.6), which you should be familiar with from 4.1.5. Don't ask me why the name was slightly changed. You could just use one of those flags to act as your "palette cycle flag" and just AND against it to check for the bit you want.

I did as mentioned above and it seems to work well. When my screen flag 4 is ticked it jumps the palette cycling. This is what I put at the start...

Code:
LDA ScreenFlags00
    AND #%00010000
    CMP ScreenFlags00
    BEQ +    
    JMP SeeYaLaterPalleteMallet    
    +

EDIT: The above is incorrect. It would mean any other flags would stop the cycling... should be....

Code:
    LDA ScreenFlags00  
    AND #%00001000            ;;; the screenflag you want to use ;;;
    BNE +
    JMP SeeYaLaterPalleteMallet      
    +
 
Last edited:

TakuikaNinja

Active member
I'm looking for a little guidance please if anyone can help...

Using MetroVania Module, I get the following out of range error when I try to implement the above script for palette cycling.

The line where it stops seems to have something to do with Trampolines. I tried commenting out that section just to see what happened and I just got another out of range error in a different .asm

Thank you in advance.

***EDIT*** I've actualy solved this but I would like to learn how. I'd been playing about with a few input scripts, like wall grab, projectiles. When I removed them it compiled and the script for palette cycling works as it should. Curious to learn how the input scripts were causing the problem. Is it to so with whats being stored in RAM at the same time or something?

View attachment 3840
Value out of range = too much code in the bank
You might need to move or remove some routines to free up space.
Ideally, you'd want palette updates to happen during NMI, though it can get messy if you don't know what you're doing.
 

Jonny

Well-known member
Thank you. I thought it was something along those lines but wasn't sure. As it happens there were a few input scripts I wasn't using (just experimenting with). Once I removed them all was good. I could probably 'trim the fat' in other places to get things more efficient. I've noticed a few things in certain scripts for things I will never use, but I don't know enough about ASM or whether removing those parts of the routines will make any difference.
 

5kids2feed

Well-known member
Oooh I got this working now after all this time and understanding things better lol.

Anybody know how to get this to make it so all the colors are the first color of the palette (black) and then back to normal colors? Trying to get something blinking instead of rotating. Or if there's a way to swap between the 1st and the 2nd palette since my fist palette is all black anyways. Thanks!
 

Logana

Well-known member
This doesn’t always work with modules that have the pixel and check point tiles since if you collide with them on the same frame the pallet is changing then they will just stay on screen, but easy fix make one of your tile types when collision set to 00 00 and then change the prize and check point code to go to that tile so it works way better
 

Jonny

Well-known member
OK dumb simple thing I found a few days ago when my fades corrupted scrolling, I have NOT done full testing with it but works so far.

The third bit of the screen updates is for the map so when you want to change just the bg color during scrolling, I use this...

LDA #%00000101
STA updateScreenData


If you doing both the pallete and sprite then you need to turn the second bit on:
LDA #%00000111
STA updateScreenData

OF course though, if your using to much code, this will definitely fall apart.

Let me know if this works.


The original thing I did was look for a spot in the NMI to control the palletes which I don't want to do anymore if I can avoid it.

oh yeah PRO TIP: Screen flags can only be read once during a screen load, so I just store my flag to another set of bits when I need to use the flag during gameplay.

This seems to work well from what I've tested so far. The glitches when scrolling onto the next screen seem to be completely gone. I had a few colour attribule anomolies the first time I tried it but never since. Could have been unrelated. As far as the graphics, pretty solid so far.

The only problem I need to fix now if that the palette cycle, as it is now, doesn't stop at any particular cycle point. So, for example, when I leave a palette cycling screen to a non-palette cycling screen, that palette end ups fixed wherever it was in the cycle. Might not really be an issue for games where that palette is reserved for certain elements only (e.g waterfalls).

Thank you @drexegar
 

cramske

Member
HI! ! I have just used this code for cycling palettes! THANKS !! I am running into a problem. When I am using an NPC on the same screen as the cycling(I have used a screenflag)
When the text box writes it leaves out some letters, and when the second text writes it sometimes leaves the letters from the previous quote. Works fine when not on a cycling screen. Anyone know whats happening and if there is a fix? If not I will just have to keep NPC's off of my cycling palette screens. Tanks in advance for any help with this. I am in arcade platformer MOD but with hecka modifications and such..
 

9Panzer

Well-known member
I think I have a work around for scrolling with this. Its not perfect but if you update the beginning part of the script with this:

LDA palettesCycleTimer ;; Load the Timer
BNE PaletteCycleTimerCountDown ;; If it is not 0, we are still counting down. Hop down.

;;;;;; New Stuff
LDA updateScreenData
AND #%0000100
BEQ +doSwapper
JMP SeeYaLaterPalleteMallet
+doSwapper

;;;;;;

JSR CycleThyPalettes

Then it will check to see if the screen is Scrolling (ie loading new columns) and if it is it will skip the swap and wait until its finished loading. It will make the swap a little inconsistent but it won't break the game anymore :)
 

baardbi

Well-known member
ezgif-5-b7c6113ea1.gif
This is a great and simple tutorial. However. For some reason when making waterfalls it always felt like the water was going the wrong way. So I modified the code a little bit, and now it's working like I want it to. I also added a screen flag check so I can enable this effect on the screens I want.

;; Palette Color Rotation
;; NESMaker 4.5.6
;; Modified by Artix & the UltimateGilby (Hacked together from Dale Coop's code from 4.5.1...
;;
;; IMPORTANT!
;; Add these variables to your zero page RAM
;; palettesCycleTimer
;; tempArtix
;;
;_; It is so cruel not having Dale Coop Help X_X
;_; I feel like I am wandering in a desert, seeing code mirages of 6502 ASM....
;;
;; Add this code to your Handle_Game_Timer
;; It will rotate one of your sub palletes
;; The default is the first one (#$00)...
;;
;; I am terrible at this. It probably breaks something. You were warned! XD
;;

LDA ScreenFlags00
AND #%00000001 ;Bottom screen flag check box
BNE +doPaletteCycling
JMP SeeYaLaterPalleteMallet
+doPaletteCycling:

LDA palettesCycleTimer ;; Load the Timer
BNE PaletteCycleTimerCountDown ;; If it is not 0, we are still counting down. Hop down.
JSR CycleThyPalettes ;; It is time to cycle the palette!
LDA #8 ;; SPEED (This will cycle it every 8 frames)
STA palettesCycleTimer

PaletteCycleTimerCountDown:
DEC palettesCycleTimer ;; Decrease the Timer
JMP SeeYaLaterPalleteMallet ;; No updates on this round!

CycleThyPalettes:
;; ----------------------
;; Which Subpallete do you want to cycle?
;; #$00 = the 1st
;; #$01 = the 2nd
;; #$02 = the 3rd
;; #$03 = the 4th
LDA #$00
;; ------------------------

;; Palette Cycle
ASL ;; x2
ASL ;; x2
TAX ;; Transfer accumulator into X

LDA bckPal+1,x
STA tempArtix

LDA bckPal+3,x
STA bckPal+1,x

LDA bckPal+2,x
STA bckPal+3,x

LDA tempArtix
STA bckPal+2,x

LDA #$01
STA updateScreenData ;; Writing a 1 to this tells NESmaker it needs to update palettes.
;; Although, we might need to protect the other bits if something else is going on
;; But I do not know how to do that... Kasumi!? HELP!
RTS

SeeYaLaterPalleteMallet:
 

dale_coop

Moderator
Staff member
View attachment 7625
This is a great and simple tutorial. However. For some reason when making waterfalls it always felt like the water was going the wrong way. So I modified the code a little bit, and now it's working like I want it to. I also added a screen flag check so I can enable this effect on the screens I want.

You're right, I got the same reverse cycling effect, so... I use it like you, feels better for my projects.
 

strawmancomics

New member
I'm kinda stumped on this one.

I've got the pallet cycling to work but I want to isolate it to one screen. I modified the original code with a screen flag and it works for the special screen but for some reason when it loads the first level it goes back to screen cycling. I tried it with the flag on and off on the start screen and it started doing the pallet cycling. So I know it's working for the most part.

LDA ScreenFlags00 ; load screenflags 0-7
AND #%00000111 ; checks the screen flag 7 bit
BEQ +notChecked
JMP +checked

+notChecked:


JMP +finishPalletCycle

+checked:




;; Palette Color Rotation
;; NESMaker 4.5.6
;; Modified by Artix & the UltimateGilby (Hacked together from Dale Coop's code from 4.5.1...
;;
;; IMPORTANT!
;; Add these variables to your zero page RAM
;; palettesCycleTimer
;; tempArtix
;;
;_; It is so cruel not having Dale Coop Help X_X
;_; I feel like I am wandering in a desert, seeing code mirages of 6502 ASM....
;;
;; Add this code to your Handle_Game_Timer
;; It will rotate one of your sub palletes
;; The default is the first one (#$00)...
;;
;; I am terrible at this. It probably breaks something. You were warned! XD
;;


LDA palettesCycleTimer ;; Load the Timer
BNE PaletteCycleTimerCountDown ;; If it is not 0, we are still counting down. Hop down.

;;;;;; New Stuff
LDA updateScreenData
AND #%0000100
BEQ +doSwapper
JMP SeeYaLaterPalleteMallet
+doSwapper
;;;;;;



JSR CycleThyPalettes ;; It is time to cycle the palette!
LDA #19 ;; SPEED (This will cycle it every 29 frames)
STA palettesCycleTimer

PaletteCycleTimerCountDown:
DEC palettesCycleTimer ;; Decrease the Timer
JMP SeeYaLaterPalleteMallet ;; No updates on this round!

CycleThyPalettes:
;; ----------------------
;; Which Subpallete do you want to cycle?
;; #$00 = the 1st
;; #$01 = the 2nd
;; #$02 = the 3rd
;; #$03 = the 4th
LDA #$02

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


;; Palette Cycle
ASL ;; x2
ASL ;; x2
TAX ;; Transfer accumulator into X
LDA bckPal+1,x ;pocket colour 1 in reg y
STA tempArtix
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
LDA tempArtix
STA bckPal+3,x ;move pocket (y) to 3
LDA #$01
STA updateScreenData ;; Writing a 1 to this tells NESmaker it needs to update palettes.
;; Although, we might need to protect the other bits if something else is going on
;; But I do not know how to do that... Kasumi!? HELP!
RTS

SeeYaLaterPalleteMallet:

+finishPalletCycle
 

strawmancomics

New member
Ok. I kinda figured it out. I've already got a screen flag checked. When it checks the screen flag for the hud configuration it ignores the remaining screen flags.
 
Top Bottom