Fabio Pallini

LV 99

HP 9999/9999

MP 999/999

next level

Limit level

Benvenuti nel mio sito dal nostalgico stile anni '90!
In questo angolo remoto del web, condividerò le mie avventure nello sviluppo di un autentico gioco per PlayStation 1.
Se ne avete ancora una, rispolverate la vostra vecchia console dalla soffitta, e masterizzate un nuovo gioco su CD-ROM...
Se siete appassionati di retrogaming, e più nel dettaglio di giochi come Final Fantasy VII, FFVIII e FFIX, ovvero i famosissimi giochi pubblicati su PlayStation 1 alla fine degli anni 90, non potete perdervi questa avventura, sto sviluppando le medesime meccaniche in tutto e per tutto.

ps1 crt

Calcolo parallelo su PlayStation 1

05/11/2024

Multithreading su una macchina vecchia di 30 anni come la PlayStation 1? Ho affrontato il problema nel nuovo video appena pubblicato, ho dovuto inserire il multithread per riuscire a caricare i dati dal cd-rom senza far "scattare" il gioco. I dati audio vengono caricati in maniera costante perché la ram audio è di soli 512kb, oltre a questa problematica che ho risolto da un po', c'è anche la problematica che riguarda il caricamento di altre aree del gioco mentre si sta continuamente caricando il flusso audio dal cd-rom, bel rompicapo... non perdetevi il video per un approfondimento sulla questione, e per capire come ho risolto la problematica, anche se all’effettivo non vi è nessun calcolo parallelo.

Leggere file audio dal cd-rom

30/09/2024

In questo nuovo episodio, affronterò un problema che sembra banale, ma invece mi ha fatto tribolare per non pochi giorni. Su Play Station 1 si può leggere i file audio – sia per effetti sonori che musiche – in diversi modi: si può usare dei file .XA, che sono una sorta di compilation di tracce audio, nella maggior parte dei casi sono utilizzati per le musiche, ma come racconto nel video linkato sotto, e nel video precedente, questa tecnica può essere usata anche per la telecronaca nei giochi come FIFA 98. Con questa tecnica è facile passare da una traccia all’altra, essendoci una lettura continua dal cd-rom, sorge un problema se abbiamo bisogno di leggere altri dati dal cd-rom per caricare assets di gioco, come nel caso di un cambio di schermata, il lettore è già impegnato, di conseguenza la musica si dovrà interrompere per qualche istante. Per ovviare a questa problematica, dobbiamo usare un metodo diverso, intanto useremo dei file .VAG, convertiti dai file .WAV con il programma VAG EDIT disponibile nell’SDK della ps1. Un file audio VAG sarà sicuramente più leggero di un WAV, ma avrà comunque una dimensione di almeno 4 MB, se non superiore, in media una traccia audio peserà sui 6 MB, la memoria RAM è 2 MB, e la memoria audio è 512 kb, è quindi impossibile caricare in memoria l'intero VAG. Quello che ho implementato è un sistema, che tramite un interrupt, riesce a capire quale byte la scheda audio sta leggendo, e di conseguenza a quale secondo è il play della musica. In sostanza vengono caricati in memoria i primi 300 kb della musica, quando si arriva al kb 100, carico i successivi 100 kb del file VAG nella memoria audio fra 0 e 100, quando la scheda audio arriva a 200 faccio la solita cosa con i byte fra 100 e 200, arrivati a 300 ripeto la solita cosa fra i byte 200 e 300, a quel punto la scheda audio rileggerà dal byte 0, trovandosi davanti ulteriori 300 kb di audio da "suonare", in questo modo, con 300 kb occupati e sempre impegnati, si riesce a leggere l'intero file audio, il lettore è sempre costantemente impegnato, ma si ha un margine di tempo, in cui il lettore può leggere altri dati, perché vi è comunque un cuscinetto di 300kb di audio già caricati in memoria, che equivalgono a diversi secondi, e si ha tutto il tempo per caricare dati dal cd-rom per la schermata successiva. Ecco svelato il mistero per cui nei Final Fantasy, la musica era sempre presente, non si interrompeva mai, e potevamo correre quanto volevamo fra le strade di Midgar, o nel garden di Balamb.

Generare un file binario per gestire i fondali

28/08/2024

