Questo articolo è rivolto agli
appassionati. Tratta argomenti che i giocatori occasionali
potrebbero considerare difficili. D'altro canto per gli sviluppatori
queste cose sono ovvie e risapute.
Compilare Descent 2 (e 1) dai Sorgenti.
La compilazione consiste nel
trasformare il codice sorgente di un programma in un eseguibile
da utilizzare, collegato alle librerie che avremo installato.
Durante la compilazione, il compilatore (gcc, g++)
legge il codice sorgente e crea un eseguibile (d2x-rebirth)
collegato alle librerie necessarie, che devono essere già installate (SDL,
PhysFS).
Di seguito vedremo come compilare una
versione recente di DXX-Rebirth su una distribuzione Linux,
preferibilmente derivata da Debian.
Cosa occorre.
Sappiamo distinguere un Editor di Testo da un Word Processor?
Sappiamo installare programmi e librerie dai Repository della
nostra distribuzione?
Sappiamo usare un pochino la riga di comando?
Sappiamo prenderci delle responsabilità?
Chi opera su un computer è responsabile degli eventuali
malfunzionamenti che provoca. Anima
Prava & compagnia non ne rispondono.
Seguiamo le istruzioni del file INSTALL.markdown
nei sorgenti, ovvero pressappoco quanto segue.
Occorrono scons, gcc, g++,
Python 3.
Occorrono le librerieSDL1.2, PhysFS 3
(PhysicsFS), libpng, libsdl-image, libsdl-mixer con i
rispettivi pacchetti DEV.
Nelle distribuzioni derivate da Debian
(Ubuntu, Linux Mint, ...) si può installare tutto rapidamente come
segue. Nelle altre distro cambia il comando per l'installazione, leggere
il file INSTALL.markdown.
Se alcuni elementi sono già installati
non fa niente, meglio così.
Dagli stessi sorgenti si compilano D1 e
D2.
Per avviare la compilazione apriamo
una shell (un "terminale") nella directory principale dei
sorgenti.
Poi digitiamo: scons.
Per compilare solo D2 (senza D1): scons
d2x=1.
Per compilare solo D1 (senza D2): scons
d1x=1.
Prima dell'avvio è d'uso l'impiego di gesti
apotropaici: fare le corna, incrociare le dita, toccare ferro,
eccetera. Non è chiaro se serva davvero.
Se la compilazione ha successo.
Verremo premiati dal messaggio "scons:
done building targets" (o qualcosa del genere).
Nelle versioni recenti troveremo i file
eseguibili per D1 (d1x-rebirth) e D2 (d2x-rebirth)
nella directory build.
Non c'è più bisogno di dargli il
permesso di esecuzione(chmod u+x d2x-rebirth).
Possiamo rinominare l'eseguibile come
vogliamo. Possiamo metterlo dove ci pare, di solito in una cartella
comoda, oppure insieme all'eseguibile dei Repo (il comando which
d2x-rebirth ci dice dove si trova, di solito in /urs/games/).
Attenzione, mettendolo nella directory dove si trovano gli altri file
(~/.d2x-rebirth) a volte funziona a volte no (dipende dalla versione).
D'ora in poi useremo una versione
compilata da noi.
Che bella
soddisfazione, vero?
Se la compilazione non ha successo...
...Non c'è niente di strano: può mancare una libreria, oppure la sua
versione o posizione non sono quelle attese. Leggiamo il messaggio di
errore e cerchiamo di capirne il significato. Leggiamo il file INSTALL.markdown.
Facciamo più di una ricerca in rete in base al testo del messaggio
di errore. Approfondiamo il problema e insistiamo.
Se non ne veniamo a capo è normale
chiedere aiuto. Però attenzione: quelli di Anima Prava sono brava gente,
ma in rete si trovano anche persone da evitare. Non perdiamo troppo
tempo con i forum in lingua italiana perché se ne cava poco. Se siamo
sicuri del fatto nostro possiamo chiedere aiuto direttamente ai
manutentori del programma.
In ogni caso dovremo fornire almeno
quanto segue:
- nome e versione esatta del sistema
operativo,
- versione esatta del programma (il
Commit),
- il testo completo ottenuto lanciando scons,
- il contenuto del file sconf.log,
- come abbiamo tentato di risolvere il
problema,
- i risultati che abbiamo ottenuto.
NOTE.
Il compilatore può essere gcc o clang. Nella
procedura sopra è gcc.
I pacchetti DEV delle librerie contengono gli header
necessari per la compilazione. Quando si installa un pacchetto dev
ci si aspetta che la libreria corrispondente venga installata
automaticamente.
In caso di problemi con la libreria libpng (specialmente se
Linux gira dentro una macchina virtuale). Non è indispensabile, serve
per salvare gli screenshot in formato PNG. Si può escludere compilando
con l'opzione scons screenshot=legacy. Gli screenshot saranno
salvati nel tradizionale formato TGA.
Di solito nelle distribuzioni Linux troviamo librerie e programmi
che vanno d'accordo tra loro.
Se non vanno d'accordo o se le librerie si trovano nel posto
sbagliato, la compilazione diventa complicata.
Se cerchiamo di compilare una versione troppo vecchia (o troppo
nuova!) rispetto alla nostra distribuzione, prepariamoci a ricreare
l'ambiente richiesto.
In questi casi avremo qualche possibilità in più di fare danni se non
stiamo attenti. Meglio prendere nota di tutti i passi. In caso di
dubbi c'è sempre Anima Prava, ma non ha poteri magici.
Compilare in Windows: certo che si può. Ma è più complicato e dà più
grattacapi. Merita un articolo apposito.
Modificare il Source Code.
Perché nonmodificare
i sorgenti.
Noi non giochiamo in Multiplayer. Se
lo facessimo useremmo esclusivamente una versione originale priva di
modifiche di qualsiasi tipo.
Perché modificare i sorgenti (solo
Single Player).
- Per risolvere piccoli bachi o problemi.
- Per aggiungere funzioni o
caratteristiche che agli sviluppatori non interessano, non piacciono o
che non hanno il tempo di implementare.
IMPORTANTE. Il codice sorgente cambia:
le modifiche che funzionano adesso (nel 2023) potrebbero non
funzionare con i sorgenti dell'anno prossimo.
Cosa occorre.
Abbiamo compilato una versione di
DXX-Rebirth e la usiamo normalmente per giocare.
Modifiche - Esempi storici.
Esempio storico 1. Migliorare i movimenti.
Nelle versioni originali di D1 e D2, i
movimenti di rotazione erano poco uniformi (vedere i dettagli
nell'articolo D2 - Il
menu del 1996). A partire dal 2000, col Source Port D2X,
molti appassionati iniziarono a modificare il codice sorgente per
rendere i movimenti più scorrevoli e uniformi. Però altri appassionati
ritenevano intoccabili le caratteristiche originali e il solo
discuterne in pubblico scatenava reazioni negative. Persino nelle
recensioni di Overload (un gioco pubblicato nel 2018)
si leggono le critiche di qualche vecchio appassionato perché i
movimenti sono troppo diversi da quelli di D1 (1995) e D2 (1996).
Nel 2023: in molte versioni
moderne i movimenti del Pyro-GX sono abbastanza fluidi e uniformi,
mentre il menù offre opzioni per regolarne a piacimento le
caratteristiche.
Esempio storico 2. Eliminare il
Robot Ladro.
Non tutti apprezzano il Robot Ladro.
Per eliminarlo si poteva aprire il file descent2.hog con un
editor di missioni, eliminare il Robot Ladro da tutti i livelli e
salvare una versione modificata, oppure modificare il codice
sorgente.Anche queste modifiche erano controverse.
Nel 2023: nel menù di alcune
versioni moderne sono presenti opzioni per eliminare il Robot Ladro
o limitarne le capacità.
Esempio storico 3. Accesso libero
a tutti i livelli.
Vedere l'articolo Accesso
libero a tutti i livelli. In Descent 2 originale un semplice
trucco permetteva di accedere a tutti i livelli di una missione
multilivello senza doverli giocare prima in sequenza. Questo
divenne più difficile e poi impossibile nelle versioni Source
Port, ma i giocatori trovarono il modo di rimediare.
Nel 2023: l'accesso libero
a tutti i livelli è la norma delle versioni recenti.
Esempio storico 4. Tasti F9/F10 con ripetizione
automatica.
Contributo di InfernalCore.
Risoluzione del Bug #539.
(https://github.com/dxx-rebirth/dxx-rebirth/issues/539).
InfernalCore
ha comunicato agli sviluppatori di DXX-Rebirth la risoluzione di
questo baco il 2023.10.08 che hanno accettato la modifica il
2023.12.25 (commit d724905).
Nota. InfernalCore ha contribuito a risolvere altri bachi:
Nella Mappa (Automap,
tasto predefinito TAB) i tasti F9/F10 cambiano la
distanza di vista, nascondendo progressivamente i tunnel più
lontani. Vedere la spiegazione completa nella Introduzione
della Guida Single Player.
In D1/D2 originali i comandi di
questa funzione non erano F9/F10 ma avevano la ripetizione
automatica (non era necessario premerli ripetutamente, bastava
tenerli premuti). Nei Source Port la ripetizione
automatica andò persa e venne ripristinata in DXX-Rebirth solo a
fine 2023.
Soluzione.Funziona
in D1 e D2. Nel file automap.cpp dalle parti
della riga 1139 la riga key_toggle_repeat(0); diventa key_toggle_repeat(1);
(vedere sotto).
switch (event.type) {
case EVENT_WINDOW_ACTIVATED:
game_flush_inputs(controls);
event_toggle_focus(1);
key_toggle_repeat(1);
//MODIFICATO
break;
case EVENT_WINDOW_DEACTIVATED:
event_toggle_focus(0);
key_toggle_repeat(1);
break;
Collaudo. La soluzione è stata collaudata in D1 e D2
giocando molte ore. Risulta che nessun altro tasto tra quelli
normalmente in uso prende la ripetizione automatica.
Evidentemente, questa funzione key_toggle_repeat() agisce
solo nell'ambiente della mappa. Ora la Full Map in
D2X-Rebirth funziona meglio che in D2 originale (provare per
credere). Per non parlare di D2X-Rebirth versione 0.58.1 dove era
praticamente inutilizzabile.
Modifiche - Personalizzazioni.
Personalizzazione 1. Modificare il
nome di un Cheat Code.
Se ci piace esplorare i livelli Single
Player abbiamo notato che è scomodo digitare il Cheat Code ROCKRGRL
per vedere la Full Map e magari ogni tanto sbagliamo a digitarlo.
Proviamo a sostituirlo con MAPPA. Oltre a essere più semplice da
digitare, MAPPA non lascia attivata la vista posteriore (tasto R). Ma
questa modifica difficilmente interessa a chi non scrive in italiano.
Seguono le istruzioni dettagliate (anche troppo, ma questo è un
allenamento per modifiche più complicate).
- Copiamo e rinominiamo la cartella
con i sorgenti da modificare per non fare confusione (per esempio: dxx-rebirth-master-20230202-modifica-mappa).
- Cerchiamo il file gamecntl.cpp.
- Facciamo una copia di sicurezza di
questo file (gamecntl.cpp.ORIGINALE).
- Apriamo il file gamecntl.cpp
con un Editor di testo.
- Cerchiamo la riga che contiene il
testo "rockrgrl".
- Mettiamo due Slash (//) davanti a
questa riga. In questo modo l'abbiamo trasformata in un commento: non
verrà compilata, non funziona più.
// { "rockrgrl",
&game_cheats::fullautomap },
- Aggiungiamo un nostro commento.
// Modificato Cheat Code in
data giorno/mese/anno.
- Copiamo la riga originale (senza //)
e la modifichiamo come segue.
{ "mappa",
&game_cheats::fullautomap },
- Salviamo il file.
- Compiliamo il nuovo codice, con
gesti apotropaici a nostra scelta (facciamo le corna, incrociamo le
dita, tocchiamo ferro, eccetera...)
- Rinominiamo il file eseguibile per
non confonderlo (per esempio: d2x-rebirth-20230202-MAPPA) e
copiamolo dove teniamo gli altri eseguibili di D2 (/usr/games/).
- Lanciamolo e se funziona facciamoci
tanti complimenti. Se non funziona torniamo sui nostri passi per
trovare dove abbiamo sbagliato.
Personalizzazione 2. Full Map a comando in D1.
In D1 originale (DOS, 1995), se si
attivano i Cheat Code digitando GABBAGABBAHEY, quando si apre la
Mappa (TAB) si può vedere e nascondere la FullMap a piacere premendo
ALT-F. Purtroppo le aree inesplorate non sono in blu (questa è una
prerogativa di D2). Chiudendo la mappa e riaprendola, bisognava
premere nuovamente ALT-F per riattivare la Full Map.
Ecco come avere la Full Map in D1
(senza Cheat Code). Attenzione: molti giocatori non approverebbero questa modifica.
Partiamo da un codice pulito (privo
di personalizzazioni).
Apriamo il file automap.cpp.
Cerchiamo il codice seguente,
attorno alla riga 1022.
#if defined(DXX_BUILD_DESCENT_I) case
KEY_Q: // ERA: case
KEY_ALTED+KEY_F: if
(1==1) // ERA: if
(cheats.enabled)
{
cheats.fullautomap =
!cheats.fullautomap; //
if cheat of map powerup,
// work with full depth auto
&plrobj = get_local_plrobj();
recompute_automap_segment_visibility(LevelUniqueAutomapState,
plrobj, am);
} return
window_event_result::handled; #endif
Sostituiamo case KEY_ALTED+KEY_F: con case KEY_Q: Sostituiamo if (cheats.enabled) con if (1==1)
Compiliamo solo D1 (scons
d1x=1). Otteniamo una versione di D1 nella quale se apriamo la
Mappa (TAB) basta premere il tasto Q per attivare e
disattivare a piacere la FullMap. Il tasto Q è comodo perché è vicino
al tasto TAB ed è libero (in D2 noi lo colleghiamo all'Afterburner che
in D1 non esiste). Purtroppo le aree inesplorate non sono in blu ma si
riesce lo stesso a scoprirle. Vedere la figura seguente.
Personalizzazione 3. Eternal Full Map in D2.
Ecco come avere sempre la Full Map in
D2, con le aree inesplorate in blu, senza bisogno del
potenziamento Full Map e senza digitare un Cheat Code. Attenzione:
molti giocatori non approverebbero questa modifica.
Vedi file: automap.cpp
zona della riga 259: mostra tutto (ma non in blu)
zona della riga 1573: (zone non esplorate in blu)
riga 259: sostituito:
if (1==1) // if (cheats.fullautomap) MODIFICA
riga 1571:
{
auto &player_info =
get_local_plrobj().ctype.player_info;
if ((cheats.fullautomap ||
player_info.powerup_flags & PLAYER_FLAGS_MAP_ALL) &&
!LevelUniqueAutomapState.Automap_visited[seg])
color = am.wall_revealed_color;
}
// AGGIUNTO {
if ((1==1) &&
!LevelUniqueAutomapState.Automap_visited[seg])
color = am.wall_revealed_color;
}
// FINE AGGIUNTA
Compiliamo solo D2 (scons
d2x=1). Otteniamo una versione di D2 con la Full Map
permanente (con le aree inesplorate in blu). Non compiliamo D1
perché otterremmo una versione di D1 dove le aree inesplorate sono
visibili ma non in blu.
Spiegazione.
- Cerchiamo di modificare il codice
il meno possibile. - Riga 259. Vogliamo vedere la mappa di tutto il livello
sempre, anche quando il Cheat Code non è stato digitato: if
(1==1) equivale a dire "sempre", perché 1 è sempre uguale a
1.
- Dalle parti della riga 1573 si
trova il codice che rende le zone non ancora esplorate in blu (c'era
un difetto nella versione 0.58.1, le zone inesplorate non erano mai
rappresentate in blu). Facciamo in modo che le zone non ancora
esplorate siano sempre rappresentate in blu, anche quando il Cheat
Code non è stato digitato.
Come impostare delle directory alternative.
Se possibile, vorremmo tenere versioni di
dxx-rebirth diverse in cartelle ben separate. In Windows è facile. In
Linux no: sembra che tutte le versioni vadano a salvare i loro file
nella directory predefinita (~/.d2x-rebirth/) o (~/.d1x-rebirth/).
Ecco due cose che non funzionano: (1)
l'opzione da riga di comando -hogdir e (2) compilare
dxx-rebirth con l'opzione sharepath=path ("sets
system directory to search for game data"). Il programma leggerà
la directory che vogliamo noi ma scriverà sempre nella directory
predefinita.
Soluzione.
Vedere https://github.com/dxx-rebirth/dxx-rebirth/issues/79
- Un utente chiede come far girare sia
la versione Rebirth standard sia la versione Retro, ma in modo che
ciascun programma legga e scriva in una directory specifica (Players,
Demo, Savegame). Vorrebbe invece mantenere le directory Missions e
Data in comune.
- Lo sviluppatore risponde
consigliando di usare una variabile di ambiente (environment
variable) per cambiare la path predefinita.
Questo comportamento è stato
introdotto con il Commit 03b57ab del 18 Ottobre 2015. Il codice in
questione si trova nei sorgenti nel file physfsx.cpp.
Il programma considera prima le
variabili $D1X_REBIRTH_HOME e $D2X_REBIRTH_HOME. Se non sono definite
considera $REBIRTH_HOME. Se anche questa non è definita sceglie le
directory predefinite (~/.d1x-rebirth/) o (~/.d2x-rebirth/).
Nota: lo sviluppatore non lo dice, ma
per mantenere le directory Missions e Data in comune tra più versioni
si può usare l'opzione da riga di comando -hogdir.
Per controllare una variabile ambiente:
echo $REBIRTH_HOME
echo $D1X_REBIRTH_HOME
echo $D2X_REBIRTH_HOME
- Se avviamo D2 da riga di comando.
Bisogna creare due script bash che impostano la variabile ambiente
come desiderato (per esempio: export REBIRTH_HOME=~/.d2x-VERS-ALT) poi
lanciano la versione desiderata. In questo modo la variabile non è
permanente.
- Se avviamo D2 con il Launcher
(figure seguenti). Prepariamo due Launcher che avviano versioni
diverse in directory diverse. Mettiamo i Launcher in ~/.local/share/applications.
Per passare una variabile d'ambiente
in un Launcher, usiamo il comando env:
[Desktop Entry]
Name=Descent 2
Comment=DXX-Rebirth source port of Descent 2: Counterstrike from
1996...
Exec=/usr/games/d2x-rebirth-0.61-20230421
Icon=~/.d2x-rebirth/data/d2x-rebirth.ico
Terminal=false
Type=Application
Categories=Game;ActionGame;
StartupNotify=false
LAUNCHER 2
[Desktop Entry]
Name=Descent 2 - ALT DIR
Comment=DXX-Rebirth source port of Descent 2: Counterstrike from
1996...
Exec=env REBIRTH_HOME=~/.d2x-VERS-ALT /usr/games/d2x-VERS-ALT
Icon=~/.d2x-VERS-ALT/data/d2x-rebirth.ico
Terminal=false
Type=Application
Categories=Game;ActionGame;
StartupNotify=false
NOTA. Non impostiamo queste variabili
d'ambiente in ~/.bashrc o ~/.profile, perché così
diventerebbero permanenti. Tra parentesi, ricordiamo che Launcher
onora solo quelle scritte in ~/.profile mentre Bash quelle in
~/.bashrc e ~/.profile.
I segreti dei file DXA.
DXA sta per Descent-X-Addon.
Funzionano in D2X-Rebirth, D1X Rebirth e Source Port derivati.
Contengono file multimediali che vanno a sostituire i media originali
della missione principale (D1 FIRST STRIKE o D2 COUNTERSTRIKE):
immagini, font, musiche, i testi dei Briefing, ma non i testi dei menu
o interni al gioco.
I file DXA vanno messi nella directory
dove si trova il file HOG della missione principale (.../data/).
DXX-Rebirth li vede, li apre e usa i file contenuti al loro interno al
posto dei file con lo stesso nome che si trovano all'interno del file
HOG della missione principale.
I file DXA non funzionano per le missioni aggiuntive. Se li mettiamo
nella directory di una missione aggiuntiva non vengono letti. Questa è
la situazione nel 2023.
Dettagli sui contenuti:
- Immagini: formato .pcx
- Font: formato .fnt (font raster per windows)
- Musica: formato .ogg
- Testi: file in formato .txb (formato speciale per Descent)
I file DXA sono archivi di file
compressi in formato ZIP con l'estensione cambiata in DXA. In passato
avevano l'estensione .ZIP, poi nel 2012 gli sviluppatori cambiarono
l'estensione in .DXA per evitare malfunzionamenti: capitava che il
programma si piantasse cercando di aprire un file ZIP (per esempio un
back-up creato dal giocatore) credendolo un AddOn. Fonte delle
informazioni: il file Changelog nei sorgenti.
Se si scompatta un file DXA si ottiene
una directory che contiene dei file. Per ricreare il DXA originale
comprimere SOLO I FILE (senza la directory) in formato ZIP e poi
modificare l'estensione in .dxa (minuscolo).
Nella directory del codice sorgente
<sorgenti>/d2x-rebirth/utilities/ troviamo dei programmi
accessori che risalgono al 1995 e sono stati aggiornati nel corso
degli anni.
Qui troviamo i programmi che
convertono un normale file di testo in TXB (e viceversa):
tex2txb.c
txb2tex.c
Attenzione: il formato TXB supporta i
caratteri ASCII. Non supporta le vocali accentate italiane (o altri
caratteri non ASCII).
Si compilano così (in Linux):
gcc ./tex2txb.c
gcc ./txb2tex.c
Invece questi altri programmi (che si
compilano come sopra) estraggono il contenuto dei file HOG (e
viceversa):
hogextract.c
hogcreate.c
In pratica, se vogliamo tradurre i testi dei Briefing di D1 o D2:
- hogextract descent2.hog
- txb2tex <file TXB> <file di testo TXT>
- Tradurre il file di testo
- tex2txb <file di testo TXT> <file TXB>
(se occorre, rinominare i file e sistemare i
permessi)
- comprimere i file TXB in formato ZIP
(solo i file, non la directory)
- cambiare l'estensione in .dxa (minuscolo)
- copiare il file DXA dove si trova il file HOG.
Non possiamo usare i file DXA per
tradurre i testi di Vertigo (o di altre missioni aggiuntive che stanno
nella directory MISSION). Quindi andremo a creare un nuovo file HOG,
così:
- hogextract d2x.hog
- txb2tex d2x.txb d2x.txt
- tradurre il file di testo (d2x.txt)
- tex2txb d2x.txt d2x.txb
- mettiamo il file d2x.txb tradotto al posto di quello
originale
- hogcreate d2x.hog
- mettiamo il nuovo file HOG al posto dell'originale
(BACKUP!!!)