Jump to content



1

HMBL and HMOVE: ball is jumping scanlines


4 replies to this topic

#1 xucaen OFFLINE  

xucaen

    Star Raider

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

Posted Mon Aug 8, 2005 11:11 PM

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

Attached Files



#2 Thomas Jentzsch OFFLINE  

Thomas Jentzsch

    Thrust, Jammed, SWOOPS!

  • 16,745 posts
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Tue Aug 9, 2005 1:32 AM

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.

#3 xucaen OFFLINE  

xucaen

    Star Raider

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

Posted Tue Aug 9, 2005 1:20 PM

Thomas Jentzsch, on Tue Aug 9, 2005 2:32 AM, said:

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

View Post


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

#4 Thomas Jentzsch OFFLINE  

Thomas Jentzsch

    Thrust, Jammed, SWOOPS!

  • 16,745 posts
  • Always left from right here!
  • Location:Düsseldorf, Germany

Posted Tue Aug 9, 2005 1:52 PM

xucaen, on Tue Aug 9, 2005 9:20 PM, said:

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.

Quote

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

Quote

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.

#5 mos6507 OFFLINE  

mos6507

    River Patroller

  • 4,728 posts

Posted Tue Aug 23, 2005 12:55 PM

Thomas Jentzsch, on Tue Aug 9, 2005 12:32 AM, said:

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.

View Post


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.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users