Warp Tile Next Screen Over R, L, U, and D

DarthAT

Member
I am trying to make a warp tile that warps the player to the next screen, either UP, Down, Left, or Right based on the tile type. Goal is to move sprite from room to room using a "door" drawn on background wall, and not just moving up to next screen (that looks funny with my background).

I have been playing with code on how to do this but it no matter what I change it warps me to the lower right corner of underworld x=1, y=3. Can I please get some help with this code? I do want to warp to the underworld so that part is working, but I want it to warp me to X=2, Y=4

Code:
    ;;CPX player1_object
    ;;BNE +notPlayerForWarpTile
    
    ;WarpToScreen 0, #%00111111, #$02
        ;; arg0 = warp to map.  0= map1.  1= map2.
        ;; arg1 = screen to warp to.
        ;; arg2 = screen transition type - most likely use 1 here.
            ;; 1 = warp, where it observes the warp in position for the player.
        
    LDA 0
    STA warpMap
    
+doActivateScrollByte:
    RIGHT_SCROLL_PAD = #$60
   LDX player1_object
   LDA Object_x_hi,x
    SEC
    SBC camX
    CMP #RIGHT_SCROLL_PAD
    BEQ +doActivateScrollByte
    BCS +doActivateScrollByte
        LDA scrollByte
        AND #%00111111
        STA scrollByte
        RTS
+doActivateScrollByte
    LDA scrollByte
    AND #%01101000    ;;#%01000000
    BNE +notChangingCamDirectionForUpdate
    LDA scrollByte
    ORA #%11011010     ;;#%00000010
 +notChangingCamDirectionForUpdate
    AND #%11100101      ;;#%00111111
   ORA #%00010110      ;;#%11000000
    STA scrollByte
    ;;; just like movement byte of a player.
    ;;; bit 7 indicates horizontal movement of a player
    ;;; bit 6 indicates 0 for left, 1 for right.
    
    LDA #$01
    STA screenTransitionType ;; is of warp type
    
    LDA updateScreenData
    AND #%11111011
    STA updateScreenData
    LDA scrollByte
    AND #%11111110
    STA scrollByte
    LDA #$00
    STA scrollOffsetCounter
    

    
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.
    
+notPlayerForWarpTile:
 

CutterCross

Active member
I haven't looked into potential differences with warping on scrolling screens, but the logic is basically this:

Code:
;;;; Warp Up
   
    CPX player1_object
    BNE +notPlayerForWarpTile
   
    LDA currentNametable
    ;;;; Warping up 1 gameplay screen
    SEC
    SBC #$10    ;; Would need to be #$20 for 8x8 tile density screens
    STA warpToScreen    ;; Since warpToScreen is going to be rewritten on next screen load,
                        ;; it's okay to overwrite it in this instance.
   
    WarpToScreen warpToMap, warpToScreen, #$01
   
+notPlayerForWarpTile:

Code:
;;;; Warp Down
   
    CPX player1_object
    BNE +notPlayerForWarpTile
   
    LDA currentNametable
    ;;;; Warping down 1 gameplay screen
    CLC
    ADC #$10    ;; Would need to be #$20 for 8x8 tile density screens
    STA warpToScreen    ;; Since warpToScreen is going to be rewritten on next screen load,
                        ;; it's okay to overwrite it in this instance.
   
    WarpToScreen warpToMap, warpToScreen, #$01
   
+notPlayerForWarpTile:

Code:
;;;; Warp Left
   
    CPX player1_object
    BNE +notPlayerForWarpTile
   
    ;;;; Warping left 1 screen
    LDA currentNametable
    STA warpToScreen
    DEC warpToScreen    ;; Since warpToScreen is going to be rewritten on next screen load,
                        ;; it's okay to overwrite it in this instance.
   
    WarpToScreen warpToMap, warpToScreen, #$01
   
+notPlayerForWarpTile:

Code:
;;;; Warp Right
   
    CPX player1_object
    BNE +notPlayerForWarpTile
   
    ;;;; Warping right 1 screen
    LDA currentNametable
    STA warpToScreen
    INC warpToScreen    ;; Since warpToScreen is going to be rewritten on next screen load,
                        ;; it's okay to overwrite it in this instance.
   
    WarpToScreen warpToMap, warpToScreen, #$01
   
+notPlayerForWarpTile:

***EDIT: Accidently used warpToScreen as the current screen instead of currentNametable. Just a slight mishap when looking over my own implementation. Whoops.
 
