Jump to content

Photo

subpixel positioning (thread split)


7 replies to this topic

#1 kisrael OFFLINE  

kisrael

    HMBL 2600 coder

  • 4,071 posts
  • Location:Boston Burbs, MA

Posted Mon Aug 1, 2005 3:32 PM

* sub pixel movement (huuge gameplay improvement -- can't wait til bB can handle similar stuff natively)

Yeah baby.  Brings a whole new feel to the game.  I've got an idea I want to do in the near future that would require this.  Can't imagine doing it now --all those loops and counters.  And inertia too!

Loops, Counters?

Well, based on my half-remembered JoustPong experience, all you'd need to get something with J-P's inertia feel is 16 bit math, just some addition and/or subtraction...oh wait, you mean 8 bit fixed point? I guess that might use more bit wise looping or something.

#2 potatohead OFFLINE  

potatohead

    River Patroller

  • 4,404 posts
  • Location:Portland, Oregon

Posted Mon Aug 1, 2005 3:50 PM

* sub pixel movement (huuge gameplay improvement -- can't wait til bB can handle similar stuff natively)

Yeah baby.  Brings a whole new feel to the game.  I've got an idea I want to do in the near future that would require this.  Can't imagine doing it now --all those loops and counters.  And inertia too!

Loops, Counters?

Well, based on my half-remembered JoustPong experience, all you'd need to get something with J-P's inertia feel is 16 bit math, just some addition and/or subtraction...oh wait, you mean 8 bit fixed point? I guess that might use more bit wise looping or something.

View Post


I was thinking the latter to save on overall storage. GIven an all assembly project, one might have more bytes avaliable to them. Storage in the Batari environment is limited...

Either way, sub-pixel movement is almost always a better gameplay experience.

#3 supercat OFFLINE  

supercat

    Quadrunner

  • 6,401 posts

Posted Mon Aug 1, 2005 4:55 PM

I was thinking the latter to save on overall storage.  GIven an all assembly project, one might have more bytes avaliable to them.  Storage in the Batari environment is limited...

View Post


If you have enough variables to double them up for position and velocity, it's not too hard to do 16-bit maths. I don't have bB loaded and handy, but if you want to add vel1h:vel1l to pos1h:pos1l, you should be able to do something like:
pos1h = pos1h + vel1h
pos1l = pos1l + vel1l
if pos1l < vel1l then pos1h=pos1h+1
A little clunky in both source and compiled code, but it should be workable. Adjusting a velocity with 'clipping' can be tricky, but is doable. Suppose you're trying to accellerate an object by an amount specified in acc1h:acc1l, clipping the results at +/- 8. Something like this should do the job
vel1h = vel1h + acc1h
vel1l = vel1l + acc1l
if vel1l < acc1l then vel1h=vel1h+1
if vel1h+8 > 16 then if vel1h(7)  then vel1h=248 else vel1h = 8

Note that the latter check is missing in 'Space War' which allows a player to accellerate to absurd velocities.

#4 kisrael OFFLINE  

kisrael

    HMBL 2600 coder

  • Topic Starter
  • 4,071 posts
  • Location:Boston Burbs, MA

Posted Mon Aug 1, 2005 9:07 PM

Sorry for the thread split...I don't want to be ontopictyrant but this really interests me and it deserves not to be under some arguments about what makes a good bB cart label...

Hmmm...I don't have a good mind for 8bit/16bit "hacks"...I tried to apply your code (except for the clipping) to a man moving left and right. DId I get the implementation right? I wasn't getting the final results I hoped for...

  dim vel0hi=a 
  dim vel0lo=b 
  dim acc0hi=c 
  dim acc0lo=d 
  dim pos0hi=e 
  dim pos0lo=f 


  vel0hi = 0
  vel0lo = 0
  acc0hi = 0
  acc0lo = 0
  pos0hi = 0
  pos0lo = 0


  COLUPF = 90

  pfpixel 5 5 on

  pos0hi = 20
  player0y = 20


  player0:
  %01100110
  %00100100
  %10111101
  %10111101
  %01111110
  %00111100
  %00111100
end

startLoop
  acc0lo = 0
  acc0hi = 0

  if joy0right then acc0lo = #30
  rem if joy0left then acc0lo = #-30


  vel0hi = vel0hi + acc0hi
  vel0lo = vel0lo + acc0lo
  if vel0lo < acc0lo then vel0hi = vel0hi + 1

  pos0hi = pos0hi + vel0hi
  pos0lo = pos0lo + vel0lo
  if pos0lo < vel0lo then pos0hi=  pos0hi + 1


  player0x = pos0hi


  COLUP0 = $04

  drawscreen

  goto startLoop


#5 supercat OFFLINE  

supercat

    Quadrunner

  • 6,401 posts

Posted Mon Aug 1, 2005 10:21 PM

Hmmm...I don't have a good mind for 8bit/16bit "hacks"...I tried to apply your code (except for the clipping) to a man moving left and right. DId I get the implementation right? I wasn't getting the final results I hoped for...

View Post


Because acc0hi:acc0lo is a 16 bit number, you need to treat it as one. Most notably, a value of -30 should be -30 in the LSB and -1 in the MSB. What other problems were you having, and can you PM me the assembly code?

#6 potatohead OFFLINE  

potatohead

    River Patroller

  • 4,404 posts
  • Location:Portland, Oregon

Posted Mon Aug 1, 2005 10:57 PM

Hmmm...I don't have a good mind for 8bit/16bit "hacks"...I tried to apply your code (except for the clipping) to a man moving left and right. DId I get the implementation right? I wasn't getting the final results I hoped for...

View Post


Because acc0hi:acc0lo is a 16 bit number, you need to treat it as one. Most notably, a value of -30 should be -30 in the LSB and -1 in the MSB. What other problems were you having, and can you PM me the assembly code?

View Post


I'm going to follow this with interest, but it's going to exceed my limited experience.

I just had a random thought.

Could one get the subpixel movement with a simple bitmask?

Lets say we wanted three bits of subpixel movement. Before doing graphics calls, shift the numbers down? Too cycle expensive?

#7 supercat OFFLINE  

supercat

    Quadrunner

  • 6,401 posts

Posted Tue Aug 2, 2005 12:06 AM

Could one get the subpixel movement with a simple bitmask?


Under some circumstances. Suppose you have a bunch of objects whose sub-pixel velocity (0-255) is stored in v0..v7 and whole-pixel position is in p0..v7. Keeping track of the subpixel position of all those objects would require another eight bytes, which may not be available. As an alternative, if you have a free-running frame counter and a spare temp variable, you can use something like this:
temp=not (frame-1) and frame
if temp and v0 then p0=p0+1
if temp and v1 then p1=p1+1
etc.
This will have a pixel worth of 'jitter', but will save a bunch of memory. This approach is nice when combined with the other approach you allude to, because using both approaches together provides less jitter than using the first alone, and more precision than using the second.

Lets say we wanted three bits of subpixel movement.  Before doing graphics calls, shift the numbers down?  Too cycle expensive?

This is a fine approach if you can deal with the restricted range of motion it would imply. If you shift your positions downward by three bits, you'll be limited to 31 pixels (or double-pixels) worth of motion. Probably excessively confining. On the other hand, taking off one bit might not be a problem.

#8 potatohead OFFLINE  

potatohead

    River Patroller

  • 4,404 posts
  • Location:Portland, Oregon

Posted Wed Aug 3, 2005 12:20 PM

Could one get the subpixel movement with a simple bitmask?


Under some circumstances. Suppose you have a bunch of objects whose sub-pixel velocity (0-255) is stored in v0..v7 and whole-pixel position is in p0..v7. Keeping track of the subpixel position of all those objects would require another eight bytes, which may not be available. As an alternative, if you have a free-running frame counter and a spare temp variable, you can use something like this:
temp=not (frame-1) and frame
if temp and v0 then p0=p0+1
if temp and v1 then p1=p1+1
etc.
This will have a pixel worth of 'jitter', but will save a bunch of memory. This approach is nice when combined with the other approach you allude to, because using both approaches together provides less jitter than using the first alone, and more precision than using the second.

Lets say we wanted three bits of subpixel movement.  Before doing graphics calls, shift the numbers down?  Too cycle expensive?

This is a fine approach if you can deal with the restricted range of motion it would imply. If you shift your positions downward by three bits, you'll be limited to 31 pixels (or double-pixels) worth of motion. Probably excessively confining. On the other hand, taking off one bit might not be a problem.

View Post



...which brings us back to two byte variables... Shifting all the bits down takes care of the rounding issues. The number of bits shifted determines the fractional position, the number remaining is the range of allowed motion.




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users