8x16 and whatever else unreg wants to know

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

Well, I just spent the last 4 hours reading through to the end of this thread. :( I started on page 40. And I have just remembered that my post about attribute tables was destroyed... I don't remember why. I did find my post on page 48 kind of confusing because I didn't find all the attribute table info that was in my destroyed post... ugh. Time to prepare supper for tonight... yall have a good evening! :)
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

tepples wrote:Say you have prepared a column of attribute data. You want to write it to offsets 0, 8, 16, 24, 32, 40, 48, and 56 in the attribute table. But the PPU has no +8 increment mode, just +1 and +32. What you can do is this:
  1. Set the PPU to +32.
  2. Seek (set the address) to 0 and write the entries for 0 and 32.
  3. Seek to 8 and write the entries for 8 and 40.
  4. Seek to 16 and write the entries for 16 and 48.
  5. Seek to 24 and write the entries for 24 and 56.
MIND = VERY BLOWN

Wow, that's quite awesome tepples! THANK YOU!!! I get it now... with the PPU set to +32 you set the address to 0 and then write the entries for 0 (now the PPU increments to 32) and 32... thats just two writes with the PPU incrementing by 32 after each write!!!!!! :D VERY BLOWN :o :D thanks tepples :)

And um well... you did say that this would be possible if our levels were 12 metatiles high... why? It is so grand and I don't understand why it wouldn't work with regular 15 metatile high land. I'm afraid of your answer. Please respond. :D
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tokumaru »

unregistered wrote:you did say that this would be possible if our levels were 12 metatiles high... why?
When tepples mentioned that in the case of 12 metatiles, he said you'd write bytes 0 and 4, 1 and 5, 2, then 3 (meaning you don't have to write attribute bytes 6 and 7), but the technique works just fine with 15 metatiles, you just have to write all 8 attribute bytes.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :mrgreen: THANKS TOKUMARU!!! :D
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

...
unregistered[color=#FF40BF], on the previous page,[/color] wrote:... so, how can we get the attribute table to scroll with the screen? ...
No, not the attribute table... :oops: the collision table. I need to check the collision so our girl can fall into the non-solid water at the end of the second screen that kind of... visually scrolls over. How can we get the collision table to scroll with the screen? Wait... I remember that I didn't even have to create a collision table... it's already accessable right? Or does that sound crazy too... uhmmm... ...? :oops: : )
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

Re: 8x16 sprite is really a 16x32 pixel image?

Post by qbradq »

How are you storing your collision data? That has a lot to do with how to scroll it :D

Typically I just keep a buffer of the metatiles that are on screen, and use the tile ID to index a table of flags that include collision information. To "scroll" this, you simply update the metatile buffer every time you scroll the screen to be in synch with it.

Or if you've got WRAM you can just store the entire level in RAM at once and not have to worry about scrolling the data, just the screen.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tokumaru »

I think that the problem is that your current design is still based on the NES screen and the name tables. Most people start out that way, because it's simpler to move objects around that small area, but once you start messing with scrolling, you have to see things differently: the screen and the name tables are not the containers of the objects anymore, they are merely used as a viewport, to show a representation of part of the level, and the level is the actual container of the objects.

You should forget about the screen and the name tables for a moment, and think of the level map as the basis for your game world. Your objects exist in the level, so everything about them is relative to the level map. Sprite coordinates are not restricted to 8 bits anymore, since levels can be much wider than 256 pixels. To test for collisions, you have to do some math with the object coordinates (like we discussed before), and since the sprite coordinates are in the same domain as level map coordinates, scrolling is absolutely irrelevant to collisions.

To make things easier, ideally you'd have access to the whole map, either by decompressing it to WRAM or storing it uncompressed (or compressed in a way that allows for random access) in the ROM. Having access to the complete level makes it easy to move objects around and have them collide with the level regardless of what the screen and the name tables are showing.

Don't think of scrolling as "the level going by", but rather as "a camera panning across the level". The level is stationary, but a virtual "camera" moves around in order to display different parts of the level, and it's this camera that dictates what gets written to the name tables and the OAM. You camera must have its own coordinates, which are used to convert level coordinates into screen coordinates (i.e. level coordinates - camera coordinates = screen coordinates), and you'll have to perform this conversion whenever you render sprites to OAM or metatile to the name tables.

