READ THE RULES: Click here

Follow us on Facebook: https://www.facebook.com/xentax/ :)

Mortal Kombat X .xxx

The Original Forum. Game archives, full of resources. How to open them? Get help here.
LinkOFF
n00b
Posts: 17
Joined: Mon Sep 08, 2014 12:32 am
Has thanked: 5 times
Been thanked: 1 time

Mortal Kombat X .xxx

Post by LinkOFF » Sat Apr 18, 2015 7:48 am

I can't unpack .xxx files using Umodel. Can anyone help?

Sample: http://rghost.ru/7QJSLTyFn

daemon1
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 1888
Joined: Tue Mar 24, 2015 8:12 pm
Has thanked: 48 times
Been thanked: 1430 times

Re: Mortal Kombat X .xxx

Post by daemon1 » Sun Apr 19, 2015 8:00 am

MKX .xxx unpacker. Experimental tools, 64 bit only. No error handling, no help. Here's what you can do with it:

1. unpack xxx file

mk10_xxx_packer [xxx name]

It will make unpacked .xxx.u file. If the file is already unpacked, it will crash. At least sound .xxx are not packed at all.

2. list the contents of unpacked file

mk10_xxx [xxx name] [filter]

It will make 3 text files with imports, exports, names. Also it will make .bat file to extract all files from the package. Extra "filter" parameter may be used to list only files having particular text in its NAME (not extension).
- Exports are just a list of files contained in the package. Notice some of them may be equal.
- Imports may be wrong, I'm not too familiar with it.
- Names are essential if you plan to do anything with the contents, because all unreal formats depend on these package-dependent names.

3. extract the files

Just run "cut.bat" to extract all the files. You can also edit the file all you want. In case some files have same names, they will be overwritten. I have no time to deal with this (duplicates) yet.
You do not have the required permissions to view the files attached to this post.
Last edited by daemon1 on Sun Apr 19, 2015 2:13 pm, edited 3 times in total.

ssringo
veteran
Posts: 98
Joined: Sat Apr 19, 2014 8:02 am
Has thanked: 46 times
Been thanked: 10 times

Re: Mortal Kombat X .xxx

Post by ssringo » Sun Apr 19, 2015 8:31 am

Dunno what kind of progress gildor is making (if any as it didn't seem like he had time to work on MKX atm) but you might as well upload your tool.

daemon1
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 1888
Joined: Tue Mar 24, 2015 8:12 pm
Has thanked: 48 times
Been thanked: 1430 times

Re: Mortal Kombat X .xxx

Post by daemon1 » Sun Apr 19, 2015 2:16 pm

Ok, tools uploaded. Have fun :)

It is strange, but many .xxx files have strange (encrypted?) part in the beginning. Different size, but all about 32k. Interesting that first 31184 bytes of those are the same for all .xxx files. It doesn't affect the unpacking process, but what could that be? Any ideas?

Straight Edge
beginner
Posts: 26
Joined: Sun Oct 05, 2014 5:15 pm
Has thanked: 11 times
Been thanked: 4 times

Re: Mortal Kombat X .xxx

Post by Straight Edge » Sun Apr 19, 2015 4:21 pm

Very useful tool. I wonder is there a way of converting the Texture2D files to a readable TGA/DDS. Same with the SkeletalMesh files converting them to psk.

LinkOFF
n00b
Posts: 17
Joined: Mon Sep 08, 2014 12:32 am
Has thanked: 5 times
Been thanked: 1 time

Re: Mortal Kombat X .xxx

Post by LinkOFF » Sun Apr 19, 2015 9:13 pm

Textures in archives very strange: http://rghost.ru/6MDhfsMkX

User avatar
howfie
double-veteran
double-veteran
Posts: 929
Joined: Fri Jul 08, 2011 12:06 pm
Location: Torrance, CA
Has thanked: 9 times
Been thanked: 262 times

Re: Mortal Kombat X .xxx

Post by howfie » Wed Apr 22, 2015 2:32 pm

not strange at all. those images you think are DXT5 with blocks swizzled are actually BC7.
http://snag.gy/g4qlM.jpg

model format is similar to injustice. i'm sure gildor will support it soon.
http://snag.gy/Eeure.jpg

darksoul
beginner
Posts: 27
Joined: Wed Apr 20, 2011 4:49 pm
Has thanked: 1 time
Been thanked: 2 times

Re: Mortal Kombat X .xxx

Post by darksoul » Thu Apr 23, 2015 5:45 pm

@ howfie what program do u use to view/edit? the dds bc7
also can u provide the actual bc7 dds and or atleast the header from a bc7
i read somewhere (iirc in the mw thread)the header has an addiditional 20 bytes

