Page:  1  2  next 

All posts by TodX (16)

topic: MDL Information  in the forum: Archive
TodX Administrator #1
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
I wouldn't have posted it if I hadn't.
topic: MDL Information  in the forum: Archive
TodX Administrator #2
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 201
I've been looking at the vertex format, and the one above is definitely not correct.

I can't quite make out what they are doing in the vert data.  I've managed to find the bone indices and weights, but that's about it.  I've tried to read the data as 16bit floats and I can't seem to get a definite match on anything.  I still need to try packed 10bit data, but either way I can't seem to make any sense of it yet.

I wouldn't mind a little help here if anyone could take a look.  (Like, maybe Kesh? =)

Once we bang this out, I'll start on a 3DS Max import plugin so we can play with the models.
topic: MDL Information  in the forum: Archive
TodX Administrator #3
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 108
Took a whack at the models.
This is based on a clothing item/non-static mesh.  I know the static meshes have diff format, at least for verts.

*Updated: most of the layout is done.  Now need to make sense of unknowns.  HW chokes on these structures due to zstring bugs.*
Requires HexWorkshop 6: But doesn't working either way

#include "standard-types.hsl"

#pragma byteorder(big_endian)
#pragma maxarray(65535)

struct BoneEntry
{
    zstring    BoneName;
    DWORD    BoneID;
}BoneEntry;

struct BoneTransform
{
    DWORD Unk1[11];
}BoneTransform;

struct Material
{
    zstring TextureName;
    zstring SpecularMapName;
    zstring NormalMapName;
    char Unk1[3];
    float Unk2[3];
}Material;

struct Vertex
{
    float Unk1[3];
    DWORD Unk2[3];
    float Unk3;
}Vertex;

struct Unk16
{
    float Unks[4];
}Unk16;

struct Mesh
{
    DWORD Unk1;
    zstring MeshName;
    float Unk2[2];
    char Unk3[21];
    float Unk4;
    DWORD Unk5[3];
    DWORD MaterialCount;
    Material Materials[MaterialCount];
   
}Mesh;

struct SubMeshDesc
{
    DWORD Unk1;
    char Unk2;
    DWORD Unk3[3];
    float Unk4[6];
}SubMeshDesc;

struct MeshBuffer
{
    DWORD Unk8[2];
    DWORD SomeCount1;
    DWORD TriangleStripLength;
    DWORD VertexCount;
    DWORD SubMeshCount;
    SubMeshDesc SubMeshes[SubMeshCount];
    Vertex Vertices[VertexCount];
    WORD Faces[TriangleStripLength];
    Unk16 Unk16[VertexCount];
}MeshBuffer;

struct MDL_File
{
    DWORD Unk1[8];
    DWORD BoneCount;
    BoneEntry Bones[BoneCount];
    DWORD BoneTransformCount;
    BoneTransform BoneTransforms[BoneTransformCount];
    float Unk2[10];
    DWORD MeshCount;
    DWORD Unk3[2];
    char Unk4[13];
    DWORD Unk5[5];
    DWORD Unk6Count;
    float Unk6s[Unk6Count];
    DWORD Unk7;
    Mesh Meshes[MeshCount];
    MeshBuffer MeshBuffers[MeshCount];
}MDL_File;
This post was edited on 2009-06-20, 05:42 by TodX.
topic: LOCO File Format  in the forum: Archive
TodX Administrator #4
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
Subject: LOCO File Format
Here's a basic layout of the data structure of the locomotion.loco file.


#include "standard-types.hsl"

#pragma byteorder(big_endian)
#pragma maxarray(65536)     // max that hw 5.1 will allow
#pragma maxstring(512)

typedef struct LocoEntry1Coords
{
    DWORD    Unknown;
    float    X;
    float    Y;
    float    Z;
} LocoEntry1Coords;

typedef struct LocoEntry1
{
    DWORD    Unknown0;
    char    Name[16];
    DWORD    Unknown1;    // always == 0x0820 ?
    DWORD    Unknowns2[94];
    LocoEntry1Coords    Coords[16];
} LocoEntry1;

typedef struct LocoEntry2
{
    DWORD    Unknowns1[6];
    float    Unknowns2[94];
} LocoEntry2;

