Let's improve scrolling together! [4.5.9] (dohandlecamera updates/fixes)

ive always found the edge reaction scripts a little tricky to work with, so I've in the past done my own checks on player positions.

In theory, you would need to leave the left and right edge flags on and the auto scroll flag off in the screen settings, and the then when its time to force the screen to move, you would toggle one of the edge flags off and then the autoscroll flag on. this would start the scrolling. and since the flag changes arent saved, it would stop scrolling automatically when the next screen over is centered.

The first step I think would be to test this with an input script. something like for right D-pad: toggle right edge flag off and autoscroll flag on" and for left D-pad "toggle left edge flag off and auto scroll flag on"

if that works, then the next step would be to move the code out of the input scripts into something else.

I'll look into this tomorrow if you don't have it solved already by then
went to bed shortly after I posted my question, thanks! I'm gonna try if I can make this work now
 

SciNEStist

Well-known member
I tested it out, and this method does work.

to scroll over 1 screen right, first set all the screens to have both left and right edges turned on, and autoscroll off, then execute this code to trigger the scroll:

for right:
Code:
   LDA ScreenFlags00 ; load screenflags
   AND #%11101111 ; toggle off the right edge
   ORA #%00000100 ; toggle on autoscroll
   STA ScreenFlags00 ; save changes

for left:
Code:
   LDA ScreenFlags00 ; load screenflags
   AND #%11011111 ; toggle off the left edge
   ORA #%00000100 ; toggle on autoscroll
   STA ScreenFlags00 ; save changes

it will scroll over 1 screen and stop. then you can go back and forth as much as you want.
 

SciNEStist

Well-known member
For anyone wanting to use this script with the horizontal shooting module, you will want to be able to adjust the speed of your player object to match the scrolling speed. By default,the module has your player object move at 1 pixel per frame, which matches the fastest scrolling speed. But if you want it to speed up and slow down when scrolling at slower speeds, here is what you want to do:

Open up Scrips >defined Scripts, then click Subroutines >handle Physics. It should open up "doHandlePhysics_shooter2.asm"

scroll to the very bottom and you will find this section:

Code:
skipPhysics:

        LDA ScreenFlags00 ;; Checks for Right Edge for Scroll flag
        AND #%00010000
        BNE +skipCamMovement
        
        LDA Object_vulnerability,x
        AND #%00000001 ;; set this to "static object"
        BNE +skipCamMovement
        LDA xHold_lo
        CLC
        ADC #$00
        STA xHold_lo
        LDA xHold_hi
        ADC #$01;; this becomes the "SCROLL SPEED" - it is the offset at which the player moves.
                ;; in conjunction with camera speed update, this could make it scroll faster.
        STA xHold_hi
        LDA xHold_screen
        ADC #$00
        STA xHold_screen
        
    +skipCamMovement

you want to erase that, and replace it with this:

Code:
skipPhysics:

     LDA ScreenFlags00
     AND #%00010000
     BEQ +dontskipCamMovement
        JMP +skipCamMovement
     +dontskipCamMovement               
         LDA Object_vulnerability,x
         AND #%00000001 ;; set this to "static object"
         BNE +skipCamMovement
          
         LDA screenSpeed
         CMP #$01
         BNE +notthis
             LDA xHold_lo
             CLC
             ADC #$44
             STA xHold_lo
             LDA xHold_hi
             ADC #$00
             STA xHold_hi
             LDA xHold_screen
             ADC #$00
             STA xHold_screen
             JMP +skipCamMovement
        +notthis
        CMP #$02
        BNE +notthis
             LDA xHold_lo
             CLC
             ADC #$88
             STA xHold_lo
             LDA xHold_hi
             ADC #$00
             STA xHold_hi
             LDA xHold_screen
             ADC #$00
             STA xHold_screen
             JMP +skipCamMovement
       +notthis
        CMP #$03
        BNE +notthis
             LDA xHold_lo
             CLC
             ADC #$00
             STA xHold_lo
             LDA xHold_hi
             ADC #$01
             STA xHold_hi
             LDA xHold_screen
             ADC #$00
             STA xHold_screen
             JMP +skipCamMovement
        +notthis
             LDA xHold_lo
             CLC
             ADC #$22
             STA xHold_lo
             LDA xHold_hi
             ADC #$00
             STA xHold_hi
             LDA xHold_screen
             ADC #$00
             STA xHold_screen
             JMP +skipCamMovement     
            
     +skipCamMovement

Once that is done, your player object will speed up and slow down to match the new scrolling speed.
 
implemented your script and everything works fine my big question is, why is there no vertical scrolling, or transitions in nesmaker? or if there is, anyone else know about it?
 

SciNEStist

Well-known member
Theres a lot of technical hurdles needed to overcome to have vertical scrolling. unfortunatly, no one has written any code that can be easily added to nesmaker to allow it. The first person to do so would have the gratitude of the entire community though.
 

LaffinJoker

New member
DOWNLOAD HERE

I've been working on my own game and thought that people might benefit from a few tweaks/changes I've made to the doUpdateCamera script. (the script that handles all scrolling)

Below is a version of the script that I've modified mostly by copy/pasting from other peoples tweaks. It started with the most stable scrolling script I am aware of, the "Scrolling with Re-centering" by AllDarnDavey, which corrects a lot of screen issues on its own


Bug Fixes:

-Multiple objects spawning at once when scrolling
-No inputs scripts needed
-Screen flags no longer update every frame, instead they update when a new screen is centered. so changes can be made without being lost immediatly
-Warpto screen now updates, no longer only uses the settings set on the first screen of the level

New Features:

-toggle between no scroll, autoscroll, and player following "camera modes"
-all scrolling features can be adjusted screen by screen, so you can have sections that autoscroll and sections that follow the player in the same level.
-left and right scrolling/autoscrolling
-adjust autoscroll speed with "screenSpeed" variable in screen settings dropdown
-while scrolling, the following gets adjusted when the new screen comes fully into frame:
  • scroll speed
  • screen flags
  • warpto screen
  • tile pallette
  • music
HOW TO USE THIS
A more detailed walkthrough can be found HERE (thank you baardbi )
1: replace your "handle camera" script with the file attached to this post
2: delete all the input scripts that control scrolling
  • By default, the camera will follow the player. To change to autoscroll, screenflag6 is the flag to check. (this can be changed at the beginning of the script)
  • To determine the direction of the autoscroll, check "right edge for scroll" to go left, and "left edge for scroll" to go right.
  • For no scrolling at all, check both the right and left edge flags and the camera will not move
  • When the scrolling comes across a scroll edge, it will stop. to start it going again, uncheck the screen flag. for example, this will uncheck right edge:
Code:
LDA ScreenFlags00
   AND #%11101111
   STA ScreenFlags00


I'm sure theres a lot that can be improved or made more efficient. IF anyone has any suggestions or issues, we can all edit it together and I'll keep it updated on this first post.

EXTRA:
you can edit your physics script to help push your player along any autoscrolling areas: https://www.nesmakers.com/index.php...-along-with-your-camera-scrolling-4-5-9.8055/
for horizontal shooter games, adjust the speed of your ship along with the scrolling here: http://www.nesmakers.com/index.php?...-dohandlecamera-updates-fixes.7929/post-48125
OTHER FIXES

FOR COLLISION FIX WITH THE SEAM, CHECK OUT THIS LINK: https://www.nesmakers.com/index.php?threads/scrolling-platformer-seam-collision-fix-4-5-9.7266/

FOR CORRUPTED TILES DURING SCROLLING AFTER WARPING: http://www.nesmakers.com/index.php?...arping-without-buffer-screens.7295/post-40092
I’ve got this implemented and it’s amazing, thank you.
Can someone tell me what line I have to change in the script to make it start scrolling to the right when the character is further left on the screen (I’d like it to scroll slightly before midway).
 

TalkingCat

Member
I’ve got this implemented and it’s amazing, thank you.
Can someone tell me what line I have to change in the script to make it start scrolling to the right when the character is further left on the screen (I’d like it to scroll slightly before midway).
To do this, you can change this value in the newcamerahandler_new.asm script

Снимок экрана 2023-10-22 232522.png
 
sorry, i'm not entirely sure if this is the correct thread for my problem (as in i dont know if it originated with this,) but if im not mistaken, it allows multiple enemy groups, warps and such to be used throughout different screens.

the problem is, when i have two warps, each going back and forth to each other, they work fine, and I've set them up to only be accessible after the entire screen is loaded, yet this is where the problem is, if i move over a little, also moving the screen then go back through the warp, it reads a different screen warp data, or not even at all, thus sending me to a default warp does anyone know a solution to this problem?
 

LaffinJoker

New member
I’ve been told that you should always have the SAME warps on adjacent screens because when the game loads it loads the 2 adjacent screens as well and this may be your issue.

So if your warps that go to different locations are on Screens 2 and 5, have Screens 1 and 3 with the same Warp Data as Screen 2 (under screen info) and have Screens 4 and 6 have the same as Screen 5. As long as your warps are separated by 2 screens like this you should be fine. I would only put the Warp Tiles on the Middle Screens and put the same Warp Data all around those screens. Does this make sense?
 
here, let me try out some more tests, cause, it actually sends me to a different screen than 0 0, when the adjacent screen warps are 0 0, and also, from how i've set up the warps, i haven't gotten a wrong warp (other than the said problem) when their only spaced one apart with this little "path"screen warp set up.png

i reuse it through out the map to keep it consistent. and yes, i have set all the warps properly after doing this
 
ok, so after some testing, it looks like it only happens when the screen moves left, and it does read the left screen warp input. this doesn't happen on the right side though.
 

LaffinJoker

New member
ok, so after some testing, it looks like it only happens when the screen moves left, and it does read the left screen warp input. this doesn't happen on the right side though.
So have you put the screen to the left warp as the same (0,0- I think is where you said it goes) and did that work? If not, unfortunately this is my extent of knowledge regarding warps.
 
sorry, i was wrong about it sending me somewhere random, i forgot to mention that, but yes, it does read the left screens warp and sends the player to wherever it says.
 

baardbi

Well-known member
I found that warping to screens on the Underworld map could fail sometimes. I found out that it only worked if I had the "Warp out to Underworld" checkbox set on the first screen of the scrolling level. I checked it and found out that warpToMap is only set during doLoadScreenData. I put this in the newcamerahandler.asm file at line 650, and now warpToMap is updated as the screen scrolls. So I can have a screen in the middle of the level that warps to the Underworld map.

LDY #130
LDA (temp16),y
AND #%00000001 ;; is this overworld or underworld map?
STA warpToMap
 

nesker

New member
Hello NESmakers,

I believe I figured out a way to make scrolling work in "underworld" map. It isn't optimized so feel free to improve.

If this was already known, feel free to skip this post.

This is what I did to make it work:

Step one:

Find this around the 260-ish line (not sure since you may have made modifications)

+canUpdateScrollColumn2

LDA scrollByte
ORA #%00000101
STA scrollByte
;;;;;;;;;; DO SCROLL UPDATE.
SwitchBank #$16
LDY scrollUpdateScreen
LDA NameTablePointers_Map1_lo,y
STA temp16
LDA NameTablePointers_Map1_hi,y
STA temp16+1


LDA AttributeTables_Map1_Lo,y
STA pointer
LDA AttributeTables_Map1_Hi,y
STA pointer+1


LDA CollisionTables_Map1_Lo,y
STA pointer6
LDA CollisionTables_Map1_Hi,y
STA pointer6+1
ReturnBank
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; now we have pointers for the fetch.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; We can read from the pointers to get metatile data.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; jump to the bank
LDA scrollUpdateScreen
LSR
LSR
LSR
LSR
LSR
STA temp ; bank

SwitchBank temp

and replace it with this:


+canUpdateScrollColumn2

LDA scrollByte
ORA #%00000101
STA scrollByte
;;;;;;;;;; DO SCROLL UPDATE.
SwitchBank #$16
LDY scrollUpdateScreen
LDA warpMap
BEQ +loadOverWorldMap
;;;load from map 2 table aka Underworld
LDA NameTablePointers_Map2_lo,y
STA temp16
LDA NameTablePointers_Map2_hi,y
STA temp16+1
LDA AttributeTables_Map2_Lo,y
STA pointer
LDA AttributeTables_Map2_Hi,y
STA pointer+1
LDA AttributeTables_Map2_Lo,y
STA pointer
LDA AttributeTables_Map2_Hi,y
STA pointer+1
LDA CollisionTables_Map2_Lo,y
STA pointer6
LDA CollisionTables_Map2_Hi,y
STA pointer6+1
JMP +skip

+loadOverWorldMap
LDA NameTablePointers_Map1_lo,y
STA temp16
LDA NameTablePointers_Map1_hi,y
STA temp16+1


LDA AttributeTables_Map1_Lo,y
STA pointer
LDA AttributeTables_Map1_Hi,y
STA pointer+1


LDA CollisionTables_Map1_Lo,y
STA pointer6
LDA CollisionTables_Map1_Hi,y
STA pointer6+1

+skip


ReturnBank
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; now we have pointers for the fetch.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; We can read from the pointers to get metatile data.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; jump to the bank
LDA scrollUpdateScreen
LSR
LSR
LSR
LSR
LSR
STA temp ; bank

LDA warpMap
BEQ +loadOverWorldMap
;;modify the bank if we are in the underworld
LDA temp
CLC
ADC #$08
STA temp

+loadOverWorldMap
SwitchBank temp

Step Two:

Find this line around the 602-ish area

getCamSeam:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Since we use camScreen in this subroutine, we'll have to make sure it's properly updated
;;; before get our column and screen.
LDA camY_hi
ASL
ASL
ASL
ASL
CLC
ADC camX_hi
CMP camScreen
BNE +
JMP +skipchanges
+
STA camScreen
;;THE SCREEN HAS CHANGED BY SCROLLING TO THE NEXT!
;;UPDATE STUFF HERE

SwitchBank #$16
LDY camScreen
LDA CollisionTables_Map1_Lo,y
STA temp16
LDA CollisionTables_Map1_Hi,y
STA temp16+1
ReturnBank

LDA camScreen
LSR
LSR
LSR
LSR
LSR
STA temp ; bank
SwitchBank temp

and replace it with this

getCamSeam:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Since we use camScreen in this subroutine, we'll have to make sure it's properly updated
;;; before get our column and screen.
LDA camY_hi
ASL
ASL
ASL
ASL
CLC
ADC camX_hi
CMP camScreen
BNE +
JMP +skipchanges
+
STA camScreen
;;THE SCREEN HAS CHANGED BY SCROLLING TO THE NEXT!
;;UPDATE STUFF HERE

SwitchBank #$16
LDY camScreen
LDA warpMap
BEQ +loadOverWorldMap
;;;load from map 2 table aka Underworld
LDA CollisionTables_Map2_Lo,y
STA temp16
LDA CollisionTables_Map2_Hi,y
STA temp16+1
JMP +skip

+loadOverWorldMap
LDA CollisionTables_Map1_Lo,y
STA temp16
LDA CollisionTables_Map1_Hi,y
STA temp16+1

+skip
ReturnBank

LDA camScreen
LSR
LSR
LSR
LSR
LSR
STA temp ; bank
LDA warpMap
BEQ +loadOverWorldMap
;; modify the bank if we are in the underworld
LDA temp
CLC
ADC #$08
STA temp

+loadOverWorldMap
SwitchBank temp



You should now be able to scroll using the "underworld" map.


What led me to this conclusion?


1) A look at LoadNametableData.asm in the MACROS had this line:

;;; arg2_hold has screen bits.
;;; bit 0 = overworld (0) underworld (1)
;;; bit 1 = metaTable (0) 8x8 table (1)
...
LDA arg2

AND #%00000001
BEQ loadFromMap1table
;;;load from map 2 table
LDA NameTablePointers_Map2_lo,y
STA temp16
LDA NameTablePointers_Map2_hi,y
STA temp16+1
LDA arg0_hold
CLC
ADC #$08
STA arg0_hold
JMP GotNametableLoadPointer
loadFromMap1table:
LDA NameTablePointers_Map1_lo,y
STA temp16
LDA NameTablePointers_Map1_hi,y
STA temp16+1

I noticed there was a reference to a Map1 and a Map2. Then I noticed that the new scrolling file only references Map1 (Overworld) and not Map2 (Underworld)

So those needed to be fixed. However that wasn't enough, so I went digging some more in how the screen were loaded and then noticed this doDrawBoxLoop that the screen bank was modified any time the map was referencing the underworld:

LDA temp
CLC
ADC #$08
STA temp

