![]() |
Frame Job - Making Weapons show after a strike - Printable Version +- FF6 Hacking (https://www.ff6hacking.com/forums) +-- Forum: Discussion Forums (https://www.ff6hacking.com/forums/forum-5.html) +--- Forum: Magitek Research Facility (https://www.ff6hacking.com/forums/forum-9.html) +--- Thread: Frame Job - Making Weapons show after a strike (/thread-4260.html) |
Frame Job - Making Weapons show after a strike - C-Dude - 01-01-2023 Lightning wanted to change the strike animation so that the weapon would always show for a final frame after strike, much like how Final Fantasy 4 and 5 handle weapon graphics. In other words, the swipe on small swords needed to be replaced. After much bamboo-under-nails agony, @everything8215 came down from code heaven and explained how this stuff actually works and we were able to achieve the desired effect. So, first thing's first. There's attack graphics data (https://www.ff6hacking.com/wiki/doku.php?id=ff3:ff3us:doc:asm:fmt:attack_graphics_data) at D4D000 to D4DF3B. These are six-byte strings of information about the attack, such as which weapon tile region to draw from. That information is arranged as follows: Code: Byte 1 - Number of animation frames (range from 00-3F). 0x40 indicates the high byte of the Graphic set. 0x80 indicates 2bpp Okay, so we go to this offset and we get Regal Cutlass's attack graphics data, which is 04 21 D7 00 03 03 Byte 1 tells us that this particular weapon strike has four animation frames. Byte 2 tells it which graphics set to draw from, which in this instance is the Regal Cutlass set (which is shared with a few other weapon tiles, including the paint brushes, but we're leaving this value be for now). The next two bytes are really important, though, that's the animation offset. D7 00 is two bytes of data listed little-endian, so the low byte is first. That means that Regal Cutlass has an animation offset of 00D7. What do we do with that? Well... The game converts this offset into a pointer, but those pointers are ALSO two bytes, so we have to double the offset to find the pointer address. 0x00D7 * 0x02 = 0x01AE The pointers to Battle Animation frame data are located in a jump table from D4DF3C to D4FFFF, so we add the low end of that range to our doubled offset to get the Regal Cutlass's battle animation frame data. 0x01AE + 0xD4DF3C = 0xD4E0EA We go to 0x14E0EA in our hex editor, and we find this: 7D 05 7F 05 83 05 85 05 Each frame of the animation has its own pointer, and we know that the Regal Cutlass has four frames of animation from its graphics data (that Byte 1 from D4/D0F6). So, we need eight bytes, two for each pointer times four frames. These pointers are modifiers to the $D1 bank, so... Code: Regal Cutlass https://www.ff6hacking.com/wiki/doku.php?id=ff3:ff3us:doc:asm:fmt:frame_data Frame data comes in two byte strings. The first determines the base offset of the frame, and the second determines which graphic map to use. The graphic tile maps are handled separately; they're 0x40 times the graphic set number beyond $D20000, or $D2C000 if the graphics are 2bpp. That's outside the scope of this discussion, though. You'd think we could just change Frame 4's data to be a copy of Frame 1, but then the sword will be drawn in the wrong orientation and position. We need to horizontally flip it, so we add 0x40 to the second byte. Then... we need to discuss what these two bytes actually DO. Code: Byte 0: X, Y position of the graphic block in 16 pixel intervals Okay, so the X and Y position sounds great, right? Except, it's not. It's not pixels. It's not even TILES. It seems to be stamps of the entire graphic, so even a change of 1 to either value will have a HUGE impact on the position of the graphic. This is why animation scripts have finer positioning commands. If we use the same positioning data as Frame 3, with a flipped sprite of Frame 1 (D1/0585 from 12 07 to 12 40), we end up drawing the sword on the attacker's foot. (Original Discord tutorial had an image here, you'll have to use your imagination or try the change yourself) That's no good. But if we try to change the position of the sword, it'll get drawn off in space, with no apparent relation to the attacker at all. We're going to have to change the animation script to match. Weapon animation pointers are dictated by a jump table located at D1/EAD8. This jump table consists of two-byte little-endian addresses, so we need to adjust our offset to match (doubling it, like we did before with the other jump table). 0x29 * 0x02 = 0x52, and 0x52 + 0xD1EAD8 = 0xD1EB2A The value at that address is 90 7D. All of the battle animation scripts are in the $D0 bank, which means that Regal Cutlass calls the animation script at D0/7D90. That's great and all, but this animation script is shared by a BUNCH of weapons. Either all the associated weapons need to have their frames changed to match, or we need to repoint Regal Cutlass to freespace where we can control how its animation plays out. I'll leave that decision up to you. For the purposes of this tutorial, we're just going to change that animation in-line. From the battle animation document... we can see what's going on at D0/7D90 Code: ; [ Animation Script $0016: Chocobo Brsh (sprite) ] So, see how the weapon frames are shifted up 8 between $01 and $02? We need to change that shift. We want $03 to be shifted so that the sword is drawn in the right spot. So first, we're going to increase the offset of Frame 3 so that we have some room to nudge around. D1/0585 Change from 12 07 to 02 40 (Original Discord tutorial had an image here, of a sword about 11 pixels left of Celes's foot) Okay, so we need to move this sword up and to the right. To do that, we need to change the animation script. There's an instruction to move up 8 pixels, but we want to move it up and back. 83 E0 will move our frame up/back 1 pixel, so we need to count up until we get to a value that looks appropriate. After some experimenting, I found that 83 EB works well. So we'll swap that in to the animation script at D0/7DAB, in place of the original move command. But uh oh, by changing that command, we've messed up Frame 2! (Original Discord tutorial had an image of a slash over Celes, too far to the right) Fortunately this problem is easy to fix: we'll adjust the X value of Frame 2 to match. D1/0583 Change from 12 06 to 02 06 This forces the slash and the sword in these last two frames to line up with each other, which achieves the look we were shooting for! So in total, the code changes were: Code: D0/7DAB (Chocobo Brsh animation) Weapons that share the Chocobo Brush animation: 16, 17, 1A, 1B, 1C, 20, 23, 26, 27, 29, 2A, 2B, 2C, 5A, 5B Fifteen total. 16 (Chocobo Brush), 17 (Magical Brush), 1A (Hawk Eye), 1B (???), 1C (Striker Class), 20 (Bone Club), 23 (Guardian), 26 (Air Lancet), 27 (Dirk Class), 29 (SwordBreaker), 2A (???), 2B (Rune Edge), 2C (Flame Sabre Class), 5A (ValiantKnife), 5B (Falchion) Attack graphics data for these weapons Code: D4D084 (0x16) Code: D4E05A (0x16) Code: (0x16) Chocobo Brsh RE: Frame Job - Making Weapons show after a strike - Joshua H. - 01-03-2023 Seems like changing battle animations is gonna be a little over my head for a while. Now that I'm nearing the end stage of my script project, I've been digging through FF6Tools, and I've been able to delete just a few of the event trigger tiles on the various maps to bypass some of the minor events in the game. Things like Banon's tissue event and the like. Super basic stuff, like that, has been eye-opening. Just recently, I've been playing around with the "items" section of both FF6Tools and FF3usME, and that got me fixated on battle animations. Particularly, the ones with any kind of pop-culture vibe to them...I'd like to see if I can remove them eventually. Is the Jason Vorhees mask listed as a pointer anywhere around here? I was assuming I could just clear out the color pallet for the mask. Is something like that possible? Or, would I need to go down a different rabbit hole? RE: Frame Job - Making Weapons show after a strike - C-Dude - 01-03-2023 This is more about animation than graphic display. I believe the hockey mask is part of the chainsaw graphic, which is more 3bpp graphics data. To that end, you could probably find it in FF6Tools or YYCHR and simply erase it, since you're not seeking to move it to another animation. For information on how to navigate 3bpp graphics in YYCHR, you should check out Mutteo's harp tutorial thread. It's very helpful to find the data and see how to work with it. https://www.ff6hacking.com/forums/thread-4013.html In one of the images in the middle, YYCHR is open to address 1343B0 and you can see the autocrossbow at the bottom of the shot. I bet the two chainsaws are near there. EDIT: If you go to 135C70 in YYCHR and set the display mode to 3bpp, you'll see the mask in the upper left of the window. The top of the mask is in the second tile row, it's the first two tiles there. The bottom of the mask is in the first tile row on tiles 2 and 3, it's connected to the top of the chainsaw handle so you'll need to be conscientious as you're erasing it. RE: Frame Job - Making Weapons show after a strike - Joshua H. - 01-03-2023 Nice! I’ll give it a shot sometime this weekend. RE: Frame Job - Making Weapons show after a strike - Lightning - 01-23-2023 I forgot to thank you here for this! This feature has been incorporated into my hack thanks to this tutorial. The weapon animations are so much more exciting! |