Rage Software XFS: Difference between revisions

From XentaxWiki
Jump to navigation Jump to search
imported>Ikskoks
imported>Ikskoks
 
(49 intermediate revisions by the same user not shown)
Line 3: Line 3:
* ''' Format Type ''':    Archive <br>  
* ''' Format Type ''':    Archive <br>  
* ''' [http://en.wikipedia.org/wiki/Endianness Endian Order] ''': Little Endian <br>
* ''' [http://en.wikipedia.org/wiki/Endianness Endian Order] ''': Little Endian <br>
 
* ''' Signature ''':    DID DAT\x1A <br>


=== Format Specifications ===  
=== Format Specifications ===  
Line 10: Line 10:
<pre>
<pre>
// XFS file format
// XFS file format
// E-racer DEMO PC


// little endian
// little endian
Line 27: Line 28:
4 bytes (uint32) - section ID // "2"
4 bytes (uint32) - section ID // "2"
4 bytes (uint32) - hash index offset
4 bytes (uint32) - hash index offset
32 bytes - padding?
32 bytes - reserved  // sections that are not used
                    // probably left for future engine development




//data section
// file data section
num_of_entries *
num_of_entries *
{
{
   4 bytes (uint32) - file size-8 / uncompressed file size
   4 bytes (uint32) - file size-8 / uncompressed file size
   4 bytes - compression flag? // "0" - uncompressed, "1" - compressed with RA compression
   4 bytes (uint32) - compression flag // "0" - uncompressed,  
                                        // "1" - compressed with RA compression
   x bytes - file data
   x bytes - file data
}
}




// DAT information section (?) (16 bytes)
// DAT information section (16 bytes)
4 bytes (uint32) - unknown // "12"
4 bytes (uint32) - section size-4 // "12"
4 bytes (uint32) - some size?
4 bytes (uint32) - number of hash entries-1 / number of files
8 bytes - nulls
8 bytes - nulls


// some structure (?)
// some data (?)
4 bytes (uint32) - section size
// Note: This section is not used by game at all.
//      It is probably some random padding data.
4 bytes (uint32) - section size-1
x bytes - data
x bytes - data


x bytes - hash index section
// hash index section (8 bytes per entry)
num_of_files+1 *
{
  4 bytes (uint32) - hash entry
  4 bytes (uint32) - file offset
}
</pre>
</pre>
</div>
</div>


=== MultiEx BMS Script ===  
=== quickBMS Script ===  


