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

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 »

Now that I think of it, the code in this post will indeed add 32 every time after the first time it reaches a multiple of 32. Say that the number is 30, after you add two it become 32, so you add another 30, making it 62, which is also 2 units away from a multiple of 32. If you add 32 to a number that is 2 units away from being a multiple of 32, it will always be 2 units away from a multiple of 32.

So, I still don't understand where you're going with this. What behavior exactly do you expect when the number is 30? shouldn't it become 62? And why shouldn't the 62 become 94? Please show me a few steps of what should happen to that number after a couple of times of going through your macro.
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:Now that I think of it, the code in this post will indeed add 32 every time after the first time it reaches a multiple of 32. Say that the number is 30, after you add two it become 32, so you add another 30, making it 62, which is also 2 units away from a multiple of 32. If you add 32 to a number that is 2 units away from being a multiple of 32, it will always be 2 units away from a multiple of 32.

So, I still don't understand where you're going with this. What behavior exactly do you expect when the number is 30? shouldn't it become 62? And why shouldn't the 62 become 94? Please show me a few steps of what should happen to that number after a couple of times of going through your macro.
It should start at 0 and increment by 2 until it becomes a multiple of 32... then increment by 32... then increment by 2 again until it becomes a multiple of 32 again.

So it should go something like this: 00... 02... 04... 06... 08... 0A... 0C... 0E... 10... 12... 14... 16....18...1A...1C...1E...40... 42... 44... 46... 48... 4A... 4C... 4E... 50...52...54...56...58...5A...5C...5E...80...82...
Last edited by unregistered on Fri Sep 21, 2012 3:40 pm, edited 1 time 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 »

Would you mind telling us what it's for? I don't get why this would be useful in any places honestly...and is this supposed to change a value it has in RAM on a per-run basis?
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 »

3gengames wrote:Would you mind telling us what it's for? I don't get why this would be useful in any places honestly...
It's so...went to look at code... it's what I need to happen during writes to screenArray. screenArray is the memory that holds one screen's collision values... it's 1 byte per 8x8pixel square.
Actually, that sounds like something I fixed for the attribute tables... ...probably was... well this code was in my prg-collisionU.asm page... it's ok. :oops: It's gone now... well, I'll have to think this over. :)

3gengames wrote:is this supposed to change a value it has in RAM on a per-run basis?
Yes. :)

edit
edit2: Well I'm sorry 3gengames and tokumaru... and everyone else who looked at this thread today. :( :oops: It my brain... it's getting so much better though... you'd have to understand the many hours I spent... ...it's ok. :oops: :)
Last edited by unregistered on Fri Sep 21, 2012 5:46 pm, edited 1 time in total.
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:00... 02... 04... 06... 08... 0A... 0C... 0E... 10... 12... 14... 16....18...1A...1C...1E...40... 42... 44... 46... 48... 4A... 4C... 4E... 50...52...54...56...58...5A...5C...5E...80...82...
Then use the code in this post but do adc #32 instead of adc #30. Then you'll get this sequence.

I don't want to be mean, but if you cared to write the desired sequence down you'd have realized that to jump from $1E to $40 you'd have to add 34 (2 INXs and then ADC #32), not 32.
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:
unregistered wrote:00... 02... 04... 06... 08... 0A... 0C... 0E... 10... 12... 14... 16....18...1A...1C...1E...40... 42... 44... 46... 48... 4A... 4C... 4E... 50...52...54...56...58...5A...5C...5E...80...82...
Then use the code in this post but do adc #32 instead of adc #30. Then you'll get this sequence.

I don't want to be mean, but if you cared to write the desired sequence down you'd have realized that to jump from $1E to $40 you'd have to add 34 (2 INXs and then ADC #32), not 32.
That's an excellent :D way of learning that I should write the desired sequence down in the future. Thanks very much 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 »

3gengames wrote:Would you mind telling us what it's for? I don't get why this would be useful in any places honestly...
It's for running through all of our metatiles... I have this run during each time through the loop... incrementing x by either 2 or 32 34 each time. Remember we are useing 16x16 metatiles. :)

