March 29, 2024, 10:06
bigger smaller reset     1020px Wide width Full width Reset   * *

Gildor's Forums

  Homepage Facebook Read news on Twitter Youtube channel Github page
Welcome, Guest. Please login or register.
Did you miss your activation email?

« previous next »
Print
Author Topic: Injustice - Gods Among Us file format  (Read 52966 times)
warrantyvoider
Full Member
***
Posts: 109


View Profile
« Reply #30 on: April 18, 2013, 08:59 »

im already busy with me3, so sry, no time. also without a sample file I cant help you anyway, as I dont have the game

greetz WV
Logged
tetzrep
Newbie
*
Posts: 6


View Profile
« Reply #31 on: April 19, 2013, 02:04 »

nice work howfie,  Grin
Ive been trying to follow what your've done to decompress the files (CHAR).
Only problem is I dont know how to decompress with lzo1x or which tool to use for it.
Are you able to write a quick tut how you decompressed the XXX file?
or is there a chance you could compile only the decompression part of the source code? (I have no idea how to read C++... atm)
Think this would help alot of people who are working on this game..
getting past the compression is quite a big step in itself!..
Logged
warrantyvoider
Full Member
***
Posts: 109


View Profile
« Reply #32 on: April 21, 2013, 00:55 »

there you go, its a quick n dirty hack, but it works^^ it decompresses all chunks and all blocks into one file, you still need to add the header back, change the compressiontype and flag, but I guess you can go on from this (including executable and source)

get it here



greetz WV
Logged
tetzrep
Newbie
*
Posts: 6


View Profile
« Reply #33 on: April 21, 2013, 07:06 »

wicked man! thanks Grin
Logged
newlegend
Newbie
*
Posts: 5


View Profile
« Reply #34 on: April 25, 2013, 20:39 »

thanks for the tool but i have been having problems adding the hearder and all in
what should in?
Logged
warrantyvoider
Full Member
***
Posts: 109


View Profile
« Reply #35 on: April 26, 2013, 01:10 »

check f.e. code of gibbeds decompressor tool here to get an idea, basically everything up to the start of the chunks and few modifications

greetz
Logged
newlegend
Newbie
*
Posts: 5


View Profile
« Reply #36 on: April 26, 2013, 18:06 »

ok thanks
Logged
tetzrep
Newbie
*
Posts: 6


View Profile
« Reply #37 on: May 11, 2013, 18:34 »

Ive uploaded a pdf file to help with decompressing these files.
theres also a guide to get the files working with umodel. (filelists and extraction)
also added a how to get the files working on xbox and ps3.
plus how to convert a few texture2D's..
http://www.filefactory.com/file/4q58u1eq31np/n/dcf_fileformatguide_rar

Logged
howfie
Newbie
*
Posts: 33


View Profile
« Reply #38 on: May 12, 2013, 00:57 »

Model format for this game is extremely friggin' easy.


However, I am stuck at decoding textures. Does Unreal use some kind of channel tiling or swizzling? For example, this one catwoman image, SizeX, SizeY and Format properties suggest it is a 0x200 x 0x200 DXT1 image (4-bits per pixel), but when I load it it looks like this lol Cheesy.



any help would be appreciated Smiley. (picture above is actually a mipmap that's why it's says 256 x 256).
« Last Edit: May 12, 2013, 01:00 by howfie » Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #39 on: May 12, 2013, 03:17 »

XBox360 has modified format of DXT textures, which is really looks like some swizzling.
Logged
tetzrep
Newbie
*
Posts: 6


View Profile
« Reply #40 on: May 12, 2013, 05:29 »

oh wow man!. Id like to know how you got the models out. Cheesy

heres some images deswizzled from off the xbox.


the xbox Texture2D files have every second byte swapped, then swizzled by 16 bytes.
the swizz is exactly the same as mk9 texture2ds. only difference between them are there header sizes.
I dont think umodel extracts dds/tga's from an already extracted Texture2D file?
but I found a program called Xpacker that can deswizzle them.
first the texture2D headers will need some fixing..

for _diff and _spec Texture2D's
delete these parts of the header:
e8-f3 (lenght: C)
88-a3 (lenght: 1C)

