Wednesday, December 21, 2011

Update your WallMarket.dat and ProudClod.dat files.....

So while doing some digging in the executable I found something rather interesting about the AX damage formulae. Turns out they're directly related to the currently blank "Additional Effects" descriptions. Believe it or not, these formulae are using those effects to alter the damage and power of the attacks! So damage formula A0 uses effect 0A, formula A1 uses effect 0B, etc. Check it all out on the wiki.

Now for the more exciting news. I previously stated to a small number of individuals that adding behaviors based on elements would require handling each attack that used that element. If you want to add a counter for a fire elemental then you'd have to make checks if the previous attack was Fire, Fire 2, Fire 3, Ifrit, or Beta. This isn't that convenient if your weapon has a fire elemental attached to it. You can still do fire damage without causing those attacks. WELL, there happens to be a AI battle address that tells you what elements the attack uses.

2120|Attack Element(s)

You can add that line to the .dat files. Oddly enough, this appears to work just fine, but it's never used in any scripts where it would make sense to use. I know there is some enemy that actually does a check if the previous attack is Fire, Fire 2, etc to see if it was attacked by a fire elemental. Like I said before, it won't know if a fire-imbued weapon attacks it though.

That's not all either! There's another address of interesting note. The Attack Properties also get a varible!

2160|Attack Properties

That's the same as the Special Attack Flags as it's labeled in the wiki. This has the potential of determining a few things like if the attack damaged MP, HP was drained, it was a critical hit, etc. Counters can get even more complex now with all this new info. There might even be one for statuses that the attack inflicts or heals. I know there are still at least two values that aren't known that the game DOES point to. There's a 2170 and a 2180 that I don't know what they do. I'll have to look it over.

Wednesday, November 16, 2011

Additional optimism for AI script separation

I was thinking about it this morning (as I was trying to get my daughter back to sleep) that instead of actually running byte-per-byte comparisons on AI scripts that have the same lengths, I can just generate CRCs per script as they load! That way I can compare the CRCs with the lengths to determine if two scripts are identical The possibility of two different scripts with the same length and the same CRC is so close to 0 that logic states it's impossible. As a result, that will turn an "n log n" function into a "< 3n" function! With over a thousand unique scripts that's a vast improvement!

Success! Let me give you an idea of what this does now. In the following list, each listed actor is unique. The entries below the actor's name indicate that there is an AI script present in that section and the number next to that section is a unique script ID assigned as it is read in order:

Mystery Ninja
0: 127
1: 128
3: 129
15: 130

Mystery Ninja
0: 127
1: 128
3: 131
15: 130

Mystery Ninja
0: 127
1: 132
3: 133
15: 130

Mystery Ninja
0: 127
1: 132
3: 134
15: 130

Mystery Ninja
0: 127
1: 132
3: 135
15: 130

Mystery Ninja
0: 127
1: 132
3: 136
15: 130

So with those six actors and 24 active script blocks, there are only 10 unique scripts between them! The init and custom event 8 blocks are all identical and most of the main scripts are the same. The only thing that uniquely identifies them is the "death counter" which will set the level that Yuffie joins the party at. This is just the kind of thing I'm trying to solve. Instead of wasting space copying three identical scripts twice. This way we can create more intricate behaviors and counters while maintaining synchronicity between all six (or a set of six) without having to modify all six.
Slick, right? :)

Friday, November 4, 2011

AI Blocks not so static....

So this just occurred to me. The pointers to AI scripts are just pointers to a script that gets run until it hits the 73h byte, right? Well it seems to me that this is a grossly underused system. What it does right now is have pointers to the pointers per enemy per script with the actual scripts in between:

[Enemy 0's AI][Enemy 1's AI][Enemy 2's AI][Enemy 0's Sections][Enemy 0's Scripts][Enemy 1's Sections][Enemy 1's Scripts][Enemy 2's Sections][Enemy 2's Scripts]

That seems pretty wasteful. You could do it this way as it is without modification or worry that it'll blow up:

[Enemy 0's AI][Enemy 1's AI][Enemy 2's AI][Enemy 0's Sections][Enemy 1's Sections][Enemy 2's Sections][All Scripts]

What's the advantage? SHARED AI SCRIPTS!! Let's say that we want Enemy 0 and Enemy 1 to behave the same way. They have a 40% chance of not attacking every other turn or so. Why not let their main scripts point to the same script? Oh, but now you say "but their attacks will be different. Unless they're using the same attack that will be useless!" No it won't. Consider this as a script:

0x000: 12 00A0
0x003: 61 0131
0x006: 72 000F
0x009: 12 00A0
0x00C: 61 0146
0x00F: 90
0x010: 60 20
0x013: 02 00A0
0x015: 92

Starting from the beginning we're loading attack ID 0131h and executing it, but starting at 009 we're loading attack 0146h and executing it! This can pose a problem for jumps, but if you pre-load attack variables in the init scripts then you can easily share a more complicated Main between two actors!

This can also be used to share counter-attack behaviors (like running) and a few other things.

Man, I'm awesome. B)

Whoops. I forgot to finish this thought.
One thing I can think of right now that can be changed is that stupid "A Chocobo!!" init script that's shared by EVERY enemy that is in a formation with a Chocobo. They're all the same script so they could all share it and free up space for more complicated script behaviors.

As a result, I was thinking of adding another category to the list of things this handles. Adding AI as a section would be great. That requires naming each one and comparing them one-by-one. That takes time. There are some easy ways to shave off this time like comparing lengths first. There can never be more than 28,672 unique AI scripts contained in the scene.bin and they can have wildly different lengths. The ones with different lengths are obviously not a match.

Also, this would be super difficult and confusing to have to load the scene.bin each time and parse through it like this. I could have PrCMDI create it's own database save with everything already parsed out that it could load much faster than the scene.bin could. You could save as this database (which could be legally freely distributed) and just export to a scene.bin that could be used by the game.

Yep, still awesome! B)

Monday, October 17, 2011


So I realize I have no legal/moral obligations to do anything with this project. I still must confess that I feel bad for not having done much lately. Then I look at my month-old daughter and realize that nothing else matters as much. I haven't given up on this, but it might be a while before I get back to it. Just hang tight for now. When baby's not so demanding and work isn't so backlogged I'll come back to this.

As it is, I believe WM is done. I was planning on making the menu text display as text edit, but I'm clearly not up to that with my current level of skill. I'll put most of the remaining effort into making PrCMDI when I get around to it.

Friday, August 12, 2011

August already?

For those that don't know, I'm expecting a little one in a few weeks. As such I haven't had much time to do any side-project developing. I have done a bit and have a really neat looking basic PrCMDI that I want to make a YouTube vid of. I need to get some recording software and find a microphone first, but it'll be awesome! At least, I'm excited about it. It's going to have a "kinder" interface than the current PrC. Less clunky and jumbled looking.

Thursday, June 9, 2011

PrC alpha4 now

That was rather embarrassing. See if you can find the error:

int16 StatBaseAddr = 0x298;
for ( x = 0; x < 3; x++ ) { SceneFile[x * 2] = (int16)ModelIDs[x] && 0xFF; SceneFile[x * 2 + 1] = ((int16)ModelIDs[x] && 0xFF00) >> 8;
StatBaseAddr += x * 184;
Array.Copy( NewStats[x], 0, SceneFile, StatBaseAddr, 184 );

If you see it, good for you. Don't feel bad if you don't get it though. I don't think there's a C++ equiv for Array.Copy( array, int, array, int, int) so I'll just tell you that it copies a certain number of values from one array into another.
See it yet? Follow StatBaseAddr for each loop:

x = 0: StatBaseAddr = 0x298 //first enemy's data
x = 1: StatBaseAddr = 0x350 //second enemy's data
x = 2: StatBaseAddr = 0x4C0 //beginning of attack data!!

So technically, the third enemy's data was getting saved, but in the wrong place. :( I changed that StatBaseAddr += x * 184; to StatBaseAddr += 184 and moved it to below the Array.Copy line and it saves just like it should now. Problem solved. :D

Wednesday, June 8, 2011

PrC alpha3

New version with some bug-fixes.

Sunday, May 15, 2011

PrC alpha2

Made a few bug fixes mostly related to enemy stats. Item names can be imported from KERNEL.BIN/kernel2.bin now.

I'd like to update the help files of these, but I think I lost the sources for them. I don't have them on the same system I develop on so I can't look for them right now. :(

Monday, May 2, 2011

New Proud Clod!

By popular demand (a total of one request :) ) the alpha version of PrC 1.5.0 is being released. It might not be perfect, but it's been a year since the last one and I KNOW that one's not perfect.

