Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

Rallisport Challenge 2 ".FA" (Xbox FlatArchive)

Featured Replies

  • Author
  • Localization

AMG, posted Tue Nov 24, 2015 7:04 pm (10068)


Hello,
I'm attaching an archive sample from RSC2
All the game data is packed in this format (.fa)
  • Author
  • Localization

aluigi, posted Tue Nov 24, 2015 10:02 pm (10070)


do you have another couple of samples containing different data?
  • Author
  • Localization

aluigi, posted Tue Nov 24, 2015 11:12 pm (10073)


This format is really horrible.
I guess it's the same or similar to the format used by Toca Race Driver for which, I remember, existed an extractor many years ago.

If you want to extract something you can use offzip but you miss filenames (that in any case use a sort of splitted scheme) and non-compressed data (a lot).
  • Author
  • Localization

AMG, posted Wed Nov 25, 2015 11:52 am (10099)


By any chance, is it similar to the Rallisport Challenge 1 format? (.rff)
Looks like it is packed the same way, but I might be wrong
I've attached an RSC1 example just for comparison
An extractor for ".rff" archives has been made years ago, I can attach it too if needed
  • Author
  • Localization

AMG, posted Wed Nov 25, 2015 3:52 pm (10104)


Yes, I knew about the RFFTool already, I just posted an ".rff" sample in case it could be helpful regarding the ".fa" format, by comparing it to ".rff" (hoping for similarities) :D
  • Author
  • Localization

aluigi, posted Wed Nov 25, 2015 3:58 pm (10107)


ah ok. no, it's totally different but I really remember that rc2 format used in other old games like Toca (the splitted filenames) but that's the max I remember.
  • Author
  • Localization

aluigi, posted Mon Mar 14, 2016 9:46 am (11971)


no
  • Author
  • Localization

AMG, posted Wed Apr 12, 2017 11:31 pm (22173)


Any hopes for a script about this format?
It would be really useful :cry:
  • Author
  • Localization

AnonBaiter, posted Sun Apr 23, 2017 9:52 pm (22583)


Perhaps it would be better to just decompress the whole .fa archive from the start, if the whole archive is compressed that is.
Actually, the 0x04 location of an .fa archive implies that the zlib file is actually just an index.

