Ducati World DC GT20 Header file

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
domingo
Posts: 83
Joined: Fri Aug 19, 2016 11:53 am

Ducati World DC GT20 Header file

Post by domingo »

Hello, I have extracted an IDX and IMG file and all the extracted files carry this header GT20, so I see they are compressed files.
Is there a tool or script to decompress and compress the files again?

Example

RCIMG.zip
domingo
Posts: 83
Joined: Fri Aug 19, 2016 11:53 am

Re: Ducati World DC GT20 Header file

Post by domingo »

Would a script be possible, if only to decompress?
I have discovered that the game also reads unzipped files, testing on the pc version
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Ducati World DC GT20 Header file

Post by aluigi »

If you know the correct compression algorithm... yes

I think this is the format of the file:

Code: Select all

comtype ???
idstring "GT20"
get SIZE long
get DUMMY long  # 3
get OFFSET long
get ZSIZE asize
math ZSIZE - OFFSET
get NAME basename
clog NAME OFFSET ZSIZE SIZE
domingo
Posts: 83
Joined: Fri Aug 19, 2016 11:53 am

Re: Ducati World DC GT20 Header file

Post by domingo »

Oh great, thank you so much Aluigi
domingo
Posts: 83
Joined: Fri Aug 19, 2016 11:53 am

Re: Ducati World DC GT20 Header file

Post by domingo »

Just today, I received these files from one of the game's programmers, perhaps with them it is possible to get a tool, or identify the algorithm

GTHDR.H file

Code: Select all

/*******************************************************************\
*                                                   *
*   GT Compression header file.                              *
*                                                   *
\*******************************************************************/

#ifndef _GTCOMPRESSION_H
#define _GTCOMPRESSION_H

/*********\
* Defines *
\*********/

#define COMPSIGNATURE   0x30325447      // GT20
#define NOCOMPSIGNATURE 0x54474f4e      // NOGT


/************\
* Structures *
\************/

typedef struct
   {
   UINT32 GTSignature;         // Signature DWORD
   UINT32 GTOrgSize;         // Uncompressed size
   UINT32 GTOverlap;         // Overlap for in-situ decompression
   UINT32 GTSkip;            // Number of bytes to skip to GT data
   }
   GTHEADER,
   * PGTHEADER;


/*********************\
* Function prototypes *
\*********************/

extern void *ungtc(UINT8 *, UINT8 *);

#endif


UNGTDC.C file

Code: Select all

/*******************************************************************\
*                                                   *
*   GT lossless compression system, multi platform C code.         *
*                                                   *
\*******************************************************************/

#ifdef _WINDOWS
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <stdlib.h>
#endif

#include "\dev\common\atd.h"
#include "\dev\common\gthdr.h"


#ifdef _WINDOWS
#define READINFOBIT(v,p,c) {v=*((UINT32 *)p)++;c=32;}
#define GETSRCWORD(v,p) v=*((UINT16 *)p)++
#else
#define READINFOBIT(v,p,c) {v=((*(p+3))<<24)+((*(p+2))<<16)+((*(p+1))<<8)+*p;p+=4;c=32;}
#define GETSRCWORD(v,p) v=*p++;v+=((*p++)<<8)
#endif

#define NEXTINFOBIT(v,p,c) v>>=1; if (!(--c)) READINFOBIT(v,p,c)



/*******************************************************************\
*                                                   *
*   GT32 decompressor written in C for porting speed and also for   *
*   decompression speed. Should still be faster than loading off   *
*   CD for most data.                                    *
*                                                   *
\*******************************************************************/

void *ungtc(UINT8 *GtPtr,UINT8 *DestPtr)
{
   register UINT32 InfoBits;
   register UINT16 InfoCnt;
   register UINT8 *CopySrc;
   register UINT16 CopyCnt;


   /*********************\
   * Advance Past Header *
   \*********************/

   GtPtr+=((PGTHEADER)GtPtr)->GTSkip;
   GtPtr+=sizeof(GTHEADER);


   /*******************\
   * Pre Read InfoBits *
   \*******************/

   READINFOBIT(InfoBits,GtPtr,InfoCnt);


   /*******************\
   * Process Forever ! *
   \*******************/

   while (1)
      {
      if (!(InfoBits & 1))
         {
         /*********\
         * Literal *
         \*********/

         *DestPtr++=*GtPtr++;
         }
      else
         {
         /****************\
         * Encoded String *
         \****************/

         NEXTINFOBIT(InfoBits,GtPtr,InfoCnt);

         if (InfoBits & 1)
            {
            /***************\
            * Medium String *
            \***************/

            GETSRCWORD(CopyCnt,GtPtr);
            CopySrc=DestPtr+((CopyCnt>>3) | 0xffffe000);

            if (CopyCnt = CopyCnt & 7)
               {
               CopyCnt+=2;
               }
            else
               {
               /***************\
               * Longer String *
               \***************/

               CopyCnt=*GtPtr++;

               if (CopyCnt & 128) CopySrc-=0x2000;

               CopyCnt &= 127;


               /*************************\
               * Check for Special Codes *
               \*************************/

               if(CopyCnt == 1) return(DestPtr);
               if(!CopyCnt)
                  {
                  GETSRCWORD(CopyCnt,GtPtr);
                  }
               else
                  {
                  CopyCnt+=2;
                  }
               }
            while (CopyCnt--) *DestPtr++=*CopySrc++;
            }
         else
            {
            /**********************************************\
            * Short String: 2-5 bytes long, up to 256 back *
            \**********************************************/

            CopySrc=DestPtr + (0xffffff00 | *GtPtr++);

            *DestPtr++=*CopySrc++;
            *DestPtr++=*CopySrc++;

            NEXTINFOBIT(InfoBits,GtPtr,InfoCnt);


            /***********************************\
            * InfoCnt MUST Be 1 Or Greater Here *
            \***********************************/

            if(InfoBits & 1)
               {
               *DestPtr++=*CopySrc++;
               *DestPtr++=*CopySrc++;
               }

            NEXTINFOBIT(InfoBits,GtPtr,InfoCnt);

            if(InfoBits & 1)
               {
               *DestPtr++=*CopySrc++;
               }
            }
         }
      NEXTINFOBIT(InfoBits,GtPtr,InfoCnt);
      }
}



In addition to this game, there are others that use this same compression system, such as Rollcage and Syberia2, I think I remember.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Ducati World DC GT20 Header file

Post by aluigi »

domingo
Posts: 83
Joined: Fri Aug 19, 2016 11:53 am

Re: Ducati World DC GT20 Header file

Post by domingo »

Brilliant!!! Works!!! Great job!!! :lol: