PDA

View Full Version : New here and looking for some help in a megaman hack


Caesura
10-19-2008, 01:43 AM
I'm simply trying to replace the megaman sprite with protoman (because protoman is a badass) and I've got the sprite down--I know how to anyway--and most of the color.

I have a problem though. During gameplay, once a check point is passed and the character dies, he comes back to the checkpoint in his original colors. Which sucks. If the pause menu is brought up the colors go back to custom! I'm working on this with the emulator FCEUXD SP. And I've checked out the hex editor and found the hex values where the color changes. If I "freeze" these values the colors work fine, but the problem isn't fixed for other emulators. I'd kind of like to be able to make this a permanent fix.

Anybody know how to fix this issue?

Ugly Joe
10-19-2008, 02:02 AM
This would imply that Megaman's palette exists in more than one location in the ROM. You've successfully replaced one (or more) of them, but not all of them. Search the ROM for any remaining copies of Megaman's original palette and replace it with Protoman's palette.

Caesura
10-19-2008, 03:33 AM
Okay, so I've gone through the hex and searched for any sequence of C211 (dark blue, light blue) and replaced all the results of the search with 3D06 (red, gray). During the game, it'll still revert though. I can see where it changes too. I just can't keep it changed.

During emulation though, only the hex only changes in "NES memory" view, and I can't change (or figure out how to) change that.

edit. and thanks for the help!
and 2C not C2 sorry

Ugly Joe
10-19-2008, 05:04 AM
So you can see in the NES memory view where the color change is made? Like, you can see the bytes 3D 06 being overwritten with C2 11? If that's the case, you're probably best off using the debugger. Setup a write breakpoint for the memory addresses that are being used to store Megaman's palette. Play the game until you know it's going to write in the Megaman palette and then take a look at the debugger. With any luck, you'll be able to determine where it's pulling the old blue palette colors from.

Also, which Megaman game are you hacking?

Caesura
10-19-2008, 07:49 AM
Yeah, I can see where it overwrites, and I know when it overwrites.

I looked into the debugger, but I haven't actually been able to understand it. I'm not sure how to make breakpoints and I definitely don't know how to write, or understand, conditions.

I'm just working on the first for now (it's definitely not my favorite). I figured it'd be the easiest to understand. This is my first ever hack. Besides playing with the sprites in that megaman 7 8-bit file.

Caesura
10-21-2008, 03:21 PM
I've messed around with the debugger a little bit. I still don't understand break points, but I found this:

$03E1:3D 06 0F AND $0F06,X @ $1005 = #$80(/DF)

and it gets overwritten by this:

$03E1:2C 11 0F BIT $0F11 = #$00

soooo... what does that mean? I'll keep messing around with it.

