(Link to AcmlmWiki) Offline: thank ||bass
Register | Login
Views: 13,040,846
Main | Memberlist | Active users | Calendar | Chat | Online users
Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album
05-08-24 09:45 PM
0 users currently in ROM Hacking.
Acmlm's Board - I3 Archive - ROM Hacking - GBA Fire Emblem Spells and FE8 skills
  
User name:
Password:
Reply:
 
Options: - -
Quik-Attach:
Preview for more options

Max size 1.00 MB, types: png, gif, jpg, txt, zip, rar, tar, gz, 7z, ace, mp3, ogg, mid, ips, bz2, lzh, psd

UserPost
Zeld
Posts: 3/53
I'm currently working on a fire emblem patch myself, which I have decided will include custom battle animations. I'm going to give my character a...sniper...rifle.

Don't laugh!

Anyhow, I've found some semblance of animation data in the rom using unLZ but it's only part of it. See, at the address e8aca0 there is some data concering the Hero's animation. This data includes how long the frames are displayed and some flags for things such as the white flash generated by striking an enemy and I think there may even be some flags for sprite rotation. Frie Emblem 6 made wicked use of sprite rotation for the battle animations...anyhow, also in this data are these 16 bit values...if I switch these 16 bit values around with each other, I can manage to reorder the frames of animation of the Hero's attack. But I don't want to reorder the frames, I want to edit which tiles are used in the frames and where they appear on the screen in relation to each other.

I found this particular animation data by searching through the rom with unLZ and finding the graphical sheet for the Hero. I noted that the address was at e83e58, and searched for that value in a hex editor, thinking that it would be pointed to. Well, it is, but the data that points to it is compressed. Luckily, I found the pointer anyway, because the first time that value appears in the compressed data would have to be uncompressed so that the rest of the compressed data can associate with that value...I read a little bit about sliding window compression, but I'm no expert, so if I sound dumb...it's because I am.

Anyhow, I found the pointer and used unLZ to decompress the data at the address closest to that point. Later on, I went into battle and viewed the WRAM and saw that all of the data I had found was right there. Now that I was able to screw with data while it was in the WRAM, I didn't have to worry about screwing my rom or losing data from compressing uncommon bytes. I know that sounds retarded, because last I checked LZ77 was supposed to be lossless. Maybe it was just my inability to recognize 8 bit and 16 bit values for stuff that made the game freeze so much. Yes, when I was fooling around with the data I would change single bytes at a time to witness the results, without thinking that the byte I was changing was part of a 2 byte value, and that I needed to change two bytes to a value used elsewhere in the data in order for it to not freeze the game.

So, I've come awful close to making custom animations, but not quite. I can't think of how to find tile and X, Y position data for those tiles and I'd like some help, and since Zephyr and IOS are also looking for help in working with animation, I thought it would be a good idea for us to help each other.

That said, I think I've seen some spell sheets in the rom data, but they're all off by themselves away from everything else.

The issue you two are having reminds me of my issue; in my patch for FE 7 I debated with my friend who should get to use the Ereshkigal animation. I decided to let him have it and gave myself gespenst since I already ahd flametongue. I plan on rewriting the sheet for flametongue and turning the fireballs into sniper shells, then rewriting the data that compiles that sheet into the animation the dragon pwns you with into something more rifle-like. I took the liberty of converting those two spells into sword type weapons.

I didn't like having to surrender the most awesome dark spell animation to my friend, and I wanted to find a way to share it with him. This can't be done unless we hack the spell animations that the weapons use or if I decided to unPrf the weapon from my friend. Unfortunately, I'm too tied to the idea of my friend and I having our amazing weapons Prf'd to us alone - they're our unique weapons and no other class can use them. I want to keep it that way, so hacking the animation is probably for the best.
IOS
Posts: 11/33
labmaster, I think I may of found the animation data, and the brave weapon data. But how would I make this into a new item/skill? Thank you
ZephyrShakuraus
Posts: 9/9
*is late*

