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

Author Topic: Super Mario World Custom Sprite Palette Help  (Read 5921 times)

Jonesy47

  • Full Member
  • ***
  • Posts: 116
    • View Profile
Super Mario World Custom Sprite Palette Help
« on: January 31, 2014, 09:08:50 pm »
Hey everybody. I'm fairly new to hacking mario world (almost zero experience with assembly) but have run into a weird sort of problem.
When I first started inserting custom sprites in my rom, i couldn't get a majority of them to display the palette correctly, so i read around and found out how to open a custom palette in lunar magic.
This is my process. I import the .pal and awesome, now the palette the custom sprite uses (in this case palette row 8 or 0xF) is in my rom, according to lunar magic. I save my level to rom but, when I open my rom in an emulator, the colors look like this:



I save state and open the exgraphics for the custom sprite in yychr to see whats going on. Using the ingame palette in yychr, it shows the sprite PERFECTLY (bad pic).



But when I load the game in an emulator or lunar magic, it still displays the off colors, as displayed in the 8x8 tile editor.



Now, I've tinkered with it a little bit and it seems that the last 8 colors in the palette row, while SAYING they are displaying like this:



are ACTUALLY repeating the first 8 colors instead and looking like this:



WHY DOES IT DO THIS?
Have I not installed a needed patch?
Is there a palette property i need to mess with inside of the sprite's .asm?
It's really frustrating because I can half-ass it and just sample the sprite down to use half the colors in yychr by just using the first 8 palette colors but i KNOW there HAS TO BE A WAY to access the full palette, otherwise i assume people wouldnt put up .pal files with their custom sprites that can only use half the colors the file specifies.
I honestly cant figure this out on my own it seems.
Any help would be much appreciated.
Thank you.

February 01, 2014, 05:24:08 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Ok, the hunt continues for how to fully have control over my custom sprite palettes.
I have gathered more info, going through each and every question thread that pertains to the subject.
I think Im having a similar problem to the member in this thread:

Changing Custom Sprite Palettes
http://www.smwcentral.net/?p=viewthread&t=52144

First, I opened the .cfg in cfgeditor and saw this:



So, there IS some sort of an option to use the "second graphics page" which i think refers to a full 16 color palette instead of 8 colors doubled but, when i change the palette that is used from F or unclick "use second graphics page" the sprite stays the same, just like in the thread i linked to which leads me to believe that the sprite palette info IS within the .asm file, but in YXPPCCCT format and that the "use second graphics page" option is off.

After reading this tutorial:

http://www.smwcentral.net/?p=viewthread&t=25106

I am still lost.
The info closest to what Im looking for is in the first thread i linked to, the forum suggested looking for $0303 in the graphics routine, so i found it, but the graphics routine looks different than in the first thread example.

Mine looks like this:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PROPERTIES: dcb $7F,$3F

;The tables must now have 16 bytes.
;THE LAST 8 ARE ONLY CREATED BECAUSE OF XDISP.

;0-4 BYTE   - FRAME 1 RIGHT
;4-8 BYTE   - FRAME 2 RIGHT
;8-12 BYTE  - FRAME 1 LEFT
;12-16 BYTE - FRAME 2 LEFT