The 9th Sage
10-22-2008, 03:07 AM
I have a friend who knows a LOT about Megaman, and he says this (note that I can't take credit for this):

at 1C2AA is a routine that includes A9 2C and A9 11. the 2C and 11 are palette values he needs to change. he would have been able to find this by using FCEUXD's debugger and setting a write breakpoint on 3E1. when he respawns at either of the last two checkpoints, the debugger will break and show him the address where the palette writing is happening. going back a single instruction shows where the value is loaded from.

Caesura
10-22-2008, 05:10 AM
Thanks, and thank your friend for me!

That worked. I knew where to write the breakpoint but I don't know how to write conditions, which is why I couldn't do that part myself. Can anyone direct me to a good tutorial?

Ugly Joe
10-22-2008, 12:21 PM
Check the second half of this post:

http://www.the-interweb.com/serendipity/index.php?/archives/29-Initial-release-of-FCEUXD-SP-1.0.html#extended

That's the only documentation I've ever been able to find on FCEUXD SP's conditional breakpoints. It's really all you need, though.

Caesura
10-23-2008, 03:15 PM
I've seen this, and read through it. I get lost around here:

"A condition is a simple C-style expression. Supported values are A (register), X (register), Y (register), N, V, U, B, D, I, Z, C (all flags), hex numbers of the form #1234 and values at (CPU) memory locations of the form $1234. These values can be compared using the operators ==, !=, >=, <=, > and <. Two or more expressions can be connected using conditional OR (||) or conditional AND (&&)."

The terms "register" "flags" and the multiple operations listed confuses me.

Ugly Joe
10-24-2008, 02:16 AM
If you've never done any programming before, then, yeah, it'll probably be confusing.

A, X, and Y are registers. They can hold one byte. They sort of act like 3 special memory addresses (although they are actually part of the CPU and are not part of the memory at all). You can read/write to them using various assembly instructions. A is the Accumulator and is the most important one. Most of your conditional breakpoints will be checking for a specific A value.

The rest are flags. They can hold one bit. That's 0 or 1. They are used to signify special states that the NES can be in (vblank, interrupt, etc). Chances are you won't be setting up breakpoint conditions for these until you actually know what they stand for.

A crash course in operations:
A == #09 --> A is equal to #09
A != #09 --> A is not equal to #09
A >= #09 --> A is greater than or equal to #09
A <= #09 --> A is less than or equal to #09
A > #09 --> A is greater than #09
A < #09 --> A is less than #09

&& and || can be used to combine conditions. && is and. || is or.
A >= #05 && A <= #09 --> A is greater than or equal to #05 and less than or equal to #09
A == #05 || A == #09 --> A is equal to #05 or A is equal to #09

Caesura
10-24-2008, 03:17 AM
Wow, hey, thanks so much for taking the time to tell me that! It'll definitely be helpful!

Ugly Joe
10-24-2008, 03:55 AM
Here's a more in-depth explanation, from here (http://www.zophar.net/documents/nes/nesdev-tutorial.html):

The 6502 has a number of internal registers which are not addressable by any 6502 instruction, but are an actual part of the CPU. These include the Accumulator, the X- and Y-Index Registers, the Stack Pointer, the Program Counter, and Processor Status Register.


The Accumulator (A for short) is the heart and soul of the 6502. All arithmetic and logical operations work with data in the Accumulator, and the majority of memory transfers will take place through the Accumulator. As far as you (as an NES programmer) should be concerned, the Accumulator is the 6502.
The X- and Y-Index Registers (X and Y for short) are important registers. They can be used for memory transfer (like the Accumulator) and for holding temporary values, but their primary purpose will be in assisting the Accumulator in memory transfers by acting as a read/write offset (ie., index). This is a very important feature. Note that you cannot perform arithmetic or logical operations on X or Y.
The Stack Pointer (SP for short) acts as an offset to "The Stack" (explained later). It points to the next free space on the Stack, which can be considered synonymous with $01xx, where xx is the value in SP.
The Program Counter (PC for short) is the only 16-bit register in the 6502. It contains the address of the current instruction being executed, ie., where the 6502 "is" in the program.
The Processor Status Register (P for short) contains a series of "flags" (a flag = an indication of whether something has or has not taken place) that reflect the result of the 6502's operations. This is absolutely critical to controlling program flow, since the Branch-on-Condition instructions use the data contained in P. Here are it's flags, from right to left:

Carry (C) - this holds the "carry" out of the most significant bit of the last addition/subtraction/shift/rotate instruction. If an addition produces a result greaater than 255, this is set. If a subtraction produces a result less than zero, this is cleared (Subtract operations use the opposite of the Carry (1=0, 0=1)).
Zero (Z) - this is set if the last operation returned a result of zero.
Decimal (D) - if set, all Addition/Subtraction operations will be calculated using "Binary-coded Decimal"-formatted values (eg., $69 = 69), and will return a BCD value. Decimal mode is unavaliable on the NES' 6502, which is just as well.
Interrupt Disable (I) - if set, IRQ interrupts will be disabled.
Breakpoint (B) - this is set only if the BRK instruction is executed.
The third-highest bit is unused; it is supposed to be a logical 1 at all times. (I don't know why either).
Overflow (V) - This is set if the last operation resulted in a sign change (see below).
Negative/Sign (N) - This is simply a reflection of the highest bit of the result of the last operation. A number with it's high bit set is considered to be negative ($FF = -1); they are called "Signed" numbers.

Caesura
11-24-2008, 12:52 AM
Okay, so I realize I'm raising this thread from the dead... but, it applies to here.

So I've been doing relatively okay without the debugger for a while. I still don't understand it. I have the tools and the information about them, but no technique to put them to use. So I was wondering if I can have a real working example.

I'm currently working on a MM6 hack, the same kind I've been working on with the first three I've made. And I can't find the palette data that the mega buster's colors are stored on.

What I had been doing was opening: opening the game in fceuxd and the hex editor in that, switching to the rom view, and searching with "find" for the colors of the palettes in the PPU viewer. And I've gotten by doing that. But I've tried that with this, and it hasn't worked.

So I tried using the debugger: I set up a breakpoint in the ram where the values I wanted were changing, and I saw that they were changing to colors I didn't want. The breakpoint showed me some other values that I assumed were the values that took the palette from somewhere else to apply to the sprite. But that didn't help because I need the actual palette's offset, not the values that take the palette.

Any help on this matter would be great. And an actual example of using the debugger would be extremely helpful. Thanks!