nesdev.com
http://forums.nesdev.com/

Tips on best coding practices?
http://forums.nesdev.com/viewtopic.php?f=2&t=15852
Page 3 of 3

Author:  JWinslow23 [ Tue Apr 25, 2017 8:08 am ]
Post subject:  Re: Tips on best coding practices?

I do have vertical mirroring.

Before my game loop, bit 1 of $2001 is set:
Code:
  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001


And even still, the code that toggles the X>256 bit on wraparound isn't working. That, or the background isn't appearing at all and the sprite is glitchy. That depends on what I'm trying.

Author:  tepples [ Tue Apr 25, 2017 8:10 am ]
Post subject:  Re: Tips on best coding practices?

I mistakenly wrote $2000 where I should have written $2001. Please try it again with $2000.

Author:  JWinslow23 [ Tue Apr 25, 2017 8:12 am ]
Post subject:  Re: Tips on best coding practices?

Whoops.

OK, it seems to work now (the $E0 thing), but the X>256 bit toggle still isn't working. I think I'm fine without it, though.

Author:  tokumaru [ Tue Apr 25, 2017 8:43 am ]
Post subject:  Re: Tips on best coding practices?

JWinslow23 wrote:
Code:
  LDA <ScrollX
  BEQ NoWrap
  LDA $2000
  EOR #%00000001
  STA $2000
NoWrap:

You can't load from $2000, as it's a write-only register. If you want to modify the last written value, you must update a copy of it in RAM every time you modify it and load that instead.

Quote:
This is supposed to toggle the X>256 bit of $2000 every time the scroll x is 0

This is fine if you never scroll more than one pixel at a time, but if you do, the zero might be skipped and the NT will not toggle. To be perfectly safe, the correct thing to do is extended the ScrollX variable to 16 bits, and then you can just copy bit 0 of the high byte (i.e. the 9th bit of the 16-bit value) into the value to be written to $2000.

JWinslow23 wrote:
the X>256 bit toggle still isn't working. I think I'm fine without it, though.

If you're indeed using vertical mirroring, this means that the name tables are arranged side by side, forming a 512x240-pixel background, so you definitely need 9 bits for the X scroll. The only way I can see this working without you caring about the 9th bit is if both NTs contain the exact same graphics.

Author:  JWinslow23 [ Tue Apr 25, 2017 10:34 am ]
Post subject:  Re: Tips on best coding practices?

tokumaru wrote:
JWinslow23 wrote:
Code:
  LDA <ScrollX
  BEQ NoWrap
  LDA $2000
  EOR #%00000001
  STA $2000
NoWrap:

You can't load from $2000, as it's a write-only register. If you want to modify the last written value, you must update a copy of it in RAM every time you modify it and load that instead.

Quote:
This is supposed to toggle the X>256 bit of $2000 every time the scroll x is 0

This is fine if you never scroll more than one pixel at a time, but if you do, the zero might be skipped and the NT will not toggle. To be perfectly safe, the correct thing to do is extended the ScrollX variable to 16 bits, and then you can just copy bit 0 of the high byte (i.e. the 9th bit of the 16-bit value) into the value to be written to $2000.

JWinslow23 wrote:
the X>256 bit toggle still isn't working. I think I'm fine without it, though.

If you're indeed using vertical mirroring, this means that the name tables are arranged side by side, forming a 512x240-pixel background, so you definitely need 9 bits for the X scroll. The only way I can see this working without you caring about the 9th bit is if both NTs contain the exact same graphics.

They would contain the exact same graphics. This is meant to be a background that repeats every 2 tiles horizontally. I will, however, try and use your suggestions to make the ScrollX 16-bit.

EDIT: I did this, and I made some other adjustments to my game, including an actual death check, and updated BG tiles.

My next question is, how do I change the palette of the background? The final game would have the screen flash red while a death animation plays. I'm trying to set the palettes and/or attribute tables exactly like when it was set up at the start of the game, but this isn't working.

Attachments:
File comment: The .asm source file.
walrush.asm [12.78 KiB]
Downloaded 24 times
File comment: The .chr graphics file.
walrush.chr [8 KiB]
Downloaded 21 times
File comment: The compiled .nes file.
walrush.nes [24.02 KiB]
Downloaded 28 times

Author:  Bregalad [ Tue Apr 25, 2017 1:15 pm ]
Post subject:  Re: Tips on best coding practices?

Quote:
They would contain the exact same graphics. This is meant to be a background that repeats every 2 tiles horizontally. I will, however, try and use your suggestions to make the ScrollX 16-bit.

