Wednesday, July 3, 2013

Anno 1602

This post is an introduction to the game Anno 1602, that I'm going to study during the next blog post.


Anno 1602: Creation of a New World is a game with both real time strategyand city building elements, developed by Max Design. It's a game like "Caesar", "Colonization", "Constructor", "Exploration".
This is game is an Abandonware, so you can download it for free.
 PS C:\> Get-ChildItem "C:\Games\ANNO 1602 Version Gold" -Include *.* -Recurse | Select-Object Extension | Sort-Object -Property Extension -Unique  
 Extension  
 ---------  
 .BSH  
 .cod  
 .COL  
 .dat  
 .dll  
 .EXE  
 .GAD  
 .INC  
 .pdf  
 .rtf  
 .SCP  
 .smk  
 .szm  
 .szs  
 .WAV  
 .ZEI  

  • .BSH
  • .cod
  • .COL
  • .dat
  • .dll
  • .EXE
  • .GAD
  • .INC
  • .pdf
  • .rtf
  • .SCP
  • .smk
  • .szm
  • .szs
  • .WAV
  • .ZEI

Tuesday, July 2, 2013

Desperados : Wanted Dead or Alive - .sxt files

List of files with extension .sxt :

 PS F:\> $Dir = get-childitem -recurse F:\Game\Infogrames\Desperados\Game  
 PS F:\> $List = $Dir | where {$_.extension -eq ".sxt"}  
 PS F:\> $List | ft fullname | Format-Table  
 FullName  
 --------  
 F:\Game\Infogrames\Desperados\Game\Data\Interface\Debriefing\GameOver1.sxt
 F:\Game\Infogrames\Desperados\Game\Data\Interface\Debriefing\GameOver2.sxt
 F:\Game\Infogrames\Desperados\Game\Data\Interface\Debriefing\Victory.sxt

Example : GameOver2.xst


Size file : 13 954 bytes (0x3682)

 Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  
 00000000   23 01 7E 00 01 00 00 00 76 36 00 00 78 9C ED 7D #.~.....v6..xϒ}  
 00000010   4D 74 1A 67 9A 2E 63 50 95 8C ED 44 E9 F4 9C A3 Mt.gš.cP•ŒíDéôœ£  

Format specification :

+0x00 : Width = 0x0123
+0x02 : Height = 0x007E
+0x04 : IsCompressed = 0x00000001  
+0x08 : SizeCompressedData = 0x00003676  
Then the data are simply image in 16 bits format, view this POST for more info.

GameOver1.sxt

GameOver2.sxt

Victory.sxt


Desperados : Wanted Dead or Alive - RDO Resource

Inside .res file there is 'RDO ' (0x204F4452, notice the space at the end) entry resources.
Those resources can be managed like PICC, this type is like TOLG but notice the loop iteration (7 <> 5)

Pseudo-Code

  unknow = read(4)    
  if (magic_number == 0x204F4452):    
   a = read(4)   
   b = read(4)   
   for i in xrange(0, 7):   
    if ((1 &lt;&lt; i) &amp; b):   
     width = read(4)    
     height = read(4)    
     is_compressed = read(4)    
     size = read(4)    
     data = read(size)    
     if is_compressed == 1:    
      data = zlib.decompress(data)    
Data is still 16bits image.
Few extracted images :




Desperados : Wanted Dead or Alive - SLID Resource

Inside .res file there is 'SLID' (0x44494C53).
Those resources are exactly the same things as NPTF.

Few extracted images :




Desperados : Wanted Dead or Alive - NPTF Resource

Inside .res file there is 'NPTF' entry resources.
Those resources can be managed like PICC, this type is like TOLG but notice the loop iteration (6 <> 5)

Pseudo-Code

  magic_number = read(4)   
  unknow = read(4)   
  if (magic_number == 0x4E545442):   
   a = read(4)  
   b = read(4)  
   for i in xrange(0, 6):  
     if ((1 << i) & b):  
       width = read(4)   
       height = read(4)   
       is_compressed = read(4)   
       size = read(4)   
       data = read(size)   
       if is_compressed == 1:   
         data = zlib.decompress(data)   
