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

Author Topic: Super Mario Bros Player Palette Assignment  (Read 847 times)

mosk915

  • Newbie
  • *
  • Posts: 3
    • View Profile
Super Mario Bros Player Palette Assignment
« on: May 15, 2017, 07:40:17 pm »
In my first attempt at rom hacking, I’m trying to get a better understanding of how palettes are assigned to player sprites in Super Mario Bros.  My understanding is that because of limitations in the game, only three palettes can be used for the player sprites, which are assigned like this:

Small/big Mario – Palette #1
Small/big Luigi – Palette #2
Fire Mario/Luigi – Palette #3

What I’d like to know is, how does the game check the state of the player and assign the sprite?  For example, is there one check that checks if the player has fire regardless of which player it is (like above), and then assigns it palette #3, or are there separate checks that also check whether it’s player 1 or player 2 and then checks if the player has fire, and in either case assigns it palette #3.  Or in other words, does the game check which player is being used, as well as the state of the player, and then assigns a palette, like so:

Small Mario – Palette #1
Big Mario – Palette #1
Fire Mario – Palette #3
Small Luigi – Palette #2
Big Luigi – Palette #2
Fire Luigi – Palette #3

The reason I’m asking is because I want to know if it’s possible to make player 1 and player 2 look the same as each other for each of the three states they can be in (small, big , fire) but have three separate palettes for each state.  So ideally, it would be something like this:

Small Mario/Luigi – Palette #1
Big Mario/Luigi – Palette #2
Fire Mario/Luigi – Palette #3

Since this would require having separate palette assignments for small Mario and big Mario, is something like this even possible within the game or do they HAVE to be the same.  Similarly, can fire Mario and fire Luigi have different palette assignments or do they also HAVE to be the same.

If this is possible, could someone tell me where in the hex code these six palette assignments are stored (if there are in fact six distinct assignments) and how they are changed to assign a different palette?  I appreciate any help anyone can offer.  I've been reading other discussions on the idea of changing which palette is assigned to a sprite, but I can't seem to understand how to do what I'm trying to do.  Thanks in advance.

Disch

  • Hero Member
  • *****
  • Posts: 2716
  • NES Junkie
    • View Profile
Re: Super Mario Bros Player Palette Assignment
« Reply #1 on: May 15, 2017, 08:43:43 pm »
This will take some minor asm changes.

Using doppleganger's disassembly, I did a search for "palette" and "luigi" and eventually found a "PlayerColors" label... as well as the logic for determining how those colors are selected.  The code is here:

Code: [Select]
GetPlayerColors:
               ldx VRAM_Buffer1_Offset  ;get current buffer offset
               ldy #$00
               lda CurrentPlayer        ;check which player is on the screen
               beq ChkFiery
               ldy #$04                 ;load offset for luigi
ChkFiery:      lda PlayerStatus         ;check player status
               cmp #$02
               bne StartClrGet          ;if fiery, load alternate offset for fiery player
               ldy #$08
StartClrGet:   lda #$03                 ;do four colors
               sta $00
ClrGetLoop:    lda PlayerColors,y       ;fetch player colors and store them
               sta VRAM_Buffer1+3,x     ;in the buffer
               iny
               inx
               dec $00
               bpl ClrGetLoop


The interesting bit here is the value placed in Y, and that's ultimately the index used to refer to the "PlayerColors" label.

When Y=0, we use Mario palette
When Y=4, we use Luigi palette
When Y=8, we use Fire palette

The code here starts with Y=0  (the 'ldy' line).  It check loads the current player, and if it's nonzero (Luigi), it does a different ldy to make Y=4.  Then it checks PlayerStatus to see if it equals 2  (I assume 0=small, 1=big, 2=fire), and if it's 2, it does ANOTHER ldy to make Y=8.

Since you don't care about Mario/Luigi and only want it to go on player state, you can just take the current player state and multiply it by 4 to get the appropriate palette index.  That above code can be replaced with this:

Code: [Select]
GetPlayerColors:
               ldx VRAM_Buffer1_Offset  ;get current buffer offset
               
                    ; BEGIN CHANGES
               lda PlayerStatus         ; Get player status (0=small, 1=big, 2=fire)
               asl                      ; double it (0=small, 2=big, 4=fire)
               asl                      ; double it again (0=small, 4=big, 8=fire)
               tay                      ; put that value in Y
               jmp StartClrGet          ; Jump ahead (our code is smaller than what we're replacing)
         .db 0, 0, 0, 0, 0, 0, 0, 0, 0  ; Since our new code is smaller, we need to add some dummy values
                                        ;    to fill it out
                    ; END CHANGES

StartClrGet:   lda #$03                 ;do four colors
               sta $00
ClrGetLoop:    lda PlayerColors,y       ;fetch player colors and store them
               sta VRAM_Buffer1+3,x     ;in the buffer
               iny
               inx
               dec $00
               bpl ClrGetLoop


I'll leave it to you to figure out how to implement this in a hex editor.  If you want to do it by hand, you can use Obelisk as a reference:  http://www.obelisk.me.uk/6502/reference.html

mosk915

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Super Mario Bros Player Palette Assignment
« Reply #2 on: May 15, 2017, 09:55:42 pm »
Thanks for your help!  This definitely puts me on the right track.