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

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

Author:  pubby [ Mon Apr 24, 2017 4:03 pm ]
Post subject:  Re: Tips on best coding practices?

Nowadays people put controller reads immediately after sprite DMA in order to prevent a glitch related to DPCM sounds. See: https://wiki.nesdev.com/w/index.php/Con ... ng_OAM_DMA

You don't have to understand what those words mean in order to use it. Just copy/paste the code from the wiki into your NMI subroutine.

Author:  tokumaru [ Mon Apr 24, 2017 4:10 pm ]
Post subject:  Re: Tips on best coding practices?

pubby wrote:
Nowadays people put controller reads immediately after sprite DMA in order to prevent a glitch related to DPCM sounds. See: https://wiki.nesdev.com/w/index.php/Con ... ng_OAM_DMA

That could present a problem if done in the NMI and the logic in a lag frame samples different controller states. You can easily solve that if you just copy the controller state to a secondary variable to be used for game logic at the beginning of the game loop though.

Author:  rainwarrior [ Mon Apr 24, 2017 4:12 pm ]
Post subject:  Re: Tips on best coding practices?

pubby wrote:
Nowadays people put controller reads immediately after sprite DMA in order to prevent a glitch related to DPCM sounds. See: https://wiki.nesdev.com/w/index.php/Con ... ng_OAM_DMA

You don't have to understand what those words mean in order to use it. Just copy/paste the code from the wiki into your NMI subroutine.

It's a valid way to prevent the DPCM glitch but it's not always appropriate to read your controller in the NMI. (ilag frames leading to inconsistent state throughout the update, missed button presses, etc.)

Edit: tokumaru already covered it.

Author:  tokumaru [ Mon Apr 24, 2017 4:17 pm ]
Post subject:  Re: Tips on best coding practices?

I said you could easily solve the problem using a secondary variable but I didn't really spend much time thinking about all the implications of that. Missed button presses could happen either way I suppose. Is there anything else that could go wrong in that case?

Author:  tepples [ Mon Apr 24, 2017 4:30 pm ]
Post subject:  Re: Tips on best coding practices?

tokumaru wrote:
pubby wrote:
Nowadays people put controller reads immediately after sprite DMA in order to prevent a glitch related to DPCM sounds.

That could present a problem if done in the NMI and the logic in a lag frame samples different controller states. You can easily solve that if you just copy the controller state to a secondary variable to be used for game logic at the beginning of the game loop though.

Or by reading input only after DMA to OAM. In lag frames, the flag for "display list is ready" won't be set.

Author:  JWinslow23 [ Mon Apr 24, 2017 5:38 pm ]
Post subject:  Re: Tips on best coding practices?

Sumez wrote:
Absolutely. You can easily store all 8 button states on a single NES controller in a single byte, with each bit indicating wether the button is pressed. I also do comparisons with the previous NMI to see if a button was just pressed to trigger events on button pulses (such as attacking or jumping), and store those in a separate byte.

Yes, I do do this.
Code:
ReadJoypad:
  LDA <ButtonsHeldNow
  STA <ButtonsHeldLastFrame ; Store ButtonsHeldNow into ButtonsHeldLastFrame
  LDA #$01
  STA $4016             ; Continuously reload the buttons
  STA <ButtonsHeldNow   ; Initialize ButtonsHeldNow
  LSR A
  STA $4016             ; Stop reloading; ready to read controller
JoypadLoop:
  LDA $4016
  LSR A                 ; Store button state into carry
  ROL <ButtonsHeldNow   ; Rotate carry into ButtonsHeldNow
  BCC JoypadLoop        ; Carry will be 1 once all buttons are read
                        ; So jump back if carry is 0
  RTS                   ; Return

tokumaru wrote:
stuff that does things in places

Did that, and it works. Thanks!
pubby wrote:
Nowadays people put controller reads immediately after sprite DMA in order to prevent a glitch related to DPCM sounds. See: https://wiki.nesdev.com/w/index.php/Con ... ng_OAM_DMA

You don't have to understand what those words mean in order to use it. Just copy/paste the code from the wiki into your NMI subroutine.

As I don't use DPCM sounds (yet; I might possibly have a title scream or something), I'm just not going to bother with that. Besides, my controller routine will only read the first controller (this will be a one player game), and it also stores the last button held, so I'm not sure what that does to the cycles.

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

Bump.

Right now, I want to be able to add scrolling to this game. I'm a bit confused by the docs over at the NESDev Wiki, I'm not exactly sure what to do. How do I actually make the background scroll? I'll be scrolling horizontally, and the background repeats, if that helps.

Author:  Bregalad [ Tue Apr 25, 2017 4:32 am ]
Post subject:  Re: Tips on best coding practices?

JWinslow23 wrote:
Bump.

Right now, I want to be able to add scrolling to this game. I'm a bit confused by the docs over at the NESDev Wiki, I'm not exactly sure what to do. How do I actually make the background scroll? I'll be scrolling horizontally, and the background repeats, if that helps.

The scrolling pages on the wiki are currently being reworked, currently they are a bit messed up. They'll be fixed in the near future.

As how to make a repeating BG scroll it's extremely simple, you use the $2000 and $2005 registers to do that.

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

Bregalad wrote:
JWinslow23 wrote:
Bump.

