Programmare la PSP: Lezione 02
Creazione Del Primo Programma
Un'introduzione all'impostazione, alla creazione e all'esecuzione di una semplice applicazione "Hello World" per Sony PSP
Così, dopo aver letto la Lezione 01, hai un ambiente di sviluppo funzionante in cui creare i tuoi programmi. Adesso? Bene, questa è la parte che stavi aspettando, il tuo primissimo programma per PSP . Questo tutorial spiegherà le basi del linguaggio di programmazione C e svilupperà il fondamento su cui creerai il tuo regn- err... i tuoi programmi.
Creeremo una gerarchia di cartelle per organizzare il nostro progetto. Avvia CYGWIN bash shell, e scrivi "mkdir projects" e premi invio. Questo comando ("mkdir") sta per "make directory" e creerà una directory, o cartella, nell'attuale directory in cui stai operando. Adesso abbiamo una nuova cartella per tutti i nostri progetti , entraci scrivendo "cd projects" e premi invio. Adesso creeremo un altra directory per questo progetto specifico. Scrivi "mkdir helloworld" e premi invio. Ora passa alla nuova directory con "cd helloworld".
Il prossimo passo è aprire un editor di teso. Non importa quale apri, può essere il BloccoNote, il Wordpad, qualsiasi tu voglia. Io preferisco usare degli editor che siano dedicati alla modifica dei sorgenti in C/C++ perchè hanno integrati in essi le opzioni di sintassi (I uso Dev-C++), ma onestamente, non importa
(a condizione che sappiate usarlo).
Ora, creiamo un nuovo file e chiamiamolo "main.c" nella directory "helloworld". Questo conterrà il codice sorgente del nostro programma. Per coloro che non sanno cosa sia un codice sorgente (so che ci sarà qualcuno), il codice sorgente è quello che scriviamo per creare un programma. E' scritto in un modo che gli umani possono capire. In molti linguaggi, il sorgente ha bisogno di essere convertito in un formato che il computer (o nel nostro caso, la PSP) può capire. Questi sono chiamati linguaggi compilati, e il C e il C++ sono in questa categoria (la conversione è fatta da un compilatore che abbiamo impostato nella Lezione 01). Ci sono altri linguaggi di programmazione che usano quello che è chiamato un interprete per interpretare il codice sorgente e mandarlo alla macchina. Questi sono chiamati linguaggi di scripting (un esempio di linguaggio di scripting è il PHP).
Bene, così abbiamo un nuovo file che conterrà il nostro codice sorgente. Adesso dobbiamo cominciare a scriverlo. La prima parte del programma dovrebbe contenere dei commenti per dire a chiunque legga il nostro codice che tipo di programma sia, quando è stato scritto, e chi è l'autore. I commenti sono linee di codice sorgente che vengono omesse nella compilazione (o saltate dall'interprete nell'interpretazione nei linguaggi di scripting). I commenti sono parti molto importanti del codice, perchè quando tu (o qualcun'altro) tornerai a modificare il codice sorgente dopo, non ricorderai tutti gli intrecci del programma. Così, puoi lasciare a te stesso delle note sottoforma di commenti. I commenti sono segnalati dai caratteri "//" e "/ *" . Ogni volta che vedi un "//" vuol dire che il resto della linea sarà un commento. Un "/ *" dice che il compilatore (o l'interprete) ignorerà il codice fino a che raggiungerà un "* /" . I commenti segnalati da un "/ *" possono essere posti su più linee, mentre i commenti segnalati da "//" solo sul resto della stessa linea.
Allora, per cominciare il nostro programma, lasciamo un commento all'inizio su cosa è, quando è stato creato e da chi è stato scritto.
// Hello World - La mia prima App per PSP
/ *
Questo programma è stato creato da (Il tuo nome qui) il (Data Qui)
E' una semplice Applicazione "Hello World".
* /
La prossima porzione del programma è dove diciamo al compilatore quali header files e quali include files dobbiamo usare nel nostro programma. In genere quello che fa "#include" è copiare il codice dal file segnalato all'inizio del programma. Ciò permette di mantenere il programma semplice , usando comunque il codice avanzato che è già stato scritto per te. L' include può includere sia header files del compilatore (o che aggiungi al compilatore), o header files specifici per uno specifico progetto su cui stai lavorando. Il modo con cui includere questi file è usando < > o "" per farlo. Minore di e maggiore di includono un file dalla directory "include" del compilatore, mentre le virgolette includono un file dalla stessa directory del file che li sta includendo. Noi includeremo due file nel nostro programma. Il primo è "pspkernel.h". Questo file deve essere incluso in ogni singolo programma che scrivi per PSP. Contiene tutto il codice specifico per la tua PSP. Il tuo programma non funzionerà su PSP se non includi questo file. Il secondo file che includiamo è "pspdebug.h". Questo file contiene parecchie funzioni utili per il debugging dei tuoi programmi, ma specificatamente esso include la funzione che stiamo andando ad usare per scrivere il testo su schermo.
Così, aggiungi questo codice al tuo programma:
#include < pspkernel.h >
#include < pspdebug.h >
Ora diremo alla PSP qualcosa circa il nostro programma. Questo non è realmente importante, il programma può essere compilato senza di esso, ma è sempre una buona idea inserirlo (per compatibilità). Il primo attributo è il nome del programma, ma non è realmente il nome del programma che apparirà
(lo cambieremo dopo). Gli altri valori sono altri attributi (mantienili), versione principale, versione secondaria. Li lasceremo tutti eccetto il nome come default. Allora, aggiungi la seguente linea al tuo programma:
PSP_MODULE_INFO("Hello World", 0, 1, 1);
Adesso imposteremo la funzione che useremo per scrivere su schermo. Questo passo è facoltativo, ma rende i programmi basati sulla scrittura di testo più semplici da scrivere. La base dietro questo codice è cambiare la funzione propria della PSP, chiamata "pspDebugScreenPrintf" in qualcosa più semplice. Questa funzione è usata per scrivere su schermo (che vedrete successivamente). Quello che in definitiva stiamo facendo è rinominare "pspDebugScreenPrintf" in "printf". Così ogni volta che userai "printf" da ora in poi, il compilatore lo tratterà come se avessimo scritto "pspDebugScreenPrintf". E quello che fareno ora; definiremo "printf" come "pspDebugScreenPrintf" in questo modo:
#define printf pspDebugScreenPrintf
Ok, ho una cattiva notizia ed una buona notizia. La cattiva notizia, il prossimo blocco di codice è abbastanza complicato. La buona notizia, non hai bisogno di capirlo. Ecco una breve spiegazione su cosa fa (lasceremo la sintassi reale e la spiegazione linea per linea successivamente). Quello che questo blocco di codice contiene sono le funzioni che saranno chiamate nel nostro programma. Le funzioni imposteranno il tuo programma per avviarsi su PSP e per permettere che non vi preoccupiate di un possibile blocco della PSP o dell'uscita del gioco quando non lo volete. Inserisci questo blocco nel tuo programma:
/ * Exit callback * /
int exit_callback(int arg1, int arg2, void *common) {
sceKernelExitGame();
return 0;
}
/ * Callback thread * /
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/ * Imposta il callback thread e ritorna il suo thread id * /
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0) {
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
Ora, definiremo la funzione "main". Ogni programma in C e C++ necessita la funzione mai. Questo è dove il codice delle funzioni C (ed alcune C++) viene eseguito nel paradigma procedurale. Ciò significa che il codice va in un percorso lineare. Per esempio, se avete il seguente codice:
//Non metterlo nel tuo programma.
//E' un esempio.
int myFunction() {
//Stampa 'A'
return 0;
}
int main() {
//Stampa 'B'
myFunction();
//Stampa 'C'
return 0;
}
I commenti mostrano cosa viene eseguito (guarda sopra se non ricordi cosa sono i commenti). Il programma stamperebbe 'B' allora stamperebbe 'A' allora stamperebbe 'C' perchè il compilatore comincia dalla funzione main. Stampa la 'B' vedendo che è chiamata in "myFunction" che è definito sopra e arriva qui, vedendo che è necessario stampare 'A' e a questo punto ritorno dove era rimasto e stampa 'C.' Tutti i tuoi programmi (fino a che non utilizziate il C++ avanzato) seguiranno questa struttura lineare. Così, la funzione "main" è vitale per il tuo programma. Per definire una funzione, utilizzate la seguente struttura: "[tipo di ritorno] [nome funzione]() {". Il tipo di ritorno è quello che la funzione manderà indietro al programma. Per "main" questo dovrebbe essere sempre di tipo "int" (che sta per integer, numero intero). Il nome della funzione è il vostro nome per la funzione, la funzione "main" sarà ovviamente chiamata "main." Così definisci la tua funzione inserendo la seguente linea nel tuo codice:
int main() {
Adesso dobbiamo aggiungere due linee per impostare lo schermo e per usare delle funzioni che inseriremo presto (di cui non necessiti sapere come funzionant). Anche se non dovete sapere come quelle funzioni lavorino, è importante afferrare il concetto di come chiamare le funzioni. E' attualmente molto semplice. Devi solo inserire il nome della funzione con le parentesi alla fine (e se ha dei parametri, devi inserirli nelle parentesi, ma lo vedremo dopo). Ogni linea nel tuo programma necessita un punto e virgola alla fine. La ragione è perchè il compilatore non vede nessuno spazio bianco. Tra le linee di codice, potresti avere 100 linee vuote, e il compilatore non ne farebbe caso. Ciò è utile perché permette di formattare il codice come desideri , in un modo che puoi capire. Puoi raggruppare insieme le linee, o fare quello che vuoi con lo spazio bianco. Ma, alla fine della linea, hai bisogno di un punto e virgola. Così, aggiungi queste due linee al tuo programma per impostarlo:
pspDebugScreenInit();
SetupCallbacks();
Adesso è tempo di scrivere del codice di cui potremo vedere i risultati. Ricordi che abbiamo definito "pspDebugScreenPrintf" come "printf"? Bene, ora è il momento di usare quella funzione. Il modo con cui stamperemo il testo sul video è chiamando la funzione "printf" con un parametro. Un parametro è una variabile che puoi passare ad una funzione per essere usata. Diventere più pratici quando scriverete le vostre proprie funzioni. Così, con "printf" per fargli eseguire dell'output sullo schermo, dobbiamo passargli una stringa. Inseriremo come output "Hello World" passando questa stringa alla funzione. "Printf" è una funzione potente, perchè potete anche usarla per mostrare altre variabili sullo schermo. Passeremo questi come altri parametri, ma questo lo vedremo a tempo debito. Per adesso, stamperemo su schermo "Hello World", così:
printf("Hello World");
Ecco fatto, avete detto con "printf" si stampare su schermo. Adesso dobbiamo solo completare alcune cose e allora il nostro codice sorgente sarà pronto per essere compilato. Dobbiamo fermare il nostro programma, in modo da poter vedere l'output sullo schermo. Se non lo facciamo, il programma può bloccarsi o ritornare al Menu della PSP. Inoltre non vedrai la tua bella frase sullo schermo, visto che sarà cancellata troppo velocemente. Allora, aggiungi questa linea per fermare il programma fino a che il tasto "Home" sia premuto e l'utente torni al sistema operativo della PSP.
sceKernelSleepThread();
Adesso dobbiamo dare alla nostra funzione un valore di ritorno, da quando lo abbiamo definito ("int main()"), abbiamo detto al compilatore di ritornare un numero intero. Così fai ritornare uno '0' (è uno zero, non una 'o') facendo così:
return 0;
E finalmente termina la funzione inserendo una parentesi graffa chiusa:
}
E questo è tutto per il programma! Ora dobbiamo solo dire al compilatore come vogliamo compilare questo progetto creando un Makefile. Così, creiamo un nuovo file chiamato "Makefile" senza estensione. Una volta fatto questo, aprilo con un text editor.
Inserisci questo nel tuo Makefile:
TARGET = hello
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/ lib/ build.mak
Puoi usare questo Makefile come base per tutti i tutti i tuoi progetti semplici. Qualche volte avrai bisogno di aggiungere librerie o altro a questo file, ma per adesso è ragionevolmente semplice. In pratica dice al compilatore di prendere "main.c" e di costruire, usano il PSPSDK, un file .pbp che la tua PSP può leggere. Quello che dovrai modificare se usi questo Makefile in altri progetti. è dove dice "PSP_EBOOT_TITLE = Hello World". Puoi cambiare dove dice "Hello World" con il titolo del tuo programma, questo è il nome che apparirà nel menu Gioco della PSP quando selezioni il file.
Ora avvia CYGWIN Bash Shell e con "cd" recati su "projects/helloworld". Digita "make" e la shell ti ritornerà alcune informazioni. Ti dirà se il tuo codice sorgente contiene degli errori che lo rendono non compilabile. Generalmente, se mostra degli avvertimenti, non è un gran problema. Gli errori sono le cose che devi evitare, gli avvertimenti sono solo possibili punti che potrebbero causare dei bug.
Se non ricevi nessun errore, congratulazioni! Hai creato e compilato con successo la tua prima applicazione per la PSP. Scommetto che morite dalla voglia di testarlo. Bene, inserisci "C:/cygwin/home/NomeUtente/projects/helloworld/EBOOT.PBP" sulla tua PSP come qualsiasi altra applicazione homebrew, e provala in prima persona!
State connessi per la Lezione 03, che spiegherà come creare i loops, gli stati di if/then , e come rilevare l'input di un tasto.