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:
une sauvegarde fait donc TOUJOURS 36885 bytes
Dans le code source, la sauvegarde se fait uniquement dans le fichier SAVEGAME.DAT
.
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
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).
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
la carte du jeu est sauvegardée “tel quel” sans aucune encryption ni compression.
; 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
Pareil pour la structure des unités/batiments, sauvegardée “tel quel” sans aucune encryption ni compression.
; 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
Avant de fermer le fichier, Planet X3 sauvegarde le compteur de temps générale (1 mot) et le temps “en jeu” 3 bytes
MOV AH,0x3e ; close file MOV BX,word ptr [fhandler_SaveGame] INT 0x21 RET
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).
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.
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, …)
offset | byte | Description |
---|---|---|
+0 | 1 | Décors de la carte ('1','2','3') |
+1 | 1 | Unité sélectionnée |
+2 | 1 | Réserve de minerais |
+3 | 1 | Réserve de Gaz |
+4 | 1 | Réserve d'électricité |
+5 | 0xB | inconnu |
offset | byte | description |
---|---|---|
+0 | 2 | temps global en jeu (en ms) |
+2 | 1 | Temps : Secondes |
+3 | 1 | Temps : minutes |
+4 | 1 | Temps : heures |
Offset | Taille | Taille en Bytes | Joueur/ Ordinateur | Type | Description |
---|---|---|---|---|---|
0000 | 8000 | 32768 | 256×128 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 |
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 |