Jump to content
IGNORED

Does limiting horizontal movement to 127 have any advantage?


Ra1ny Tapestry

Recommended Posts

Hi I'm new to this forum,

 

I was following a guide on programming for the Atari 2600, and when the guide introduced horizontal positioning, he used an AND   #%01111111 instruction to wrap the player around to the other side, but then he silently abandoned it and moved on to just using comparisons to check whether the player is at #0 or #160. I thought this was an amazing trick, since an AND only uses 2 cycles, but every time I try forcing myself to include AND   #%01111111 in my positioning code, it actually winds up using more space and cycles than my normal implementation. I'm still scratching my head wondering why it's inefficient, because when I first saw the first method I went "oh, so that's why you can't move to the edge in a lot of Atari games. It's more efficient to just bound them to 127," so I can't help but be convinced there's some way I just don't know about.

 

Here are a few examples of what I'm talking about:

 

Combat (Walls seem to bound players to 127 positions)

bWJhdC5qcGc

 

Space Invaders (Movement doesn't seem to be limited by design)

bS9ybU41dS5qcGc

These are just to illustrate what I'm talking about. I don't have any of the ROMs, so I can't say for certain any of them are bound to 127 positions. Also, in case there is no efficiency trick, I'd also appreciate explanations why these and a lot of other games limit player movement.

Link to comment
Share on other sites

  • 2 weeks later...

Not sure if this is the reason for these games, but in mine there is reason to limit my bounds to the range 0-134.

 

My game was built off of the fundamentals shown in SpiceWare's Let's Make a Game! tutorial, and in it there's the routine PosObject that sets the x position of TIA objects

 

;===============================================================================
; PosObject
;----------
; subroutine for setting the X position of any TIA object
; when called, set the following registers:
;   A - holds the X position of the object
;   X - holds which object to position
;       0 = player0
;       1 = player1
;       2 = missile0
;       3 = missile1
;       4 = ball
; the routine will set the coarse X position of the object, as well as the
; fine-tune register that will be used when HMOVE is used.
;===============================================================================
PosObject:
        sec
        sta WSYNC
DivideLoop
        sbc #15        ; 2  2 - each time thru this loop takes 5 cycles, which is 
        bcs DivideLoop ; 2  4 - the same amount of time it takes to draw 15 pixels
        eor #7         ; 2  6 - The EOR & ASL statements convert the remainder
        asl            ; 2  8 - of position/15 to the value needed to fine tune
        asl            ; 2 10 - the X position
        asl            ; 2 12
        asl            ; 2 14
        sta.wx HMP0,X  ; 5 19 - store fine tuning of X
        sta RESP0,X    ; 4 23 - set coarse X position of object
        rts            ; 6 29

For arbitrary x positioning across the entire screen, it's hard to do much better than this code. But it does come with a downside... it takes a variable 1-2 scanlines per call to position an object, which made it impractical when I want to reset my positions after drawing the HUD and Text kernel elements.

 

As such, I came up with this instead:

 

;==============================================================================
; PosWorldObjects
;----------
; Sets X position for all TIA objects within the world view
; X position must be between 0-134 ($00 to $86)
; Higher values will waste an extra scanline
; Does not touch Y register
;==============================================================================
PosWorldObjects: SUBROUTINE
    ldx #4
PosWorldObjects_X: SUBROUTINE
    sec            ; 2
.Loop
    sta WSYNC      ; 3
    lda plX,x      ; 4  4 - Offsets by 12 pixels
DivideLoop
    sbc #15        ; 2  6 - each time thru this loop takes 5 cycles, which is
    bcs DivideLoop ; 2  8 - the same amount of time it takes to draw 15 pixels
    eor #7         ; 2 10 - The EOR & ASL statements convert the remainder
    asl            ; 2 12 - of position/15 to the value needed to fine tune
    asl            ; 2 14 - the X position
    asl            ; 2 16
    asl            ; 2 18
    sta.wx HMP0,X  ; 5 23 - store fine tuning of X
    sta RESP0,X    ; 4 27 - set coarse X position of object
;                  ;   67, which is max supported scan cycle 
    dex            ; 2 69
    bpl .Loop      ; 3 72
    
    sta WSYNC
    sta HMOVE
    rts

By sacrificing some xpos locations, I'm able to position N different TIA objects in a constant N+1 scanlines. In practice, I use it to update both player sprites in 3 scanlines with PosWorldObjects_X and all 5 objects in 6 scanlines with PosWorldObjects.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...