Author
|
Topic: Changing palette pointers (NES) (Read 624 times)
|
seirj
Guest
|
|
« on: November 11, 2007, 05:17:42 pm » |
|
Are there any documents on changing palette pointers? (on NES) In the game I'm editing, 2 sprites use the same palette, and I would like to change that. There is even a set of colors in the palette that the game isn't using, and I want to make a certain sprite use those other unused colors. Can anybody help?
|
|
|
|
Sliver X
Guest
|
|
« Reply #1 on: November 11, 2007, 06:16:23 pm » |
|
The best way to start going about this is to find the palette that *is* being accessed, and setting a Read breakpoint for it and back-tracing from there.
In PPU memory, the first address to hold Palette 0 is $3F00, Palette 1 is at $3F03, 2 at $3F07, etc.
Once you find the area of code that says "Use this particular palette", you simply need to point it to the one you're wanting to use.
In theory, this is extremely easy, but in practice can be bedeviling, especially if you've never done something like it before.
*edit* If you get absolutely stumped, tell me what game it is/what palette you're trying to use and I can walk you through the procedure of altering it.
|
|
|
|
seirj
Guest
|
|
« Reply #2 on: November 13, 2007, 04:30:13 pm » |
|
So am I supposed to set a Read breakpoint in the PPU memory? When I do that nothing happens. Is the PPU memory write only? I tried to find the palette in NES memory, and I think I found it at $CAAE-$CAB1, and when I put a Read breakpoint on that, it will break when the sprite is loaded. It says this in the debugger... $C84B:B1 00 LDA ($00),Y @ $CAAE = #$0F And when I press Run a few times it will change... $C84B:B1 00 LDA ($00),Y @ $CAAF = #$0F $C84B:B1 00 LDA ($00),Y @ $CAB0 = #$04 $C84B:B1 00 LDA ($00),Y @ $CAB1 = #$1C 0F 0F 04 1C is the palette colors... And above that in the debugger it says this.... $C83C:AA TAX $C83D:BD 95 C8 LDA $C895,X @ $C8A8 = #$83 $C840:85 00 STA $0000 = #$AE $C842:BD 96 C8 LDA $C896,X @ $C8A9 = #$AE $C845:85 01 STA $0001 = #$CA $C847:A6 22 LDX $0022 = #$13 $C849:A0 00 LDY #$00 $C84B:B1 00 LDA ($00),Y @ $CAAE = #$0F I don't know what any of it means really, I don't know what I'm looking for. Am I doing the right thing here? And if I am, what's the next step? Thanks in advance.
|
|
|
|
KingMike
Guest
|
|
« Reply #3 on: November 13, 2007, 11:03:38 pm » |
|
When anything is read from an address above $8000, it is the ROM being read. So, while the debugger (FCEUXD SP) is snapped, open the hex editor, scroll down to the address ($CAAE), right-click, choose the option to jump to that point in the ROM.
|
|
|
|
seirj
Guest
|
|
« Reply #4 on: November 13, 2007, 11:15:57 pm » |
|
Yeah, and doing that takes me to the location of palette in the rom, which I already know, and have already changed. I'm looking for the location of pointer that tells the sprite to use that palette, not the location of the palette itself.
|
|
|
|
never-obsolete
Guest
|
|
« Reply #5 on: November 14, 2007, 02:09:36 pm » |
|
$C83C:AA TAX $C83D:BD 95 C8 LDA $C895,X @ $C8A8 = #$83 $C840:85 00 STA $0000 = #$AE $C842:BD 96 C8 LDA $C896,X @ $C8A9 = #$AE $C845:85 01 STA $0001 = #$CA $C847:A6 22 LDX $0022 = #$13 $C849:A0 00 LDY #$00 $C84B:B1 00 LDA ($00),Y @ $CAAE = #$0F
this gets a pointer from a table and stores to the zero page ($00 and $01) for indirect addressing. from the snippet i think you won't find a pointer for each object, but instead an index into a pointer table. figure out where line $C83C gets the A value from and you'll probably find your answer.
|
|
|
|
seirj
Guest
|
|
« Reply #6 on: November 14, 2007, 03:23:42 pm » |
|
How do I find out where it gets the value from? Does it tell me if I scroll it up more? Do you want more of the log? $C807:A4 97 LDY $0097 = #$00 $C809:20 19 C8 JSR $C819 $C80C:A9 0A LDA #$0A $C80E:20 39 C8 JSR $C839 $C811:A9 02 LDA #$02 $C813:20 83 C1 JSR $C183 $C816:A4 97 LDY $0097 = #$00 $C818:C8 INY $C819:B1 08 LDA ($08),Y @ $FB2B = #$15 $C81B:48 PHA $C81C:A9 04 LDA #$04 $C81E:20 83 C1 JSR $C183 $C821:68 PLA $C822:4C 39 C8 JMP $C839 $C825:86 04 STX $0004 = #$D3 $C827:20 2E C8 JSR $C82E $C82A:A5 04 LDA $0004 = #$D3 $C82C:D0 0B BNE $C839 $C82E:48 PHA $C82F:A9 02 LDA #$02 $C831:85 03 STA $0003 = #$02 $C833:A9 01 LDA #$01 $C835:20 8C C8 JSR $C88C $C838:68 PLA $C839:85 02 STA $0002 = #$0A $C83B:0A ASL $C83C:AA TAX $C83D:BD 95 C8 LDA $C895,X @ $C8A8 = #$83 $C840:85 00 STA $0000 = #$AE $C842:BD 96 C8 LDA $C896,X @ $C8A9 = #$AE $C845:85 01 STA $0001 = #$CA $C847:A6 22 LDX $0022 = #$13 $C849:A0 00 LDY #$00 $C84B:B1 00 LDA ($00),Y @ $CAAE = #$0F
|
|
|
|
never-obsolete
Guest
|
|
« Reply #7 on: November 14, 2007, 03:34:03 pm » |
|
is that copied from the debugger or trace logger?
check the "Log A,X,Y" option, set an execute breakpoint on $C83B. look through the logged code and see where the value of A at $C83B is read from.
|
|
|
|
seirj
Guest
|
|
« Reply #8 on: November 14, 2007, 03:50:23 pm » |
|
It was from the debugger. I did a trace log like you said. $C85D:A5 02 LDA $0002 = #$15 A:15 X:12 Y:10 P:nvUbdIzc $C85F:10 0E BPL $C86F A:15 X:12 Y:10 P:nvUbdIzc $C86F:E8 INX A:15 X:12 Y:10 P:nvUbdIzc $C870:D0 D9 BNE $C84B A:15 X:13 Y:10 P:nvUbdIzc $C84B:B1 00 LDA ($00),Y @ $9EA1 = #$FF A:15 X:13 Y:10 P:nvUbdIzc $C84D:C8 INY A:FF X:13 Y:10 P:NvUbdIzc $C84E:C9 FF CMP #$FF A:FF X:13 Y:11 P:nvUbdIzc $C850:F0 40 BEQ $C892 A:FF X:13 Y:11 P:nvUbdIZC $C892:86 22 STX $0022 = #$03 A:FF X:13 Y:11 P:nvUbdIZC $C894:60 RTS A:FF X:13 Y:11 P:nvUbdIZC $C80C:A9 0A LDA #$0A A:FF X:13 Y:11 P:nvUbdIZC $C80E:20 39 C8 JSR $C839 A:0A X:13 Y:11 P:nvUbdIzC $C839:85 02 STA $0002 = #$15 A:0A X:13 Y:11 P:nvUbdIzC $C83B:0A ASL A:0A X:13 Y:11 P:nvUbdIzC $C83C:AA TAX A:14 X:13 Y:11 P:nvUbdIzc $C83D:BD 95 C8 LDA $C895,X @ $C8A9 = #$AE A:14 X:14 Y:11 P:nvUbdIzc $C840:85 00 STA $0000 = #$91 A:AE X:14 Y:11 P:NvUbdIzc $C842:BD 96 C8 LDA $C896,X @ $C8AA = #$CA A:AE X:14 Y:11 P:NvUbdIzc $C845:85 01 STA $0001 = #$9E A:CA X:14 Y:11 P:NvUbdIzc $C847:A6 22 LDX $0022 = #$13 A:CA X:14 Y:11 P:NvUbdIzc $C849:A0 00 LDY #$00 A:CA X:13 Y:11 P:nvUbdIzc Edit: I have a 4MB trace log file. It shows $C83B a few times, but I don't see where it reads a value. Am I looking for a LDA or a STA or something else?
|
|
« Last Edit: November 16, 2007, 02:51:27 pm by seirj »
|
|
|
|
KingMike
Guest
|
|
« Reply #9 on: November 17, 2007, 11:38:39 pm » |
|
Oh yeah, I see it now.
LDA #$0A ;load A with the value $0A ASL ;shift the bits of A left, effectively doubles the value in A TAX LDA $C895,X ;here's your answer. $C895 (and the $C896 a little later) is likely the pointer. So check if the pointer table is at whatever ROM address $C895 converts to.
|
|
|
|
seirj
Guest
|
|
« Reply #10 on: November 18, 2007, 01:37:35 am » |
|
Unfortunately, changing that address in the rom does nothing. $C895 takes me to 0x1C8A5, and editing that address or the one next to it doesn't change the chosen palette. Maybe I'm out of luck.
|
|
|
|
Dr. Floppy
Guest
|
|
« Reply #11 on: November 18, 2007, 02:12:16 am » |
|
Out of curiosity, what game is it you're trying to hack/which object palettes do you want to re-orient? I've been going over this thread like a starved coyote, as I want to do the same thing in SMB1. The hills/bushes in the background of the overworld levels use the same palette/pointer as the vertical pipes; I want to keep the bushes green while changing the hills to a purple/white snowy theme. As if to tease me, the programmers seem to have included a slate of unused palettes within 12-16 bytes of the current default. The default palette starts at location CDB, which translates to $8CCB. Setting a read-breakpoint to this CPU address snaps the game instantly upon reset at $8EB9, yielding this: $8EB1:02 UNDEFINED $8EB2:C8 INY $8EB3:4A LSR $8EB4:4A LSR $8EB5:AA TAX $8EB6:B0 01 BCS $8EB9 $8EB8:C8 INY $8EB9:B1 00 LDA ($00),Y @ $8CCB = #$0F $8EBB:8D 07 20 STA $2007 = #$00 $8EBE:CA DEX $8EBF:D0 F5 BNE $8EB6 $8EC1:38 SEC $8EC2:98 TYA $8EC3:65 00 ADC $00 = #$C8 $8EC5:85 00 STA $00 = #$C8 $8EC7:A9 00 LDA #$00 $8EC9:65 01 ADC $01 = #$8C $8ECB:85 01 STA $01 = #$8C $8ECD:A9 3F LDA #$3F $8ECF:8D 06 20 STA $2006 = #$00 $8ED2:A9 00 LDA #$00 $8ED4:8D 06 20 STA $2006 = #$00 Unfortunately, due to a combination of fatigue, inexperience and missing my second daily dose of Adderallâ„¢, I am unable to make any sense out of this... Perhaps I need to set breakpoints for the specific handlers of the scenery I want to re-orient?
|
|
|
|
never-obsolete
Guest
|
|
« Reply #12 on: November 18, 2007, 12:52:51 pm » |
|
$C80C:A9 0A LDA #$0A A:FF X:13 Y:11 P:nvUbdIZC <--- #1 $C80E:20 39 C8 JSR $C839 A:0A X:13 Y:11 P:nvUbdIzC $C839:85 02 STA $0002 = #$15 A:0A X:13 Y:11 P:nvUbdIzC $C83B:0A ASL A:0A X:13 Y:11 P:nvUbdIzC $C83C:AA TAX A:14 X:13 Y:11 P:nvUbdIzc $C83D:BD 95 C8 LDA $C895,X @ $C8A9 = #$AE A:14 X:14 Y:11 P:nvUbdIzc <--- #2 $C840:85 00 STA $0000 = #$91 A:AE X:14 Y:11 P:NvUbdIzc $C842:BD 96 C8 LDA $C896,X @ $C8AA = #$CA A:AE X:14 Y:11 P:NvUbdIzc <--- #2 $C845:85 01 STA $0001 = #$9E A:CA X:14 Y:11 P:NvUbdIzc $C847:A6 22 LDX $0022 = #$13 A:CA X:14 Y:11 P:NvUbdIzc $C849:A0 00 LDY #$00 A:CA X:13 Y:11 P:nvUbdIzc
try changing the #$0A to something else. or... changing the pointer at $C895/96 won't effect what #$0A indexes, as that is the base pointer. you would need to change ($C895 + (#$0A *2)) and ($C896 + (#$0A *2)), which are $C8A9 and $C8AA respectively.
|
|
|
|
seirj
Guest
|
|
« Reply #13 on: November 18, 2007, 01:42:41 pm » |
|
Ok, now there is at least progress. Changing $C80C, $C8A9, and $C8AA, actually changes colors. But the changes are kind of unpredictable.
Sometimes it shifts ALL the palettes to different colors, and sometimes it just shifts the palettes of the 2 sprites I want to change to different colors. It doesn't seem to isolate just sprite #1 or sprite #2, but always both of them at the same time, so far.
I guess I could try 768 different values and see what happens, but that doesn't sound like fun.. does it?
|
|
|
|
|