News: 11 March 2016 - Forum Rules, Mobile Version
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia

Author Topic: Super Mario Bros 2. NES - Change palette set for bosses.  (Read 302 times)

RadioShadow

  • Sr. Member
  • ****
  • Posts: 297
  • Holding the Mega Drive controller
    • View Profile
Super Mario Bros 2. NES - Change palette set for bosses.
« on: May 12, 2017, 06:09:01 pm »
So most of the palette sets according to the database for the items and enemies are located here: 0x01F4FC to 0x01F540.

This doesn't seem to include Birdo (3 sets), Mouser, Triclyde or Wart.  What's strange is Clawgrip and Fryguy are in there, which makes it more irrating.

What I'm trying to do is make Triclyde (Hydra) use the 4th palette set in the Pony Poki Panic I'm working on:


Interestingly, 1F51B changes the palette for the fireballs that the boss fires, but that's not what I'm after.  I suspect maybe the boss values are grouped together, but I have had no luck finding them.  I did change the values that were near the other values, but no luck.

I found Wart's attribute palette date (during the ending where he is knocked out), which was located where his tiles to load data (2C6B to be exact).  I did find Triclyde's tile data to load (which there are a lot of), but found no values that change the palette set to load.

I did have a quick look in the debugger at RAM offset 201, but I couldn't see anything where it was getting the attribute data from (although I may need to have a proper look).

Any ideas would be great?

« Last Edit: May 13, 2017, 05:27:43 pm by RadioShadow »

Disch

  • Hero Member
  • *****
  • Posts: 2569
  • NES Junkie
    • View Profile
Re: Super Mario Bros 2. NES - Change palette set for bosses.
« Reply #1 on: May 13, 2017, 01:12:32 am »
My go-to technique here is to do a CPU trace.

From what I've seen in games, they typically rebuild the $0200 page from scratch every frame.. so once you're in the fight and Triclyde is visible, it'll be pretty easy to trigger a breakpoint and find the drawing code.

Since you already know where the tile data is, I'd start there.  Offset 0x02C6B, when swapped into PRG space, is going to have a CPU address of either $8C5B or $AC5B (or, much less likely, $CC5B).  So put a read breakpoint on those addresses.  Hopefully that'll snap the debugger and take you straight to the drawing routine -- which hopefully should make it easy to spot where it's getting the attribute data from.

This is pretty low tier in the 6502 department.  So if you don't have much (or any) experience with it, this is probably a fine place to start.  See if you can manage to trigger the above mentioned breakpoint, and then copy/paste the code you see in the debugger into this thread, and we can see about walking you through it.  Worst case scenario is the code you post is irrelevant (unrelated to drawing).

RadioShadow

  • Sr. Member
  • ****
  • Posts: 297
  • Holding the Mega Drive controller
    • View Profile
Re: Super Mario Bros 2. NES - Change palette set for bosses.
« Reply #2 on: May 13, 2017, 01:03:50 pm »
The tile for enemy's head (4 bytes) is stored in the rom at 6098.  Looking at the CPU Memory (RAM), the data gets stored at $A088.

So I put a read breakpoint at $A088, and it breaks at two locations:




Looking at the first image, it's storing storing the Absolute Y Value (STA) into 0202 in the RAM, which is 01.  That makes sense.  Then something @ 020A which I'm not sure of.  I hope I'm on the right track.

sics

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Re: Super Mario Bros 2. NES - Change palette set for bosses.
« Reply #3 on: May 13, 2017, 02:19:16 pm »


c017 ???
« Last Edit: May 13, 2017, 07:26:18 pm by sics »

Disch

  • Hero Member
  • *****
  • Posts: 2569
  • NES Junkie
    • View Profile
Re: Super Mario Bros 2. NES - Change palette set for bosses.
« Reply #4 on: May 13, 2017, 02:53:52 pm »
So what you're interested in, is byte 2:  https://wiki.nesdev.com/w/index.php/PPU_OAM#Byte_2

Specifically, the low 2 bits.  So looking at this drawing code, we're interested in writes to $0202 (or that +4, +8, +C, etc).  And we can see it in your screenshot.  At offset $5D3B* it's doing this:

Code: [Select]
LDA #$40
ORA $03
STA $0202,Y
STA $0206,Y

That first LDA is loading the 'A' register with the value of $40 (in binary:  %01000000).  If you look at the wiki page linked above, you'll see that the $40 bit corresponds to the "flip horizontal" bit.

From there, it's doing an OR with whatever value is at address $0003 -- so that address must be where it has the palette assignment stored.  And as you can see from the trace, the palette assignment is '$01', which means the 'A' register is now going to be $41.  The 'STA' instructions then writes that value to the $0200 page to assign the sprite attributes.

So you're halfway there!!!  $0003 is a RAM address, but ultimately we need to know where that value is coming from in ROM.  So the next step is to look for where it got the value to write to address $0003.  There are two approaches you can take here:

Approach 1
Open up the trace logger and run it.  Then run the game until your $A088 breakpoint triggers.  At which point the tracelogger will fill with a bunch of code (this is the code that ran before your breakpoint triggered).  Starting from the end of the log, look back to see if you can find where it writes (probably with a 'STA' instruction) to address $0003.

Approach 2
Put a 'write' breakpoint on address $0003 and hopefully that'll take you directly to the code without having to scour the tracelog.  The problem is, $0003 is probably generic RAM space so it might be written to and used for stuff completely unrelated to what you're looking for.  If you're going to take this approach, you're only interested in times when the game writes '01' to that address... so you can set a condition for the write breakpoint in FCEUX so it only breaks when "A==#01"



Whichever approach you take, it should bring you to the code that reads a value from ROM and writes it to address $0003... and that'll give you the ROM offset you're looking for.  If you get to the code and can't decipher it, you can post it here and I can walk you through it.


Good luck!


*why is it showing ROM offsets?  Shouldn't it be showing CPU addresses?  Must be a weird setting you have set  =x.  Whatever, it doesn't matter.



EDIT:  @sics:  He's not trying to change the colors.  He's trying to change which palette the sprite uses.

RadioShadow

  • Sr. Member
  • ****
  • Posts: 297
  • Holding the Mega Drive controller
    • View Profile
Re: Super Mario Bros 2. NES - Change palette set for bosses.
« Reply #5 on: May 13, 2017, 05:26:22 pm »
*why is it showing ROM offsets?  Shouldn't it be showing CPU addresses?  Must be a weird setting you have set  =x.  Whatever, it doesn't matter.

I had the "ROM Offsets" ticked in the Debugger.  That's why it's showing the ROM Offsets.  I've unticked it.

Thanks for explaining it Disch.  So at CPU address 9273, it loads: STA $0003 = #$01


I'm not seeing any code for the offsets, unless I'm not looking hard enough.  Unless I need to go back further?

Disch

  • Hero Member
  • *****
  • Posts: 2569
  • NES Junkie
    • View Profile
Re: Super Mario Bros 2. NES - Change palette set for bosses.
« Reply #6 on: May 13, 2017, 06:43:27 pm »
Hmmm.  This might be an unrelated STA.  Remember that $0003 is likely temp RAM, so this could be completely different code.

Put both your 0003 and your A088 breakpoints on at the same time.  The STA 03 you're looking for is the one that happens just before the A088 code.

So when the debugger snaps on this code, if you press "Run" the debugger should snap immediately at the A088 code.  Can you check to make sure that happens?