help on first demo?

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

tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

blargg wrote:On most assemblers, .db $nn defines one or more bytes of constant data. .ds n is what reserves n bytes without specifying their values. BTW, it makes no sense to assign values to RAM, since the assembler doesn't generate any initialization code, just gives names to addresses. At the very least an assembler should give a warning if you attempt to give RAM an initial value.
True, if the RAM segment is set to a "BSS" type. But there is another type of RAM segment called "DATA" that is designed to be copied from ROM at reset time.
As for clearing all RAM, it makes a lot of sense to me now, since you can declare a variable then rely on it being initialized to zero if you haven't used it yet.
And in fact, C guarantees that uninitialized variables at file scope are zero at the start of main().
kyuusaku wrote:What could you be waiting for though? An RC time constant in the POR circuit?
Cap charging might be part of it, but I guessed that it had something to do with state. It's likely that the PPU's internal state isn't necessarily consistent until it has rendered a complete field, and the easiest way to detect that the PPU has been through a complete field is to wait for the vblank before it and the vblank after it.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

tepples wrote:
As for clearing all RAM, it makes a lot of sense to me now, since you can declare a variable then rely on it being initialized to zero if you haven't used it yet.
And in fact, C guarantees that uninitialized variables at file scope are zero at the start of main().
I don't know guys, I'm still not convinced! =) The "if you haven't used it yet" part can be very tricky, because this condition may be true the first time you run a piece of code, but not at subsequent times... if this was the case, a possible bug would be pretty difficult to find. But if you instead initialized the variable at a convenient time, it would be correctly set whenever that piece of code was executed.

I'm not trying to convince anyone (as I'm sure nobody is trying to convince me) of anything, I'm just trying to express my point of view on variables and how to initialize them, since I seem to be alone on this one.

My current project has a pretty complex scrolling system, a pretty complex sprite system, and I can get away just fine by initializing memory only when I need it. I think this is the case because there really isn't a value I use that much that would justify writing it to every memory location. 0 is pretty much meaningless for most of my code...

Even when I (supposedly) do need to clear a block of RAM, such as the object slots used for active objects, I can usually get away with clearing just a small part of it. In the case of the object slots, each one has a byte that indicates the type of the object loaded there, and I know that the engine will check that value before anything else, and if I use 0 as a flag to indicate that the slot is empty, what do I care about the crap stored in the other bytes? And since I will surely clear those "object type" bytes before a level (re)starts, I see no need to clear that memory before that.

But I know this is only my case, and I guess I can accept that people out there will benefit from clearing it all on start up. This is not for me though... Even when programming in high-level languages I can't seem to assume any values on things I haven't initialized. OK, shutting up now.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

In fact Tokumaru you are mostly right, it's better to rely on clean programming methods. It's simply that on the NES, it's often best to put code efficiency over colde clarity, so in some cases, but not always, initialising memory can increase code efficiency. The sound code exemple I give above is typical : Having the clearing RAM routine do it instead of a custom "SoundInit" routine is more efficient, even if that's not the cleaner programming method ever. Once the game starts, if you want to stop a music you'll have to call music_stop or something, so maybe just calling music_stop on startup would also do the trick very well.
Finally, anyone is free to clear the whole RAM on startup, only a part of it or nothing at all, I guess there is nothing better or worse here. Depend on the programmer. Final Fantasy games are the only commercial games that doesn't initialise RAM at all as far I noted. Some game however only initialise zero-parge RAM or not the entiere "bss" RAM.
User avatar
Skidlz
Posts: 50
Joined: Sun Nov 11, 2007 5:24 pm

bg pal?

Post by Skidlz »

I got some basic scrolling and collision detection going but I'm having palette trouble. How to do use multiple palettes on the background? Say I wanted a black and white could, a green bush, a yellow sun and brown ground. How would I make some bg sprites use a different palette from other bg sprites?

Thanks
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Look up the Attribute Tables. It's a bit complicated to explain everything, so you should probably read all the documentation that is already avaliable about them, then come back here and ask about what you didn't understand! =)
User avatar
Skidlz
Posts: 50
Joined: Sun Nov 11, 2007 5:24 pm

been there

Post by Skidlz »

I have looked at lots of things on the Attribute tables but none of them tell how to use it. I found hardware docs but I didn't find any software explanations. $23C0 is attribute table 0 and every byte controls 4 bg sprites in a square. But how do I interface it? I read the documentation on the NSA program but the code was too cryptic and I didn't see that it wrote to $23c0 so it didn't really help. I did some guess and check by dumping values into $23c0 but it only seemed to offset the sprites and leak bg tiles into foreground sprites.