Data is still 16bits image.
Few extracted images :




Desperados : Wanted Dead or Alive - WAVE Resource

Inside .res file there is 'WAVE' (0x45564157) entry resources.
Those resources can be managed like TEXT, the only difference is that string are not of type wchar_t.

WAVE specification

 +0x00 : Unknow_00 (Maybe index)  
 +0x04 : Nb entry Text  
 +0x06 : Size Entry  
 +0x08 : Buffer [Size Entry]   

Pseudo-Code

  magic_number = read(4)    
  unknow = read(4)    
  if (magic_number == 0x45564157):    
   unknow = read(4)    
   nb_TEXT_entry = read(2)    
   for i in xrange(0, nb_TEXT_entry ):    
   size_str = read(2)    
   str = read(size_str)  
Few extracted path :
 Dialogues\Phase1.wav  
 Dialogues\Phase2.wav  
 Dialogues\Phase3.wav  
 Dialogues\Phase4.wav  
 Dialogues\Phase5.wav  
 Dialogues\Phase6.wav  
 Dialogues\Phase7.wav  
 Dialogues\Phase8.wav  
 Dialogues\Phase9.wav  
 Dialogues\PhaseFake.wav  

Desperados : Wanted Dead or Alive - TEXT Resource

Inside .res file there is 'TEXT' (0x54584554) entry resources.

TEXT specification

 +0x00 : Unknow_00 (Maybe index)  
 +0x04 : Nb entry Text  
 +0x06 : Size Entry  
 +0x08 : wchar_t Buffer [Size Entry]   

Pseudo-Code

  magic_number = read(4)   
  unknow = read(4)   
  if (magic_number == 0x54584554):   
   unknow = read(4)   
   nb_TEXT_entry = read(2)   
   for i in xrange(0, nb_TEXT_entry ):   
    size_str = read(2)   
    str = read(size_str * 2)  
Few extracted strings :
 Bonjour vous tes avec le professeur Oscar Toffel pour votre 746ime leon de patois  
 Entrainez vous rptez la phrase qui suit puis enregistrez vous sur K7 et envoyez la nous donc.  
 Le meilleur accent il gagnera un disque.  
 Attention rptez aprs moi.  
 Truc incomprhensible, si vous comprenez envoyez moi une carte postale.  
 Allez ! Encore une fois pour voir.  
 Oh lalala ca c'est donc pas facile.  
 Tais toi donc et bosse un petit peu ! Rptes cette phrase non di diou  
 Allez la balle est dans votre camp maintenant, a vous de jouer. Bonne Chance.  
 Je vais pouvoir rcuprer mon matriel.  
 J'ai laiss mes clefs dans la cariole, peut tre qu'en crochetant la porte...  
 Attention ! Sam ! Derriere-toi il y a un crocodile !  
 Je vais essayer de l'endormir l'aide de mes fioles.  
 Est-ce que c'est vraiment efficace ? Je suis curieux de voir a...  
 Je vais te faire un pansement, un bisou sur le bobo et tout ira bien.  
 A quoi sert le porte manteau qu'il y a dans ton sac ?  
 Ca sert a tromper les cowboys qui veulent ma peau.  
 Pour les fioles, je peux mme endormir une cible lointaine.  
 Debout Sam ! Il est temps de se remettre en route mais auparavant, montres moi de quoi tu es capables.  
 Peut-tu faire exploser prcisement ton baton de dynamite de l'autre ct de la rivire ?  
 Belle chute.. On ferait mieux de le ligoter avant de le cacher.  
 Arrtes, on en aura peut-tre besoin plus tard, pour piger les ennemis ou effrayer les chevaux.  
 Le chemin est bloqu...  ...je m'en occupe, je vais tout dblayer...  
 WAHAHAHAHAHAHAHAHAHAH !  
 Nous voila, devant La Fortezza, la prison la plus sure de cet tat.  
 Et c'est ici ou ils ont emprisonne Sanchez. Mais on va le dlivrer...  
 Je ne comprends pas: On a fait pas mal d'efforts pour trouver ce bandit et pour le mettre sous les verroux.  
 Mais maintenant tu dis que l'on va le liberer de nouveau. Il est tout coup devenus ton pote, ou quoi?  