Anyway, here`s my WIP script:
Code:
open FDDE "fa" 0

get INDEX_SIZE long
get DUMMY2 long
savepos INDEX_OFFSET
xmath INDEX_ZSIZE "INDEX_SIZE * (2 * 8)"
putarray 0 i INDEX_ZSIZE

clog MEMORY_FILE INDEX_OFFSET INDEX_SIZE INDEX_ZSIZE
  • Author
  • Localization

aluigi, posted Sun Apr 23, 2017 10:15 pm (22584)


This is a classical job for offzip, just as I said 2 years ago.
Maybe with the -c 0x20000 option because the files "may" be chunked.

The reason is simple, you have a TOC (information about the archived files) which is compressed and located at offset 8 after the size of compressed TOC 8 and the size of alignment (0x800). The problem is the format of this TOC which is chaotic and messed up so if you have time and experience feel free to reverse engineer that format, otherwise go easy with offzip and get most of the archive with nameless files and zero time wasted.

The solution already exists from 2 years.
  • Author
  • Localization

AnonBaiter, posted Mon Apr 24, 2017 3:45 pm (22612)


Sorry for not listening to you, but it seems like I'm already there and almost done with the format.

The only formats which used messy TOC I can think of is Dragon Quest VIII(PS2), Rogue Galaxy, and these big .PAK files that came out of SCEE PS2 games(and with lz-like compression, even!).
  • Author
  • Localization

aluigi, posted Mon Apr 24, 2017 3:56 pm (22613)


I forgot to add @AMG in my previous post :)
Good to know that you are working on this format and I hope you will solve the mistery of that TOC
  • Author
  • Localization

AnonBaiter, posted Mon Apr 24, 2017 4:03 pm (22615)


aluigi wrote:
Good to know that you are working on this format and I hope you will solve the mistery of that TOC
I hope so.
Code:
# Rallisport Challenge 2 (Xbox)
# TODO:
# 1. Decompression.
# 2. Directory tree support.

open FDDE "fa" 0

comtype deflate_noerror
get INDEX_SIZE long
get PAD_OFF long
get B1 byte
get B2 byte
savepos INDEX_OFFSET
xmath INDEX_ZSIZE "PAD_OFF * 4"
putarray 0 i INDEX_ZSIZE

clog MEMORY_FILE INDEX_OFFSET INDEX_SIZE INDEX_ZSIZE
get VER byte MEMORY_FILE
get FILES threebyte MEMORY_FILE
get FOLDERS short MEMORY_FILE
get DUMMY01 short MEMORY_FILE
for i = 0 < FOLDERS
   get SUB_ENTRIES short MEMORY_FILE
   get ENTRIES short MEMORY_FILE
   get DUMMY06 short MEMORY_FILE
   get DUMMY07 short MEMORY_FILE
   getdstring NAME 0x18 MEMORY_FILE
next i
for i = 0 < FILES
   get DUMMY09 longlong MEMORY_FILE
   get OFFSET long MEMORY_FILE
   get SIZE long MEMORY_FILE
   get BASE_OFF short MEMORY_FILE
   get CHUNKS short MEMORY_FILE
   getdstring NAME 0x2c MEMORY_FILE
   math OFFSET PAD_OFF
   putarray 1 i OFFSET
   putarray 2 i SIZE
   putarray 3 i BASE_OFF
   putarray 4 i CHUNKS
   putarray 5 i NAME
next i

for i = 0 < FILES
   getarray OFFSET 1 i
   getarray SIZE 2 i
   getarray BASE_OFF 3 i
   getarray CHUNKS 4 i
   getarray NAME 5 i
   putvarchr MEMORY_FILE2 SIZE 0
   log MEMORY_FILE2 0 0 MEMORY_FILE
   append
   for x = 0 < CHUNKS
      get CHUNK_SIZE long MEMORY_FILE
      get CHUNK_ZSIZE long MEMORY_FILE
      get CHUNK_OFFSET long MEMORY_FILE
      get CHUNK_ZOFFSET long MEMORY_FILE
      # in case the decompression fails, just use offzip instead(with "-a -c 0x20000" parameters)
      /*
      if CHUNK_ZSIZE == CHUNK_SIZE
         log MEMORY_FILE2 CHUNK_OFFSET CHUNK_SIZE MEMORY_FILE
      else
         clog MEMORY_FILE2 CHUNK_OFFSET CHUNK_SIZE CHUNK_ZSIZE MEMORY_FILE
      endif
      */
   next x
   append
#   log MEMORY_FILE 0 SIZE MEMORY_FILE2
#   log NAME 0 SIZE MEMORY_FILE
next i
The attached .txt file is what I got so far. Decompression though is another story...
  • Author
  • Localization

AMG, posted Mon May 22, 2017 9:27 am (23403)


Hi there, I'm back with useful informations about the format, from my friend Yallis.
He's working on his own tool for decompressing this format, but as he said, at the moment it doesn't work on all .FA files since he only examined few smaller files for now.

Anyway, here's the main .FA file layout:

Quote:
uint32 compressedHeaderSize;
uint32 blockDataOffset;
byte compressedHeader[compressedHeaderSize];
byte blockData[...];

The header data is a DEFLATE compressed stream. The inflated header has
a list of nested directories with files. The files in turn consists of
a list of blocks which are DEFLATE compressed chunks in the blockData
section of the main file. When inflated these blocks are concatenated to
construct the extracted files.

This is the structure of the uncompressed header:

byte unknown0;
uint16 fileCount;
byte unknown1;
uint16 directoryCount;
uint16 blockCount;

struct Directory {
uint16 directoryCount;
uint16 fileCount;
uint16 firstFile;
uint16 firstDirectory;
char name[24];
} directories[directoryCount]

struct File {
FILETIME time;
uint32 offset;
uint32 uncompressedSize;
uint16 firstBlock;
uint16 blockCount;
char name[44];
} files[fileCount]

struct Block {
uint32 compressedSize;
uint32 uncompressedSize;
uint32 compressedOffset;
uint32 uncompressedOffset;
} blocks[blockCount];


Hoping these infos will be useful for understanding the format compression.
  • Author
  • Localization

AnonBaiter, posted Mon May 22, 2017 1:03 pm (23417)


OK, I updated the script this time.

But what about the chunks? If the header is a DEFLATE compressed stream, then how come the rest of the files have a zlib header? Perhaps you could direct that question to your friend.
  • Author
  • Localization

AnonBaiter, posted Mon May 22, 2017 1:28 pm (23419)


Whoa! I hope my VM machine will handle enough memory for this.

Oh and are the full filenames supposed to be like this? Or maybe it`s just my VM?
Code:
- open input file G:\MICROSOFT\XBOX\RALLISPORT_CHALLENGE_2\Layer0\Cars.fa
- open script G:\MICROSOFT\XBOX\RALLISPORT_CHALLENGE_2\rallisport_challenge_2.bm
s
- c_structs (1): "uint32" "compressedHeaderSize"
- c_structs (1): "uint32" "blockDataOffset"
- c_structs (2): "byte" "unknown0" "MEMORY_FILE10"
- c_structs (2): "uint16" "fileCount" "MEMORY_FILE10"
- c_structs (2): "byte" "unknown1" "MEMORY_FILE10"
- c_structs (2): "uint16" "directoryCount" "MEMORY_FILE10"
- c_structs (2): "uint16" "blockCount" "MEMORY_FILE10"
- c_structs (2): "uint16" "directoryCount" "MEMORY_FILE10"
- c_structs (2): "uint16" "fileCount" "MEMORY_FILE10"
- c_structs (2): "uint16" "firstFile" "MEMORY_FILE10"
- c_structs (2): "uint16" "firstDirectory" "MEMORY_FILE10"
- c_structs (2): "char" "name[24]" "MEMORY_FILE10"
- c_structs (2): "FILETIME" "time" "MEMORY_FILE10"
- c_structs (2): "uint32" "offset" "MEMORY_FILE10"
- c_structs (2): "uint32" "Size" "MEMORY_FILE10"
- c_structs (2): "uint16" "firstBlock" "MEMORY_FILE10"
- c_structs (2): "uint16" "blockCount" "MEMORY_FILE10"
- c_structs (2): "char" "name[44]" "MEMORY_FILE10"
- c_structs (2): "uint32" "compressedSize" "MEMORY_FILE10"
- c_structs (2): "uint32" "uncompressedSize" "MEMORY_FILE10"
- c_structs (2): "uint32" "compressedOffset" "MEMORY_FILE10"
- c_structs (2): "uint32" "uncompressedOffset" "MEMORY_FILE10"
- set output folder G:\MICROSOFT\XBOX\RALLISPORT_CHALLENGE_2\Layer0

  offset   filesize   filename