MusicNerd
beginner
Posts: 27
Joined: Sun Aug 14, 2011 7:48 am
Been thanked: 1 time

Re: Mortal Kombat X .xxx

Post by MusicNerd » Thu Apr 23, 2015 7:39 pm

howfie wrote:not strange at all. those images you think are DXT5 with blocks swizzled are actually BC7.
http://snag.gy/g4qlM.jpg

model format is similar to injustice. i'm sure gildor will support it soon.
http://snag.gy/Eeure.jpg
hey man, I would also like to know how you reversed it back to .dds format. I am close, and was able to dump them into these files using tools:
"image0.Texture2D" but I am guessing It's a headerless BC7 file?

User avatar
howfie
double-veteran
double-veteran
Posts: 929
Joined: Fri Jul 08, 2011 12:06 pm
Location: Torrance, CA
Has thanked: 9 times
Been thanked: 262 times

Re: Mortal Kombat X .xxx

Post by howfie » Thu Apr 23, 2015 11:48 pm

I wrote code to convert BC7 stream to RGBA format. Notice I use a function called "AVPCL::decompress" to decompress BC7 blocks to RGBA format. That function comes from a C++ library written by some dude from NVIDIA named Walter Donovan who wrote the BC6 specification. You can download the library here.

You can also use Noesis if you like Python.

Code: Select all

#define MK_RGBA 0x00
#define MK_ARGB 0x01
#define MK_DXT1 0x02
#define MK_DXT3 0x03
#define MK_DXT5 0x04
#define MK_ATI2 0x05
#define MK_BC7  0x06

struct MKTEXTURE2D {
 STDSTRING filename;
 uint32 offset; // offset to data
 uint32 dx;
 uint32 dy;
 uint32 format;
};