Desperados : Wanted Dead or Alive - CUR Resource

Inside .res file there is 'CUR ' (notice the space at the end) entry resources.
Those resources can be managed like PICC.

Pseudo-Code

  magic_number = read(4)   
  unknow = read(4)   
  if (magic_number == 0x20525543):   
   unknow_1 = read(4)  
   unknow_2 = read(2)  
   unknow_3 = read(2)  
   unknow_4 = read(2)  
   unknow_5 = read(2)  
   nb_CUR_entry = read(4)   
   for i in xrange(0, nb_CUR_entry ):   
    width = read(4)   
    height = read(4)   
    is_compressed = read(4)   
    size = read(4)   
    data = read(size)   
    if is_compressed == 1:   
     data = zlib.decompress(data)   
Data is still 16 bits image.
Few extracted images :




Desperados : Wanted Dead or Alive - BTTN Resource

Inside .res file there is 'BTTN' entry resources.
Those resources can be managed like PICC, this type is like TOLG but notice the loop iteration (4 <> 5)

Pseudo-Code

  magic_number = read(4)   
  unknow = read(4)   
  if (magic_number == 0x4654504E):   
   a = read(4)  
   b = read(4)  
   for i in xrange(0, 4):  
     if ((1 << i) & b):  
       width = read(4)   
       height = read(4)   
       is_compressed = read(4)   
       size = read(4)   
       data = read(size)   
       if is_compressed == 1:   
         data = zlib.decompress(data)   
Data is still 16bits image.
Few extracted images :




Desperados : Wanted Dead or Alive - TOGL Resource

Inside .res file there is 'TOGL' entry resources.
Those resources can be managed like PICC, but with few differences.

Pseudo-code

  magic_number = read(4)   
  unknow = read(4)   
  if (magic_number == 0x4C474F54):   
   a = read(4)  
   b = read(4)  
   for i in xrange(0, 5):  
     if ((1 << i) & b):  
       width = read(4)   
       height = read(4)   
       is_compressed = read(4)   
       size = read(4)   
       data = read(size)   
       if is_compressed == 1:   
         data = zlib.decompress(data)   
Data is still 16 bits image.
Few extracted images :




Desperados : Wanted Dead or Alive - PIC Resource

Inside .res file there is 'PIC ' (notice the space at the end) entry resources.
Those resources can be managed like PICC.
The only difference is this resource got only one entry.

Pseudo-code

  magic_number = read(4)   
  unknow = read(4)   
  if (magic_number == 0x20434950):   
   unknow = read(4)   
   width = read(4)   
   height = read(4)   
   is_compressed = read(4)   
   size = read(4)   
   data = read(size)   
   if is_compressed == 1:   
     data = zlib.decompress(data)   
Data is still 16 bits image.
Few extracted images :







Desperados : Wanted Dead or Alive - PICC Resource

Inside .res file there is 'PICC' entry resources.

PICC specification

 +0x00 : Unknow  
 +0x04 : Nb PICC entry  
 +0x08 : Entry Data (view class CResEntry)  

CResEntry

An entry can be represented by this structure :
 00000000 CResEntry    struc ; (sizeof=0xC)  
 00000000 Width      dw ?  
 00000002 Height     dw ?  
 00000004 IsCompressed  dd ?  
 00000008 SizeFile    dd ?  
 0000000C CResEntry    ends  
If the field IsCompressed is set to 1, data are compressed using zlib version 1.1.3.

