Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Zande

Pages: [1] 2 3
1
Nope, FFT doesn't becuase the sound wasn't programmed by Minoru Akao, but by Hidenori Suzuki.

2
Scripting and Reverse Engineering / Re: PSX Dissambler
« on: 2012-09-18 11:06:17 »
The emulator pSX have a builtin r3000 disassembler that works pretty good.

3
I never spent too much time with the enemy data, but the actual enemy chunk looks something like this:

Code: [Select]
0x0010: word    HP
0x0012: word    MP
0x0014: word    Gil
0x0016: word    Experience
0x0018: byte    Drop Item (Slot 1)
0x0019: byte    Drop Item (Slot 2)
0x001A: byte    Drop Item (Slot 3)
0x001B: byte    Drop Item (Slot 4)
0x001C: byte    Steal Item (Slot 1)
0x001D: byte    Steal Item (Slot 2)
0x001E: byte    Steal Item (Slot 3)
0x001F: byte    Steal Item (Slot 4)

0x0022: word    Model ID
0x0024: word    Animation ID 1
0x0026: word    Animation ID 2
0x0028: word    Animation ID 3
0x002A: word    Animation ID 4
0x002C: word    Animation ID 5
0x002E: word    Animation ID 6

0x0036: word    Attack Power
0x0038: byte    Speed
0x0039: byte    Strength
0x003A: byte    Magic
0x003B: byte    Spirit

0x0040: byte    Elemental Guard
0x0041: byte    Elemental Absorb
0x0042: byte    Elemental Half
0x0043: byte    Elemental Weakness
0x0044: byte    Level
0x0045: byte    Class

0x0047: byte    Physical Defence
0x0048: byte    Physical Evade
0x0049: byte    Magical Defence
0x004A: byte    Magical Evade
0x004B: byte    Blue Magic (0x4D-0x64, or 0x00 for none)

Elemental Flags:
Bit 1 = Fire
Bit 2 = Ice
Bit 3 = Thunder
Bit 4 = Earth
Bit 5 = Water
Bit 6 = Wind
Bit 7 = Holy
Bit 8 = Shadow

Class Flags:
Bit 1 = Humanoid
Bit 2 = Beast
Bit 3 = Demon
Bit 4 = Dragon
Bit 5 = Undead
Bit 6 = Stone
Bit 7 = Insect
Bit 8 = Aerial

4
I found some basic data for items, not really what you were looking for but you may be interested in it anyway... This block contains 18 bytes for each item, and this data is for all 256 items, for a total of 4608 bytes.
The data layout is something like this:
Code: [Select]
word Name Pointer
word Description Pointer
byte ?
byte ?
byte ?
byte ?
byte Icon ID (0-35 only)
byte Icon Palette ID (0-15 only)
byte ?
byte Base Stat Increase Flags?
byte Ability 1 (0 = None)
byte Ability 2 (0 = None)
byte Ability 3 (0 = None)
byte Flags {
  Bit 1 = Useable
  Bit 4 = Equipable (Add-on)
  Bit 5 = Equipable (Armour)
  Bit 6 = Equipable (Head gear)
  Bit 7 = Equipable (Arm gear)
  Bit 8 = Equipable (Weapon)
}
byte ?
byte ?

The first two items have this data:
Code: [Select]
00 00 00 00 FA 00 08 00 00 00 01 00 00 00 00 80 15 00
05 00 0F 00 40 01 00 08 01 00 01 00 65 00 00 80 16 00

The physical defence/evade and magical defence/evade for equpiment I know pretty much where it's stored but I have to look at it abit more... Atleast it's stored using 4 bytes for each item: physical defence, physical evade, magical defence, magical evade. You may be able to find where it's stored anyway if you know these four values for an item...

The elemental flags for equipment is abit tricky, it may be stored near the defence/evade data, but it's only ever used when in combat I think. It doesn't seems to be stored in the character data nor can you somewhere see if your characters absorbs or nullifies certain elements (except for the static description for items, but is just a text anyway), kinda stange.

