Ra1ny Tapestry Posted September 10, 2022 Share Posted September 10, 2022 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) Space Invaders (Movement doesn't seem to be limited by design) 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. Quote Link to comment Share on other sites More sharing options...
mzxrules Posted September 19, 2022 Share Posted September 19, 2022 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. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.