TILEMAP:
   dcb $00,$02,$20,$22 ; WALKING 1   ;\ RIGHT
   dcb $04,$06,$24,$26 ; WALKING 2   ;/ RIGHT
   dcb $00,$02,$20,$22 ; WAITING 1   ;\ RIGHT
   dcb $84,$86,$A4,$A6 ; WAITING 2   ;/ RIGHT
   dcb $40,$42,$60,$62 ; RETREAT 1   ;\ RIGHT
   dcb $44,$46,$64,$66 ; RETREAT 2   ;/ RIGHT
   dcb $08,$0A,$28,$2A ; THROW 1   ;\ RIGHT
   dcb $0C,$0E,$2C,$2E ; THROW 2   ;/ RIGHT
   dcb $80,$82,$A0,$A2 ; LEAPING 1   ;\ RIGHT
   dcb $80,$82,$A0,$A2 ; LEAPING 2   ;/ RIGHT
   dcb $8C,$8E,$AC,$AE ; STUNNED 1   ;\ RIGHT
   dcb $C0,$C2,$E0,$E2 ; STUNNED 2   ;/ RIGHT
   dcb $48,$4A,$68,$6A ; DYING 1   ;\ RIGHT
   dcb $48,$4A,$68,$6A ; DYING 2   ;/ RIGHT

   dcb $00,$02,$20,$22 ; WALKING 1   ;\ LEFT
   dcb $04,$06,$24,$26 ; WALKING 2   ;/ LEFT
   dcb $00,$02,$20,$22 ; WAITING 1   ;\ LEFT
   dcb $84,$86,$A4,$A6 ; WAITING 2   ;/ LEFT
   dcb $40,$42,$60,$62 ; RETREAT 1   ;\ LEFT
   dcb $44,$46,$64,$66 ; RETREAT 2   ;/ LEFT
   dcb $08,$0A,$28,$2A ; THROW 1   ;\ LEFT
   dcb $0C,$0E,$2C,$2E ; THROW 2   ;/ LEFT
   dcb $80,$82,$A0,$A2 ; LEAPING 1   ;\ LEFT
   dcb $80,$82,$A0,$A2 ; LEAPING 2   ;/ LEFT
   dcb $8C,$8E,$AC,$AE ; STUNNED 1   ;\ LEFT
   dcb $C0,$C2,$E0,$E2 ; STUNNED 2   ;/ LEFT
   dcb $48,$4A,$68,$6A ; DYING 1   ;\ LEFT
   dcb $48,$4A,$68,$6A ; DYING 2   ;/ LEFT

YDISP:    
   dcb $F0,$F0,$00,$00 ; WALKING 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; WALKING 2   ;/ RIGHT
   dcb $F0,$F0,$00,$00 ; WAITING 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; WAITING 2   ;/ RIGHT
   dcb $F0,$F0,$00,$00 ; RETREAT 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; RETREAT 2   ;/ RIGHT
   dcb $F0,$F0,$00,$00 ; THROW 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; THROW 2   ;/ RIGHT
   dcb $F0,$F0,$00,$00 ; LEAPING 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; LEAPING 2   ;/ RIGHT
   dcb $F0,$F0,$00,$00 ; STUNNED 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; STUNNED 2   ;/ RIGHT
   dcb $F0,$F0,$00,$00 ; DYING 1   ;\ RIGHT
   dcb $F0,$F0,$00,$00 ; DYING 2   ;/ RIGHT

   dcb $F0,$F0,$00,$00 ; WALKING 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; WALKING 2   ;/ LEFT
   dcb $F0,$F0,$00,$00 ; WAITING 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; WAITING 2   ;/ LEFT
   dcb $F0,$F0,$00,$00 ; RETREAT 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; RETREAT 2   ;/ LEFT
   dcb $F0,$F0,$00,$00 ; THROW 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; THROW 2   ;/ LEFT
   dcb $F0,$F0,$00,$00 ; LEAPING 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; LEAPING 2   ;/ LEFT
   dcb $F0,$F0,$00,$00 ; STUNNED 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; STUNNED 2   ;/ LEFT
   dcb $F0,$F0,$00,$00 ; DYING 1   ;\ LEFT
   dcb $F0,$F0,$00,$00 ; DYING 2   ;/ LEFT