5
Here's next piece of junk/chunk... At 0x5CDCC starts a block of 768 bytes which holds all the AP needed for all action & support abilities. Each ability uses 2 bytes, the second byte is the number of AP needed to master/learn, the first one I think is ID for the ability. Every class (I rather call it, as opposed to character) have 48 abilities each and there are 8 classes stored in this order: Theif, Black Mage, Summoner/White Mage, Knight, Dragon Knight, Blue Mage, White Mage/Summoner, Monk/Ninja.
The 16 first byte of this block (and the data for Zidane's first 8 abilities), looks like this:

Code: [Select]
65 28 66 28 67 28 68 23 69 32 6A 37 6B 55 6C 64

Edit: This block of data may actually be larger, and include temporary/guest character classes, I don't know yet but the other is still correct.

Another Edit: So I tried to use the code form the ability screen to get the MP cost for abilities, and allthough I found them, the MP cost display under the ability screen are stored locally within the ability/equip module, and the MP cost actually used in battle is most likely read from somewhere else... -_-
But I think I've pretty much managed to track down where the battle data is stored aswell...




Ok, so the data for abilities when they are used in battle are read from file 22 in directory 1, @0xBB2B. Each ability uses 16 bytes and there's 192 abilities listed, for a total of 3072 bytes. An identical copy of this data is also stored in the ability/equip module ( 8 ) in directory 0.
The things I found so far:
Code: [Select]
; Target (Bits ???)

; Sub-Dialog (Bits 6-8)
; 0 = None
; 1 = HP MAX
; 2 = MP MAX
; 3 = Status Bad
; 4 = Status Good
; 5 = (illegal)
; 6 = (illegal)
; 7 = (illegal)
0x0000: byte    Target/Sub-Dialog

0x0004: byte    Command ID
0x0005: byte    Coefficient

0x000A: byte    MP Cost

0x000C: word    Animation Pointer
0x000E: word    String Pointer

The data for the first two abilities looks like this:

Code: [Select]
Ability 0 (Void) 00 00 00 00 00 00 00 00 00 00 00 00 0A 00 00 00
Ability 1 (Cure) 33 09 00 20 0A 10 00 00 47 00 06 01 08 00 03 00

6
In the japanese execute (SLPS_020.00) there's a collection of data for all weapons stored from address 0x5E38C. There's 12 bytes for each weapon, and the 6th byte is the attack power value (I don't know what the other values are for, I tried messing around with them alittle, but I didn't notice any changes yet, oh well). The pointer is most likely not the same for the US version (but probably close) and I don't have a copy of so I can't check, but I'll provide the value for the first weapons, should be able to find it by searching for the values...

Code: [Select]
weapon 0 (Cinna's Hammer) = 01 00 25 00 05 0C 00 00 00 00 00 00
weapon 1 (Dagger)         = 05 00 DC 01 01 0C 00 00 11 00 C8 00

7
Beats me, though I think ability names are also stored in the SLUS file?
It's abit strange like that, the prices for items are stored in the execute aswell, but the synthesis data and shop inventories are stored in the shop module.

8
Where would you think spell power or similar data is stored?  SLUS file or in multiple modules?
For PC's, in the SLUS file I would assume, yes. For enemies it's stored within the enemy formation data (directory 5 I think it is).

9
I'll give you some general hints;
FF9 splits the user memory into four main parts: two parts for the main execute (SLPS_020.00/SLES-02965 or whatever version/disc), one part that acts like a code segment and one that acts as a data segment, these two parts are always avalible. The other two parts may be switched at any time, the first part is larger and acts as engines or whatnot, the last part is a smaller and may be seen as sub to the engines (though they are independant) and they are all (but one) menu based.
The enigne and submodule parts are what's stored in Directory 0, and this is what they contain:
Code: [Select]
Engines:
 0 = Dummy
 1 = Field
 2 = Battle
 3 = Worldmap
 4 = Tetra Master
 5 = Title
 6 = Blackjack

Submodules/Menusystem:
 7 = Chocobo Hot & Cold
 8 = Equip & Abilities
 9 = Config
10 = Card
11 = Item
12 = Status
13 = Save & Load
14 = Name Input
15 = Party Select
16 = Shop
17 = Dummy
18 = Disc Change
19 = *Movie Module
20 = Victory

Now to go back to the original question. Things like attack power values for all weapons are used by several engine/modules (like battle, shop, equip etc.) so therefore they are usually stored in the main execute so it's always avalible. Though this isn't always the case, the data in FF9 is abit of a mess and sometimes stored in strange ways. Like the enemy data, it's not stored per enemy, but per formation (so changing the values for one enemy doesn't change all occurences of that enemy, only within that particular encounter formation). Also there are other things, like images and strings, that are duplicated several times, like the small character portraits are stored in several submodules (like in the save/load, name input, shop modules).
I'm not sure if I have a pointer for the attack power values in the execute, but even if do have it'd be from the japanese version and different from what version you use probably...


10
WIP / Re: Halkun's new Project... Introducing N-gears
« on: 2011-08-04 13:25:21 »
Hmm, well I used to have wiki access, at least for the FF9 section. :)


Abit of expansion of your savemap info:

$602E-$6030: Gil

$603B: Number of characters in party

$603C-$6042: Character indices/slots
$6043-$6049: Levels
$604A-$6050: Low byte of current HP
$6051-$6057: High byte of current HP
$6058-$605E: Equipped headgear
$605F-$6065: Equipped armour
$6066-$606C: Equipped bracers
$606D-$6073: Equipped accessory
$6074-$607A: Equipped weapon
$607B-$6081: Equipped materia

$60C1-$60C7: Low byte of max HP
$60C8-$60CE: High byte of max HP

All the data from levels to max HP are stored in an array of seven bytes, one by for each character (so for level, $6043 for Cloud, $6044 for Barret etc..).

Also, in bank 0 @$D4F8 ($54F8 in the ROM), there's 56 bytes which contains the initial stats of all seven characters (with 8 bytes each), it's stored like this:

byte Level
byte Headgear
byte Armour
byte Bracers
byte Accessory
byte Weapon
byte Materia
byte Materia Level

11
WIP / Re: Halkun's new Project... Introducing N-gears
« on: 2011-08-04 07:48:13 »
Did you see what it does to the stack? :P
Nopes, don't think I have yet, what's it do?

Have you compiled together any document with known data inside the rom?

12
WIP / Re: Halkun's new Project... Introducing N-gears
« on: 2011-08-04 01:08:27 »
Yepp, it seems to copy 256 bytes into $400 for the bank switching though, but the actual code for the swap is only 19 bytes, ah well. :D

13
WIP / Re: Halkun's new Project... Introducing N-gears
« on: 2011-08-03 21:16:46 »
Right, so if I've understood the bank system right it works something like this...

There's only one program bank with a size 32k, using the range $8000-$FFFF. The bank is switched with a 12 bit value made up from the values written to $5000 and $5200. The low nibble of the $5000 value is used for the low nibble (bit 0-3) of the bank value, and the whole byte of $5200 is used for bits 4-11 of the bank selection value.
With a 12 bit value for the bank selection, the maximum amount of banks this mapper can handle is 4096 (for max memory of 128 MB)? Oo

Since the entire program bank is swapped at once, the bank swapping code is written to the system ram @$0400, and then executed from there instead (in abit fo a stange way... Oo). Each bank have atleast one bank swap code, in the very end of the bank.
(Can I post/link to dissed code?)

What's $5300 used for? I don't know, but the only value written by the game seems to be $04.


I have to dive thru that thread on romhacking.net...

14
WIP / Re: Halkun's new Project... Introducing N-gears
« on: 2011-08-02 13:29:45 »
Can't you use the source code of an emulator as a documentation for the mapper? Provided it supports it, everything should be in there, aye? Maybe not the most convenient way but still...
If you want some help with the disasm and analyzing I could assist you abit, it's always fun to waste some time with.

15
Yes that's correct, so OR'ing (or adding I guess) them together to set more conditions, like 127 would result in all seven conditions been set.


Also just for the record, at offset 0x3E of each character slot there's four 16 bit values which holds a bonus stats pool that are used in the algorithm for calculating character's stats. I haven't looked very carefully how the pools works, but at least they acculumate any +stats from gear every time a character levels up. They are stored like this:

0x003E: Speed Pool
0x0040: Strength Pool
0x0042: Magic Pool
0x0044: Spirit Pool

16
The status bit stores the state of the seven negative status effects that doesn't disappear after a battle. The first bit is Petrification, second is Venom, third Virus, fourth Silence, fifth Darkness, sixth Trouble, seventh Zombie. I don't know whenever the last bit is used for something, but I don't think so.

17
That's some great stuff there... haha ;D

Seems to be some problems with his site though, creativecpp.com...

Bandwidth
Exceeded

Website Temporarily Unavailable!

awww, but I wants to read!

18
Quote
* yoshi314 crosses fingers, hoping to see Dead or Alive: hot swedish blondes edition.
I don't think so, it's most likely to expensive to make a new, seperate release for scandinavia.
If you feel lucky then you may purchase it from Webhallen though, as they sell imported copies despite Bergsala cancelling the release... could lead to problems? I don't know... Oo

19
Quote
On topic, yes I am aware that this law and certain others are overreactions and a bit silly.
Total moral panic.. if you like that and very selfish and impolite people, then you'll love Sweden!

Change their displayed age to 18 and release it? Easy... They don't even look that young. Oo

20
Ok so I'm going to resurrect this topic abit, don't know whenever you're working on this anymore, but for anyone interested...