edit: and well tokumaru, I found the paper page where I figured this out so I could remember what I was thinking... and it says
[color=#FFBF00]...from some pages ago[/color] I wrote:x goes from 0 to 30
then skips 32
& goes from 64 to 94
...
It seems my math thought 30 + 32 = 64... though I think I remember keeping the 32 because it was a power of 2. Next time I'm going to write out what I expect... that was a great lesson, thanks. :)
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 »

I'm confused about my collision detection process.

I know that 1 page of RAM (256 bytes) is big enough to hold 1 screen of information (240 bytes) because 1 screen is 256 pixels wide and 240 scan lines tall. Each of my metatiles are 16 pixels high and 16 pixels wide. That 16 pixel square is big enough to hold four 8 pixel by 8 pixel tiles.
256 (screen width) / 16 (metatile width) = 16. And 240 (screen height) / 16 (metatile height) = 15. And so there are 16 x 15 = 240 metatiles. Since 1 screen of information is 240 bytes that allows 1 byte of collision data per metatile.

I don't understand... the part I'm having problems with is: How do I create a tile map with 240 bytes when each byte is supposed to represent the four 8x8 pixel tiles of my metatiles? Well, I am going to continue to try and find the posts where you all spent your time to teach this to me... my sister is helping me.
tepples
Posts: 22705
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 »

Usually, you'd make a lookup table from metatile numbers to the tile numbers for the top left, top right, bottom left, and bottom right tiles of the metatile. Then you'd either have a fifth table for the attribute value or do like SMB1 and use the upper 2 bits of the metatile number for the attribute.
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 »

And also a 6th table with collision information.
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 »

Do either of you have 16x16 metatiles? Is your collision table memory 240 bytes? How do you find out what value to store there? Does that value depend on what the four tiles are?
Denine
Posts: 397
Joined: Wed Feb 17, 2010 5:42 pm

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

Post by Denine »

I do have 16x16 metatiles. But my map is 224 bytes long. I don't wirte collision table but metatiles ID themselfs to have more options.
I write the value into RAM while decompressing map from PRG.
Something like this:
-Decompres a map byte from ROM.
-Save the byte into Level table in RAM
-JSR to function that draws metatile.
Does that value depend on what the four tiles are?
I use solid\non solid metatiles only and 1 metatile-one collision type(meaning, I can't make half of metatile as non solid and other half as solid).
When I want to check a Hero's collision with background, I calcutale his position and convert the result to X register. Later I use X to read from Level data in RAM that I saved before.
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 »

You don't need to have a separate collision table in RAM. In fact, I doubt most games have. Normally, if you wanted to test the solidity of a metatile, you'd access that metatile in the level map (which might be in RAM, if you decompressed it there, or in ROM), and then read the collision information associated with that metatile. It's a bit more indirect, but saves you a lot of memory. It goes something like this:

-calculate level map position of metatile to check;
-load metatile index from level map and put it into an index register;
-load from collision table in ROM, using the index from the previous step;

It makes little sense to store an entire screen of collision information separate from the metatiles, because the same kind of metatile will always have the same type of solidity, and you're not making use of that redundancy.
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 »

Denine wrote:... When I want to check a Hero's collision with background, I calcutale his position and convert the result to X register. Later I use X to read from Level data in RAM that I saved before.
Thank you Denine; your help is much appreciated. Hope your game is growing healthyly too. :)
tokumaru wrote:You don't need to have a separate collision table in RAM. In fact, I doubt most games have. Normally, if you wanted to test the solidity of a metatile, you'd access that metatile in the level map (which might be in RAM, if you decompressed it there, or in ROM), and then read the collision information associated with that metatile. It's a bit more indirect, but saves you a lot of memory. It goes something like this:

-calculate level map position of metatile to check;
-load metatile index from level map and put it into an index register;
-load from collision table in ROM, using the index from the previous step;

It makes little sense to store an entire screen of collision information separate from the metatiles, because the same kind of metatile will always have the same type of solidity, and you're not making use of that redundancy.
Wat is the level map? What info does it hold other than the metatile index? I don't think I have a level map. Was planning on creating one for collision... but I'm already susposed to have one? Hmm... :? Thank you for helping me tokumaru! :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:Wat is the level map? What info does it hold other than the metatile index? I don't think I have a level map.
If you have a level, you should have a level map. Storing straight name/attribute table is not efficient at all, even if you compress each screen, because you don't take advantage of all the redundancy of blocks that repeat.

A level map is usually a 2D grid of metatiles, where each byte is a metatile index. The level map can be used both for rendering (read a row/column of metatiles from the map, use their indexes to load the tiles that make up the metatiles and write them to VRAM) and for collision (get the metatile index and use it to get the metatile's collision information).

Here's a straightforward representation of a level that uses 32x32-pixel (4x4 tiles) metatiles:

Code: Select all

;16 tiles for each of the 4 metatiles
;metatile:  $00  $01  $02  $03

MatatileTile00:
	.db $00, $04, $08, $0c
MatatileTile01:
	.db $00, $04, $09, $0c
MatatileTile02:
	.db $00, $04, $0a, $0c
MatatileTile03:
	.db $00, $04, $0a, $0c
MatatileTile10:
	.db $00, $05, $0b, $0d
MatatileTile11:
	.db $00, $05, $0a, $0c
MatatileTile12:
	.db $00, $05, $0a, $0c
MatatileTile13:
	.db $00, $05, $0b, $0d
MatatileTile20:
	.db $00, $06, $06, $0e
MatatileTile21:
	.db $00, $06, $06, $0c
MatatileTile22:
	.db $00, $06, $06, $0c
MatatileTile23:
	.db $00, $06, $06, $0e
MatatileTile30:
	.db $00, $07, $07, $0f
MatatileTile31:
	.db $00, $07, $07, $0f
MatatileTile32:
	.db $00, $07, $07, $0f
MatatileTile33:
	.db $00, $07, $07, $0f

MatatileAttributes: ;4 palette indexes for each metatile
	.db %00000000 ;palettes for metatile $00
	.db %01010101 ;palettes for metatile $01
	.db %01010000 ;palettes for metatile $02
	.db %11000011 ;palettes for metatile $03

MetatileCollision: ;%00 = air, %01 = solid, %10 = water, %11 = hazard
	.db %00000000 ;metatile $00 is all air
	.db %01010101 ;metatile $01 is all solid
	.db %01010000 ;only the top of metatile $02 is solid
	.db %11110101 ;the top of metatile $03 hursts the player, the bottom is solid

LevelMap01: ;this small level is 16x8 metatiles (512x256 pixels) large
	.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	.db $00, $00, $00, $00, $00, $02, $02, $00, $00, $00, $00, $00, $00, $00, $00, $00
	.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $02, $02
	.db $00, $00, $00, $01, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
	.db $01, $01, $01, $01, $00, $00, $00, $00, $00, $01, $01, $01, $03, $03, $01, $01
	.db $01, $01, $01, $01, $00, $00, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
See how everything connects? Whenever you want to check what is present at a certain map location, you convert the coordinates into an index which you can use to read a metatile index from the level map. Once you know the metatile's index, you can use it to get any information you want about it. If you are rendering the background, read from the MatatileTileXX tables and and write the tile indexes to the name tables, and the attributes to the attribute tables. If you're testing for collisions, read from the MetatileCollision table to know how the objects should react to the metatile.

Se how one thing points to another, that points to another and so on? This is how you manage to reuse your level data effectively compressing it to much less than it would be if you had raw name/attribute table data. The data above is just 200 bytes. If I were to represent that in uncompressed form, this 2-screen wide level would have been 2048 bytes large.

Anyway, this is not a lesson about compression (although the maps are indeed compressed), this is to show you one of the possible ways in which a level can be represented, and how you can access everything on it. Does this make sense to you?
Post Reply