One thing at a time but, how big of a pain is collision detection? I've just used sprite 0 hit as a check for hitting while jumping. I don't know how to test falling or walking collision. If you could point me in the direction of some tutorials that would be greatly appreciated.

Thanks for everything.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

There is plenty of docs arround that proprely doccument how attribute table works. Unlike the Name Table, the attribute table is only 8 blocks long and 8 blocks tall, taking 64 bytes (the nametable is 32 blocks long and 30 blocks tall) so converting adresses between the two can be a pain. Each byte control a block of 4x4 BG tiles, so the attribute byte at $23c0 correspond to tiles at $2000, $2001, $2002, $2003, $2020, $2021, $2022, $2023, $2040, $2041, $2042, $2043 and $2060, $2061, $2062 and $2063, this is the topmot leftmost 8x8 BG tiles corner.
The simpler way to see this is that attribute bytes at $23c0-$23c7 controls the first 4 lines of tiles ($2000-$207f), attributes byte at $23c8-$23cf constol the next 4 lines of tiles ($2080-$20ff), etc... Each line in nametable is $20 bytes long, each 4 lines are then $80 bytes long, and an attibute line, which is $8 bytes long have control over groups of 4 lines.

Each group of 2 bits in an attribute byte correspond to a smaller block of 2x2 tiles among the 4x4 block mentionned above, allowing attribute tables to control colors over groups of 2x2 tiles. Note that the attribute table allows to give attribute to 32x32 tiles, while the map is only 32x30, so there is a "ficionnal row of tiles" you give them colors, but the tiles themselves are usually never drawn on the screen. You can still draw them from the attribute table itself (wich can also be drawn as a nametable) by setting the vertical scroll values $f0-$ff, wich normally should be never used. There is hardly any good use of this, tough.

Now you should know enough about attribute tables, if this isn't enough just read some docs.
User avatar
Skidlz
Posts: 50
Joined: Sun Nov 11, 2007 5:24 pm

Post by Skidlz »

Cool. I understand name table vs. attribute table allot better now. So 1 byte in attribute is 16 tiles in name and 2 bits in attribute is 4 tiles in name. I still don't understand what to send to $23c0 though. I modified gbaguy's name table loader for attribute like so...

Code: Select all

		ldx #0
load_atribute:
	lda atribute_table, x
	sta $23C0
	inx
	cpx #64
	bne load_atribute
But I assume this is totally wrong because it did absolutely nothing.

Thanks for the attribute tutorial there. Much better than the docs I've read.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

This is totally wrong. You must write to $23c0 in PPU's memory and not in CPU's memory. You must write $23, $c0 to $2006 then write your stuff in $2007.
User avatar
Skidlz
Posts: 50
Joined: Sun Nov 11, 2007 5:24 pm

Success!

Post by Skidlz »

I thought something seemed wrong there. Strange that writing there (in cpu) during vblank offsets sprites. Thanks for setting me straight on that. Really nice to have that working. Now off to edit palettes and name tables.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Success!

Post by tokumaru »

Skidlz wrote:Strange that writing there (in cpu) during vblank offsets sprites.
That probably happens due to mirroring. The wiki says that $23C0 is in a erea that mirrors the PPU registers, so when you wrote stuff there you were actually affecting register $2000, which controls a few parameters of sprites and background.
User avatar
Skidlz
Posts: 50
Joined: Sun Nov 11, 2007 5:24 pm

Post by Skidlz »

Well, I got bored and I felt assembly meant a little more than ASCII so I wrote something.

Please Download --> http://www.mediafire.com/?71xuinnmga1
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

You are welcome! =) I didn't do much though...!
User avatar
Skidlz
Posts: 50
Joined: Sun Nov 11, 2007 5:24 pm

Post by Skidlz »

I feel like I'm taking advantage of you guys(and or girls) by asking so many questions. Feel free to say something if I'm being a bother.

Well, I have an uncanny skill at underestimating and overestimating varyingly. Not as bad as my friend who typed "cows" as his source code and expected a game involving cows. But I assume collision detection is somewhat difficult and I've yet to find anything that addresses it. Only some confusing source from galaxy patrol. All I can manage is sprite 0 hit and I'm sure thats not how you go about doing this. If someone could point me towards a tutorial or give me a place to start that would be wonderful.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Skidlz wrote:But I assume collision detection is somewhat difficult and I've yet to find anything that addresses it.
First would you like to learn about collision between sprite and sprite, or would you like to learn about collision between sprite and background?
Post Reply