typedef struct LOCO        // environment map
{
    DWORD    Unknown1;
    DWORD    Unknown2;
    DWORD    LocoEntry1Size;
    DWORD    LocoEntry2Size;
    DWORD    Unknown3;
    DWORD    Entry1Count;
    DWORD    Entry2Count;
    DWORD    Entry3Count;
    DWORD    StringsSectionSize;
    DWORD    Unknown7;
   
    LocoEntry1    Entries1[Entry1Count];
    LocoEntry2    Entries2[Entry2Count];
    DWORD    Entries3[Entry3Count];
    char    StringsSection[StringsSectionSize];
   
} LOCO;
topic: Hashing advice requested  in the forum: Archive
TodX Administrator #5
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 86
MD5 will be sufficient to detect file damage and modification.  Generating MD5 collisions is pretty easy, true, but not for a particular file.  Most likely if some one is trying to modify the game and they are that serious about it, they'll just modify the exe to send the hash values the server expects.  This can be done by using a nonmodified copy of the file to generate the hash, but have the game engine actually load a modified file, or just have it read the precomputed hash values from from an outside file.  But if you still want to try for something more secure, there's always the SHA hash functions, I don't believe I've heard of anyone that's made much progress against those.
topic: GENV File Format  in the forum: Archive
TodX Administrator #6
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
Subject: GENV File Format
This seems to be an environment map, don't know what it's linking to yet though.


#include "standard-types.hsl"

#pragma byteorder(big_endian)
#pragma maxarray(65536)     // max that hw 5.1 will allow
#pragma maxstring(512)

typedef struct GENV        // environment map
{
    DWORD    Unknowns1[5];
    DWORD    CellsX;
    DWORD    CellsY;
    DWORD    Unknown2;
   
    DWORD    Map[CellsX*CellsY];    // Environment ID for that cell
} GENV;
topic: ENGINE_LEVEL - LevelGraphicsFile Format  in the forum: Archive
TodX Administrator #7
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
Subject: ENGINE_LEVEL - LevelGraphicsFile Format
Here's what I have so far on the engine_level/LevelGraphicsFile format.  This format will not properly work in HW as it seems to cut off the strings after 10 chars and thus screws the rest of the format, and in the process sucks up a ton of cpu and mem (a 2.2kb file sucked up 1.4gb ram).  There may also be additional file types that I have not yet run into.

This file seems to have links to a number of other files used for loading/rendering the level.  This includes heightmaps and flora models.  The flora models are followed by what looks like instancing data to spawn instances with.

#include "standard-types.hsl"

#pragma byteorder(big_endian)
#pragma maxarray(65536)     // max that hw 5.1 will allow
#pragma maxstring(512)

typedef struct Coord3D
{
    float    X;
    float    Y;
    float    Z;
} Coord3D;

typedef struct LGFFloraInstance
{
    Coord3D    Coord;
    float    Unknown1;    // these two floats seem to always be very small, very close to 0
    float    Unknown2;    // they could be used for rotation maybe? though that's usually done with quaternions
} LGFCoordEntry;

typedef struct LGFUnknownBBEntry    // looks like it might be bounding box, but not sure
{
    DWORD    Start;
    DWORD    End;
    Coord3D    StartCoord;
    Coord3D    EndCoord;
} LGFUnknownBBEntry;

typedef struct LGFFileEntry
{
    DWORD    Type;
    zstring    FileName;
   
    switch (Type)
    {
        case 0x4:
            DWORD    Unknown1;
            DWORD    Unknown2;
            break;
        case 0x5:    break;
        case 0x15:
            char    Unknowns1[11];
            DWORD    CoordCount;
            float    Unknowns2[11];
            char    Unknowns3Null[24];
            LGFFloraInstance    Coords[CoordCount];
            DWORD    UnknownBBCount;        // I think these might be bounding boxes, but not sure
            LGFUnknownBBEntry    UnknwonBBs[UnknownBBCount];
            break;
        case 0x20:    break;
        default:    break;
    }
   
} LGFFileEntry;

typedef struct LevelGraphicsFile
{
    char    LevelGraphicsFileTag[17];    // = "LevelGraphicsFile"
    DWORD    Unknown1;
    DWORD    FileCount;
    LGFFileEntry    Files[FileCount];
   
} LevelGraphicsFile;
This post was edited on 2008-12-05, 19:23 by TodX.
topic: Source Code (Publicly available source via Subversion)  in the forum: Archive
TodX Administrator #8
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 32
I would suggest to just make a post in this thread with your code release and update that post with each new release.  This should allow us to have one central place where all available code can be easily accessed.  Then start a new thread for discussion of the code if necessary.  I'd like to keep this thread limited to just source code releases, and as so I'll probably be splitting this thread pretty soon.
topic: Source Code (Publicly available source via Subversion)  in the forum: Archive
TodX Administrator #9
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 25
You can use anything you like.  In terms of getting it committed in subversion, as long as everything required to build and run it is checked in you should be ok.  Alternatively if you're not planning on having multiple contributing developers you can just post the code in a thread or anywhere else to your liking.

