Page 1 of 1

Illusion Softworks (*.DTA) SFL Block Compression

Posted: Tue Mar 25, 2014 4:44 pm
by Ekey
Hi every one. I try make generic unpacker for old games by Illusion Softworks such as:
  • * Mafia - (DTA version ISD0) - Encrypted
    * Chameleon - (DTA version ISD1) - Encrypted
    * Hidden & Dangerous 2 - (DTA version ISD0) - Encrypted
    * Hidden & Dangerous 2 : Sabre Squadron - (DTA version ISD0 + ISD1) - Encrypted
    * Wings of War - (DTA version ISD1) - Not Encrypted
but need help with decompressing file datas. With comptype scanner i found compression method - it's SFL Block (#34). Ok here general info about structure DTA's , quick and crappy code.

Code: Select all

struct t_DTAHeader
{
   DWORD dwID; //Can be ISD0 and ISD1
   DWORD dwTotalFiles;
   DWORD dwTableOffset;
   DWORD dwTableSize;
};

struct t_DTATableEntry
{
   DWORD dwUnknown;
   DWORD dwOffsetAH;  // Offset for additional header
   DWORD dwOffsetFD;  // Offset for compressed file data
   char pFileNameHint[16];
};

// Additional header
struct t_DTA_AC_ISD1
{
    DWORD dwExtra1;
    DWORD dwExtra2;
    DWORD dwExtra3;
    DWORD dwExtra4;
    DWORD dwSize; // Decompressed size
    DWORD dwBlocksCount; // Nums of compressed block for current file data
    DWORD pExtra5;
    DWORD pFNameLength; // &0x7FFF (or you can use 2x short)
};
  
   DWORD dwTempPos = 0;
   t_DTAHeader pDTAHeader;
   t_DTATableEntry pDTATableEntry;
   t_DTA_AC_ISD1 pDTAACISD1;
   
   // Reading header
   fread(&pDTAHeader, sizeof(pDTAHeader), 1, fi);
   fseek(fi, pDTAHeader.dwTableOffset, SEEK_SET);
   
   for(int i = 0; i < pDTAHeader.dwTotalFiles; i++)
   {
      fread(&pDTATableEntry, sizeof(pDTATableEntry), 1, fi);
      fseek(fi, pDTATableEntry.dwOffsetAH, SEEK_SET);
	  

      // Read additional header
      fread(&pDTAACISD1, sizeof(pDTAACISD1), 1, fi);
      unsigned char* pFileName = new unsigned char[pDTAACISD0.pFNameLength & 0x7FFF];
      memset(pFileName, 0, pDTAACISD1.pFNameLength & 0x7FFF);
      fread(pFileName, sizeof(char), pDTAACISD1.pFNameLength & 0x7FFF, fi);
      dwTempPos = ftel(fi);
		 
      WORD wZSize;
      WORD wOSize = 0;
      WORD wUnknown;
		 
      unsigned char* pDstBuffer = new unsigned char[pDTAACISD1.dwSize];
      memset(pDstBuffer, 0, pDTAACISD1.dwSize);
      
      int pResult = 0;	 
      for(int j = 0; j < pDTAACISD1.dwBlocksCount; j++)
      {
            //Read compressed sizes after filename in additional header
            fseek(fi, dwTempPos, SEEK_SET);
            fread(&wZSize, 2, 1, fi);
            fread(&wUnknown, 2, 1, fi);
            dwTempPos = ftel(fi);
            
            unsigned char* pScrBuffer = new unsigned char[wZSize];
            memset(pScrBuffer, 0, wZSize);
            fseek(fi, pDTATableEntry.dwOffsetFD, SEEK_SET);
            fread(pScrBuffer, wZSize, 1, fi);
            pDTATableEntry.dwOffsetFD = ftel(fi);
			
            //https://github.com/imatix/gsl/blob/master/src/sflcomp.c
            wOSize = expand_block(pScrBuffer, pDstBuffer[pResult], wZSize);
            pResult = pResult + wOSize;
            free((void*) pScrBuffer);
      }
      //Save file... bla bla bla.....
   }
}
  

Well, 1st block decompressed fine, but with next blocks something wrong :( . Can someone help? Top secret files here from Wings of War.

Thanks advance for any hint :)

Re: Illusion Softworks (*.DTA) SFL Block Compression

Posted: Wed May 07, 2014 12:51 pm
by hdmaster
I already wrote a working generic unpacker but actually never released the sources [roll] . I'll post a link to source code here soon.
Although the DTA compression looks similar to SFL Block to me, it is a little bit different. Both use LZSS and RLE but DTA also uses some kind of differential pulse code modulation (DPCM) for WAV files.

EDIT: I've uploaded a quick & dirty VC++ 2013 sample project (uncommented): https://dl.dropboxusercontent.com/u/321 ... w_data.rar

Re: Illusion Softworks (*.DTA) SFL Block Compression

Posted: Fri May 09, 2014 2:27 pm
by Ekey
Interesting. Thanks for share :)

btw:

Chameleon

Code: Select all

bilboard0.dta    0xDE75DDF2      0xDEDC644B
bilboard1.dta    0xDE75DDF2      0xDEDC644B
bilboard2.dta    0xDE75DDF2      0xDEDC644B
isdata.dta       0xDE75DDF2      0xDEDC644B
Mafia

Code: Select all

bilboard0.dta   0xA1B2C3D4      0x23463458
bilboard1.dta   0xA1B2C3D4      0x23463458
bilboard2.dta   0xA1B2C3D4      0x23463458
isdata.dta      0xA1B2C3D4      0x23463458

Re: Illusion Softworks (*.DTA) SFL Block Compression

Posted: Wed Jun 25, 2014 2:22 pm
by huckleberrypie
What kind of encryption did Illusion use for Mafia and some of their other LS3D games? Also, what exactly does the Mafia DTA Extractor do to rw_data.dll, besides allowing loose archives to be read of course? Does it disable whatever signature or encryption flag the game imposes on things?

Re: Illusion Softworks (*.DTA) SFL Block Compression

Posted: Mon May 25, 2020 11:01 pm
by Habanero
Edit: Nevermind, I didn't see this thread when I searched (it showed up in Google instead). Thank you!

Oh nice, there's already a thread up for this. I wanted to extract Chameleon's music and sound (just started playing it -- nice game so far, underrated). I got a compiled EXE of huckleberrypie's unpacker that was posted by Ekey way back in 2015, but I'm getting a PATH error. How do I set the directory? Or is there another mistake I made? Additionally, if someone could reupload the source code for the unpacker for posterity's sake, that'd be appreciated. Thank you.

Image

By the way, here's some documentation on the format if anyone's interested.

http://www.kamalook.de/Mafia/DTA.html