Outils pour utilisateurs

Outils du site


back2root:reverse-engineering:planet-x3:part2-savegame_dat

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
back2root:reverse-engineering:planet-x3:part2-savegame_dat [2023/01/12 09:16] fraterback2root:reverse-engineering:planet-x3:part2-savegame_dat [2023/01/17 09:07] (Version actuelle) frater
Ligne 1: Ligne 1:
-====== Format of "savegame.dat" ======+====== Planet X3 - Format of "savegame.dat" ======
  
 Ce fichier est un "dump mémoire" du jeu, il n'est pas compressé ni crypté; on y retrouve la meme structure que dans le code source. Ce fichier est un "dump mémoire" du jeu, il n'est pas compressé ni crypté; on y retrouve la meme structure que dans le code source.
  
 +Le fichier est composé de 3 "blocs" de données:
  
 +  * 1 [[#blockmap|block]] de 32 Kb (0x8000 bytes) avec la carte en cours
 +  * 1 [[#blockunit|block]] de 2560 bytes (0x1010 bytes) contenant les unités/batiments des 2 factions
 +  * 1 [[#blocktimer|block]] de 5 bytes (0x0005 bytes) contenant principalement les timers du jeu.
  
 +une sauvegarde fait donc TOUJOURS 36885 bytes
  
 +===== Function de sauvegarde/chargement =====
 +
 +Dans le code source, la sauvegarde se fait <color #ed1c24>**uniquement**</color> dans le fichier ''SAVEGAME.DAT''.
 +
 +<code asm>
 +Game_WriteSaveGame:
 + MOV AH,0x3c ; bug no mod selected : random ?
 + MOV CX,0x0
 + MOV DX,fname_SaveGame_DAT ; = "SAVEGAME.DAT"
 + MOV AH,0x3c
 + INT 0x21 ; Create/truncate file
 + JC exitError ; exit function without handling
 + MOV [fhandler_SaveGame],AX ; preserve file handler
 +     JMP continue
 +exitError: RET
 +</code>
 +On découvre ici que cette fonction ne gère **aucune** erreur, la sauvegarde est simplement abandonnée en cas d'erreur d'ouverture de fichier.
 +
 +L'usage du **JMP** pour sauter au dessus du **RET** d'erreur ressemble beaucoup à une structure de gestion d'erreurs (qui a été éliminée de la version finale) propre aux processeurs sans caches (8088, 8086, 6502, etc).
 +
 +Personnellement, je n'aurais pas rompu le flux avec un **JMP** j'aurais placé la gestion (ou non) des erreurs à la fin de la fonction, et réservé le saut (rupture de flux) aux erreurs, afin de ne pas forcer un "flush cache" sur des processeurs plus puissant (x386 et suivant).
 +
 +<code asm>
 +continue: MOV BX,word ptr [fhandler_SaveGame] ; fhandler
 +
 + ; save current game map
 + MOV DX,0x0
 + MOV CX,0x8000 ; 0x8000 = 256*128 
 + MOV AH,0x40
 + PUSH DS ; switch to map's Segment
 + MOV DS,word ptr [g_Seg_GameMap]
 + INT 0x21 ; write map (32kb)
 + POP DS ; restore DS
 +</code>
 +
 +la carte du jeu est sauvegardée "tel quel" sans aucune encryption ni compression.
 +
 +<code asm>
 + ; save unit/building records
 + MOV BX,word ptr [fhandler_SaveGame]
 + MOV DX,Game_UnitsArr_Type
 + MOV CX,0x1010 ; Write 256 units/buildings (10 attributes)
 + MOV AH,0x40
 + INT 0x21
 +</code>
 +
 +Pareil pour la structure des unités/batiments, sauvegardée "tel quel" sans aucune encryption ni compression.
 +
 +<code asm>
 + ; save Ingame timers
 + MOV BX,word ptr [fhandler_SaveGame]
 + MOV DX,Timer_InGame_Counter
 + MOV CX,0x5 ; 1 word (total seconds) + 3 bytes (Hours:minutes:seconds)
 + MOV AH,0x40
 + INT 0x21
 +</code>
 +
 +Avant de fermer le fichier, Planet X3 sauvegarde le compteur de temps générale (1 mot) et le temps "en jeu" 3 bytes
 +
 +<code asm>
 + MOV AH,0x3e ; close file
 + MOV BX,word ptr [fhandler_SaveGame]
 + INT 0x21
 + RET
 +</code>
 +
 +===== Block Map =====
 +{{anchor:blockmap}}
 +{{tablelayout?rowsHeaderSource=Auto&colwidth=""}}
 +^  Offset  ^  Size    Description  ^
 +| 0x0000   | 0x8000  | Carte         |
 +| 0x8000   | 0x1010  | Unités/batiments |
 +| 0x9010   | 0x0005  | timers  |
 +
 +==== Block d'unités/Batiments =====
 +{{anchor:blockunit}}
 +{{tablelayout?rowsHeaderSource=Auto&colwidth="83px,,413px"}}
 +^  Offset  ^  Size    ^  Description             ^
 +| +0x0000  |  0x0100  | Type d'Unités/batiments  |
 +| +0x0100  |  0x0100  | Position X               |
 +| +0x0200  |  0x0100  | Position Y               |
 +| +0x0300  |  0x0100  | Target X                 |
 +| +0x0400  |  0x0100  | Target Y                 |
 +| +0x0500  |  0x0100  | OOT Type                 |
 +| +0x0600  |  0x0100  | Unknow                   |
 +| +0x0700  |  0x0100  | Points de Vie            |
 +| +0x0800  |  0x0100  | Unknow                   |
 +| +0x0900  |  0x0100  | Generic Parameter A      |
 +| +0x0A00  |  0x0100  | Generic Parameter B      |
 +| +0x0B00  |  0x0100  | Generic Parameter C      |
 +| +0x0C00  |  0x0100  | Generic Parameter D      |
 +| +0x0D00  |  0x0100  | AL                       |
 +| +0x0E00  |  0x0100  | Unknow                   |
 +| +0x0F00  |  0x0100  | Etat du Silo Missile     |
 +| +0x1000  |  0x0010  | Bloc de configuration    |
 +
 +
 +Pour n'importe quel sous-block de 0x100 bytes est divisé en 2 sous sections, 1 pour les humains (offset 0x0000), 1 pour l'ordinateur (offset 0x0080).
 +
 +{{tablelayout?rowsHeaderSource=Auto&colwidth="153px"}}
 +^  Offset  ^  Taille  ^  Description               ^
 +| +0x0000  |  0x14    | Unités mobiles Humaines    |
 +| +0x0014  |  0x6C    | Batiments Humains          |
 +| +0x0080  |  0x14    | Unités mobiles Ordinateur  |
 +| +0x0094  |  0x6C    | Batiments Ordinateur       |
 +
 +Suivant le code, le nombre maximum d'unités mobiles humaine diffère.
 +
 +  * Dans 2 fonctions, PX3 vérifie le status (offset 0x0000) pour les indices de 0 à 20 (0x00-0x14)
 +  * Dans 1 fonction, PX3 vérifie le status (offset 0x0000) pour les indices de 20 à 50 (0x14-0x32) 
 +  * Dans 5 fonctions, PX3 vérifie le status (offset 0x0000) pour les indices de 0 à 64 (0x00-0x40) 
 +  * Dans 2 fonctions, PX3 vérifie le status (offset 0x0000) pour les indices de 20 à 64 (0x14-0x40) 
 +
 +<WRAP round help>
 + meme si le code présente bien des limites pour le joueur, je n'ai pas trouvé trace de limite similaire pour l'ordinateur (logiquement placée aux offset 0x80, 0x94, ...)
 +</WRAP>
 +
 +==== Block de configuration ====
 +
 +^  offset  ^  byte  ^ Description  ^
 +|   +0          | Décors de la carte ('1','2','3') |
 +|   +1          | Unité sélectionnée  |
 +|   +2          | Réserve de minerais |
 +|   +3          | Réserve de Gaz  |
 +|   +4          | Réserve d'électricité  |
 +|   +5      0xB   | inconnu  |
 +===== Block "Timer" =====
 +{{anchor:blocktimer}}
 +
 +^  offset  ^  byte  ^  description   ^
 +|   +0          | temps global en jeu (en ms) |
 +|   +2          | Temps : Secondes |
 +|   +3          | Temps : minutes |
 +|   +4          | Temps : heures |
 +
 +===== Information détaillée =====
 +
 +{{tablelayout?rowsHeaderSource=Auto&colwidth=",,"}}
 +^  Offset  ^  Taille  ^  Taille en Bytes  ^  Joueur/\\ Ordinateur  ^  Type     ^ Description                                                       ^
 +| 0000         8000 |             32768 |                        |           | 256x128 tableau de case (carte de jeu) 0x0000 = coin haut-gauche  |
 +| 8000           14 |                20 | Joueur                 | Unité     | type                                                              |
 +| 8014           6C |               108 | Joueur                 | Batiment  | type                                                              |
 +| 8080           80 |               128 | Ordinateur             | mixte     | type                                                              |
 +| 8100           14 |                20 | Joueur                 | Unité     | position X                                                        |
 +| 8114           6C |               108 | Joueur                 | Batiment  | position X                                                        |
 +| 8180           80 |               128 | Ordinateur             | mixte     | position X                                                        |
 +| 8200           14 |                20 | Joueur                 | Unité     | position Y                                                        |
 +| 8214           6C |               108 | Joueur                 | Batiment  | position Y                                                        |
 +| 8280          480 |              1152 | Ordinateur             | mixte     | position Y                                                        |
 +| 8700           14 |                20 | Joueur                 | Unité     | Vie                                                               |
 +| 8714           6C |               108 | Joueur                 | Batiment  | Vie                                                               |
 +| 8780          190 |               400 | Ordinateur             | Batiment  | Vie                                                               |
 +| 8910          6F0 |              1776 | Joueur                 | Missile   | Silot Vide/Plein                                                  |
 +| 9000              |                                          |                                                                             |
 +
 +====== Type de Carte/Décors ======
 +{{anchor:tileset}}
 +^ Valeur  ^ Description ^
 +|  0x31   | Champs "green valey" |
 +|  0x32   | Monde de glace (ice) |
 +|  0x33   | désert |
 +
 +{{:back2root:reverse-engineering:planet-x3:pasted:20230112-162052.png}}  {{:back2root:reverse-engineering:planet-x3:pasted:20230112-162101.png}}  {{:back2root:reverse-engineering:planet-x3:pasted:20230112-162037.png}}
 +
 +
 +====== Type d'Unité mobiles ======
 +{{anchor:unit}}
 +{{tablelayout?rowsHeaderSource=Auto}}
 +^  Valeur  ^ Description  ^
 +|  0x01    | builder      |
 +|  0x02    | tank         |
 +|  0x03    | Heavy Tank   |
 +|  0x04    | frigate      |
 +|  0x1F    | Missile ?    |
 +
 +====== Type de Batiments ======
 +{{anchor:batiment}}
 +{{tablelayout?rowsHeaderSource=Auto&colwidth=""}}
 +^  Valeur  ^  Proriétaire  ^ Description              ^
 +|  0x14    | Joueur        | Headquarters             |
 +|  0x15    | Joueur        | Radar                    |
 +|  0x16    | Joueur        | Power Station            |
 +|  0x17    | Joueur        | Solar Panel              |
 +|  0x19    | Joueur        | factory                  |
 +|  0x1A    | Joueur        | Missile Silo             |
 +|  0x1B    | Joueur        | Smelter                  |
 +|          | Joueur        | Refenery                 |
 +|  0x21    | Ennemi        | Headquarters (Pyramids)  |
 +|          | Ennemi        | Academy                  |
 +|          | Ennemi        | Clone Facility           |
 +|          | Ennemi        | Research Building        |
 +|          | Ennemi        | Factory                  |
 +|          | Ennemi        | Sentry Pod               |
 +
 +
 +====== Tiles ======
 + 
 +{{:back2root:reverse-engineering:planet-x3:pasted:20230114-113015.png}}
back2root/reverse-engineering/planet-x3/part2-savegame_dat.1673511397.txt.gz · Dernière modification : 2023/01/12 09:16 de frater