Status Bar + palette swap

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

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

Re: Status Bar + palette swap

Post by Bregalad »

If you're not scrolling vertically you should just write to $2006, really. No point to doing "ticks" when those aren't even necessary in the 1st place.

Also it's up to personal opinion but in the case of a RPG, changing the colour for a text box is not always required. Many games goes well by reserving one (or even two) colour palettes to pre-defined constant values. Another approach is to not care about the colour which are used to show the text, as long as the hues are known, some games have their status bars or text boxes switching colours form level to level, and this is not always a problem.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Status Bar + palette swap

Post by tokumaru »

It's true, you don't need the full $2006/5/5/6 combo if you're not scrolling vertically and/or the gameplay window always starts at the top half of a tile. You still have to make sure that the fine X scroll (the only part of the scroll not affected by $2006) is correct though, so you need at least one $2005 write somewhere.
User avatar
Broke Studio
Formerly glutock
Posts: 177
Joined: Sat Aug 15, 2015 3:42 pm
Location: France
Contact:

Re: Status Bar + palette swap

Post by Broke Studio »

Finally got some time to have a look at this again, and finally get it to work !!!

So thanks everyone for your help so far !
Also it's up to personal opinion but in the case of a RPG, changing the colour for a text box is not always required. Many games goes well by reserving one (or even two) colour palettes to pre-defined constant values. Another approach is to not care about the colour which are used to show the text, as long as the hues are known, some games have their status bars or text boxes switching colours form level to level, and this is not always a problem.
Of course, and I don't know if I'll use it anyway, but since I started trying to do this , I want to understand how it works
When you write 0 to 2006, 2005, 2005, 2006, you're resetting the full scroll to (0,0), which is why it appears to re-scroll to the top of the screen. (Is this the problem you're referring to? If so, for now, you can just use a shorter version that writes specific non-zero values to 2006 twice, since you seem to be not changing X or Y fine scroll.)
Actually it was the problem.
I used the $2005/6 trick and after tweaking and tweaking values (and understanding how it works btw), it's ok now !