bool MKK_ProcessTexture2D(const MKTEXTURE2D& info)
{
 // Typically, Texture2D files contain 0x20 bytes directly before the texture data that has the
 // size of the data and an identifier. Width and height are typically displayed at the top.

 // open file
 using namespace std;
 ifstream ifile(info.filename.c_str(), ios::binary);
 if(!ifile) return error("Failed to open file.");

 // filename properties
 STDSTRING pathname = GetPathnameFromFilename(info.filename.c_str()).get();
 STDSTRING shrtname = GetShortFilenameWithoutExtension(info.filename.c_str()).get();

 // determine size of data
 uint32 datasize = 0;
 switch(info.format) {
   case(MK_RGBA) : datasize = UncompressedDDSFileSize(info.dx, info.dy, 0, 32); break;
   case(MK_ARGB) : datasize = UncompressedDDSFileSize(info.dx, info.dy, 0, 32); break;
   case(MK_DXT1) : datasize = DXT1Filesize(info.dx, info.dy, 0); break;
   case(MK_DXT3) : datasize = DXT3Filesize(info.dx, info.dy, 0); break;
   case(MK_DXT5) : datasize = DXT5Filesize(info.dx, info.dy, 0); break;
   case(MK_ATI2) : datasize = ATI2Filesize(info.dx, info.dy, 0); break;
   case(MK_BC7)  : datasize = GetBC7DataSize(info.dx, info.dy, 0); break;
   default : return error("Format not supported.", __LINE__);
  }

 // seek data
 ifile.seekg(info.offset);
 if(ifile.fail()) return error("Seek failure.", __LINE__);

 // read data
 boost::shared_array<char> data(new char[datasize]);
 ifile.read(data.get(), datasize);
 if(ifile.fail()) return error("Read failure.", __LINE__);

 // create DDS header
 DDS_HEADER ddsh;
 switch(info.format) {
   case(MK_RGBA) : CreateR8G8B8A8DDSHeader(info.dx, info.dy, 0, FALSE, &ddsh); break;
   case(MK_ARGB) : CreateA8R8G8B8DDSHeader(info.dx, info.dy, 0, FALSE, &ddsh); break;
   case(MK_DXT1) : CreateDXT1Header(info.dx, info.dy, 0, FALSE, &ddsh); break;
   case(MK_DXT3) : CreateDXT3Header(info.dx, info.dy, 0, FALSE, &ddsh); break;
   case(MK_DXT5) : CreateDXT5Header(info.dx, info.dy, 0, FALSE, &ddsh); break;
   case(MK_ATI2) : CreateATI2Header(info.dx, info.dy, 0, FALSE, &ddsh); break;
   case(MK_BC7)  : CreateR8G8B8A8DDSHeader(info.dx, info.dy, 0, FALSE, &ddsh); break;
   default : return error("Format not supported.", __LINE__);
  }

 // save DDS file
 STDSTRINGSTREAM ss;
 ss << pathname << shrtname << TEXT(".dds");
 if(info.format == MK_BC7)
   {
    // block properties
    const unsigned int blocksize = 16;
    const unsigned int block_dx = 4;
    const unsigned int block_dy = 4;
   
    // compute expected size
    unsigned int block_rows = std::max((DWORD)1, (DWORD)((info.dy + 3)/4));
    unsigned int block_cols = std::max((DWORD)1, (DWORD)((info.dx + 3)/4));
    unsigned int n_blocks = block_rows*block_cols;
    unsigned int expected_size = blocksize*n_blocks;
    if(expected_size < datasize) return false;
   
    // create RGBA data
    uint32 outpitch = 4*info.dx;
    uint32 outsize = outpitch*info.dy;
    boost::shared_array<char> outdata(new char[outsize]);
   
    // premultiplied
    uint32 left_offset[4] = { 0, outpitch, 2*outpitch, 3*outpitch };
   
    // for each block
    const char* block = data.get();
    Tile t(4, 4);
    for(uint32 i = 0; i < n_blocks; i++)
       {
        // decompress
        AVPCL::decompress(&block[0], t);
   
        // now map data to RGBA image
        uint32 base_x = (i % block_cols) * block_dx;
        uint32 base_y = (i / block_cols) * block_dy;
        uint32 base_index = 4*(info.dx*base_y + base_x);

        // convert char* to unsigned char* so we can assign 0 to 255 to items
        unsigned char* ptr = reinterpret_cast<unsigned char*>(outdata.get());

        // row1
        uint32 offset = base_index;
        ptr[offset++] = (uint08)t.data[0][0].Z();
        ptr[offset++] = (uint08)t.data[0][0].Y();
        ptr[offset++] = (uint08)t.data[0][0].X();
        ptr[offset++] = (uint08)t.data[0][0].W();
        ptr[offset++] = (uint08)t.data[0][1].Z();
        ptr[offset++] = (uint08)t.data[0][1].Y();
        ptr[offset++] = (uint08)t.data[0][1].X();
        ptr[offset++] = (uint08)t.data[0][1].W();
        ptr[offset++] = (uint08)t.data[0][2].Z();
        ptr[offset++] = (uint08)t.data[0][2].Y();
        ptr[offset++] = (uint08)t.data[0][2].X();
        ptr[offset++] = (uint08)t.data[0][2].W();
        ptr[offset++] = (uint08)t.data[0][3].Z();
        ptr[offset++] = (uint08)t.data[0][3].Y();
        ptr[offset++] = (uint08)t.data[0][3].X();
        ptr[offset]   = (uint08)t.data[0][3].W();
   
        // row2
        offset = base_index + left_offset[1];
        ptr[offset++] = (uint08)t.data[1][0].Z();
        ptr[offset++] = (uint08)t.data[1][0].Y();
        ptr[offset++] = (uint08)t.data[1][0].X();
        ptr[offset++] = (uint08)t.data[1][0].W();
        ptr[offset++] = (uint08)t.data[1][1].Z();
        ptr[offset++] = (uint08)t.data[1][1].Y();
        ptr[offset++] = (uint08)t.data[1][1].X();
        ptr[offset++] = (uint08)t.data[1][1].W();
        ptr[offset++] = (uint08)t.data[1][2].Z();
        ptr[offset++] = (uint08)t.data[1][2].Y();
        ptr[offset++] = (uint08)t.data[1][2].X();
        ptr[offset++] = (uint08)t.data[1][2].W();
        ptr[offset++] = (uint08)t.data[1][3].Z();
        ptr[offset++] = (uint08)t.data[1][3].Y();
        ptr[offset++] = (uint08)t.data[1][3].X();
        ptr[offset]   = (uint08)t.data[1][3].W();
   
        // row3
        offset = base_index + left_offset[2];
        ptr[offset++] = (uint08)t.data[2][0].Z();
        ptr[offset++] = (uint08)t.data[2][0].Y();
        ptr[offset++] = (uint08)t.data[2][0].X();
        ptr[offset++] = (uint08)t.data[2][0].W();
        ptr[offset++] = (uint08)t.data[2][1].Z();
        ptr[offset++] = (uint08)t.data[2][1].Y();
        ptr[offset++] = (uint08)t.data[2][1].X();
        ptr[offset++] = (uint08)t.data[2][1].W();
        ptr[offset++] = (uint08)t.data[2][2].Z();
        ptr[offset++] = (uint08)t.data[2][2].Y();
        ptr[offset++] = (uint08)t.data[2][2].X();
        ptr[offset++] = (uint08)t.data[2][2].W();
        ptr[offset++] = (uint08)t.data[2][3].Z();
        ptr[offset++] = (uint08)t.data[2][3].Y();
        ptr[offset++] = (uint08)t.data[2][3].X();
        ptr[offset]   = (uint08)t.data[2][3].W();
   
        // row4
        offset = base_index + left_offset[3];
        ptr[offset++] = (uint08)t.data[3][0].Z();
        ptr[offset++] = (uint08)t.data[3][0].Y();
        ptr[offset++] = (uint08)t.data[3][0].X();
        ptr[offset++] = (uint08)t.data[3][0].W();
        ptr[offset++] = (uint08)t.data[3][1].Z();
        ptr[offset++] = (uint08)t.data[3][1].Y();
        ptr[offset++] = (uint08)t.data[3][1].X();
        ptr[offset++] = (uint08)t.data[3][1].W();
        ptr[offset++] = (uint08)t.data[3][2].Z();
        ptr[offset++] = (uint08)t.data[3][2].Y();
        ptr[offset++] = (uint08)t.data[3][2].X();
        ptr[offset++] = (uint08)t.data[3][2].W();
        ptr[offset++] = (uint08)t.data[3][3].Z();
        ptr[offset++] = (uint08)t.data[3][3].Y();
        ptr[offset++] = (uint08)t.data[3][3].X();
        ptr[offset]   = (uint08)t.data[3][3].W();
   
        // move to next block
        block += blocksize;
       }

    SaveDDSFile(ss.str().c_str(), ddsh, outdata, outsize);
   }
 else
    SaveDDSFile(ss.str().c_str(), ddsh, data, datasize);

 return true;
}

