Jump to content



1

New 2600 Programmer Confused by Player Positioning


5 replies to this topic

#1 brainwagon OFFLINE  

brainwagon

    Combat Commando

  • 7 posts

Posted Thu Sep 8, 2005 8:52 AM

I'm having some difficulty understanding horizontal positioning code, in that it doesn't behave like I expect. I began by looking at the "Revolutionary Horizontal Positioning Code", but that didn't work as expected, and so I started running some experiments on my own. This only serves to confuse me more.

Here's what I think, and what I found out. I'm trying to position a player flush with the left most edge of the playfield. The playfield begins 68 TIA clocks into a scanline. So, I execute the following code

sta wsync
nop <repeated 10 times, for 20 cycles>
sta resp0

By my count, this should execute 23 cycles or 69 clocks into the line, leaving one blank space (which presumably I could move by loading hmp0 with $10 and executing an hmove). But instead, I get the player several pixels in from the left (see the attachment).

Am I fundamentally missing something about how the cycle timings work? Is there some edge condition that I'm unaware of? Until I can figure out how these simple examples work, it seems understanding the more complicated revolutionary stuff is just a pipe dream.

Thanks for your patient instruction.

Attached Thumbnails

  • Untitled_4.png


#2 vdub_bobby OFFLINE  

vdub_bobby

    Quadrunner

  • 5,831 posts
  • Boom bam.
  • Location:Seattle, WA

Posted Thu Sep 8, 2005 9:58 AM

See here: http://www.atariage....ndpost&p=894475

Quote

A RESP will set the objects position to the pixel at which the write happens. But the TIA needs a couple of cycles from the pixel clock to set up the actual output. Therefore all objects will be delayed by a couple of pixels.

The offset is 4 pixels for missiles and the ball, 5 pixels for single-width players, and 6 pixels for double- and quadrouple-width players. You need to take these offsets into account when calculating the position of an object.

Edit: And also, any RESxx during HBlank (cycles 0 to 22) will position the object at the left-most edge* of the screen; you don't have to hit RESxx exactly at cycle 23.

*Taking into account the offset listed above, of course. So hitting RESP0 between cycle 0 and 22 will position player 0 at pixel 5.

Here is a sprite positioning routine that is a little easier to use than most of the others I have seen:
PositionASpriteSubroutine
   sta HMCLR
   sec
   sta WSYNC         ;                      begin line 1
DivideLoop
   sbc #15
   bcs DivideLoop    ;+4/5    4/ 9.../54

   eor #7            ;+2      6/11.../56
   asl
   asl
   asl
   asl               ;+8     14/19.../64

   sta.wx HMP0,X     ;+5     19/24.../69
   sta RESP0,X       ;+4     23/28/33/38/43/48/53/58/63/68/73
   sta WSYNC         ;+3      0              begin line 2
   sta HMOVE         ;+3
   rts               ;+6      9

Set X to the index into which object you want to position (0 = player 0, 1 = player 1, 2 = missile 0, 3 = missile 1, 4 = ball)
Set A to the pixel you want to position the object at. The nice thing about this routine is that, for normal-width players, setting A to zero will position the player at the left-most edge of the screen. Setting A to 159 will position the player at the right-most edge of the screen.
The other nice thing about this routine is that it will always always take exactly the same number of cycles* - call this with 14 cycles left in the scanline and it will always return 99 cycles later (9 cycles into the 2nd scanline).

I have used this or a variation of it in almost every 2600 binary I have written.

*If you feed it a position between 0 and 159

Edited by vdub_bobby, Thu Sep 8, 2005 10:13 AM.


#3 brainwagon OFFLINE  

brainwagon

    Combat Commando

  • 7 posts

Posted Thu Sep 8, 2005 11:19 AM

This was exactly the information I needed. I find it a bit surprising that this useful information isn't in any of the tutorial information that I've found so far. Your presentation (and routine) are probably just about the most clear that I've seen.

Hmm. perhaps I should write a tutorial myself. :-)

#4 vdub_bobby OFFLINE  

vdub_bobby

    Quadrunner

  • 5,831 posts
  • Boom bam.
  • Location:Seattle, WA

Posted Thu Sep 8, 2005 12:11 PM

brainwagon, on Thu Sep 8, 2005 10:19 AM, said:

This was exactly the information I needed.  I find it a bit surprising that this useful information isn't in any of the tutorial information that I've found so far.  Your presentation (and routine) are probably just about the most clear that I've seen. 

Hmm.  perhaps I should write a tutorial myself. :-)

View Post

Yeah, it can be hard to find this info. I was tearing my hair out about 6 months ago because I couldn't figure out why my double- and quad-width sprites weren't positioned where they were supposed to be. I double- and triple-checked my code for bugs, and then finally created a test binary to confirm that, yes, double-width and quad-width sprites are positioned one pixel to the right of normal-width ones. I'd never seen that information anywhere!

#5 xucaen OFFLINE  

xucaen

    Star Raider

  • 94 posts
  • Looking for new owner for commodore 64
  • Location:Ma

Posted Mon Jun 26, 2006 8:42 AM

I just wanted to link this post to another that explains the sta.wx HMP0,X notation.

http://www.atariage....s...st&p=905221

#6 Devin OFFLINE  

Devin

    Moonsweeper

  • 487 posts
  • Its all HCLR to me!
  • Location:Sacramento, California,

Posted Fri Dec 21, 2007 12:11 AM

View Postvdub_bobby, on Thu Sep 8, 2005 7:58 AM, said:

Here is a sprite positioning routine that is a little easier to use than most of the others I have seen:

PositionASpriteSubroutine
   sta HMCLR
   sec
   sta WSYNC;					  begin line 1
DivideLoop
   sbc #15
   ...
   rts			;+6	  9

EDIT: Excellent! My biggest worry about my first program was positioning sprite. With just a dozen or so lines - you dispelled my problems!

Thank you.

Edited by Devin, Fri Dec 21, 2007 4:48 AM.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users