[4.5.9] How To Activate The Night & Day Feature

Bucket Mouse

Active member
So if I set nightbyte to 1, and screenState to 04, then will I be in a triggered night screen?
No, screenState would have to be 03, since it's from 00 to 03.
Also: it doesn't look like I accounted for screenState 03 in the modification to doLoadBackgroundPallettes. It should be this:

Code:
LDA screenState
        CMP #$00 ; not night
        BEQ +
        CMP #$02 ; not night either
        BEQ +
        LDY #$20 ; to load the night palettes, Y must be shifted forward by 32 (20 in hex)
        JMP +night
        +

I made the correction to the script on page 1.
 

IMBrendan

Member
This is sooooo close - with the most recent edit from BucketMouse it seems night triggers on load - but doesn't seem to switch back to day after any amount of time passed (I tested timings for both 40/80 and 20/40 but i'll update if I test others and they also don't work). But I follow with great interest guys.
 

Kanbei85

Member
Okay, looking back, here's what I really did: I flipped on the nightbyte flag, not the screenState flag, because screenState is taken care of in the other script. For example this one's for a tile:
Code:
CMP #$B2 ; entrance to dark cave
BNE +
LDA #$01
STA nightbyte
JMP warphere
+

There is one instance of screenState being changed, but nightbyte is changed at the same time.
Code:
LDA #$01
STA nightbyte
STA screenState

I'm attempting to have a pickup change the screen from Day to Night. I used the following:

LDA #$01
STA nightbyte
STA screenState

According to you, this code should have the effect of putting the screen into normal night mode. What it actually does is to put the screen into triggered day mode. Which is something, I guess, since I no longer need to use the TriggerScreen macro. But still, this is not night mode.
 

Bucket Mouse

Active member
I have to ask....do you have the colors wrong? Like, are your day colors the same as your night colors? If you followed the directions, setting nightbyte to 1 should put everything in screenState 01 which is night. The code can't be more clear on that. 01 is night!
 

Kanbei85

Member
I have to ask....do you have the colors wrong? Like, are your day colors the same as your night colors? If you followed the directions, setting nightbyte to 1 should put everything in screenState 01 which is night. The code can't be more clear on that. 01 is night!
As of now I haven't changed the background tiles, but I changed the monster spawns.
 

Kanbei85

Member
If I set nightbyte to #$00, THEN the screenState variable works TEMPORARILY, but the command to update the background palette has to be run manually:

LoadBackgroundPalettes newPal

It has no effect on monster spawning locations, however, and the change is gone if you reload the screen.

This tells me that modifying the screenState variable manually is not enough. In some way, we must figure out what's going on with the TriggerScreen macro to see what it's doing that allows a persistent global change to occur.
 

Kanbei85

Member
Okay, looking back, here's what I really did: I flipped on the nightbyte flag, not the screenState flag, because screenState is taken care of in the other script. For example this one's for a tile:
Code:
CMP #$B2 ; entrance to dark cave
BNE +
LDA #$01
STA nightbyte
JMP warphere
+

There is one instance of screenState being changed, but nightbyte is changed at the same time.
Code:
LDA #$01
STA nightbyte
STA screenState

Look carefully at the doLoadScreenData routine. nightbyte is just a variable. Somewhere, you need some code that actually STORES this variable to a place in the memory, and then the doLoadScreenData routine will pull from that memory location and set the nightbyte variable based on that. Without such a code, then there cannot be any persistent changes to the nightbyte, which means we cannot actually trigger the screen to be night mode the way the other screen trigger works.

What you've done here makes it possible to load a screen into a "Night palette" state as needed, but those changes will disappear if you reload the screen, and that's not what I need personally. I need the ability to make a persistent change.

Since the monster spawns are loaded when you first enter a screen, that means without a persistent change we also cannot make any use of the nightmode monster spawnpoints, and THAT is really what I need to be able to do.
 

capacitor

New member
If I set nightbyte to #$00, THEN the screenState variable works TEMPORARILY, but the command to update the background palette has to be run manually:

LoadBackgroundPalettes newPal

>>>>>>>>It has no effect on monster spawning locations, however, and the change is gone if you reload the screen.<<<<<<<<<<<<<