for _norm Texture2D's
delete these parts of the header:
138-143 (lenght: C)

then run them through the xpacker program as xbox360 mk9 texture2d's
export the largest image (usually at the top) into .dds

I've had to manually deswizzle the playerselect cell image. because the size wasnt supported.
only a small image 128x256. but, took awhile..

texture2D's on the PS3 version arent swapped or unswizzled.
to get the ps3 texture2d's into .dds. same thing with the headers, then use texture2d tool made by scorpion2k7.

I think the 3dmodel format changes between xbox and ps3? it did for mk9.
hope this helps.


« Last Edit: May 12, 2013, 05:43 by tetzrep » Logged
howfie
Newbie
*
Posts: 33


View Profile
« Reply #41 on: May 12, 2013, 06:07 »

thx, i'll see what i can do with the xbox sdk libraries... there's some sample code around that uses the static libs from the SDK to deswizzle stuff and i'll check that out.

i don't have time to mess with the complexity of the unreal export/import table so i just took the decompressed package and found the offset to the model files. for CHAR_catwoman_A the model file entry is at offset 0x0080c41b and the size of the data is 0x0009bf8f bytes. i just copied that to an empty binary file.

there is only one vertex buffer and one index buffer. preceding the index buffer data is a list of items describing how the mesh is separated into parts. the skeleton is near the beginning of the file, format per joint is quaternion (x, y, z, w) followed by position in relative coordinates. right after the joint data is the parent data, a list of parent indices (note, this game doesn't use 0xFFFFFFFF for joint with no parent, it uses parent index same as joint index).

the following code is what i used to extract the bones.

Code:
bool TestInjustice(void)
{
 using namespace std;
 string filename = "c:\\users\\semory\\desktop\\model3.bin"; // catwoman's body is the 3rd model file in the export table
 ifstream ifile(filename.c_str(), ios::binary);
 if(!ifile) return error("Failed to open file.");

 string pathname = GetPathnameFromFilename(filename);
 string shrtname = GetShortFilenameWithoutExtension(filename);

 // move to parent data
 ifile.seekg(0x16BC);
 if(ifile.fail()) return error("Seek failure.");

 // read number of joints
 uint32 n_joints1 = BE_read_uint32(ifile);
 if(ifile.fail()) return error("Read failure.");

 // read parent data
 boost::shared_array<uint16> parents(new uint16[n_joints1]);
 if(!BE_read_array(ifile, parents.get(), n_joints1)) return error("Read failure.");
 for(uint32 i = 0; i < n_joints1; i++) cout << parents[i] << endl;

 // move to joint data
 ifile.seekg(0x90C);
 if(ifile.fail()) return error("Seek failure.");

 // read number of joints
 uint32 n_joints = BE_read_uint32(ifile);
 if(ifile.fail()) return error("Read failure.");

 AMC_SKELETON2 skel2;
 skel2.format = AMC_JOINT_FORMAT_RELATIVE | AMC_JOINT_FORMAT_MATRIX | AMC_JOINT_FORMAT_X_BONEAXIS;
 skel2.name = "skeleton";

 // read joint data
 for(uint32 i = 0; i < n_joints; i++)
    {
     real32 p01 = BE_read_real32(ifile); // 0x04 unit quaternion
     real32 p02 = BE_read_real32(ifile); // 0x08 unit quaternion
     real32 p03 = BE_read_real32(ifile); // 0x0C unit quaternion
     real32 p04 = BE_read_real32(ifile); // 0x10 unit quaternion
     real32 p05 = BE_read_real32(ifile); // 0x14 position
     real32 p06 = BE_read_real32(ifile); // 0x18 position
     real32 p07 = BE_read_real32(ifile); // 0x1C position
     cout << p05 << ", " << p06 << ", " << p07 << endl;

     cs::math::quaternion<real32> quat(p04, p01, p02, p03); // w, x, y, z
     cs::math::normalize(quat);
     cs::math::matrix4x4<real32> mat;
     cs::math::quaternion_to_matrix4x4(&quat[0], mat.get());
     cout << "mat = " << mat << endl;

     stringstream ss;
     ss << "jnt_" << setfill('0') << setw(3) << i;
     
     // create and insert joint
     AMC_JOINT joint;
     joint.name = ss.str();
     joint.id = i;
     joint.parent = (parents[i] == i ? AMC_INVALID_JOINT : parents[i]);
     joint.m_rel[0x0] = mat[0x0];
     joint.m_rel[0x1] = mat[0x1];
     joint.m_rel[0x2] = mat[0x2];
     joint.m_rel[0x3] = mat[0x3];
     joint.m_rel[0x4] = mat[0x4];
     joint.m_rel[0x5] = mat[0x5];
     joint.m_rel[0x6] = mat[0x6];
     joint.m_rel[0x7] = mat[0x7];
     joint.m_rel[0x8] = mat[0x8];
     joint.m_rel[0x9] = mat[0x9];
     joint.m_rel[0xA] = mat[0xA];
     joint.m_rel[0xB] = mat[0xB];
     joint.m_rel[0xC] = mat[0xC];
     joint.m_rel[0xD] = mat[0xD];
     joint.m_rel[0xE] = mat[0xE];
     joint.m_rel[0xF] = mat[0xF];
     joint.p_rel[0] = p05;
     joint.p_rel[1] = p06;
     joint.p_rel[2] = p07;
     joint.p_rel[3] = 1.0f;
     skel2.joints.push_back(joint);
    }

 ADVANCEDMODELCONTAINER amc;
 amc.skllist2.push_back(skel2);
 SaveAMC(pathname.c_str(), shrtname.c_str(), amc);

 return true;
}
Logged
tetzrep
Newbie
*
Posts: 6


View Profile
« Reply #42 on: May 12, 2013, 07:51 »

thanks, looks like I'm going have do some homework on that though?

heres a modified header for catwoman_A.
http://www.filefactory.com/file/6bu1rgli4xld/n/CHAR_Catwoman_A_header_rar
replace everything in the decompressed header with it and then use umodel to extract all the files or to get all the table info listed to .txt.
probably dont need it, but its there if you want..
Logged
howfie
Newbie
*
Posts: 33


View Profile
« Reply #43 on: May 12, 2013, 08:38 »

awesome, thanks, got it lol.



as simple as using the XBOX360 SDK lol

Quote
// open DDS file
 ifstream ifile(filename, ios::binary);
 if(!ifile) return error("Failed to open file.");

 uint32 h01 = LE_read_uint32(ifile);
 uint32 h02 = LE_read_uint32(ifile); // dwSize;
 uint32 h03 = LE_read_uint32(ifile); // dwFlags;
 uint32 h04 = LE_read_uint32(ifile); // dwHeight;
 uint32 h05 = LE_read_uint32(ifile); // dwWidth;
 uint32 h06 = LE_read_uint32(ifile); // dwPitchOrLinearSize;
 uint32 h07 = LE_read_uint32(ifile); // dwDepth;
 uint32 h08 = LE_read_uint32(ifile); // dwMipMapCount;
 uint32 h09[11];                     // reserved
 LE_read_array(ifile, &h09[0], 11);
 uint32 h10 = LE_read_uint32(ifile); // dwSize;
 uint32 h11 = LE_read_uint32(ifile); // dwFlags;
 uint32 h12 = LE_read_uint32(ifile); // dwFourCC;
 uint32 h13 = LE_read_uint32(ifile); // dwRGBBitCount;
 uint32 h14 = LE_read_uint32(ifile); // dwRBitMask;
 uint32 h15 = LE_read_uint32(ifile); // dwGBitMask;
 uint32 h16 = LE_read_uint32(ifile); // dwBBitMask;
 uint32 h17 = LE_read_uint32(ifile); // dwABitMask;
 uint32 h18 = LE_read_uint32(ifile); // dwCaps;
 uint32 h19 = LE_read_uint32(ifile); // dwCaps2;
 uint32 h20 = LE_read_uint32(ifile); // dwCaps3;
 uint32 h21 = LE_read_uint32(ifile); // dwCaps4;
 uint32 h22 = LE_read_uint32(ifile); // dwReserved2;

 // read image data
 uint32 size = 0;
 if(h12 == 0x31545844) size = DXT1Filesize(h05, h04, h08);
 else if(h12 == 0x35545844) size = DXT5Filesize(h05, h04, h08);
 boost::shared_array<char> data(new char[size]);
 boost::shared_array<char> copy(new char[size]);
 ifile.read(data.get(), size);
 if(ifile.fail()) return error("Read failure.");

 // endian swap
 uint32 pitch = 0;
 if(h12 == 0x31545844) pitch = (h05/4) * 8;
 else if(h12 == 0x35545844) pitch = (h05/4) * 16;
 XGEndianSwapSurface(copy.get(), pitch, data.get(), pitch, h05, h04, D3DFMT_DXT1);
 std::swap(data, copy);

 // DXT1 pitch...
 // 16 dx
 // 4 x 4 blocks
 // 16 dx/4 = 4 blocks
 // number of bytes in 4 blocks = 4 * 8

 // compute pitch
 DWORD gpuformat = 0;
 if(h12 == 0x31545844) gpuformat = XGGetGpuFormat(D3DFMT_DXT1);
 else if(h12 == 0x35545844) gpuformat = XGGetGpuFormat(D3DFMT_DXT5);
 XGUntileTextureLevel(h05, h04, 0, gpuformat, XGTILE_NONPACKED, copy.get(), pitch, NULL, data.get(), NULL);

 // create output file
 stringstream ss;
 ss << GetPathnameFromFilename(filename);
 ss << GetShortFilenameWithoutExtension(filename);
 ss << "_deswizzled.dds";
 ofstream ofile(ss.str().c_str(), ios::binary);
 if(!ofile) return error("Failed to create output file.");

 // save data
 LE_write_uint32(ofile, h01);
 LE_write_uint32(ofile, h02); // dwSize;
 LE_write_uint32(ofile, h03); // dwFlags;
 LE_write_uint32(ofile, h04); // dwHeight;
 LE_write_uint32(ofile, h05); // dwWidth;
 LE_write_uint32(ofile, h06); // dwPitchOrLinearSize;
 LE_write_uint32(ofile, h07); // dwDepth;
 LE_write_uint32(ofile, h08); // dwMipMapCount;
 LE_write_array(ofile, &h09[0], 11);
 LE_write_uint32(ofile, h10); // dwSize;
 LE_write_uint32(ofile, h11); // dwFlags;
 LE_write_uint32(ofile, h12); // dwFourCC;
 LE_write_uint32(ofile, h13); // dwRGBBitCount;
 LE_write_uint32(ofile, h14); // dwRBitMask;
 LE_write_uint32(ofile, h15); // dwGBitMask;
 LE_write_uint32(ofile, h16); // dwBBitMask;
 LE_write_uint32(ofile, h17); // dwABitMask;
 LE_write_uint32(ofile, h18); // dwCaps;
 LE_write_uint32(ofile, h19); // dwCaps2;
 LE_write_uint32(ofile, h20); // dwCaps3;
 LE_write_uint32(ofile, h21); // dwCaps4;
 LE_write_uint32(ofile, h22); // dwReserved2;
 ofile.write(copy.get(), size);

 return true;
Logged
warrantyvoider
Full Member
***
Posts: 109


View Profile
« Reply #44 on: May 13, 2013, 16:09 »

Do you guys still need tools or do you already have what you need? I completed my browser/decompressor so far that you can browse names, import, exports and export data. Now all you need is to write classes that handle the different export classes, like f.e. Texture2D as seen here in screenie. Dunno how much you know about it, it starts with properties, the pattern is
-64bit name
-64bit type
-32bit size
-32bit index
-(size in bytes) propertydata
read that until you read "None" as propertyname (only 8 bytes in total!). Now thats the same for all classes, so you need to write some kind of propertyreader that reads them and gives you the endoffset of them. From there on you have to write classes for the (serialized) binary, to readout/change whatever you want (you can edit the properties obviously too)



get it here

greetz WV
« Last Edit: May 13, 2013, 16:16 by warrantyvoider » Logged
Print 
« previous next »
Jump to:  

Powered by SMF | SMF © 2006-2009, Simple Machines LLC
Leviathan design by Bloc | XHTML | CSS