Miscellaneous Forums > Scripting and Reverse Engineering

[FF8 steam]Character importer

(1/7) > >>

Shunsq:
Hi everyone,
I'm trying to get the bone positions from the chara.one file , present in each field archive. The wiki states that the model data is lzs compressed but i can't figure out how to decompress the file.
I've read about LZS compression and wrote a program to decompress chara.one.
It is based on this:
http://forums.qhimm.com/index.php?topic=2023.msg28900#msg28900

Anyway all i obtain is garbage. Or maybe it's not looking like what i'm expecting: isn't it supposed to look like the .MCH file,with number of bones, vertices , etc... in the header?

This is how my code works:

--- Code: ---typedef struct ALONE ALONE;
struct ALONE
{
    long long int one_offset;
    long int one_datasize;//appears twice
    long long int has_tim;//if >0xd0 then no tim_offset and directly model data offset( which is 0)
    long long int tim_offset;//0 if has_tim>0xd0
    long long int alone_offset;//0 if has_tim>0xd0
    char name[9];
};

//Reads the header then creates a list of ALONE structures ( one for each character of the chara.one)
//I've not included the code here

//---LZS Decompression---//I create a .alone file for each character "i"
for(i=0; i<alone_count; i++)
    {
        sprintf(outputpath,"%s%s.alone",outdir_name,alone_list[i].name);
        FILE*alone=fopen(outputpath,"ab+");

        fseek(inputfile,alone_list[i].one_offset,SEEK_SET);

        memset(outputpath,'\0',255);
        int ctrl_bit[8];//control byte before the compressed data
        char comp[2];//the two bytes of the compressed data
        int comp_len=0;
        int comp_offset=0;
        long int new_pos=0;
        long int last_pos=0;

        memset(ctrl_bit,0,8*sizeof(int));
        memset(comp,'\0',2);

        while(ftell(inputfile)<alone_list[i].one_offset+alone_list[i].one_datasize)
        {
            fscanf(inputfile,"%c",&cbyte);
            convert_to_bits(cbyte,ctrl_bit);//Reference byte

            for(j=0; j<8; j++)
            {
                if(ctrl_bit[7-j]==0)//compressed data
                {
                    for(k=0; k<2; k++)
                    {
                        fscanf(inputfile,"%c",&cbyte);
                        comp[k]=cbyte;//read from left to right
                    }

                    comp_len=comp[1]%0x10+3;//minimum is 3bytes
                    comp_offset=comp[0]+(comp[1]-comp[1]%0x10)*0x10;//if the two byte are read from left to right 0xa4 0xb1 then comp_offset=0xba4;
                    new_pos=ftell(alone)-(ftell(alone)-18-comp_offset)%0x1000;//reference byte pos

                    k=0;
                    if(new_pos<0)
                    {
                        for(k=0;k<comp_len;k++)
                        {
                            fprintf(alone,"%c",NULL);
                        }
                    }
                    else if(new_pos>0)
                    {
                        fseek(alone,new_pos,SEEK_SET);
                        for(k=0;k<comp_len;k++)
                        {
                            fscanf(alone,"%c",&cbyte);//reads at comp_offset
                            fprintf(alone,"%c",cbyte);
                        }
                    }

                }
                else if(ctrl_bit[7-j]==1)//literal data
                {
                    cbyte=0;
                    fscanf(inputfile,"%c",&cbyte);
                    fprintf(alone,"%c",cbyte);
                }
            }
        }
        fclose(alone);
    }
    fclose(inputfile);

--- End code ---

Vehek:
The wiki also mentions Playstation version when mentioning the compression. As in, only the Playstation version. You don't need to decompress further in the PC version.

Shunsq:
When i read the chara.one file, i don't see any similarity with the .MCH.That's why i thought it was compressed.
How did you proceed Vehek?

EDIT: I think i've found something that was not mentionned anywhere.
In chara.one, for main characters, there is only animation data. The first 4 bytes are likely to be animation count, frame count and bone count. It's exactly what Vehek wrote about animations here:http://forums.qhimm.com/index.php?topic=13261.0

On a side note why Vehek information is not in the wiki?




Halfer:
http://wiki.qhimm.com/view/FF8/FileFormat_ONE

It is on wiki, but i'm not sure how exact the information is.

A little reminder, world map chara.one seems to be completely different from field map chara.one

sithlord48:
you can check you programs output by comparing it to a known working LZS decompressor..  such as the one myst6re has provided for ff7tk (he also wrote the wiki entry linked above) that should help you figure out if the file is different or your just decompressing it incorrectly. i added a compression tool to the ff7tk demo program but it currently only is using the LGP class. You would need to either mod it to use LZS class or just use the source as a reference for your code.

https://github.com/sithlord48/ff7tk/blob/master/utils/LZS.h
https://github.com/sithlord48/ff7tk/blob/master/utils/LZS.cpp

Navigation

[0] Message Index

[#] Next page

Go to full version