This tells me that modifying the screenState variable manually is not enough. In some way, we must figure out what's going on with the TriggerScreen macro to see what it's doing that allows a persistent global change to occur.
in the adventure module for me looks like the same code effect, no effect on monster spawning and the change is gone if you reload the screen; but in the scrolingPlataform module the monster spawning works well and the night and day colors circle work ok too, whitout fade transitions but work, all whith the macro "LoadBackgroundPalettes" on in the timer. you got to make the fade transitions works in that stuff??? I trying something using the parameters of "fade out" and fade out whith the color white(#$20) too, but got nothing concrete yet.. problems whith the second screenFlags now ^^, my ScreenFlag01 do not want to work for some reason...
 

nes-lover

New member
I have a problem where my game is on "day" game state, but uses the "night" palette. Also the game state doesn't seem to be changing after a set amount of time.
 

Retrofaija

Member
This seems cool and what I need, but for me the doLoadBackgroundPalette.asm code makes all my graphics night palette by default. I'm using Adventure module base, and everything else seems to work (well, not that far yet) - but as soon as I put the changed asm to backgroundpalette, it forces everything to nightpalette, and also my monster graphic is forced to the first one. Sprite palette is still day one, it doesnt affect the day night state, just loads the night palette for background by default.

Edit: Got it fixed. in doLoadBackgroundPalette - I removed the duplicate of this:

LDY #$20 ; to load the night palettes, Y must be shifted forward by 32 (20 in hex)
JMP +night
+

So just to have one of them, not two. Now it works, but the persistence doesnt still - if I go from screen to another, it's day again, as mentioned before.
 
Last edited:

Retrofaija

Member
Ok. I THINK my stupid brain got this all sorted out. As I'm a total noob and "trying" things out brute forcing and trying to logically think. Here's the codes that work for, day/night cycle works in adventure mode, as well the day / night time monsters (they load up if you day if you enter during day, and night if you enter during night).

FORGET THIS post - it's an awful mess.

Timer script is what makes things happen, but you need to add in the timer a code to store the value for nightbyte as well. Then it works.

Edit: Tested and triggers work as well. If I trigger screen at night, it turns to triggered, and triggered day as well if I wait (and come back to screen when it's day).

Here's my doHandleGameTimer.asm: - btw, the timer is very fast in mine, coz I wanted to test it (like 5-6 seconds per day / night).



Code:
;;; handle game timer.
    LDA gameTimerTicks
    CLC
    ADC #$04 ;; change this to how fast you want the timer to run.
    STA gameTimerTicks
    LDA gameTimerLo
    ADC #$00
    STA gameTimerLo
    LDA gameTimerHi
    ADC #$00
    STA gameTimerHi

    LDA gameTimerHi
    BEQ +resethi
    CMP #05 ; this should be exactly half of your total time
    BEQ +hihalfway
    LDA gameTimerLo
    BEQ +resetlo ; if lo number reaches zero, this decreases hi number
    DEC gameTimerLo ; otherwise, it decreases the lo digit then cycles again
    JMP +
    +resetlo:
    DEC gameTimerHi
    LDA #100 ; the low mumber counts this number of frames, then decreases the high number by 1
    STA gameTimerLo
    JMP +
    +resethi
    LDA #10 ; enter the amount of time you want between night and day here
    STA gameTimerHi
    LDA #$00
    STA nightbyte
    STA screenState
    LoadBackgroundPalettes newPal
        LDA #$01
    STA updateScreenData
    JMP +
    +hihalfway
    DEC gameTimerHi
    LDA #$01
    STA nightbyte
    STA screenState
    LoadBackgroundPalettes newPal
        LDA #$01
    STA updateScreenData
    +

I made the similar "failsafe" storing of the screenState data to the nightbyte on different places as well. Just to be sure and I'm not a genius, so I wanted to play safe. :D

onLoadScreenData.asm - where originally was only one row of code added ahead of JSR Loadmonster 1: (the original nightbyte code is ok I think).

Code:
LDA nightbyte
STA screenState     
LDX screenState ;; activates night text group 

        JSR LoadMonster_1

I THINK these were the changes I made, but now I have working day / night cycle with atleast normal day and normal night - I'm not sure how triggering works there.

I'm gonna have my self a glass of wine now. :D
 
Last edited:

Retrofaija

Member
Here's the problem now - nightbyte naturally stores over screenState, so triggers don't save, even though the day night cycle do transfer over. If there is a possibility to have nightbyte 4 bytes (so it would be day, day triggered, night, night triggered), then maybe it could work. Dunno, i'm just a dumb non-coder...
 

Retrofaija

Member
Ok - i've got it to work so, that it turns day and night with timer and persists to other screens.

Also: It works with day, triggered day and triggered night. Normal night doesnt work for some reason and I don't have a clue why. So everything else works now, but I cannot have normal night monsters separate from day monsters. Triggered day and night monsters work like charm with day night cycle.

Edit: I got it! I got persistence over screens and all monsters working as they should (with triggers also).

I think the main thing here was to store and compare the nightbyte value rather than messing up with the screenState. Timer needs to store nightbyte to 01 or 00, which then is compared in the screenstate code (doLoadScreenData).
 
Last edited:

Retrofaija

Member
Here's the code for doLoadScreenData.asm (same part as with the first page first code part and instruction):

Code:
GetScreenTriggerInfo:
        JSR doClearAllMonsters
;;;;; MONSTERS
    ;;; constants for banks
 
       
        GetTrigger
   
        ;; result of screenType trigger stored in temp3 and also in accum
        ;; x and y restored.
        BEQ thisScreenIsNotTriggered
            ;; this screen IS triggered
            LDA nightbyte
            CMP #$01
            BNE isTriggeredDay
                ;; triggered and night
                LDA #$03

                STA screenState
                JMP triggeredStateInfoIsLoaded
            isTriggeredDay
   
                ; triggered and day
                LDA #$02

                STA screenState
       
            JMP triggeredStateInfoIsLoaded
        ;;=================================
        thisScreenIsNotTriggered
           
        LDA nightbyte
            CMP #$01
            BNE isNormalDay
           
                ;; normal and night
                LDA #$01

                STA screenState
JMP triggeredStateInfoIsLoaded
            isNormalDay:
       
                ; normal and day
                LDA #$00

                STA screenState

        triggeredStateInfoIsLoaded:

LDX screenState ;; activates night text group

My timer scripts looks like this:


Code:
   LDA gameTimerHi
    BEQ +resethi
    CMP #05 ; this should be exactly half of your total time
    BEQ +hihalfway
    LDA gameTimerLo
    BEQ +resetlo ; if lo number reaches zero, this decreases hi number
    DEC gameTimerLo ; otherwise, it decreases the lo digit then cycles again
    JMP +
    +resetlo:
    DEC gameTimerHi
    LDA #100 ; the low mumber counts this number of frames, then decreases the high number by 1
    STA gameTimerLo
    JMP +
    +resethi
    LDA #10 ; enter the amount of time you want between night and day here
    STA gameTimerHi
    LDA #$00
    STA nightbyte
    LoadBackgroundPalettes newPal
        LDA #$01
    STA updateScreenData
    JMP +
    +hihalfway
    DEC gameTimerHi
    LDA #$01
    STA nightbyte
    LoadBackgroundPalettes newPal
        LDA #$01
    STA updateScreenData
    +


And my doLoadBackgroundPalette.asm looks like this. Here I think I changed the LDA from screenState to nightbyte.


Code:
doLoadBackgroundPalettes:
    ;; This is tied to the macro LoadBackgroundPalettes.
    ;; It uses bank and 16 bit label.
    TXA
    PHA
    TYA
    PHA
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;Get Palette Label based on INDEX
    SwitchBank #$16
        LDY arg0_hold
        LDA GameBckPalLo,y
        STA temp16
        LDA GameBckPalHi,y
        STA temp16+1
 
     
        LDA nightbyte
        CMP #$00 ; not night
        BEQ +
        CMP #$02 ; not night either
        BEQ +
        LDY #$20 ; to load the night palettes, Y must be shifted forward by 32 (20 in hex)
        JMP +night
        +


        LDY #$00
        +night
        LDX #$00

        loop_LoadBackgroundPalette:
            LDA (temp16),y
            STA bckPal,x
            INY
            INX
            CPX #$10
            BNE loop_LoadBackgroundPalette
        ;;;; end of loop.
        LDA updateScreenData
        ORA #%00000001 ;; palette
        STA updateScreenData


    ReturnBank
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    PLA
    TAY
    PLA
    TAX
    RTS
 
Last edited:

Retrofaija

Member
Here is also a video proof of it working. I have same screen type on both screens so when I trigger it by getting the knife, also the outside screen is triggered (as you can see from the position of zombies etc). Also the Bitcoin looking tiles (are my invisible NPC loot tiles) change place and react to triggers as well.

 

Retrofaija

Member
Ok - the code that "fixed" my day/night cycle destroyed my object sprite loading from different sheets than 00. HERE is the updated and fixed code. Basically what you need, is in the original post make the nightbyte variable, and add LDA nightbyte on the ORIGINAL code of doLoadScreenData. Do not change it.

So here, replace this code part from the original, find the exact location from the script. Other scripts work fine, but this one was culprit, because the original post and my continuation did not store the monsterTableOffsets at all - it was lost in the original.

ATTENTION: I didnt get all the triggerings still to work. I only have Day monsters, Night Monsters and Day Triggered monsters working. Day Triggered monsters are also present in Night Triggered screen - so basically day/night + one trigger screen works now. And all the graphics.


Code:
GetScreenTriggerInfo:
        JSR doClearAllMonsters
 ;;;;; MONSTERS
    ;;; constants for banks
  
          
        GetTrigger
      
        ;; result of screenType trigger stored in temp3 and also in accum
        ;; x and y restored.
        BEQ thisScreenIsNotTriggered
            ;; this screen IS triggered
            LDA gameHandler
            AND #%00000001 ;; one = night
            BEQ isTriggeredDay
                ;; triggered and night
                LDA #$03
LDA nightbyte
                STA screenState
                TAX
                LDY #152
                LDA (collisionPointer),y
                LSR
                LSR
                LSR
                LSR
            ;    LDA #$03
                STA monsterTableOffset
                JMP triggeredStateInfoIsLoaded
            isTriggeredDay
      
                ;; triggered and day
                LDA #$02
LDA nightbyte
                STA screenState
                TAX
                LDY #153
                LDA (collisionPointer),y
                AND #%00001111
            ;    LDA #$02
                STA monsterTableOffset
          
            JMP triggeredStateInfoIsLoaded
        ;;=================================
        thisScreenIsNotTriggered
            JMP isNormalDay
            LDA gameHandler
            AND #%00000001 ;; one = night
            BEQ isNormalDay
              
                ;; normal and night
                LDA #$01
LDA nightbyte
                STA screenState
                TAX
                LDY #152
                LDA (collisionPointer),y
                LSR
                LSR
                LSR
                LSR
            ;    LDA #$01
                STA monsterTableOffset
                JMP triggeredStateInfoIsLoaded
            isNormalDay:
          
                ;; normal and day
                LDA #$00
LDA nightbyte
                STA screenState
                TAX
                ;;;;;;;;;;;
                ;Load correspnding monster tileset.
                LDY #152
                LDA (collisionPointer),y
                AND #%00001111
            ;    LDA #$00
                STA monsterTableOffset
        triggeredStateInfoIsLoaded:
  
        ;;=================================
        ;Now, here, load all of the state specific stuff.
        ;This will use X as an offset for small tables in ZeroOutAssets file.
        ; We'll have to use the stack for any part of these routines that might need X.
        ; ;;;;; considerations for the states.
            ; ;1: Get Object Graphics Bank   
            ; ;2: String Data
            ; ;3: Monster Spawn positions
            ; ;4: Monster group (this is more complicated than a single digit)
            ; ;5: Object palettes (also more complicated than a single digit)
            ; ;6: Object tiles to load.
            ; ;7: Object IDs
            ; ;8: Song to play
;;=============================================================
;;============================================================= 
        LDA StringDataChoice,x
        TAY ;; now y holds the byte offset value for the text string group.
        LDA (collisionPointer),y
        STA stringGroupPointer
      
      
            TXA
            PHA
        ;    LDX monsterTableOffset
        ;;; Handle monster 1
LDX screenState ;; activates night text group         
        JSR LoadMonster_1
 
Last edited:

Jonny

Well-known member
Super confused about what this all does. With the vanilla code, changing the last bit of gameHandler achieves the same thing regarding day/night doesn't it?
 
Top Bottom