--------------------------------------
  00000000 176128     ///cars/a110alpine/accent/accentrc/astrair/astrarc/beetler
si/bmw318/celicab/celicahc/cordoba/corolla/deltas4/focussvt/gt70/imprezahc/impre
zawrx/lancere65hc/lancere6rc/lancere8/lancia037/megane/metro/micra/octavia/peuge
ot205/peugeot206/peugeot306/peugeot405hc/puma/quattros1/quattros1hc/r5turbo/rs20
0/rs200rc/saab93hc/saab93rc/stratos/tacoma/vitarahc/volvo240/volvos40/xsara/xsar
arc/mesh/dirtdust.res

- it's not possible to create that file due to its filename or related
  incompatibilities (for example already exists a folder with that name), so
  now you must choose a new filename for saving it.
  if you press ENTER a new name will be generated automatically.
  - old: cars\a110alpine\accent\accentrc\astrair\astrarc\beetlersi\bmw318\celica
b\celicahc\cordoba\corolla\deltas4\focussvt\gt70\imprezahc\imprezawrx\lancere65h
c\lancere6rc\lancere8\lancia037\megane\metro\micra\octavia\peugeot205\peugeot206
\peugeot306\peugeot405hc\puma\quattros1\quattros1hc\r5turbo\rs200\rs200rc\saab93
hc\saab93rc\stratos\tacoma\vitarahc\volvo240\volvos40\xsara\xsararc\mesh\dirtdus
t.res
  - new: ^C
  • Author
  • Localization

AnonBaiter, posted Mon May 22, 2017 1:54 pm (23422)


Sorry for the doublepost, but this is the file that refuses to work with the script:
TrackMisc.rar
  • Author
  • Localization

aluigi, posted Mon May 22, 2017 2:08 pm (23424)


Yeah sorry a mistake I made while I was trying to "optimize" the script before the release.plus a new thing not available in the previous samples.
Script 0.1.1
  • Author
  • Localization

aluigi, posted Mon May 22, 2017 2:15 pm (23425)


Is it necessary also a script for the res archives? I can add it in the current script on the fly
Guest
This topic is now closed to further replies.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.