PPF PC hacking

From Puyo Nexus Wiki
Jump to: navigation, search

At $D01C0 (in v1.05) or $DB998 (in v1.12) is a table with records of length ten int32s ($28 bytes). Each record in this table is for a base (i.e. an individual cutscene from the screen fade-in to the screen fade-out). The fields in this table are as follows:

  • Field 0, offset $00: Unknown.
  • Field 1, offset $04: Japanese script pointer.
  • Fields 2-5, offset $08-$14: English script pointers. The extra copies were probably reserved for other languages that were never added.
  • Field 6, offset $18: Voice pointer.
  • Field 7, offset $1C: Number of cuts (i.e. animation events that occur between speech).
  • Field 8, offset $20: Unknown pointer.
  • Field 9, offset $24: Unknown.

The rows in this table are as follows:

  • Row 0, offset $0000: RunRun 1
  • Row 1, offset $0028: RunRun 2
  • Row 2, offset $0050: RunRun 3
  • Row 3, offset $0078: RunRun Ending
  • Row 4, offset $00A0: Blank
  • Row 5, offset $00C8: Blank
  • Row 6, offset $00F0: Blank
  • Row 7, offset $0118: Blank
  • Row 8, offset $0140: Blank
  • Row 9, offset $0168: WakuWaku 1
  • Row 10, offset $0190: WakuWaku 2
  • Row 11, offset $01B8: WakuWaku 3
  • Row 12, offset $01E0: WakuWaku 4
  • Row 13, offset $0208: WakuWaku 5
  • Row 14, offset $0230: WakuWaku 6
  • Row 15, offset $0258: WakuWaku 7
  • Row 16, offset $0280: WakuWaku 8
  • Row 17, offset $02A8: Blank
  • Row 18, offset $02D0: HaraHara 1
  • Row 19, offset $02F8: HaraHara 2
  • Row 20, offset $0320: HaraHara 3
  • Row 21, offset $0348: HaraHara 4
  • Row 22, offset $0370: HaraHara 5
  • Row 23, offset $0398: HaraHara 6
  • Row 24, offset $03C0: HaraHara 7
  • Row 25, offset $03E8: HaraHara 8 (Popoi version)
  • Row 26, offset $0410: HaraHara 8 (Carbuncle version)

At $A66D8 (in v1.05) is a table with records of length four int32s ($10 bytes). Each record in this table is also for a base. The fields are as follows:

  • Field 0, offset $00: Unknown, always $41F210 except for row 0
  • Field 1, offset $04: Pointer to image loading code.
  • Field 2, offset $08: Pointer to animation script code.
  • Field 3, offset $0C: Unknown, always $46CE10 except for row 0

The rows in this table are as follows:

  • Row 0, offset $0000: Unknown. May not be part of the table, but contents are similar.
  • Row 1, offset $0010: RunRun 1
  • Row 2, offset $0020: RunRun 2
  • Row 3, offset $0030: RunRun 3
  • Row 4, offset $0040: RunRun ending
  • Row 5, offset $0050: WakuWaku 1
  • Row 6, offset $0060: WakuWaku 2
  • Row 7, offset $0070: WakuWaku 3
  • Row 8, offset $0080: WakuWaku 4
  • Row 9, offset $0090: WakuWaku 5
  • Row 10, offset $00A0: WakuWaku 6
  • Row 11, offset $00B0: WakuWaku 7
  • Row 12, offset $00C0: WakuWaku 8
  • Row 13, offset $00D0: HaraHara 1
  • Row 14, offset $00E0: HaraHara 2
  • Row 15, offset $00F0: HaraHara 3
  • Row 16, offset $0100: HaraHara 4
  • Row 17, offset $0110: HaraHara 5
  • Row 18, offset $0120: HaraHara 6
  • Row 19, offset $0130: HaraHara 7
  • Row 20, offset $0140: HaraHara 8 (Popoi version)
  • Row 21, offset $0150: HaraHara 8 (Carbuncle version)

By following the pointer to the image loading code, there will be pointers to filename strings which are prefixed by 6A 00 6A 00 68, presumably x86 machine code. This code and the strings can be edited to load different images.


  • 3rd pointer: "0x60944600"