Right now, I want to be able to add scrolling to this game. I'm a bit confused by the docs over at the NESDev Wiki, I'm not exactly sure what to do. How do I actually make the background scroll? I'll be scrolling horizontally, and the background repeats, if that helps.

The scrolling pages on the wiki are currently being reworked, currently they are a bit messed up. They'll be fixed in the near future.

As how to make a repeating BG scroll it's extremely simple, you use the $2000 and $2005 registers to do that.

...use them how? That's my question. :P OK, I've made the screen "scroll" horizontally, but it seems that the background has also been shifted up 2 rows (when my ScrollX is always 0). What do I do to remedy this? Here is my code that handles scrolling (with .inesmir 0 as the mode):
Code:
  DEC <ScrollY
  BIT $2002
  LDA <ScrollY
  STA $2005
  LDA #$00
  STA $2005

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

You appear to have switched X and Y there... The first $2005 write sets the horizontal scroll (X) while the second write sets the vertical scroll (Y).

Note that depending on the NT mirroring you're using, the total background size will be either 256x480 pixels (horizontal mirroring) or 512x240 pixels (vertical mirroring), meaning that one of the scroll values can't be represented in just 8 bits (8 bits can only go up to 255, but you need to go up to 479 or 511). For this reason, in addition to writing to $2005, you need to update the "9th bit" of the scroll values using register $2000 (the lower 2 bits).

If the background is supposed to be the same 256x480 or 512x240 area over and over, simply changing the scroll registers will do, but if you want to display a larger background, such as a level in SMB, you'll need to progressively update the name tables each vblank in coordination with the scroll changes.

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

tokumaru wrote:
You appear to have switched X and Y there... The first $2005 write sets the horizontal scroll (X) while the second write sets the vertical scroll (Y).

Note that depending on the NT mirroring you're using, the total background size will be either 256x480 pixels (horizontal mirroring) or 512x240 pixels (vertical mirroring), meaning that one of the scroll values can't be represented in just 8 bits (8 bits can only go up to 255, but you need to go up to 479 or 511). For this reason, in addition to writing to $2005, you need to update the "9th bit" of the scroll values using register $2000 (the lower 2 bits).

If the background is supposed to be the same 256x480 or 512x240 area over and over, simply changing the scroll registers will do, but if you want to display a larger background, such as a level in SMB, you'll need to progressively update the name tables each vblank in coordination with the scroll changes.

Well, the writes are how they're supposed to be. I gotta be less stupid in variable naming, that should be ScrollX (horizontal scrolling) :P . And the background will simply be repeating, as in my original two games. The problem here is, there seem to be two blank rows of background appearing now that weren't there earlier. I've "fixed" it by setting the scroll y to always equal $F0, but I'm sure there's a better way.

What I have now seems to work for my purposes, but to do this "correctly", how would I change $2000? I'm trying this:
Code:
  LDA <ScrollX
  BEQ NoWrap
  LDA $2000
  EOR #%00000001
  STA $2000
NoWrap:

This is supposed to toggle the X>256 bit of $2000 every time the scroll x is 0, but this is causing the sprite to render incorrectly. How would I fix this?

Author:  Bregalad [ Tue Apr 25, 2017 6:18 am ]
Post subject:  Re: Tips on best coding practices?

JWinslow23 wrote:
The problem here is, there seem to be two blank rows of background appearing now that weren't there earlier. I've "fixed" it by setting the scroll y to always equal $F0, but I'm sure there's a better way.

You should explain your problem better. $f0 is a "negative" vertical scroll value and you should avoid it as it will show attribute table data as name table data. This should make 16 glitchy lines at the top of the screen, although 8 will be hidden by overscan so 8 will show.

If you need to move the screen down by 16 pixels, use the value $e0 instead.

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

Bregalad wrote:
JWinslow23 wrote:
The problem here is, there seem to be two blank rows of background appearing now that weren't there earlier. I've "fixed" it by setting the scroll y to always equal $F0, but I'm sure there's a better way.

You should explain your problem better. $f0 is a "negative" vertical scroll value and you should avoid it as it will show attribute table data as name table data. This should make 16 glitchy lines at the top of the screen, although 8 will be hidden by overscan so 8 will show.

If you need to move the screen down by 16 pixels, use the value $e0 instead.

Not working. The screen is blank if I use $E0 for some reason.

The thing is, I'm thinking $00 should work and show the whole screen, but even in NTSC mode, there seem to be blank rows on the bottom that don't show up without the scrolling code. This is confusing to me. :?

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

If Y=224 ($E0) blanks the screen, then you probably have the cartridge set to 256x480 (aka vertical arrangement or horizontal mirroring), and it's reading the wrong nametable. Try setting bit 1 of the value you write to $2000, that is, ORing it with the value $02.


EDIT: corrected brain fart

Author:  Bregalad [ Tue Apr 25, 2017 7:41 am ]
Post subject:  Re: Tips on best coding practices?

tepples wrote:
If Y=224 ($E0) blanks the screen, then you probably have the cartridge set to 256x480 (aka vertical arrangement or horizontal mirroring), and it's reading the wrong nametable. Try setting bit 1 of the value you write to $2001, that is, ORing it with the value $02.

$2000 not $2001. That or simply use vertical mirroring / horizontal arrangement.

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