If your BG repeats every 16 pixels, you don't need the scroll counter to be wider than 8 bits, actually it being only 4 bit is enough as you can wrap arround from 15 to 0 and nobody will notice.

Quote:
My next question is, how do I change the palette of the background?

Come on, this is a really basic question, if you reached the point where you have a scrolling BG I'm pretty sure you know how to write the palettes which is one of the first thing to do if you want to display anything other than a grey screen.

Author:  tokumaru [ Tue Apr 25, 2017 2:07 pm ]
Post subject:  Re: Tips on best coding practices?

JWinslow23 wrote:
how do I change the palette of the background?

Exactly like you do it the first time (select PPU address $3F00 using register $2006, write 32 bytes through $2007), but you can only do it during vblank, which is the only time you're allowed to access VRAM.

So when the game logic decides that the death animation will begin, instead of immediately accessing the PPU and changing the palette, just set a flag indicating that the palette needs changing, and then, in your vblank handler, you check this flag and act accordingly. Any changes that require the use of $2006/7 must be buffered and signaled by the game logic and executed during vblank.

Author:  Sumez [ Tue Apr 25, 2017 2:11 pm ]
Post subject:  Re: Tips on best coding practices?

We're reaching the point were your questions are best answered something like this:

https://www.google.dk/search?q=site%3Aw ... tte+colors

It seems like you know how to program, and honestly the NES could hardly be any better documented than it already is thanks for the wiki on this very site.

Author:  JWinslow23 [ Tue Apr 25, 2017 5:55 pm ]
Post subject:  Re: Tips on best coding practices?

I'm sorry, guys, but for some reason, the things I'm trying weren't working. I will try them again, and get back to you.

Author:  JWinslow23 [ Tue Apr 25, 2017 7:34 pm ]
Post subject:  Re: Tips on best coding practices?

Alright, for now I have the palette-swap code. It turns out what I was doing wrong, as stupid as it sounds, was not waiting any frames before I changed it back. I did have the right code; it just was being reverted immediately. Leave it to me to not actually check what my code is doing before compiling it :P

I have now attached my code (same .chr), with one more minor problem: for one frame before and after the red flash, the background is shifted with some weird offset before returning to normal the next frame. Is this normal, or is there some way I can avoid this?

Attachments:
File comment: The .nes file.
walrush.nes [24.02 KiB]
Downloaded 24 times
File comment: The .asm file.
walrush.asm [14.29 KiB]
Downloaded 19 times

Author:  tokumaru [ Tue Apr 25, 2017 8:21 pm ]
Post subject:  Re: Tips on best coding practices?

JWinslow23 wrote:
for one frame before and after the red flash, the background is shifted with some weird offset before returning to normal the next frame. Is this normal, or is there some way I can avoid this?

This usually happens when rendering is enabled mid-screen, in which case the solution is to only enable/disable rendering during vblank. There's no reason to turn rendering off to update the palette though, so I'm guessing you're not setting the scroll after updating the palette. Remember, using $2006/7 messes up the scroll, so you should always set the scroll as the last thing in your vblank code.

Author:  JWinslow23 [ Tue Apr 25, 2017 8:54 pm ]
Post subject:  Re: Tips on best coding practices?

You're right, I'm not setting the scroll after the palette swap. I forgot that register messed up the scroll coordinates. I'll fix this, thanks!

Author:  Bregalad [ Wed Apr 26, 2017 1:35 am ]
Post subject:  Re: Tips on best coding practices?

tepples wrote:
I mistakenly wrote $2000 where I should have written $2001. Please try it again with $2000.

This proves that your practice of assigning names to registers does harm - you don't even remember which register is which ^^

@JWinslow23 : Usually your game engine should have a "system" where the game loop can request palettes updates to the VBlank NMI handler by setting a flag, and a shadow palette somewhere in RAM that you update during the game logic. That's not the only way to do this, but it's a very common "standard" way to do it. You can also restrict yourself to have a more generic VRAM update system in your VBlank handler, and have it write to palettes the same way it writes anywhere else in VRAM. It's really up to your tastes.

Author:  tokumaru [ Wed Apr 26, 2017 1:43 am ]
Post subject:  Re: Tips on best coding practices?

The NES doesn't have that many memory mapped registers, so I think using either addresses or names is OK. The Atari 2600, on the other hand, has nearly 70 memory mapped registers (most are in ZP, but even that doesn't really make them any easier to remember!), so there's no way anyone can memorize all that. Ever since I first worked with the 2600, a adopted the habit of naming registers on the NES too, and I think that does result in slightly more readable code.

Page 3 of 3 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/