This is the pointer to the animation script. I've tried switching this pointer with other animation script pointers and yes, the animation change to the corresponding newly appointed script! Well, I guess there's nothing left to do but follow it and look at the script. And what you see is some awful stuff which is almost incomprehensible. It ends at 0x694CF (because the next bytes are the load image bytes, so I'm pretty sure it ends there). I've been trying out some stuff with it, but it's really difficult. Game either crashes when I change stuff, or the characters simply won't appear. So a little bit of info from what I've seen:

  • At the end of the script, there are pointers. These pointers point back into the script. I think they point to individual events listed in the script.
  • The header usually seems the same for all scripts. The 16th byte appears to be the amount of pointers+1.

I've been looking closely at all those weird stuff, but I can't see anything resembling the sequence of animations. The only thing that somewhat looks like one is the pointers at the end, but changing those hasn't been very fruitful up till now. (freeze, crash, no animation at all or script act normally)


I think this is going to be the last post from me on the PPF hacking. So I've been trying to investigate the animation script and like I said it's pretty awful. There must be a lot more behind these scripts, but I'm unable to figure it out. So the scripts start with a header of 26 bytes. The 17th byte is the number of pointers/ events. The 23-26th is a pointer to the pointer table at the end of the script. Going to the pointer table: The first pointer shouldn't be changed. It starts up the script or something. All other pointers are pointers to events. (events are e.g. the appearance of the characters, doing an animation etc.) And now for the confusion: a lot of event pointers are the same. For example: the third and 4th event have the same pointer, but still the events are totally different. So the event is also dependent on the current event number. You can still switch them of course, with an event from another cutscene (provided the #th event actually does something on that cutscene). And what's even worse, if you follow the pointer, it will lead you to a tiny line of code, sometimes between 9~17 bytes. All these codes look almost identical, yet the game crashes if you make changes or try to copy other codes that look similar. So it pretty much leads to a dead end and it's confusing as hell as to why all those pointers lead to this place.

So I don't know what kind of cutscenes Keiji has in mind. If it's a very simple one (like an appearance and that's it), it's no problem. If you want to have an animation or perhaps introducing a new character on the screen at the xxth event (where xx is some number) it could be hard. The higher xx the less chance an existing animation fits on that event.

Text flags

In the text script data, the following flags are used. Flags are preceded by a % and may take an argument (xx) which is 2 decimal ASCII characters.

  • c = color xx - specifies the new text color (not name color).
  • e = end - ends the cut and returns to the main animation engine
  • n = nametext - toggles between writing to the name and text areas
  • p = clear - clears all text on screen
  • r = newline - goes to the next line of text (maximum 3)
  • s = speed xx - sets the speed
  • v = voice xx - plays a voice file
  • w = wait xx - waits some time

Battle animations

haxxtalk: It's ridiculously easy to switch the animations. First search for the word "cf##" where ## is a number (00=amitie etc). Then look above it (not below, which you might think at first), there is a pointer table there with 22 pointers (or 21? I'm not so sure about the 1st pointer, it seems to be very irregular when compared between characters).I took 21 pointers from Amitie and copied them into Dongurigaeru's. In v1.12 that's: from 0xBBB6C to 0xBBBBF (Amitie's animation pointers) I copied those bytes into 0xBB314 to 0xBB367 (Dongie's pointers)

Note: There is sometimes more data between the pointer table and the cf## string, I didn't fully try out every character, but I'm pretty sure they all have the same pointer table.


Some more about character animations: It seems that Amitie's animation can't be changed for some reason. If I change her pointers, she doesn't change her animations (and I'm sure it's her pointers, if I copy it into others they get Amitie's animations).

And I analyzed some of the pointers. Like I said, there are 22 pointers. Though, the second pointer seems always the same (60 43 47 00), so maybe this one and the 1st one are not part of the animations, I dunno. Changing them does not seem to affect any animation too. Anyway, continuing, the 3rd pointer is for the image (size, offset, positioning etc) for the 1st attack. Change this and some other part of the spritesheet gets loaded and/or gets moved. 4th pointer is the 2nd attack etc. I don't know how many are for the attacks.

  • 12th pointer is for the fever image (when the character is shown with the Fever banner)
  • 13th pointer is for the 1st attack animation
  • 14th pointer is for the 2nd attack animtion etc.
  • The animation pointers ,13th pointer and on, are very picky. The animation must be accompanied with the correct image loaded. For example: Changing Popoi's attack animation only will lead to a crash of the game. Only if I also copy the image info pointer, Popoi's attack turns into someone else's.

Conclusion: it all seems fine if you load both image and animation. It's possible to define your own set of animations.