Un fondale pre-renderizzato non è solo una banale immagine usata come sfondo, lo spazio 3d è presente a tutti gli effetti, e ogni schermata può prevedere svariate interazioni:
oggetti e NPC con cui interagire, collisioni con muri, percorsi calpestabili e non, porte, ostacoli vari ecc.. capite bene che serve qualcosa con cui poter definire cosa è presente nella scena per ogni singola schermata, definire da dove si arriva, da dove si esce, cosa può succedere e cosa no.

Per fare questo ci sono svariati modi, per fare un gioco semplice sicuramente potremmo definire una struttura dati dove poi andare a inserire tutti i dati necessari per ogni scena, per fare le cose per bene dovremmo allocare la struttura dati nella heap, definire il tutto nello stack sarebbe impossibile, la ps1 ha solo 2MB di ram, e anche se possiamo definire quanta stack utilizzare quando inizializziamo la memoria, non ci possiamo permettere di utilizzare 100-500 KB solo per definire le schermate, e questo solo per un gioco che potrebbe avere solo qualche decina di schermate, ma pensate ai giochi come Final Fantasy VII o VIII, hanno centinaia di fondali.

Quindi anche se carichiamo tutti i dati nella heap, il problema rimane, lo spazio scarseggia, abbiamo quindi bisogno di qualcosa che possa essere salvato nel cd-rom, e che possiamo leggere al bisogno, caricando in memoria solo le parti della schermata che ci interessa, potremmo usare un file JSON, o un XML, dove definire ogni scena, con le sue proprietà, e poi fare una funzione che legga il file, ne capisca la sintassi, e quindi estragga i valori necessari.
Oggi i file JSON e XML sono abusati, parser per questi tipi di file sono ormai uno standard, ma noi siamo negli anni 90, la cpu e la ram sono sicuramente sufficienti per riuscire a fare una cosa del genere, ma è un operazione meno efficiente da effettuare, e siccome siamo negli anni 90, ci piace ancora ottimizzare il più possibile, useremo un file binario.
Nel video qui sotto spiegherò nel dettaglio come ho implementato la lettura (lato PS1) di un file binario, e la scrittura.

Ottimizzazione lettura modelli 3d da cd-rom

01/08/2024

La memoria RAM della PS1 è limitata a 2MB e, oltre a questo limite, anche la CPU (33.8 MHz) non è particolarmente veloce rispetto agli standard odierni.
Quando ho iniziato ad inserire vari modelli 3d, per gestire le animazioni, ho notato che la lattura da cd-rom era molto veloce, ma il parsing dei dati dei files 3d era molto lento, il problema però non era specifico nella modalità in cui leggevo la geometria dei modelli, ma bensì, di come li caricavo in memoria.
In sostanza, leggevo tutti i dati della geometria, e per ogni indice, riallocavo in memoria con realloc, questo è estremamente lento:

for (i = 0; i < mesh->indicesLength; ++i) { int k; for(k = 0; k < 4; k++){ if(mesh->indices == NULL) { mesh->indices = malloc3(4 * sizeof(int)); if (mesh->indices == NULL) { printf("error on mesh->indices malloc3 \n"); return; } } else { mesh->indices = realloc3(mesh->indices, (4 * (n+1)) * sizeof(int)); if (mesh->indices == NULL) { printf("error on mesh->indices realloc3 \n"); return; } } mesh->indices[n] = f[kk]-1; n++; kk += 2; } }

una soluzione molto semplice è eliminare tutta la parte di malloc e realloc dentro al for, conoscendo già la lunghezza massima degli indici, posso fare un malloc unico:

if(mesh->indices == NULL) { mesh->indices = malloc3((4 * (mesh->indicesLength+1)) * sizeof(int)); if (mesh->indices == NULL) { printf("error on mesh->indices malloc3 \n"); return; } } for (i = 0; i < mesh->indicesLength; ++i) {...}

Il risultato è che, prima, ci voleva circa 30 secondi per caricare i dati dei modelli in RAM, mentre adesso è quasi istantaneo.

Animare modelli 3d su PlayStation 1

14/07/2024

Finalmente sono riuscito a gestire correttamente le animazioni dei modelli 3D, e il gameplay sta iniziando a prendere forma.
Nei prossimi aggiornamenti, mi concentrerò sui menu del combattimento, in particolare sulla gestione del menu degli oggetti e delle tecniche speciali.
Inoltre, amplierò le aree esplorabili, passando così da una versione minimale con poche schermate a una versione più completa e giocabile.