Jump to content
IGNORED

HMBL and HMOVE: ball is jumping scanlines


Recommended Posts

Hi, I've been experimenting with HMOVE and HMBL. All I'm doing is moving a ball horizontally. I place the ball at about scanline 89 (counting from the bottom) and set the HMBL to move the ball one clock to the left (1111). But for some reason at somewhere around color clock 60 (give or take) the ball seems to jump up to scanline 90. This happens in stella as well as z26 emulators. At first I thought my timers were off, so I changed the code to use an index but I get the same effect. I'm unable to figure out why the ball is jumping scanlines. I'm attaching source code example that uses the timer (ball2.zip) and attaching code that uses index (ball2a.zip).

 

Jim

ball2.zip

ball2a.zip

Link to comment
Share on other sites

The problem is called tearing and it has nothing to do with HMOVE and HMBL. There are quite a lot of 2600 game which suffer from it, thought it can almost always be avoided.

 

I happens because you enable/disable/change an object inside the visible area (~cycles 23..75) of the screen. Make sure that your write to ENABL happens during cycles 0..22.

Link to comment
Share on other sites

screen. Make sure that your write to ENABL happens during cycles 0..22.

907424[/snapback]

 

Thanks, I was purposely using the SLEEP macro to put the write to ENABL in the visible area. I guess I misunderstood how it worked. I removed the SLEEP statement and.. well, now the glitch happens at the left edge of the screen. I think my cycle counting is off a bit. :-)

 

Question, are all of the ENA* registers the same where they have to be written to during Hblank?

 

I think I'm starting to fully understand the relationship between the RES* and ENA* registers.

 

->writing to the RES* registers will place the object at the color clock when it was written to.

->Writing to an RES* register every frame will essentially prevent the object from moving horizontally (I know that probably sounds obvious, but I didn't understand until I actually saw it happen)

->I'm thinking write to the RES* register once before the game loop begins to place the objects the first time

->write to the RES* register during the game loop only if the object is going to change it's position

->write to the ENA* register to start drawing the object on the "current "scanline

->write to the ENA* register again to turn it off.

->write to the HM* and HMOVE registers at least once per frame (either during VBlank or Overscan) to tell the object to begin horizontal motion.

-> write to the HM* register again to turn off horizontal motion. HMCLR to stop all horizontal motion.

 

Question, I have not tried this yet, but would I ever want to write to HM* and HMOVE during the 192 scanline loop? My guess is no.

 

 

Thanks!

 

Jim

Link to comment
Share on other sites

Question, are all of the ENA* registers the same where they have to be written to during Hblank?

Yes (and a little no). ENAM* should be accessed during HBlank (better: during the area where they are never visible). The same is true for GRP* (using VDELP* gives you more flexibility here)

 

ENABL however can be used together with VDELBL, which delays the write to ENABL until the next write to GRP1. Anyway, that's rather complicated and probably not important for you now.

 

->write to the HM* and HMOVE registers at least once per frame (either during VBlank or Overscan) to tell the object to begin horizontal motion.

-> write to the HM* register again to turn off horizontal motion. HMCLR to stop all horizontal motion.

Everything else is about right, but you only have to write to HM* again, if you use HMOVE again (e.g. to stop one sprite while the other one has to be repositioned). So usually you write to all necessary RES* and HM* registers outside the kernel, followed by a single HMOVE. That's all.

 

Question, I have not tried this yet, but would I ever want to write to HM* and HMOVE during the 192 scanline loop? My guess is no.

Sure, for kernels where you want to reuse a sprite again (e.g. Frogger, River Raid etc.). Then you have to reposition the sprite and therefore need to use RES*, HM* and HMOVE inside the kernel too.

Link to comment
Share on other sites

  • 2 weeks later...
The problem is called tearing and it has nothing to do with HMOVE and HMBL. There are quite a lot of 2600 game which suffer from it, thought it can almost always be avoided.

 

I happens because you enable/disable/change an object inside the visible area (~cycles 23..75) of the screen. Make sure that your write to ENABL happens during cycles 0..22.

907424[/snapback]

 

One game that has a really bad tearing problem is Motorodeo. When the trucks are in mid jump it looks almost like there is a missing scanline.

 

I hate tearing with a passion. I couldn't believe you managed to avoid this in the DD kernel.

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...