It is currently Wed Dec 13, 2017 5:41 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3
Author Message
PostPosted: Tue Apr 25, 2017 8:08 am 
Offline
User avatar

Joined: Mon Apr 24, 2017 5:52 am
Posts: 30
Location: West Allis, WI
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.


Last edited by JWinslow23 on Tue Apr 25, 2017 8:10 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 8:10 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
I mistakenly wrote $2000 where I should have written $2001. Please try it again with $2000.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 8:12 am 
Offline
User avatar

Joined: Mon Apr 24, 2017 5:52 am
Posts: 30
Location: West Allis, WI
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.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 8:43 am 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 10:34 am 
Offline
User avatar

Joined: Mon Apr 24, 2017 5:52 am
Posts: 30
Location: West Allis, WI
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
Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 1:15 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
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.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 2:07 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
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.


Last edited by tokumaru on Tue Apr 25, 2017 2:12 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 2:11 pm 
Offline
User avatar

Joined: Thu Sep 15, 2016 6:29 am
Posts: 461
Location: Denmark (PAL)
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.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 5:55 pm 
Offline
User avatar

Joined: Mon Apr 24, 2017 5:52 am
Posts: 30
Location: West Allis, WI
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.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 7:34 pm 
Offline
User avatar

Joined: Mon Apr 24, 2017 5:52 am
Posts: 30
Location: West Allis, WI
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
Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 8:21 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Tue Apr 25, 2017 8:54 pm 
Offline
User avatar

Joined: Mon Apr 24, 2017 5:52 am
Posts: 30
Location: West Allis, WI
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!


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 1:35 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
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.


Top
 Profile  
 
PostPosted: Wed Apr 26, 2017 1:43 am 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3

All times are UTC - 7 hours


Who is online

Users browsing this forum: LocalH and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group