Re: Tomb Raider (2012) (PC) (PS3) (XBOX) (*.000.tiger)
Posted: Sat Mar 02, 2013 8:57 pm
Updated filelists for PS3: Added names for Patch 1.01
It's DXT compressed texture (PS3T = PS3 texture?)Ekey wrote:Yeah but after decompressing with ZLIB, files have new compression. You can see here examples (_dec.dat) . Compressed data begin from offset 0x24.
Code: Select all
4 Bytes - PS3T (Always) 4 Bytes - Compressed Size (Without Header (size 0x24) - Endian Big) 4 Bytes - Decomrpessed Size ? (Endian Big) 4 Bytes - Unknown (Endian Little) 4 Bytes - Unknown (Endian Little) 4 Bytes - Unknown (Endian Little) 4 Bytes - Unknown (Endian Little) 8 Bytes - Nulls
If you only check the header, yes there is a lot of dead data. but if you look inbetween the gaps of the files listed in the bigfile header, you will find files. It also doesn't make sense that the main model (laracroft.drm) is only 161KB (xbox version).Rick wrote:patch.000.tiger in PC version has ~111MB of dead/unused data.
Edit: this can't be right... if it is, PC version has 4GB+ of dead/unused data.
Rick wrote:patch.000.tiger in PC version has ~111MB of dead/unused data.
Edit: this can't be right... if it is, PC version has 4GB+ of dead/unused data.
Packer will not be possible until the DRM stuff is understood.michalss wrote:Hi Rick,
I did check your repository and i can see you update it with TR9, are you also considering to make packer for PC,X360 please ?
Rick wrote:Packer will not be possible until the DRM stuff is understood.michalss wrote:Hi Rick,
I did check your repository and i can see you update it with TR9, are you also considering to make packer for PC,X360 please ?
Code: Select all
bigfile - +391
bigfile_english - +1066
patch - +56
title - +58
pack8 - +10
Code: Select all
inline uint32 LE_read_uint32(std::istream& ifile)
{
uint32 temp;
ifile.read((char*)&temp, sizeof(temp));
return temp;
}
int main()
{
//
// READ TABLE
//
using namespace std;
ifstream ifile("bigfile.000.tiger", ios::binary);
if(!ifile) return error("shit");
// skip all the useless shit
ifile.seekg(0x1A800);
uint32 n_files = 0;
struct TABLESUBENTRY1 {
uint32 p01;
uint32 p02;
uint32 p03;
uint32 p04;
uint32 p05;
};
struct TABLESUBENTRY2 {
uint32 p01;
uint32 p02;
uint32 p03;
uint32 p04;
};
struct TABLEENTRY {
uint32 p01; // 0x16
uint32 p02;
uint32 p03;
uint32 p04;
uint32 p05;
uint32 p06;
uint32 p07; // number of entries
uint32 p08;
deque<TABLESUBENTRY1> sub1;
boost::shared_array<char> namelist;
deque<TABLESUBENTRY2> sub2;
};
deque<TABLEENTRY> entrylist;
set<uint32> fileset;
for(;;)
{
uint32 currpos = (uint32)ifile.tellg();
cout << "Table Entry #0x" << hex << entrylist.size() << " at 0x" << currpos << dec << endl;
TABLEENTRY entry;
entry.p01 = LE_read_uint32(ifile);
entry.p02 = LE_read_uint32(ifile); // string length part 1
entry.p03 = LE_read_uint32(ifile); // string length part 2
entry.p04 = LE_read_uint32(ifile);
entry.p05 = LE_read_uint32(ifile);
entry.p06 = LE_read_uint32(ifile);
entry.p07 = LE_read_uint32(ifile); // number of sections this file is composed of
entry.p08 = LE_read_uint32(ifile);
if(entry.p01 != 0x16) break;
n_files += entry.p07;
for(uint32 i = 0; i < entry.p07; i++) {
TABLESUBENTRY1 se;
se.p01 = LE_read_uint32(ifile);
se.p02 = LE_read_uint32(ifile);
se.p03 = LE_read_uint32(ifile);
se.p04 = LE_read_uint32(ifile);
se.p05 = LE_read_uint32(ifile);
entry.sub1.push_back(se);
}
// there can be strings here, they are already null terminated
// wtf? why did they do this retarded ass shit lol?
uint32 len = entry.p02 + entry.p03;
if(len) {
boost::shared_array<char> name(new char[len]);
LE_read_array(ifile, name.get(), len);
entry.namelist = name;
cout << " ";
for(uint32 i = 0; i < len; i++) {
if(name[i] == 0) cout << " ";
else cout << name[i];
}
cout << endl;
}
for(uint32 i = 0; i < entry.p07; i++) {
TABLESUBENTRY2 se;
se.p01 = LE_read_uint32(ifile);
se.p02 = LE_read_uint32(ifile); // offset + bigfile index
se.p03 = LE_read_uint32(ifile); // size of section
se.p04 = LE_read_uint32(ifile);
entry.sub2.push_back(se);
fileset.insert(se.p02); // add offset and bigfile index to set of files
}
entrylist.push_back(entry);
// move to next 0x800-aligned position
uint32 position = ifile.tellg();
position = ((position + 0x7FF) & (~0x7FF));
ifile.seekg(position);
if(ifile.fail()) return error("Seek failure.");
}
ifile.close();
cout << "Number of entries = 0x" << hex << entrylist.size() << dec << endl;
cout << "Number of files = 0x" << hex << n_files << dec << endl;
cout << "Number of unique files = 0x" << hex << (uint32)fileset.size() << dec << endl;
// WORKS GREAT!
// now let's read all these entries
ifstream filelist[4];
filelist[0].open("bigfile.000.tiger", ios::binary);
filelist[1].open("bigfile.001.tiger", ios::binary);
filelist[2].open("bigfile.002.tiger", ios::binary);
filelist[3].open("bigfile.003.tiger", ios::binary);
for(uint32 i = 0; i < entrylist.size(); i++)
{
cout << "Table Entry #0x" << hex << i << dec << endl;
for(uint32 j = 0; j < entrylist[i].sub2.size(); j++)
{
// file offset and size of data
uint32 offset = (entrylist[i].sub2[j].p02 & 0xFFFFFF00);
uint32 size = entrylist[i].sub2[j].p03;
// big file index
uint32 bigfile = (entrylist[i].sub2[j].p02 & 0xFF);
if(bigfile > 3) return error("Invalid bigfile index.");
// move to offset
filelist[bigfile].seekg(offset);
if(filelist[bigfile].fail()) return error("Seek failure.");
// read CDRM
uint32 magic = LE_read_uint32(filelist[bigfile]);
if(filelist[bigfile].fail()) return error("Read failure.");
if(magic != 0x4D524443) return error("Not a CDRM section.");
}
}
return 0;
}