So out of boredom I started to dig alittle thru FF9 again yesterday, and I started to look for a checksum rutine in the load/save module, and it didn't take too long to discover what I wanted (though I did have some luck aswell :P). The checksum used for the savegames is a standard CRC-16-CCITT algorithm (x16 + x12 + x5 + 1), and besides the CRC calulation rutine there's also a initation rutine for the lookup table which uses the polynomial 0x8404 for the generation. I wrote two C++ equivalents for the generation and calculation so I could try it with a save file. The calculation is done using all bytes from the beginning of a saveslot and up to (but ofcourse excluding) the checksum value, that's 5118 (0x13FE) bytes for the calculation. I would assume that the game data also use the same CRC, but I haven't tried that so I can't confirm that's the case.

Here's the C++ code I wrote for the checksum, I also included a complete lookup table (which do make the initiation function totally pointless, but still Oo), have fun.

Code: [Select]
unsigned short LookupTable[256] = {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};

void InitiateCRC(void) {
    for(unsigned short Index = 0; Index < 256; Index++) {
        unsigned short Value = Index;

        for(unsigned short Bit = 0; Bit < 8; Bit++) {
            if(Value & 0x0001) {
                Value >>= 1;
                Value ^= 0x8408;
            } else {
                Value >>= 1;
            }

            LookupTable[Index] = Value;
        }
    }
}

unsigned short CalculateCRC(unsigned char *Pointer, unsigned short Size = 0x13FE) {
    unsigned short Checksum = 0xFFFF;

    while(Size--)
        Checksum = (Checksum >> 8) ^ LookupTable[(Checksum ^ *Pointer++) & 0xFF];

   return Checksum;
}


21
Question 3: How do the NTSC codes look like, and are there other versions (Spanish, German, etc)?

It would be great if there only were 2 versions of this: NTSC and PAL.  :-D
There's seven different versions of the game, here's the disc ID's for them all:

Code: [Select]
Japanese      SLPS_020.00, SLPS_020.01, SLPS_020.02, SLPS_020.03
English (USA) SLUS_012.51, SLUS_012.95, SLUS_012.96, SLUS_012.97
English (EU)  SLES_029.65, SLES_129.65, SLES_229.65, SLES_329.65
French        SLES_029.66, SLES_129.66, SLES_229.66, SLES_329.66
German        SLES_029.67, SLES_129.67, SLES_229.67, SLES_329.67
Italian       SLES_029.68, SLES_129.68, SLES_229.68, SLES_329.68
Spanish       SLES_029.69, SLES_129.69, SLES_229.69, SLES_329.69

For the savefiles, the first 2 characters (region code?) in the ID is BE for all european discs (eg. BESLES-02965), BA for the USA ones (eg. BASLUS-01251), and BI for the japanese ones (eg. BISLPS-02000). And they all use the same save file format structure (but the japanese version uses a different character table for strings of course), which is probably also the reason サラマンダー wasn't called Salamander (but Amarant) outside of Japan as it doesn't fit the 8 byte character name limit.

22
Could be interested of that. I've been digging thru quite abit of code of some of the WSC remade Square games. Alltho it's mostly 魔界塔士サガ (Makaitoushi Saga, Final Fantasy Legend, what have you), of which I've got almost all data down and a couple of megs worth of code, there's parts of Final Fantasy aswell.
I wrote a parser/disassembler for the WSC which outputs code like this (and then I've added in the comments).
Was a while ago since I last worked with this, could be fun to start up again and dig thru both the WSC and NES versions at the same time. Would have to read up on the 6502 again though, that part's abit rusty, heh.

23
Oh and the name size is not 8 it's 10 symbols
Hmm, ye kinda seems so. In the japanese version (which is the only one I found right now), there's even 2 names stored for afew characters. Like Zidane have both "ジタン" and "?" stored within these 10 bytes, Garnet have both "ガーネット" and "ダガー" etc. Can remember that in the english version (besides, it kinda shouldn't be possible to store both anyway!). I also though it was 8 because Salamader wouldn't fit, hence he's called Amarant, oh well. :)

I'll see if I can dig out some savegames, I usually don't use more then 1 slot though.
What's the 2nd MAX HP/MP for anyway?

24
Only thing I have about the save files is this, never spent much time with the save data.

25
Also the directory supposedly containing the summons seems to have a different structure, can't read it yet.

It's a bit different, although the actual data is in the same format (just doesn't have the DB chunk headers). It's padded with 0xFF instead of zero also.
For the 3D model data, you'll have to work with the B and C polygon types, they are only used for summon models. I'll see if I can dig out some old code with a somewhat decent description of them.

Edit:
I was bored...
...so bored

Pages: [1] 2 3