Not written yet.
* [https://aluigi.altervista.org/bms/rage_xfs.bms rage_xfs.bms]


=== Notes and Comments ===  
=== Notes and Comments ===  
Line 64: Line 74:
=== Related structures ===  
=== Related structures ===  
RA compressed data format:
RA compressed data format:
<div class="toccolours mw-collapsible" id="mw-customcollapsible-myDivision" style="width:800px; overflow:auto;">
<pre>
<pre>
// little endian
// little endian
Line 73: Line 84:
x bytes - compressed data
x bytes - compressed data
</pre>
</pre>
</div>
=== Hash calculation ===
Hash entries can be calculated using custom algorithm.
Below is Python implementation of it:
<div class="toccolours mw-collapsible" id="mw-customcollapsible-myDivision" style="width:800px; overflow:auto;">
<pre>
def calculate_eracer_hash(in_filename):
    len_filename = len(in_filename)
    curr_char_IDX = 0
    hash_part_LAST = 0
    curr_char = ""
    hash_part3 = 0
   
    for i in range(len_filename-1):
        if curr_char_IDX < len_filename:
            curr_char = int(ord(in_filename[i]))
            part_hash1 = curr_char + curr_char_IDX
            part_hash2 = curr_char + 7
           
            while 1:
                hash_part3 = part_hash1 * part_hash2 * (int(ord(in_filename[curr_char_IDX])) + 19) * (int(ord(in_filename[curr_char_IDX])) + curr_char_IDX)
                curr_char_IDX += 1
                hash_part_LAST += hash_part3
                if curr_char_IDX >= len_filename:
                    break
               
            curr_char_IDX = i
        curr_char_IDX += 1
   
    conv = int(str(hex(hash_part_LAST))[-8:], 16) # workaround!
    hash_part_LAST = conv
   
    OUT_HASH = hash_part_LAST % 0xEE6B2800
    return OUT_HASH
</pre>
</div>


=== Games ===  
=== Games ===  
Line 83: Line 131:
=== Compatible Programs ===  
=== Compatible Programs ===  


* [https://github.com/bartlomiejduda/Tools/blob/master/NEW%20Tools/E-racer/E-Racer_XFS_Tool.py E-Racer_XFS_Tool.py] (not finished)
* [https://github.com/bartlomiejduda/Tools/blob/master/NEW%20Tools/E-racer/ E-Racer_XFS_Tool.py]
* [https://forum.xentax.com/download/file.php?id=10517 DecompRA]
* [https://forum.xentax.com/download/file.php?id=10517 DecompRA]
<br/><br>
<br/><br>




[[Category:Complete Almost Done|Rage Software XFS]]
[[Category:Complete Complete|Rage Software XFS]]
[[Category:Platform PC|Rage Software XFS]]
[[Category:Platform PC|Rage Software XFS]]
[[Category:CE None|Rage Software XFS]]
[[Category:CE Compressed|Rage Software XFS]]
[[Category:Format_Archive | Type: Archive]]
[[Category:Format_Archive | Type: Archive]]
[[Category:Extension_xfs | Extension: xfs]]
[[Category:Extension_xfs | Extension: xfs]]
[[Category:BMS_None | BMS: None]]
[[Category:File Format]]
[[Category:File Format]]
[[Category:Custom compression]]
[[Category:Custom compression]]
[[Category:RA Compression]]
[[Category:RA Compression]]
[[Category:Hash]]

Latest revision as of 16:10, 3 January 2022

XFS

  • Format Type : Archive
  • Endian Order : Little Endian
  • Signature : DID DAT\x1A

Format Specifications

// XFS file format
// E-racer DEMO PC

// little endian

//header (16 bytes)
8 bytes (char) - magic // "DID DAT\x1A"
4 bytes (uint32) - section table checksum // "64" + "\xFF\xFF"
4 bytes (uint32) - section table size/8   // "8"   // 8*8=64

// section table (64 bytes)
4 bytes (uint32) - number of sections // "3"
4 bytes (uint32) - data start offset // "80"
4 bytes (uint32) - section ID // "0"
4 bytes (uint32) - data end offset / DAT info start offset
4 bytes (uint32) - section ID // "1"
4 bytes (uint32) - some structure offset
4 bytes (uint32) - section ID // "2"
4 bytes (uint32) - hash index offset
32 bytes - reserved  // sections that are not used
                     // probably left for future engine development


// file data section
num_of_entries *
{
   4 bytes (uint32) - file size-8 / uncompressed file size
   4 bytes (uint32) - compression flag  // "0" - uncompressed, 
                                        // "1" - compressed with RA compression
   x bytes - file data
}


// DAT information section (16 bytes)
4 bytes (uint32) - section size-4 // "12"
4 bytes (uint32) - number of hash entries-1 / number of files
8 bytes - nulls

// some data (?)
// Note: This section is not used by game at all.
//       It is probably some random padding data.
4 bytes (uint32) - section size-1
x bytes - data

// hash index section (8 bytes per entry)
num_of_files+1 *
{
   4 bytes (uint32) - hash entry
   4 bytes (uint32) - file offset
}

quickBMS Script

Notes and Comments

  • This file format occurs in games from Rage Software studio.
    It was probably designed by Digital Image Design before company was sold to Rage Games Limited.
  • This file format uses custom RA compression method which is implementation of LZ77-based algorithm.
  • XFS files seems to be enhanced version of "DID.DAT" archives from older Digital Image Design games.

Related structures

RA compressed data format:

// little endian

2 bytes (uint16) - magic // "RA"
2 bytes (uint16) - version // "\x00\x02"
2 bytes (uint16) - uncompressed file size
2 bytes (uint16) - checksum of the uncompressed data
x bytes - compressed data

Hash calculation

Hash entries can be calculated using custom algorithm. Below is Python implementation of it:

def calculate_eracer_hash(in_filename):
    len_filename = len(in_filename)
    curr_char_IDX = 0
    hash_part_LAST = 0
    curr_char = ""
    hash_part3 = 0
    
    for i in range(len_filename-1):
        if curr_char_IDX < len_filename:
            curr_char = int(ord(in_filename[i]))
            part_hash1 = curr_char + curr_char_IDX 
            part_hash2 = curr_char + 7
            
            while 1:
                hash_part3 = part_hash1 * part_hash2 * (int(ord(in_filename[curr_char_IDX])) + 19) * (int(ord(in_filename[curr_char_IDX])) + curr_char_IDX)
                curr_char_IDX += 1
                hash_part_LAST += hash_part3
                if curr_char_IDX >= len_filename:
                    break
                
            curr_char_IDX = i
        curr_char_IDX += 1
    
    conv = int(str(hex(hash_part_LAST))[-8:], 16) # workaround!
    hash_part_LAST = conv
     
    OUT_HASH = hash_part_LAST % 0xEE6B2800
    return OUT_HASH

Games

List of games using this file format:

  • E-Racer / eRacer
  • Rage Rally
  • Lamborghini (cancelled xbox game)
  • Eurofighter Typhoon

Compatible Programs