The PAL version attached works well on both, emulators (FCEUX,Nintendulator,Nestopia) and hardware (tested on a flat screen and not a CRT TV, don't know if there's a difference for this, I'd say no but ? ...).

The NTSC version seems ok on emulators, but in Nintendulator there's a one pixel line jitter (but not in Nestopia nor FCEUX - I know, FCEUX is crap ;) ). If someone could test it on real hardware, it would be very nice !!

Again, thanks for your help !

If someone is interested, I can post the source code.

EDIT : NTSC version updated which seems to work ok even on PAL hardware (with a little "line-glitch" though, but totally acceptable).
Attachments
sprite_0_hit+palette_swap_NTSC.nes
(32.02 KiB) Downloaded 124 times
sprite_0_hit+palette_swap_PAL.nes
(32.02 KiB) Downloaded 114 times
My first game : Twin Dragons available at Broke Studio.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Status Bar + palette swap

Post by Bregalad »

I am too lazy to test on my Power Pak, but on emulators it appears it does not work.

Normally it should be fairly simple if you do the writes in that order :

- Poll $2002 to wait sprite zero hit
- Write $00 to $2001
- Write $3f00 (or another adress) to $2006
- Write your palette value to $2007
- Write $1e (or whathever value you're using) to $2001
- Write $0000 (or whathever adress tile you want to be shown, AND-ed with $0fff) to $2006
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Status Bar + palette swap

Post by tokumaru »

Bregalad wrote:I am too lazy to test on my Power Pak, but on emulators it appears it does not work.
Did you press "A"?

glutock, congratulations on working hard and solving the problem. One way you can improve the jitter problem is to check the sprite 0 hit flag using BIT + BVC/BVS instead of LDA + AND + BNE/BEQ. Reducing the number of cycles in the waiting loop will reduce the gap between the minimum and maximum amount of cycles it can take to respond to the flag changing.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Status Bar + palette swap

Post by tepples »

For resilience against crashes due to sprite 0 hit failure, I'd recommend a BIT/BEQ sequence:

Code: Select all

  lda #%11000000   ; Allow either vblank or sprite 0 to break this loop
loop:
  bit $2002
  beq loop
  ; At this point, either bit 7 or bit 6 is true.
  ; If bit 6 is true, sprite 0 hit occurred.  If not,
  ; sprite 0 was missed and vblank started.
  bvc sprite_0_hit_failed
  ; At this point, you can process raster effects
  ; at the sprite 0 hit point.
If handled properly, a failure will cause flicker instead of a freeze.
User avatar
Sogona
Posts: 186
Joined: Thu Jul 23, 2015 7:54 pm
Location: USA
Contact:

Re: Status Bar + palette swap

Post by Sogona »

glutock wrote:If someone is interested, I can post the source code
I'd be interested in seeing it.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Status Bar + palette swap

Post by tokumaru »

tepples wrote:For resilience against crashes due to sprite 0 hit failure, I'd recommend a BIT/BEQ sequence
This is a good suggestion for general sprite 0 hit use, but when we're talking about a status bar that's handled in the NMI, only some sort of hardware glitch that corrupted sprite 0 could prevent the hit.
User avatar
Broke Studio
Formerly glutock
Posts: 177
Joined: Sat Aug 15, 2015 3:42 pm
Location: France
Contact:

Re: Status Bar + palette swap

Post by Broke Studio »

For resilience against crashes due to sprite 0 hit failure, I'd recommend a BIT/BEQ sequence:
Thanks Tepples for the tip, I'm not using it here because I know for sure that the sprite 0 hit will happen, but it's good to know for sure !
One way you can improve the jitter problem is to check the sprite 0 hit flag using BIT + BVC/BVS instead of LDA + AND + BNE/BEQ.
OK I've updated my code with this method, tweaked a bit the values for "scanline waiting", and add an PAL/NTSC auto-detect feature so it adjusts the values according to the mode.

I'm only changing two colors here, so it may needs to be adjusted for more.

Tested ok for PAL and NTSC on emulators and ok for PAL on hardware. (Nestopia doesn't seem to like the PAL/NTSC detection routine and gives me black screen in PAL mode)

Again, if someone would be kind enough to test it on a NTSC console it would be very nice !

Source code is in the .rar file. Not perfectly coded but hey ... it works !
Attachments
sprite_0_hit+palette_swap.rar
(7.04 KiB) Downloaded 187 times
sprite_0_hit+palette_swap_auto_detect.nes
(32.02 KiB) Downloaded 120 times
My first game : Twin Dragons available at Broke Studio.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Status Bar + palette swap

Post by rainwarrior »

glutock wrote:I know for sure that the sprite 0 hit will happen
IMHO you never know for sure. In any complex program there is a potential for bugs that will break your sprite 0 hit, but more likely than that on the hardware there's all sorts of unpredictable things that can happen.

The real question in my mind is not whether it can happen (it can always happen, think about how many times you've seen temporarily corrupted CHR on an NES), but whether it's acceptable for the program to crash when it does. For something like a graphics demo, sure, that's absolutely acceptable, or if it's just on the title screen, but if you think about a game that someone's been playing for three hours and all of a sudden it hangs, you might want to do what's in your power to keep running here.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Status Bar + palette swap

Post by tokumaru »

I've been thinking, and I don't think tepples' trick will work for a status bar handled in the NMI.

Let's think about this: say that the sprite 0 hit didn't happen because of a hardware glitch. The CPU will stay sick in the waiting loop until the next NMI fires, which will prevent the waiting loop from detecting the VBlank flag.

The new NMI will also try to detect a sprite 0 hit. If the hit happens this time, there will be some scroll problems when the previous waiting loop ends, but everything should be fine the next frame, without you having to deal with the problem directly.

If the glitch persists though, NMIs will pile up and the program will crash. The vblank flag will not do you any good.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Status Bar + palette swap

Post by rainwarrior »

I didn't really evaluate the exact details of tepples' code yet, but this is code I've been using for a "safe" sprite-0 hit:

Code: Select all

	lda #1
	sta nmi_lock          ; prevents NMI handler from trying to do anything in failure case
	:
		bit $2002
		bvs :-             ; make sure sprite 0 is clear before polling for it (i.e. wait for end of vblank)
	:
		bit $2002
		bmi @sprite_0_fail ; if vblank is detected, we completely missed the sprite 0 hit
		bvc :-             ; sprite 0 not hit yet
For me this has worked fine. In the failure case basically I just get a rendering glitch and 50% slowdown (as vblank substitutes for the sprite 0 hit), but otherwise I haven't seen any negative consequences. Of course that bmi adds 2 more cycles of jitter to the whole operation, which you need to account for in your timing margins if you're trying to hit hblank.

edit:
I think tepples' solution is be better timing-wise, hadn't thought of masking the bit instruction. I'm not triggering this from within the NMI handler, but even in that case I don't think NMIs necessarily have to "pile up" in the failure case. It's easy to prevent that with a lockout variable like the one in my example. (Bottom line: after implementing it, test it to make sure the failure case really works.)
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Status Bar + palette swap

Post by tepples »

RAR has no free decompressor.

I tried the .nes file on my NTSC NES + PowerPak. I get "THIS TEXT SHOULDN T BE VISIBLE" at the top, about 16 pixels of space, then what appears to be a quarter of a head, then a horizontal strip of grass with a tree in the middle. Do I fail it?
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Status Bar + palette swap

Post by lidnariq »

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

Re: Status Bar + palette swap

Post by tepples »

With A, the top right corner of head becomes a red square, and the rest of the status bar becomes white except for a red and orange line across the screen behind the red square. There's some flickering in about the rightmost 4 pixels of the border. The top scanline of the tree is cut off.
Post Reply