Pseudo-Code to read PICC

 magic_number = read(4)  
 unknow = read(4)  
 if (magic_number == 0x43434950):  
   unknow = read(4)  
   nb_PICC_entry = read(4)  
   for i in xrange(0, nb_PICC_entry):  
     width = read(4)  
     height = read(4)  
     is_compressed = read(4)  
     size = read(4)  
     data = read(size)  
     if is_compressed == 1:  
       data = zlib.decompress(data)  
Then the data are simply image in 16 bits format, you can convert it into 24 bits, with the following pseudo-code :
 void setRGB(png_byte *ptr, unsigned char r,   
                unsigned char g, unsigned char b)  
 {  
     ptr[0] = r;  
     ptr[1] = g;  
     ptr[2] = b;  
 }  
 ...  
 int x, y;  
 for (y = 0 ; y < height ; y++)  
 {  
     for (x = 0 ; x < width ; x++)  
     {  
         int a;  
         unsigned short *tab;  
         unsigned short color;  
         a = = (x + (y * width)) * 2;  
         tab = (unsigned short*)(buffer + a);  
         color = *tab;  
         setRGB(&(row[x * 3]),   
                     (color >> 11 << 8) / 32,   
                     (((color >> 5) & 0x3F) << 8) / 64,   
                     ((color & 0x1F) << 8) / 32);  
     }  
     png_write_row(png_ptr, row);  
 }  

Monday, July 1, 2013

Desperados : Wanted Dead or Alive - Extracted Resources

Some randoms resources that I managed to extract :





more info coming soon...

Desperados : Wanted Dead or Alive - .res / .RES files

List of files with extension .res or .RES :
 PS F:\> $Dir = get-childitem -recurse F:\Game\Infogrames\Desperados\Game  
 PS F:\> $List = $Dir | where {$_.extension -eq ".res"}  
 PS F:\> $List | ft fullname | Format-Table  
 FullName  
 --------  
 F:\Game\Infogrames\Desperados\Game\Data\Interface\DEFAULT.RES  
 F:\Game\Infogrames\Desperados\Game\Data\Interface\Texts.res  
 F:\Game\Infogrames\Desperados\Game\Data\Sounds\Expressions\Expressions.res  

Method to open .res file :
 005D8270 ReadResFile proc near  

File format specification

 +0x00 : Magic Number  
 +0x04 : Archive Version  
 +0x08 : Nb Entry  
 +0x0C : Format  
 +0x10 : Unknow_0  
 ....
Magic number must be equal to 0x53455253 ('SERS').
ArchiveVersion must be equal to 0x100 (256).
Format can be equal to :

  • 0x45564157 ('EVAW') : 0x005D96A0 WaveResFile proc near
  • 0x43434950 ('CCIP') : 0x005D8D50 PiccResFile proc near
  • 0x44494C53 ('DILS') : 0x005DA0E0 SlidResFile proc near
  • 0x20525543 (' RUC') : 0x005D9CA0 CurResFile proc near
  • 0x20434950 (' CIP') : 0x005D8A10 PicResFile proc near
  • 0x204F4452 (' ODR') : 0x005DA800 RdoResFile proc near
  • 0x4E545442 ('NTTB') : 0x005DA470 BttnResFile proc near
  • 0x4654504E ('FTPN') : 0x005D8630 NptfResFile proc near
  • 0x4C474F54 ('LGOT') : 0x005DAB90 ToglResFile proc near
  • 0x54584554 ('TXET') : 0x005D90B0 TextResFile proc near
Refer to other articles to understand each entry type.

Sunday, June 30, 2013

Desperados : Wanted Dead or Alive - Files Extension

All files extensions find inside game folder :

 PS > Get-ChildItem -recurse F:\Game\Infogrames\Desperados\Game\* | Select-Object Extension | Sort-Object Extension | Get-Unique -asString  
 Extension  
 ---------  
 .cfg  
 .cpg  
 .dat  
 .dll  
 .dvd  
 .dvf  
 .dvm  
 .exe  
 .fnt  
 .fxg
 .log  
 .map  
 .pak  
 .res  
 .RES  
 .sbk  
 .scb  
 .stf  
 .sxt  
 .tmp  
 .wav