I know it sounds complicated, but nobody said that scrolling was easy, specially if done right. If you do it the wrong way and keep everything oriented to screen coordinates, things will surely get out of hand (like the problem you are having now, where objects aren't aligning with the collision data).
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

levels can be wider than 256 pixels... according to my math I could have a level with 256 256pixel wide screens... or a have a level at the amount of 65536 pixels wide with 16bit algebra... from 0 to 65535. That's BIG! :D Though, I wonder how do you use 16bit algebra in 8bit CPU? Let's say we are using the number (8192+1)... tha'd be 8193 or 00100000 00000001b ...woah this is kind of like using the number 256 or 00000001 00000000b with numbers 0 to 255... but that works because there are 256 numbers... 255 and the 0. There are not 65536 numbers are there? :?

This is my beginning step with 16 bit math, I think... sorry. :(
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tepples »

You can't fit a 16-bit number in one byte, but you can fit it in two. Here's how to do 16 bit addition, using the example of 508 + 8 = 516 ($01FC + $0008 = $0204):

Code: Select all

position_hi = $0701
position_lo = $0700

  ; set the position to $01FC
  lda #$01
  sta position_hi
  lda #$fc
  sta position_lo

  ; now add eight ($0008) to this position
  clc
  lda #$08  ; add the low byte first
  adc position_lo
  sta position_lo
  lda #$00
  adc position_hi
  sta position_hi
When you add two 8-bit numbers and the result is more than 256, the CPU subtracts 256 and turns on the carry flag. The carry flag tells the CPU to add one extra the next time it adds anything, just as you'd carry the 1 when adding multi-digit base 10 numbers in first grade. Most of the time, an addition will start with the carry off; that's what the clc does. (Clearing a flag means turning it off; setting means turning it on.)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tokumaru »

What tepples said. We only have 10 different digits for representing numbers (0 to 9) but that doesn't mean it's impossible to count to 10: if we use more places for digits, we can represent bigger numbers.

With one digit we can only represent 10 different numbers (0 to 9), but with one more digit we have a total of 100 combinations (0 to 99: each new digit multiplies the number of possible combinations by 10). With bytes it's the same thing. A single byte can only represent 256 different numbers (0 to 255), but if we use a second byte we get a total of 65536 possible combinations (0 to 65535: each new byte multiplies the number of possible combinations by 256).

16, 32 and 64-bit CPUs make the whole thing easier (and faster) by manipulating multiples bytes at a time, while 8-bit CPUs have to do it byte by byte, but they can still perform math with big numbers.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

tokumaru wrote:I think that the problem is that your current design is still based on the NES screen and the name tables. Most people start out that way, because it's simpler to move objects around that small area, but once you start messing with scrolling, you have to see things differently: the screen and the name tables are not the containers of the objects anymore, they are merely used as a viewport, to show a representation of part of the level, and the level is the actual container of the objects.

You should forget about the screen and the name tables for a moment, and think of the level map as the basis for your game world. Your objects exist in the level, so everything about them is relative to the level map. Sprite coordinates are not restricted to 8 bits anymore, since levels can be much wider than 256 pixels. To test for collisions, you have to do some math with the object coordinates (like we discussed before), and since the sprite coordinates are in the same domain as level map coordinates, scrolling is absolutely irrelevant to collisions.

To make things easier, ideally you'd have access to the whole map, either by decompressing it to WRAM or storing it uncompressed (or compressed in a way that allows for random access) in the ROM. Having access to the complete level makes it easy to move objects around and have them collide with the level regardless of what the screen and the name tables are showing.

Don't think of scrolling as "the level going by", but rather as "a camera panning across the level". The level is stationary, but a virtual "camera" moves around in order to display different parts of the level, and it's this camera that dictates what gets written to the name tables and the OAM. You camera must have its own coordinates, which are used to convert level coordinates into screen coordinates (i.e. level coordinates - camera coordinates = screen coordinates), and you'll have to perform this conversion whenever you render sprites to OAM or metatile to the name tables.

I know it sounds complicated, but nobody said that scrolling was easy, specially if done right. If you do it the wrong way and keep everything oriented to screen coordinates, things will surely get out of hand (like the problem you are having now, where objects aren't aligning with the collision data).
Wow, Awesome! Thank you so very much tokumaru!! :D Your words speak to me; they've spoken to me about this new way of thinking about the level staticly... it will all be accessable just like collision is? I'll probably see that answer when I read these important words once again. Thank you very incredibly much for them!! :D
tepples wrote:You can't fit a 16-bit number in one byte, but you can fit it in two. Here's how to do 16 bit addition, using the example of 508 + 8 = 516 ($01FC + $0008 = $0204):

Code: Select all

position_hi = $0701
position_lo = $0700

  ; set the position to $01FC
  lda #$01
  sta position_hi
  lda #$fc
  sta position_lo

  ; now add eight ($0008) to this position
  clc
  lda #$08  ; add the low byte first
  adc position_lo
  sta position_lo
  lda #$00
  adc position_hi
  sta position_hi
When you add two 8-bit numbers and the result is more than 256, the CPU subtracts 256 and turns on the carry flag. The carry flag tells the CPU to add one extra the next time it adds anything, just as you'd carry the 1 when adding multi-digit base 10 numbers in first grade. Most of the time, an addition will start with the carry off; that's what the clc does. (Clearing a flag means turning it off; setting means turning it on.)
Thank you so much tepples! :D This explains how to do 16 bit math on an 8 bit cpu; it will help me alot. :D It has simplified and enritched the way I think about the CPU subtraction! :D ...And I will continue to keep 3gengames' "Set subtract. Clear add." in my head too! :)
tokumaru wrote:What tepples said. We only have 10 different digits for representing numbers (0 to 9) but that doesn't mean it's impossible to count to 10: if we use more places for digits, we can represent bigger numbers.

With one digit we can only represent 10 different numbers (0 to 9), but with one more digit we have a total of 100 combinations (0 to 99: each new digit multiplies the number of possible combinations by 10). With bytes it's the same thing. A single byte can only represent 256 different numbers (0 to 255), but if we use a second byte we get a total of 65536 possible combinations (0 to 65535: each new byte multiplies the number of possible combinations by 256).

16, 32 and 64-bit CPUs make the whole thing easier (and faster) by manipulating multiples bytes at a time, while 8-bit CPUs have to do it byte by byte, but they can still perform math with big numbers.
This is so excellent and helpful to me too tokumaru... THANK YOU!!! :D

edit.
edited again.
last edit.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

qbradq wrote:How are you storing your collision data? That has a lot to do with how to scroll it :D

Typically I just keep a buffer of the metatiles that are on screen, and use the tile ID to index a table of flags that include collision information. To "scroll" this, you simply update the metatile buffer every time you scroll the screen to be in synch with it.

Or if you've got WRAM you can just store the entire level in RAM at once and not have to worry about scrolling the data, just the screen.
My sister doesn't like me asking questions... so I went to the nesdev wiki and searched for "wram". I learned that it stands for (Work RAM (Random Access Memory)). And then I read some of the 300 character search results and have concluded that WRAM is available on a mapper. :) And after another search I learned that MMC5 is the biggest mapper on then NES. So then I went to retrousb.com and discovered that MMC5 support on the powerpak is buggy. (I think mapper 5 is for MMC5.) And I also learned that my powerpak has enough hardware to run MMC5 games! :D So now I'd like to ask yall what are some reasons I shouldn't choose and try to use MMC5 for having WRAM? :) (And I'm aware of ideas that MMC5 is expensive... is it still expensive in todays market? The American economy isn't doing well... so that may be a yes. :?)

edit: Thank you qbradq for help!
Last edited by unregistered on Wed Nov 21, 2012 4:02 pm, edited 2 times in total.
3gengames
Formerly 65024U
Posts: 2284
Joined: Sat Mar 27, 2010 12:57 pm

Re: 8x16 sprite is really a 16x32 pixel image?

Post by 3gengames »

WRAM is great to have, I suggest you use it if you want it, it's cheap today. Especially for 32KB of it. But MMC5 would be bad because while it can support it, it's still a long ways from anywhere near 100% understood and nowhere near workable, it doesn't even work for most games with loopys latest release. Plus it'd be super expensive to recreate. MMC3 would offer the best features and price, and has WRAM support, I'd suggest looking at that if you need a mapper. That, UNROM, or MMC1 are the most commonly used. :)
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered »

Ok thank you 3gengames!! :D
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tokumaru »

unregistered wrote:And then I read some of the 300 character search results and have concluded that WRAM is available on a mapper.
WRAM can be added to any cart, even NROM (i.e. no mapper) ones. The wiki has some information about it.
So now I'd like to ask yall what are some reasons I shouldn't choose and try to use MMC5 for having WRAM?
Because it's the most complex mapper there is. It's overkill to use such an advanced mapper just for the WRAM, while many other simpler and common mappers have support for WRAM as well. Also, the MMC5 still hasn't been fully cloned by anyone in the community, so it's not possible to make carts of new MMC5 games unless you use donor cartridges (MMC5 ones aren't even very common).
(And I'm aware of ideas that MMC5 is expensive... is it still expensive in todays market? The American economy isn't doing well... so that may be a yes. :?)
Current economy has very little to do with this. The MMC5 chip used in Nintendo cartridges simply isn't manufactured anymore, because they were never used for anything besides game cartridges, and Nintendo hasn't released an NES cart in over 15 years. The chips that are currently used to replicate mappers (CPLDs, FPGAs, etc.) become more expensive as they become more complex, so implementing an MMC5 clone will always be more expensive than implementing an MMC3 clone.

My advice is: don't chose a mapper just because of WRAM. Any cart, even NROM ones, can have WRAM. If you're gonna use a mapper, pick the simplest one that has the features you need.
Post Reply