XDISP:    
   dcb $00,$10,$00,$10 ; WALKING 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; WALKING 2   ;/ RIGHT
   dcb $00,$10,$00,$10 ; WALKING 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; WALKING 2   ;/ RIGHT
   dcb $00,$10,$00,$10 ; RETREAT 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; RETREAT 2   ;/ RIGHT
   dcb $00,$10,$00,$10 ; THROW 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; THROW 2   ;/ RIGHT
   dcb $00,$10,$00,$10 ; LEAPING 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; LEAPING 2   ;/ RIGHT
   dcb $00,$10,$00,$10 ; STUNNED 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; STUNNED 2   ;/ RIGHT
   dcb $00,$10,$00,$10 ; DYING 1   ;\ RIGHT
   dcb $00,$10,$00,$10 ; DYING 2   ;/ RIGHT

   dcb $10,$00,$10,$00 ; WALKING 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; WALKING 2   ;/ LEFT
   dcb $10,$00,$10,$00 ; WALKING 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; WALKING 2   ;/ LEFT
   dcb $10,$00,$10,$00 ; RETREAT 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; RETREAT 2   ;/ LEFT
   dcb $10,$00,$10,$00 ; THROW 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; THROW 2   ;/ LEFT
   dcb $10,$00,$10,$00 ; LEAPING 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; LEAPING 2   ;/ LEFT
   dcb $10,$00,$10,$00 ; STUNNED 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; STUNNED 2   ;/ LEFT
   dcb $10,$00,$10,$00 ; DYING 1   ;\ LEFT
   dcb $10,$00,$10,$00 ; DYING 2   ;/ LEFT

SUB_GFX:
   JSR GET_DRAW_INFO

   LDA $1602,x
   STA $03                 ; | $03 = index to frame start (0 or 4)


   LDA $14         ;\ Frame counter ..
   LSR A         ; |
   LSR A         ; | Add in frame animation rate; More LSRs for slower animation.
   LSR A         ; |
   AND #$01      ; | 01 means we animate between 2 frames (00 and 01).
   ASL A          ; |
   ASL A         ; | ASL x2 (0-4) makes it switch between the first byte and fifth byte,
   STA $03       ;/ i.e. first animation and second animation. The result is stored into $03.

   LDA SPRITE_STATE,x      ; If jumping up
   CMP #$06
   BNE NOT_DEAD
   LDA $03
   CLC
   ADC #$30                ;    ...set killed frame
        STA $03         
        LDA $15F6,x            ; \
        ORA #$80            ; | ...flip vertically
        STA $15F6,x            ; /
        BRA DONE_WALKING

NOT_DEAD:
   LDA SPRITE_STATE,x      ; if retreating into shell
   CMP #$04
   BNE KNOCKED_BACK         ; |
   LDA $03               ; |
   CLC                  ; |
   ADC #$10            ; | ...use stun frames.
   STA $03               ; /
   BRA DONE_WALKING

KNOCKED_BACK:
   LDA SPRITE_STATE,x      ; if retreating into shell
   CMP #$05
   BNE YELLING            ; |
   LDA $03               ; |
   CLC                  ; |
   ADC #$28            ; | ...use stun frames.
   STA $03               ; /
   BRA DONE_WALKING

YELLING:
   LDA SPRITE_STATE,x      ; if yelling at Mario
   CMP #$00
   BNE JUMPING            ; |
   LDA $03               ; |
   CLC                  ; |
   ADC #$08            ; | ...use stun frames.
   STA $03               ; /
   BRA DONE_WALKING

JUMPING:
   LDA SPRITE_STATE,x      ; if exiting the level
   CMP #$07
   BNE IN_THE_AIR            ; |
   LDA $03               ; |
   CLC                  ; |
   ADC #$20            ; | ...use stun frames.
   STA $03               ; /
   BRA DONE_WALKING

IN_THE_AIR:
   LDA SPR_OBJ_STATUS,x   ;return if on the ground
   CMP #$04            ; |
   BEQ THROWING_SHELL         ; |
   LDA $03               ; |
   CLC                  ; |
   ADC #$20            ; | ...use stun frames.
   STA $03               ; /
   BRA DONE_WALKING