MusicNerd
beginner
Posts: 27
Joined: Sun Aug 14, 2011 7:48 am
Been thanked: 1 time

Re: Mortal Kombat X .xxx

Post by MusicNerd » Fri Apr 24, 2015 6:37 am

Thanks for your script man, awesome stuff. I saved it as a .bms but quick BMS didn't seem to like it, tried putting it in with the BC7 Extractor scripts no go. I am trying to rip the Texure2D files from PC. Tried it on the file LoadScreen_TYM_TinLion.XXX extracted Texture2D files) and Char_Kitana_Diff.XXX (Extracted Texture2D file, the same one you used to make the .DDS texture)

User avatar
howfie
double-veteran
double-veteran
Posts: 929
Joined: Fri Jul 08, 2011 12:06 pm
Location: Torrance, CA
Has thanked: 9 times
Been thanked: 262 times

Re: Mortal Kombat X .xxx

Post by howfie » Fri Apr 24, 2015 9:03 am

btw, a guy pmed me on gildor's forum saying he had models for mkx all figured out using his noesis script, so if he's cool ya'll should be getting your models and textures soon. i think zaramot was also interested in doing a script. gildor said he'd still try too. so patience and time.

now i know you texture modders are here so if you know c++ (not quickbms), i have given you enough info on how to convert bc7 to rgba, which you can take into photoshop and edit, and then use the nvidia texture tools library i used to compress rgba back to bc7, for which you can paste back into the Texture2D.

User avatar
zaramot
double-veteran
double-veteran
Posts: 717
Joined: Wed Jan 05, 2011 12:41 pm
Has thanked: 39 times
Been thanked: 768 times

Re: Mortal Kombat X .xxx

Post by zaramot » Fri Apr 24, 2015 1:16 pm

Yes, Howfie you're right I'm doing script right now, going to finish and post it here. Unless, you want to do this too? You was first and did an awesome job!:)
Making model-import scripts, PM

User avatar
howfie
double-veteran
double-veteran
Posts: 929
Joined: Fri Jul 08, 2011 12:06 pm
Location: Torrance, CA
Has thanked: 9 times
Been thanked: 262 times

Re: Mortal Kombat X .xxx

Post by howfie » Fri Apr 24, 2015 5:30 pm

nope! it's all yours max_shift :) ! i just wanted one model hehehe.

MusicNerd
beginner
Posts: 27
Joined: Sun Aug 14, 2011 7:48 am
Been thanked: 1 time

Re: Mortal Kombat X .xxx

Post by MusicNerd » Sat Apr 25, 2015 8:05 am

howfie wrote:btw, a guy pmed me on gildor's forum saying he had models for mkx all figured out using his noesis script, so if he's cool ya'll should be getting your models and textures soon. i think zaramot was also interested in doing a script. gildor said he'd still try too. so patience and time.

now i know you texture modders are here so if you know c++ (not quickbms), i have given you enough info on how to convert bc7 to rgba, which you can take into photoshop and edit, and then use the nvidia texture tools library i used to compress rgba back to bc7, for which you can paste back into the Texture2D.
Ahh sweet thanks man, sorry I thought it was a BMS script. my knowledge of C++ is zero so I guess I will wait it out, but thanks for all you research on this format :) (Any everone else too including gildor)

Post Reply