It can now modify enemy stats! Pretty neat, huh? Formation AI still isn't cooperating and I'm going to address that around the same time as the disassembly (which isn't working at all). A few other things have changed too. See the first post in the official topic for more details.

Tuesday, March 8, 2011

Let the FF9 reversing commence

A little side-project for the moment is I'm trying to help gjoerulv figure out the CRC checks on the save games. Initial feeling is "hopeful".

I found the "Data corrupted." text. It's at 0x00112D81 in the FF9.IMG file. I'm not sure what that translates to in PSX address or how to get to that, but I'm getting closer. ;)

Let's see if it will let me save this.
That text is located in FFIX.IMG:Dir00/File39h/0x02B0. Relative Location is 0x0290 and some index of constant strings I don't remember.

Wednesday, February 16, 2011

Don't think to deeply about this

It's not completely ready yet. Click for better view.

Tuesday, February 8, 2011

Meaningful changes

As some of you might be aware due to posts on qhimm, WM is going through a pretty big change now. I'm trying to make the text work correctly and even make it more non-English language friendly. (Did you know that the exp range for a character is between 31851 and 8123024? You can't make a character need exp outside of that range to get to level 99. Just thought I'd throw that in.) As such, there are going to be two major changes and several minor ones.

First off, WallMarket.dat will be OUT and WallMarket.xml will be IN (yay!). WallMarket.xml will have all the battle info that WallMarket.dat had, but it will be structured differently and not have the character map at the beginning that wasn't really working anyway. It will have things like attack descriptions and materia types in it that if you don't like the way I wrote it, you can re-write it or translate it into a different language. This would allow for multi-language support under most conditions.

Secondly, the text boxes are going to change to look like they would in the game. So instead of seeing the name of the item in black against a white background, you can see the actual font used by FFVII against the default FFVII dialog background colors! This, of course, will mean you can import your own font faces in case you're using a different one! That will probably be in a directory and require an entry in the xml to distinguish between which one(s) to use.

Lots of minor things are going to be changed too like the weapons' menu actions not updating correctly or the materia subtypes not changing properly, etc. Exp curves will now max out at the level 99 value whatever that will be so you can get the clearest view of the growth curve. Drop-downs menus will expand to fit the name of the things that contain them. Lots of really neat stuff. :D

PrC will probably undergo SOME of these changes too (definitely the xml idea), but not many. I don't know if font changes will be worth what I'm doing to WM because of the low level of text usage in the scene.bin. I'll probably still allow for raw data manipulation, though.

Monday, January 24, 2011

A "fix" to the embarassing error

Apparently, someone got me to take a closer look at what was happening. As it turns out (I believe), the whole "text from the WallMarket.dat file" thing is screwed up. I only did that for people that wanted to use a different font type and I never got around to implementing that exactly. What I'm going to do next is create a default font face based on the game's used font and allow users to substitute their own in there. That would eliminate a LOT of processing when saving text because it will be saved as binary already and won't have to go through decoding/encoding when loading stuff. That will likely cut down on loading time immensely. Expect that to take a while in coming though. I only vaguely remember my PoC working, but I haven't done anything to WM or PrC that relates to it.

On another note, I'm happy to announce that I've finally ordered a new laptop! This will replace the four year old one whose screen barely works with a pretty snazzy one. I feel a little traitorous because it's an HP (for now anyway) and I don't really like buying computers from corporations. I don't have much choice anymore sadly. No one really "builds" laptops from the ground up. :( Here's hoping this one lives up to what I want out of it.