Last edited:

DarthAT

Member
Hmmm, I feel like the LDA warpToScreen is pointing to the Warp Info settings in Screen Details (am I wrong here?) What I need is the LDA to point to the current screen I am on and then INC/DEC/Carry to that screen, but I don't know what the correct syntax for my current screen would be.

1605969435454.png

Am I on the right path here? I tried plugging in the above code (multiple ways) and it is not behaving like I want.
What I do know:
  • In the code in the pic above as is, will warp me out to the settings in my warp info in screen settings. I have verified this by changing the warp out location from the room. As there will be multiple doors in any given room, I need the code to check the room itself and NOT look at the warp out info.
  • If I comment out LDA warpToScreen (see below), it will act like it is warping (with the warp transition) but place me back in the same room.
1605969688244.png

I know the answer lies somewhere in between, I am just not sure what accumulator/variable/etc. to call at this point????
 

DarthAT

Member
Ugggg, I have tried everything (lol, I know that does not help). I have tried INC on camScreen, currentNametable, tileY... I just cant figure this out with my limited understanding of ASM, and much more.

This is just some of the things I have tried.

1605981176345.png
 

CutterCross

Active member
I just realized my examples started off with using warpToScreen as the starting screen instead of currentNametable. That's fixed now. Again, haven't messed around with NESmaker's scrolling engine much but it may or may not need to be replaced with camScreen.
 

dale_coop

Moderator
Staff member
The general logic of what you need to do, is:
get the current screen (LDA currentNametable or LDA screenCam)
calculate the one you want to go (depending of the directions...right: ADC #$01 or left: SBC #$01 or down: ADC #$10 or up: SBC #$10)
warp to that "calculated" screen (STA warpToScreen)

Check again the script CutterCross updated, it should work (maybe you will have to replace currentNametable by screenCam for the scrolling module)
 

DarthAT

Member
Thank you Dale and Cuttor!! I have this working now using the following code:
Code:
;;;; Warp 1 Screen Up
  
    CPX player1_object
    BNE +notPlayerForWarpTile
 
       LDA 0
    STA warpMap
    
    LDA currentNametable
    SEC
        ;;SEC - Set Carry Flag.  Sets the Carry Flag to 1
    SBC #$10 ;;1 screen Up
    STA currentNametable
    
    LDX player1_object
    STA Object_screen,x
    STA camScreen
    LDA #$00
    STA camX_lo
    STA camX
    
    LDA 1
    STA screenTransitionType ;; is of warp type
    
    LDA updateScreenData
    AND #%11111011
    STA updateScreenData
    LDA scrollByte
    AND #%11111110
    STA scrollByte
    LDA #$00
    STA scrollOffsetCounter
    
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.

+notPlayerForWarpTile:

One last bit of help, if I may ask...
I need it to warp me into a specific place in the room. I found some code that points to warp in location and have tried to manipulate it, without success. How would incorparate this into the above code so I can set a static warp in location?
Code:
;; 128 - Warp In Position
;; This might need to be skipped under certain warp conditions
;; and should only be observed if the transition is of warp type.
    LDA screenTransitionType
    BEQ skipSettingWarpInXY
    CMP #$01
    BEQ setToStartValue
    CMP #$02
    BEQ setToContinueValue
        ;;; other cases go here
setToContinueValue
    LDA continueX
    STA newX
    LDA continueY
    STA newY
    JMP skipSettingWarpInXY
setToStartValue:

    LDA (collisionPointer),y
    AND #%11110000
    STA newY
    
    LDA (collisionPointer),y
    AND #%00001111
    ASL
    ASL
    ASL
    ASL
    STA newX
    
    
skipSettingWarpInXY:
    LDA #$00
    STA screenTransitionType ;; reset screen transition type
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Again,
thank you for all the help, I really appreciate and learn from it every time.
 

dale_coop

Moderator
Staff member
You could try...

In that last script (doLoadScreenData.asm), after the line 109:
Code:
    ;;; other cases go here
Add this:
Code:
    JMP skipSettingWarpInXY

Then in your warp tile scripts, instead of
Code:
    WarpToScreen warpToMap, warpToScreen, #$01
Use:
Code:
    LDA #$50    ;; <-- vertical coord position
    STA newY
    LDA #$20   ;; <-- horizontal coord position
    STA newX
    WarpToScreen warpToMap, warpToScreen, #$00  ;; <-- "00" here !
 
Top Bottom