Yeah, something like that would be great.

I can understand you being busy with school though. I'm in the same boat. Any time you could look at it would help us. We really only need a push in the right direction.

If you need any more info about what we want/what you need to know, we'll do our best to help you out.
IOS
Posts: 2/33
That would be great for me and Zephyr, because were trying to come up with patches that really stand out compared to the others...
labmaster
Posts: 48/51
I'm back at school now so am a bit pressed for time, but if I get a chance this weekend I'll take a look at it.
IOS
Posts: 1/33
Phew, I'm trying to make sense of all this. Do you think you could run through how to implement a Brave Weapon type skill, so I get the hang of how to do it for other skills please? Thanks.
ZephyrShakuraus
Posts: 8/9
They're not the same as class abilities and no-one knows where they are. I guess it looks like a time-comsuming process moreso than a difficult one.
labmaster
Posts: 47/51
Sorry for the delay.

Do these skills work in the same way as class abilities, or is there some other mechanism (or does no-one know?)

Assuming that the 'class has certain skill' property is contained within the class data, once you know where it is it's just a simple case of breakpointing as per the tutorial above. If you don't know where it is, then you can either randomly or systematically corrupt parts of the class data until you find it. Alternatively, you can do an assembly trace from an effect of the skill itself and work backwards.

The other possibility is that when you reach a point in the game when the skill can be triggered, the game would check the class of your character and see if it's in a list (held elsewhere) of classes that have a certain skill. If this is the case, then you could modify the list so that it includes the one's you want, which would be pretty straightforward (though if you wanted to expand the list you'd likely have to relocate it which would take a bit more work).
ZephyrShakuraus
Posts: 7/9
Okay, so how would I go about trying to find the newer skills, such as the Wyvern Knight's Pierce skill or the Rogue's Pick? (Pick is non-battle and Pierce is in battle.) As well, The General's Great Shield, Sniper's Sure Shot and Bishop's Slayer are also of great interest.
labmaster
Posts: 46/51
Quite tricky, but by no means impossible.

I've taken a look at the nightmare modules that SpyroDi made, which confirms my suspicion that the class abilities are boolean flags. So, you're only going to be able to create a new skill (easily) if there is a bit that is not used (if you know that there are exactly 32 skills, then unfortunately this means that every bit has a purpose). If all of the bits are used, then you're either going to have to overwrite a skill, or do a bit of assembly work to hook a relevant part of the executable and get it to execute some handcrafted code that checks in some other location (at the end of the ROM) for data you've inserted.

The actual implementation of the skill shouldn't be too hard. It is going to involve creating a new assembly routine, which means you really do need to understand the THUMB instruction set (especially how bx's, bl's, push's and pop's need to be used). You'll also need to know how the game handles brave weapon's (i.e. where it checks if you've got one), and how to programatically access the RNG (which shouldn't be too hard).
ZephyrShakuraus
Posts: 6/9
Okay, so I haven't completed figured this out, but a friend of mine has and we've managed to change the critical bonus. Him and I will be working on the remained of the skills using this method.

Now, would there be any way to create a new skill by using some of the "padding" in the ROM? Say I wanted to make a "Class Ability 4" that would allow to give the class a % chance (The game tends to use levels for chances, I would like to learn how to use other stats as well, however) to act as if it was using a Brave Weapon. (As in it would attack twice in a row.)

If you need more data to be able to figure this out, I'm sure I could pull together anything you need.
labmaster
Posts: 45/51
If by 'other battle skills' you mean (excuse my ignorance of the game) 'other attributes for which there exists an on/off switch, but not quantitative data', then yes, you can use a similar technique. You'd just need to put the breakpoint on the address with the bit that controls that attribute, and make sure that when the game breaks, it checks the correct bit.
Zeronova
Posts: 3/3
Ah...Would this also apply to other battle skills as well?
labmaster
Posts: 44/51
Hot off my text editor:




Okay, this should be pretty simple. I'll run you through the steps for this one which should hopefully give you some idea as to what's what. I'm using the trashman dump of Sacred Stones to do this.

From the information you gave me, the flag for the Swordmaster is at 0880781c in the ROM. The game must read this value, check if a particular bit is set (the fact that the value is 0x40 leads me to believe that the game won't check if the value equals 0x40, but rather if the '4' bit is set or not). If it's set, then it'll add the bonus on.

So what we need to do, is find the assembly instructions that read from this address - it should then do a comparison of some sorts, to check if the bit is set, and if so, it'll add the bonus on.

I'll be using VBA-H as my debugger since you may not want to shell out $15 for no$gba (though it's entirely worth it, IMO).

Download the package from the link above. VBA-SDL-H is a command-line program, to open a ROM you'll need to either invoke the program from the commandline with the ROM as an argument, set up a batch file to do this for you, or simply drag the ROM onto the executable in windows explorer. This should load the ROM and start the app.

I have it set up so that it shares the same save directory as my win32 version of VBA - should be a setting somewhere in vba.ini

Now, load up a savegame where you've got a swordmaster character, and get into a battle if you aren't in one already.

Note: I wrote this out as I was hacking - turns out it wasn't such a flash idea. If you want to avoid wasting a lot of time, don't enter the breakpoint as detailed below until you've got into battle, selected a Swordmaster, and are just about to hit the 'A' button to select 'Attack' from the command menu.



Debugging in VBA-SDL-H is done from the command line. To access the debugging prompt, press F11 in game. This pauses the game and puts you at the command line. From here you can enter a8 multitude of debugging comands - enter '?' to see what there is. For now, type in:

bpr 0880781c 1

and press enter. This sets a memory read breakpoint on the ROM address 0880781c of length=1 (the address we're interested in).

Then type in

c

and press enter. This resumes the game. The breakpoint that we have set tells the emulator to pause the game when the processor reads from that address.

Back in the game, select your Swordmaster. The game will stop, and you'll see something like this in the debugging console:


Breakpoint (on read) address 0880781c word:00020140
R00=00000000 R04=0202be94 R08=00000000 R12=00000001
R01=00020140 R05=0202bcb0 R09=00000000 R13=03007db0
R02=00000000 R06=02025018 R10=00000000 R14=0801ca3d
R03=00000016 R07=00000000 R11=00000000 R15=0801d57a
CPSR=6000003f (.ZC...T Mode: 1f)
0801d578 4308 orr r0, r1


This tells us the game has read from the address 0880781c. Now, the thing is, this may not necessarily be the read that we're interested in. There is likely more than one reason that the game would want to read from this address (especially given that the game has read a word, i.e. 32-bytes, and not just the single byte that we're interested in).

To see if this is the right break, type in 'n' at the console. This advances the execution of the game by one instruction.

Repeat a couple of times and you'll see


R00=00020140 R04=0202be94 R08=00000000 R12=00000001
R01=00020140 R05=0202bcb0 R09=00000000 R13=03007db0
R02=00000000 R06=02025018 R10=00000000 R14=0801ca3d
R03=00000016 R07=00000000 R11=00000000 R15=0801d57c
CPSR=6000003f (..C...T Mode: 1f)
0801d57a 2180 mov r1, #0x80
debugger> n
R00=00020140 R04=0202be94 R08=00000000 R12=00000001
R01=00000080 R05=0202bcb0 R09=00000000 R13=03007db0
R02=00000000 R06=02025018 R10=00000000 R14=0801ca3d
R03=00000016 R07=00000000 R11=00000000 R15=0801d57e
CPSR=6000003f (..C...T Mode: 1f)
0801d57c 0349 lsl r1, r1, #0x0d
debugger> n
R00=00020140 R04=0202be94 R08=00000000 R12=00000001
R01=00100000 R05=0202bcb0 R09=00000000 R13=03007db0
R02=00000000 R06=02025018 R10=00000000 R14=0801ca3d
R03=00000016 R07=00000000 R11=00000000 R15=0801d580
CPSR=6000003f (......T Mode: 1f)
0801d57e 4008 and r0, r1
debugger> n
R00=00000000 R04=0202be94 R08=00000000 R12=00000001
R01=00100000 R05=0202bcb0 R09=00000000 R13=03007db0
R02=00000000 R06=02025018 R10=00000000 R14=0801ca3d
R03=00000016 R07=00000000 R11=00000000 R15=0801d582
CPSR=6000003f (.Z....T Mode: 1f)
0801d580 2800 cmp r0, #0x0
debugger>


I won't go into too much detail as to what this all means - once you've had some experience with THUMB opcodes, it'll make sense, but for now, take it from me that this isn't the break that we're interested in. So, type in 'c' to resume the game.

The game breaks again. If you repeat the process from above, you'll see:


Breakpoint (on read) address 0880781c word:00020140
R00=00020140 R04=020256d8 R08=00000000 R12=03003080
R01=080786c9 R05=085879d8 R09=00000000 R13=03007d7c
R02=00000014 R06=02025018 R10=00000000 R14=080786c9
R03=089a2c48 R07=00000000 R11=00000000 R15=080786cc
CPSR=0000003f (......T Mode: 1f)
080786ca 2101 mov r1, #0x1
debugger> n
R00=00020140 R04=020256d8 R08=00000000 R12=03003080
R01=00000001 R05=085879d8 R09=00000000 R13=03007d7c
R02=00000014 R06=02025018 R10=00000000 R14=080786c9
R03=089a2c48 R07=00000000 R11=00000000 R15=080786ce
CPSR=0000003f (......T Mode: 1f)
080786cc 4008 and r0, r1
debugger> n
R00=00000000 R04=020256d8 R08=00000000 R12=03003080
R01=00000001 R05=085879d8 R09=00000000 R13=03007d7c
R02=00000014 R06=02025018 R10=00000000 R14=080786c9
R03=089a2c48 R07=00000000 R11=00000000 R15=080786d0
CPSR=0000003f (.Z....T Mode: 1f)
080786ce 2800 cmp r0, #0x0
debugger>


Again, this isn't the one we're interested in easier. This code masks off the lower bit of the word, which isn't the one we're concerned with. Type in 'c' to continue.


Breakpoint (on read) address 0880781c word:00020140
R00=00000000 R04=00000003 R08=00000000 R12=030049a0
R01=00020140 R05=00000000 R09=0202be94 R13=03007d78
R02=00000000 R06=ffffffff R10=ffffffff R14=0801ae27
R03=00000000 R07=ffffffff R11=00000000 R15=0801b384
CPSR=a000003f (N.C...T Mode: 1f)
0801b382 4308 orr r0, r1
debugger> n
R00=00020140 R04=00000003 R08=00000000 R12=030049a0
R01=00020140 R05=00000000 R09=0202be94 R13=03007d78
R02=00000000 R06=ffffffff R10=ffffffff R14=0801ae27
R03=00000000 R07=ffffffff R11=00000000 R15=0801b386
CPSR=a000003f (..C...T Mode: 1f)
0801b384 2180 mov r1, #0x80
debugger> n
R00=00020140 R04=00000003 R08=00000000 R12=030049a0
R01=00000080 R05=00000000 R09=0202be94 R13=03007d78
R02=00000000 R06=ffffffff R10=ffffffff R14=0801ae27
R03=00000000 R07=ffffffff R11=00000000 R15=0801b388
CPSR=a000003f (..C...T Mode: 1f)
0801b386 4008 and r0, r1
debugger> n
R00=00000000 R04=00000003 R08=00000000 R12=030049a0
R01=00000080 R05=00000000 R09=0202be94 R13=03007d78
R02=00000000 R06=ffffffff R10=ffffffff R14=0801ae27
R03=00000000 R07=ffffffff R11=00000000 R15=0801b38a
CPSR=a000003f (.ZC...T Mode: 1f)
0801b388 2800 cmp r0, #0x0
debugger>


Again, not the right one (assembly hacking takes a fair bit of patience).

Type in 'c' again. You'll notice that it continues to break at 0801d578, which we've already decided isn't the right one. We can use a nifty command to tell the emulator to ignore breaks at this address:

db 0801d578

Continue the game, and the emulator will no longer break at this address.

Now you should be able to move your character up to an enemy and attack. The game will break when you try to move your character to a square (at 0801a880), but again, this isn't the right one. It breaks a couple of times at this address so slap a db onto it as well.

Next it breaks at 08078d7e, again, not the right one. db it as well. There's a couple more as well, which you can ignore.

If you paid attention to the note up top, skip to here after reading the above. If you do this, the first break you get will be the correct one.



Finally, it allows you to select 'attack', and we get the breakpoint that we're looking for:


Breakpoint (on read) address 0880781c word:00020140
R00=00000000 R04=0203a4ec R08=0000000b R12=0203a56c
R01=00020140 R05=0203a56c R09=00000000 R13=03007d04
R02=0000000e R06=000000ff R10=00000000 R14=0802ac25
R03=0203a552 R07=0202be94 R11=00000000 R15=0802ac40
CPSR=0000003f (......T Mode: 1f)
0802ac3e 4308 orr r0, r1
debugger> n
R00=00020140 R04=0203a4ec R08=0000000b R12=0203a56c
R01=00020140 R05=0203a56c R09=00000000 R13=03007d04
R02=0000000e R06=000000ff R10=00000000 R14=0802ac25
R03=0203a552 R07=0202be94 R11=00000000 R15=0802ac42
CPSR=0000003f (......T Mode: 1f)
0802ac40 2140 mov r1, #0x40
debugger> n
R00=00020140 R04=0203a4ec R08=0000000b R12=0203a56c
R01=00000040 R05=0203a56c R09=00000000 R13=03007d04
R02=0000000e R06=000000ff R10=00000000 R14=0802ac25
R03=0203a552 R07=0202be94 R11=00000000 R15=0802ac44
CPSR=0000003f (......T Mode: 1f)
0802ac42 4008 and r0, r1
debugger> n
R00=00000040 R04=0203a4ec R08=0000000b R12=0203a56c
R01=00000040 R05=0203a56c R09=00000000 R13=03007d04
R02=0000000e R06=000000ff R10=00000000 R14=0802ac25
R03=0203a552 R07=0202be94 R11=00000000 R15=0802ac46
CPSR=0000003f (......T Mode: 1f)
0802ac44 2800 cmp r0, #0x0
debugger> n
R00=00000040 R04=0203a4ec R08=0000000b R12=0203a56c
R01=00000040 R05=0203a56c R09=00000000 R13=03007d04
R02=0000000e R06=000000ff R10=00000000 R14=0802ac25
R03=0203a552 R07=0202be94 R11=00000000 R15=0802ac48
CPSR=0000003f (..C...T Mode: 1f)
0802ac46 d002 beq $0802ac4e
debugger>


the mov and and instructions 'mask' off the bit that we're interested in. If that bit is set, when we get to 0802ac44, r0 will equal 0x40, or else it will be 0. The game then uses 'cmp' to check if it's zero. If so, it jumps ahead to 0802ac4e.


I prefer using the disassembly view in normal VBA, so open it up with the ROM, and go to Tools->Disassembly, and go to 0802ac3e.

You'll see:


0802ac3e 4308 orr r0, r1
0802ac40 2140 mov r1, #0x40
0802ac42 4008 and r0, r1
0802ac44 2800 cmp r0, #0x0
0802ac46 d002 beq $0802ac4e
0802ac48 1c10 add r0, r2, #0x0
0802ac4a 300f add r0, #0xf
0802ac4c 8018 strh r0, [r3, #0x0]
0802ac4e bc10 pop {r4}
0802ac50 bc01 pop {r0}
0802ac52 4700 bx r0


The 'beq' instruction is a 'branch-if-equal'. If r0 equals 0, then it will branch to 0802ac4e, skipping the 3 instructions. These 3 instructions are


0802ac48 1c10 add r0, r2, #0x0
0802ac4a 300f add r0, #0xf
0802ac4c 8018 strh r0, [r3, #0x0]


If you've brushed up on your hexadecimal, you'll see that the second instruction adds 15 onto the value at r0. Sounds familiar? The first instruction must copy the critical bonus amount from register 2 to register 0, and the 3rd instruction stores this value to an address in RAM. We can modify the opcode to make it add any value that we want. This is where the GBATEK document comes in handy - knowing what hexadecimal values represents what opcode. The 'add' instruction is pretty easy, the basic format is:

3rxx

where r is the register, and xx is the value. In this case, changing the xx will change the amount that's added.

So that's about it - changing the byte at 0802ac4a changes the bonus. One more thing that might be of interest - if we were to delete the instruction at 0802ac46, everyone would get a bonus, regardless of class. We can do this by replacing the beq instruction with a nop ("no operation"), so that the game never skips the code and everyone gets a bonus. A nop instruction is represented by 46c0, but remember that because the GBA is a little-endian system, if you're editing the ROM in a hex editor in bytes, then you enter 'c046' (the bytes are reversed).

If you have any problems getting any of the above working, let me know.

edit: fixed some typos
ZephyrShakuraus
Posts: 5/9
Oh, okay. Well certain classes in the game, namely Swordmaster and Berserkers have a bonus of critical chance. In FE6, it's 30 and 15 in the other two FE games. In the class data, the thing that controls if they have it is in Class Ability 1. It's 40. You should be able to find it with 01 40 01 02 00 (being Resistance promotion gain, critical bonus in class ability 1, promoted unit, in the class ability 2 slot, and shamshir usable in the 3rd class ability slot. the last one is class ability 4, which is empty.)

However, this only determines if the unit gains the critical bonus. I want to edit the critcal bonus myself.
Zeronova
Posts: 2/3
A critical bonus increases one's chance of inflicting extra damage to the enemy units. In general, scoring a critical's a good thing.
labmaster
Posts: 43/51
I meant, more of what the purpose of a critical bonus is and what it actually does (I played a bit of 7 but wasn't paying that much attention to what was going on).
Zeronova
Posts: 1/3
Originally posted by labmaster
Ok... I haven't actually played the game (I've done some work on its text compression and that's about it) so you're going to have to fill me in on the background.


There's a class in the game called 'Swordmaster' that receives a critical boost of 15 upon promotion.

Dunno if that helps, but it's a start.
ZephyrShakuraus
Posts: 4/9
Heh heh...

To be honest, I only started this stuff yesterday. (I meant it, when I said new)

So I don't know enough to even give you any sort of background, aside from the fact I think it would be little different from Fire Emblem 6 and 7 in terms of how it's stored. I'm not sure however.
labmaster
Posts: 42/51
Ok... I haven't actually played the game (I've done some work on its text compression and that's about it) so you're going to have to fill me in on the background.
This is a long thread. Click here to view it.
Acmlm's Board - I3 Archive - ROM Hacking - GBA Fire Emblem Spells and FE8 skills


ABII

Acmlmboard 1.92.999, 9/17/2006
©2000-2006 Acmlm, Emuz, Blades, Xkeeper

Page rendered in 0.004 seconds; used 396.63 kB (max 470.61 kB)