Fire Fight (1996) VOL archive format

Read or post about compression. And decompression. Or ask questions how to decompress your files.
Post Reply
alcexhim
ultra-n00b
Posts: 5
Joined: Tue Feb 05, 2013 2:37 pm
Has thanked: 2 times

Fire Fight (1996) VOL archive format

Post by alcexhim » Mon Mar 11, 2013 12:59 pm

Hey guys,

I'm trying to understand the format of the VOL archive (at least, I think it's an archive...) used in the Windows game Fire Fight. It's a pretty old game (1996), and the company who created it no longer exists, so I don't see any issue with posting a single VOL file for the talented people at XeNTaX to look at.

It's important to note that there appears to be long sequences of plain text (though not always in English, I believe the developers were Polish or something) that are sprinkled with other non-readable values (usually one or two bytes in length)... LZSS perhaps?

It seems like it would be relatively easy to decompress, but the LZSS code I have isn't working for me. Any ideas? Your help would be greatly appreciated!
You do not have the required permissions to view the files attached to this post.

WRS
ultra-veteran
ultra-veteran
Posts: 601
Joined: Fri Nov 06, 2009 12:13 am
Has thanked: 74 times
Been thanked: 134 times

Re: Fire Fight (1996) VOL archive format

Post by WRS » Mon Apr 01, 2013 9:42 am

as you note there are some compressed chunks

edit
found the demo online and finished the script

Code: Select all

# Fire Fight (1996) VOL extractor
# Script for QuickBMS by WRS (xentax.com)
# Rev 2

comtype COMP_LZRW1

get FSIZE asize
math FSIZE -= 20

# 20-byte header at end of file

goto FSIZE
get UNCOMPRESSED_SIZE long
get DATA_TO_READ long
get FILE_COUNT long
get FILE_LIST_OFFSET long
get VERSION long

# Version check made by client v1.2

if VERSION == 0x42024202
  print "Volume is uncompressed (unknown method)"
  cleanexit
elif VERSION == 0x43024202
  # expected version
else
  print "Unsupported volume (%VERSION%)"
  cleanexit
endif

get FNAME basename
math CURPOS = 0

log MEMORY_FILE 0 0
append

for CHUNK = 1
  goto CURPOS
  get CHUNKSIZE short
  math CURPOS += 2
  clog MEMORY_FILE CURPOS CHUNKSIZE 0xfffff
  math CURPOS += CHUNKSIZE
  if CURPOS >= FSIZE
    break
  endif
next CHUNK

append

get NFSIZE asize MEMORY_FILE

# confirms header values:
#  UNCOMPRESSED_SIZE == NFSIZE
# debug
#log "rawdump" 0 NFSIZE MEMORY_FILE


## parse the filelist

goto FILE_LIST_OFFSET MEMORY_FILE

for f = 0 < FILE_COUNT

  getdstring FITYPE 260 MEMORY_FILE
  getdstring FINAME 292 MEMORY_FILE
  get FISIZE long MEMORY_FILE
  get UNKNOWN long MEMORY_FILE # 0
  get FIOFFSET long MEMORY_FILE
  get UNKNOWN long MEMORY_FILE # 95
  get UNKNOWN long MEMORY_FILE # 0

  print "Extracting type %FITYPE% :"
  log FINAME FIOFFSET FISIZE MEMORY_FILE
  
next f


Useful tool links:

alcexhim
ultra-n00b
Posts: 5
Joined: Tue Feb 05, 2013 2:37 pm
Has thanked: 2 times

Re: Fire Fight (1996) VOL archive format

Post by alcexhim » Sun Apr 14, 2013 1:23 am

Hmmm... I knew there were bits that had been compressed, but I was having difficulty figuring out which compression method it was. According to your script, it's LZRW1... I started researching that, found out that it was invented around the early 1990s... with not many implementations, which is probably why I hadn't recognized it like DEFLATE or gzip.

Your BMS script works great! But one of the reasons I joined this forum (besides asking for help with this file format, which I've wanted to open up for years!) was to learn more about the art of reverse-engineering. So, if you don't mind me asking, how did you figure this one out? It would have never occurred to me to start looking for a "header" at the END of the file...

Also, I'd like to use your information to build an asset creation studio for this game (and probably others using the Chaos Works engine, though there is only one other game I know of by this studio and it's in Polish :lol: )

If it's okay with you, how should I credit you for your hard work?

Thank you for the assistance, it is greatly appreciated! :D

WRS
ultra-veteran
ultra-veteran
Posts: 601
Joined: Fri Nov 06, 2009 12:13 am
Has thanked: 74 times
Been thanked: 134 times

Re: Fire Fight (1996) VOL archive format

Post by WRS » Mon Apr 15, 2013 5:26 pm

I credit aluigi for starting my interest here - he has created some amazing tools - but this forum is packed with little challenges if you want to get started

I will direct you to the Wiki: http://wiki.xentax.com
And the definitive guide to exploring game resources: http://wiki.xentax.com/index.php?title=DGTEFF

So for the decompression routine

From a hex editor you could tell it was lzss-variant
I used a aluigi's comtype scanner script to figure out the compression http://aluigi.altervista.org/quickbms/comtype_scan.htm



Finding the header comes with experience

I try to describe all my variables when I document a format
This also typically helps understand where various sizes or offsets come from

Before I found the filelist I thought each chunk was a file until I found the file_size wasn't equal to the number of chunks. Once the data was decompressed you can figure out things like the size of each file list entry using simple math

Code: Select all

UNCOMPRESSED_SIZE - FILE_LIST_OFFSET / FILE_COUNT
The string sizes are non-standard, so that's something I likely have wrong but its often enough just to extract

I downloaded the game afterwards and found the version check. Sadly the routine exits when it hits an uncompressed file though.

For your program, please just link to XeNTaX somewhere in your credits :)
Useful tool links:

Post Reply