THROWING_SHELL:
   LDA SPRITE_STATE,x      ; If throwing shell
   CMP #$03
   BNE DONE_WALKING            ; |
   LDA $03               ; |
   CLC                  ; |
   ADC #$18            ; | ...use stun frames.
   STA $03               ; /
;   BRA DONE_WALKING

DONE_WALKING:
   LDA $157C,x
   STA $02         ; Store direction to $02 for use with property routine later.
   BNE NoAdd
   LDA $03         ;\
   CLC         ; | If sprite faces left ..
   ADC #$38      ; | Adding 16 more bytes to the table.
   STA $03         ;/ So we can invert XDISP to not mess up the sprite's appearance.
NoAdd:
   PHX         ;\ Push sprite index ..
   LDX #$03      ;/ And load X with number of tiles to loop through.
Loop:
   PHX         ; Push number of tiles to loop through.
   TXA         ;\
   ORA $03         ;/ Transfer it to X and add in the "left displacement" if necessary.
   TAX         ;\ Get it back into X for an index.

   LDA $00         ;\
   CLC         ; | Apply X displacement of the sprite.
   ADC XDISP,x      ; |
   STA $0300,y      ;/

   LDA $01         ;\
   CLC         ; | Y displacement is added for the Y position, so one tile is higher than the other.
   ADC YDISP,x      ; | Otherwise, both tiles would have been drawn to the same position!
   STA $0301,y      ; | If X is 00, i.e. first tile, then load the first value from the table and apply that
            ;/ as the displacement. For the second tile, F0 is added to make it higher than the first.

   LDA TILEMAP,x
   STA $0302,y

   PHX         ; Push number of times to go through loop + "left" displacement if necessary.
   LDX $02         ;\
   LDA PROPERTIES,x   ; | Set properties based on direction.
   STA $0303,y      ;/
   PLX         ; Pull number of times to go through loop.

   INY         ;\
   INY         ; | The OAM is 8x8, but our sprite is 16x16 ..
   INY         ; | So increment it 4 times.
   INY         ;/
      
   PLX         ; Pull current tile back.
   DEX         ; After drawing this tile, decrease number of tiles to go through loop. If the second tile
            ; is drawn, then loop again to draw the first tile.

   BPL Loop      ; Loop until X becomes negative (FF).
   
   PLX         ; Pull back the sprite index! We pushed it at the beginning of the routine.

   LDY #$02      ; Y ends with the tile size .. 02 means it's 16x16
   LDA #$03      ; A -> number of tiles drawn - 1.
            ; I drew 2 tiles, so 2-1 = 1. A = 01.

   JSL $01B7B3      ; Call the routine that draws the sprite.
   RTS         ; Never forget this!   


Based on what I have gathered (which is probably wrong or at fault somehow), it should be contained here?


   PHX         ; Push number of times to go through loop + "left" displacement if necessary.
   LDX $02         ;\
   LDA PROPERTIES,x   ; | Set properties based on direction.
   STA $0303,y      ;/
   PLX         ; Pull number of times to go through loop.   

And thaaaaats all I have learned so far. I have tried to convert more than a few values in the .asm file surrounding the $0303 area from hex to binary, then converting the CCC to a different palette in YXPPCCCT format and changing it back to hex, inserting it back into the .asm but it results in crazy corrupted graphics everytime AND the palette stays the same so im doing it wrong.

PLLLLLLLEEEEEEASE HELP ME. I am begging at this point. My sprites look god awful with the last 8 palette colors repeating the first 8. Thanks again guys.

February 01, 2014, 08:40:49 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
edit: SOLVED. Im an idiot and was inserting all my ExGFX as 3BPP. I read a tutorial that told me never to click that box, but yeah, who knows whats changed since that was written. Anyways, AWESOME. CRISIS AVERTED.
I woulda been stuck forever on that stupid crap, i just know it. Sometimes, it's so simple...
« Last Edit: February 01, 2014, 08:40:50 pm by Jonesy47 »