So that led me to conclude that in order to scroll in the underworld, we need to check BOTH the right Map table AND the right bank.


I don't "fully" understand the entire picture but it works.
 
Last edited:
Hello NESmakers,

I believe I figured out a way to make scrolling work in "underworld" map. It isn't optimized so feel free to improve.

If this was already known, feel free to skip this post.

This is what I did to make it work:

Step one:

Find this around the 260-ish line (not sure since you may have made modifications)



and replace it with this:




Step Two:

Find this line around the 602-ish area



and replace it with this





You should now be able to scroll using the "underworld" map.


What led me to this conclusion?


1) A look at LoadNametableData.asm in the MACROS had this line:


...


I noticed there was a reference to a Map1 and a Map2. Then I noticed that the new scrolling file only references Map1 (Overworld) and not Map2 (Underworld)

So those needed to be fixed. However that wasn't enough, so I went digging some more in how the screen were loaded and then noticed this doDrawBoxLoop that the screen bank was modified any time the map was referencing the underworld:



So that led me to conclude that in order to scroll in the underworld, we need to check BOTH the right Map table AND the right bank.


I don't "fully" understand the entire picture but it works.
works beautifully!
 

smilehero65

Active member
DOWNLOAD HERE

I've been working on my own game and thought that people might benefit from a few tweaks/changes I've made to the doUpdateCamera script. (the script that handles all scrolling)

Below is a version of the script that I've modified mostly by copy/pasting from other peoples tweaks. It started with the most stable scrolling script I am aware of, the "Scrolling with Re-centering" by AllDarnDavey, which corrects a lot of screen issues on its own


Bug Fixes:

-Multiple objects spawning at once when scrolling
-No inputs scripts needed
-Screen flags no longer update every frame, instead they update when a new screen is centered. so changes can be made without being lost immediatly
-Warpto screen now updates, no longer only uses the settings set on the first screen of the level

New Features:

-toggle between no scroll, autoscroll, and player following "camera modes"
-all scrolling features can be adjusted screen by screen, so you can have sections that autoscroll and sections that follow the player in the same level.
-left and right scrolling/autoscrolling
-adjust autoscroll speed with "screenSpeed" variable in screen settings dropdown
-while scrolling, the following gets adjusted when the new screen comes fully into frame:
  • scroll speed
  • screen flags
  • warpto screen
  • tile pallette
  • music
HOW TO USE THIS
A more detailed walkthrough can be found HERE (thank you baardbi )
1: replace your "handle camera" script with the file attached to this post
2: delete all the input scripts that control scrolling
  • By default, the camera will follow the player. To change to autoscroll, screenflag6 is the flag to check. (this can be changed at the beginning of the script)
  • To determine the direction of the autoscroll, check "right edge for scroll" to go left, and "left edge for scroll" to go right.
  • For no scrolling at all, check both the right and left edge flags and the camera will not move
  • When the scrolling comes across a scroll edge, it will stop. to start it going again, uncheck the screen flag. for example, this will uncheck right edge:
Code:
LDA ScreenFlags00
   AND #%11101111
   STA ScreenFlags00


I'm sure theres a lot that can be improved or made more efficient. IF anyone has any suggestions or issues, we can all edit it together and I'll keep it updated on this first post.

EXTRA:
you can edit your physics script to help push your player along any autoscrolling areas: https://www.nesmakers.com/index.php...-along-with-your-camera-scrolling-4-5-9.8055/
for horizontal shooter games, adjust the speed of your ship along with the scrolling here: http://www.nesmakers.com/index.php?...-dohandlecamera-updates-fixes.7929/post-48125
OTHER FIXES

FOR COLLISION FIX WITH THE SEAM, CHECK OUT THIS LINK: https://www.nesmakers.com/index.php?threads/scrolling-platformer-seam-collision-fix-4-5-9.7266/

FOR CORRUPTED TILES DURING SCROLLING AFTER WARPING: http://www.nesmakers.com/index.php?...arping-without-buffer-screens.7295/post-40092
Hey SciNEStist!
I love your scrolling handler!

I know Byte-Off just started, so if you can't answer I understand...

I just need a little help to change the object that the camera can follow.
Instead of the player 1 object, it would be player 2 object (#$01)

Any suggestions?
 
Top Bottom