|
Joe
Forum Admin
    
564 Messaggi |
Scritto - 12/08/2012 : 02:08:32
|
Approfittando della frescura di un temporale estivo, eccomi qui col pc acceso a disquisire sull'algoritmo LZSS. Non è granché utilizzato, si trova in pochissimi giochi, ma è alla base di tutti i più famosi programmi di compressione, perciò vale la pena esaminarlo. Partiamo subito con le immagini, poi i dettagli.
La prima scritta del gioco:

Il contenuto di DATA.DIR:

Il contenuto di DATA.001:

DATA.DIR contiene i nomi dei files compressi e la posizione all'interno dell'archivio in cui si trovano (offset). DATA.001 contiene i files compressi, ognuno ha una intestazione di 4 byte che indica la dimensione originale non compressa (primi due) e quella compressa (ultimi due).
Innanzitutto bisogna decomprimere l'archivio. Ho usato TREK2EXT (http://wiki.xentax.com/index.php/Game_Tools#Star_Trek:_25th_Anniversary.2FJudgment_Rites) e ne ha estratti NOVEMILA !!! I file contenenti i testi sono quelli con estensione TXT e DB.
La frase che cerchiamo è nel file DEMON.TXT. Osservando il DATA.DIR si nota che i nomi hanno lunghezza fissa 8 + 3 caratteri senza il punto separatore e con il valore esadecimale 00 per gli spazi vuoti. Ho evidenziato il file in questione e l'offset da cui inizia il testo dentro DATA.001, cioé 08 EE 75,; bene andiamo a vedere nel DATA.001 ... qualcosa non torna, vero?
In effetti il codice del gioco estrae in runtime i vari files, quindi "ragiona" in codice binario, che come noto va da destra a sinistra. Invertiamo i tre byte ed ecco trovato l'indirizzo che ci serve: 75 EE 08 ! La terza immagine ha evidenziato in blu i primi 4 byte di DEMON.TXT : 32 0B A0 06.
I primi due sono la dimensione del file su disco. Leggiamola nelle proprietà del file DEMON.TXT: 2866 byte, che in esadecimale fa 0B 32, ma per la nota legge di inversione otteniamo 32 0B. Ci siamo! A0 06 sono invece la dimensione del file compresso, invertendo diventa 06 A0 che in decimale fa 1696 byte.
Segue il testo. Come funziona? L'algoritmo LZSS comprime i caratteri a gruppi di 8 e inserisce un byte all'inizio della stringa che indica quanto è compressa quella stringa. Per velocizzare la decompressione (e per nostra fortuna) se non viene compattato nulla il flag ha valore FF. Ho evidenziato alcuni flag per chiarire il funzionamento. Ora possiamo: - tradurre i file TXT e DB - convertire in esadecimale la dimensione dei file tradotti e annotarla - inserire il byte FF ogni 8 caratteri - convertire la nuova dimensione e annotarla (sarà maggiore e non compressa, ma i computer moderni non si scompongono per qualche KB in più) - aggiungere i TXT e DB "compressi" in fondo al DATA.001, sostituendo nel DATA.DIR l'offset (invertito).
DOVE STA IL PROBLEMA ovvero : non esiste traduzione senza crash!(risolto)
C'è una funzione MULTIFILES in questi archivi, non l'ho trovata descritta in nessun sito, perciò penso sia una personalizzazione dell'algoritmo LZSS fatta apposta per la Interplay. Si tratta di una compressione dell'indice, in pratica quando c'è una sequenza di file con numeri consecutivi, nel DATA.DIR viene memorizzato solo il nome del primo file e l'offset è settato con un codice particolare.
Confrontiamo due esempi: FILE000.DB ---> FILE009.DB , FILE 180.DB ---> FILE 181.DB
Nel DATA.DIR troviamo i seguenti offset per le due serie sopra citate: 8A 32 7A 82 33 F4
Non sono indirizzi presenti nell'archivio, infatti il primo byte è un flag e funziona così: 8A in binario ---> 1000 1010 82 in binario ---> 1000 0010
il bit più alto (quello più a sinistra) è un flag che indica la presenza di una sequenza di files; il semi-byte più basso indica quanti sono i file concatenati dentro DATA.001 (1010 in decimale --> 10, 0010 --> 2)
quindi la domanda è : qual è l'offset? mi restano due byte su tre, mannaggia!
Comunque ho salvato tutti i file sequenziali "in chiaro" aggiungendo i nomi in fondo al DATA.DIR e ha funzionato. L'unica avvertenza è di non esagerare con gli inserimenti in fondo al DATA.001 perché se si supera l'indirizzo 7F FF FF si arriva al 80 00 00 che ha il primo byte con il flag impostato a "multifiles".
 |
|