Memory leaks are very possible as this code was written in a bit of a hurry just to get it working.  As for delete vs delete [] they are identical in terms of memory deallocation (at least in all c++ implementations I'm aware of), the only difference is that delete [] calls destructors on the array items if they exist before releasing the memory.  Long story short, I have a bad tendency to forget to use the [] when dealing with strings/raw data buffers since I don't really see them as objects.
topic: Source Code (Publicly available source via Subversion)  in the forum: Archive
TodX Administrator #10
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
Subject: Source Code
To help the progress of tools development for Fable 2 we are running a Subversion server with source code of currently developed tools.  It is currently a very small codebase, but we're sure it will grow over time as more progress is made into the file formats.

Check out is anonymous. If you would like to commit, please talk to us about it.

Repository URL: svn://fable2mod.com:3690

Happy Coding  ;-)

P.S. Since the currently major developer of the code (myself) uses Visual Studio 2008, the code is setup to be built with visual studio 2008 solution/project files.  On another note, a great Subversion plugin for Visual Studio is AnkhSVN, pretty much a must have in my opinion.
topic: Bogus BNK File Entries  in the forum: Archive
TodX Administrator #11
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 21
Offset just tells you where the file data section starts, it has nothing to do with the file table.  You need to decompress the file CompressedFileData and use the output of that to read in the file table.  The file table will then have offsets into the file data section for each file entry.

The number you're seeing is actually the first peice of data of the first entry:
1298494312 = 4D 65 73 68 = "Mesh"

I suggest getting a hex editor and trying some of these formats by hand.  It helps a lot in understanding the data formats.  Or use hex workshop and the structs we provide and it'll do most of the parsing for you.

Also the endian conversion code you have looks kind of odd.  If I'm reading it right it is using global variables for a few things and using loops to do the endian conversion which is relatively slow, and can add up if you're going to be doing it on every little peice of file data.  I'll be posting the code to the BNK extractor soon, you can see an alternate way of doing it in there.

P.S. This format is inherently not serial as it requires random access (aka using seek).  It's just terminology, but I thought I'd mention it since you have Serialize and Deserialize names in there.
This post was edited on 2008-11-12, 11:00 by TodX.
topic: BNK File Format (technical)  in the forum: Archive
TodX Administrator #12
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 16
Yeah, you're right.  There is no good way of telling if a BNK is a BNK.  I guess they decided to leave the tag off for some odd reason.  Pretty much if it's extension is bnk then try reading it.  And yeah, just read the BNK struct starting at the beginning of the file.
topic: BNK File Format (technical)  in the forum: Archive
TodX Administrator #13
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 13
I'm refering to the z_stream struct and its internal data.  See this page for details http://www.zlib.net/manual.html.
topic: BNK File Format (technical)  in the forum: Archive
TodX Administrator #14
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 9
They're using zlib's deflate/inflate and 'managing' the streams themselves.  Thus there are no checksums at the end of compression blocks.  This means that if you use pre-setup uncompress() call it will fail since it looks for a checksum at the end of the compressed block.  Also for the file table they are maintaining the same context through out all the compressed blocks, effectively treating it as one big stream that has been broken up into peices which makes sense.  However, in the compressed files they start a new context for each block, treating each block as a new stream and then combining the outputs.
topic: Fable2 BNK Archive Extractor (Extract internal files from BNK archives.)  in the forum: Archive
TodX Administrator #15
Member since Oct 2008 · 16 posts · Location: San Diego
Group memberships: Administrators, Members
Show profile · Link to this post
In reply to post ID 4
This currently extracts all the files with the '\'s in the paths replaced with '.'s to make finding files easier.  I'll add a full directory dump option later.  For now, I figured just being able to play with the files should be a good start.
Close Smaller – Larger + Reply to this post:
Special characters:
Page:  1  2  next 
Special queries
Go to forum
Not logged in. · Lost password · Registration disabled
This board is powered by the Unclassified NewsBoard software, 20150713-dev, © 2003-2015 by Yves Goergen
Page created in 163.7 ms (125.6 ms) · 145 database queries in 76.8 ms
Current time: 2019-07-16, 17:17:05 (UTC -07:00)