Tipo di contenuto
Profilo
Sezioni
Calendario
Tutti i messaggi di Diamaxus
-
Programmazione per Game Boy Advance
Diamaxus ha risposto a una discussione di Diamaxus in Hobby e passioni
Ahah vabbè quello è normale, sono acronimi- 84 risposte
-
Programmazione per Game Boy Advance
Diamaxus ha risposto a una discussione di Diamaxus in Hobby e passioni
Ma come!? ho cercato di spiegare nel modo più semplice possibile XD Scherzo, mi rendo perfettamente conto che non è semplice, ma magari prova a leggerlo con calma.- 84 risposte
-
Ciao a tutti! Come ho detto nell’aggiornamento di qualche giorno fa, sto imparando a programmare per il GBA (GameBoy Advance) e vorrei aprire questa discussione sia per discuterne con con voi che per mostrarvi i miei progressi. Vorrei anche impostarlo come se fosse un tutorial nel caso qualcuno di voi fosse interessato a imparare, perciò citerò le fonti delle informazioni che vi darò, soprattutto per quanto riguarda le caratteristiche Hardware. Taggo @evilespeon e @ZedeFire che erano interessati alla discussione e altre persone che potrebbero essere interessate: @Macca @Porygatto che visto che sta giocando a Zaffiro magari gli interessa anche capire come caricare gli sprite sul gba , @Keroro @liviopocoyo @LadyDarkrai e @Vale e inoltre ringrazio @VictiniPika per avermi permesso di inserire i link. Partiamo proprio dall’hardware del GBA per poi passare ai comandi di base che useremo oggi. Cercherò di semplificare il più possibile. Se avete delle domande chiedete pure, farò del mio meglio per farvi capire i concetti. Chi vuole può saltare direttamente alla fine del post per vedere direttamente il risultato del mio primo programma. Il GBA ha un processore ARM a 32 bit. I giochi sono distribuiti in Game Paks che sono costituiti da una ROM per il codice e i dati e spesso dalla RAM per salvare le informazioni di gioco. Ha uno schermo LCD di 240x160 px capace di visualizzare 32768 colori (15 bit = 215 valori rappresentabili). Altre caratteristiche principali che saranno utili sono: Video: 3 modalità bitmap e 3 modalità tilemap 4 layer separati di tilemap (per gli sfondi) e 128 sprite (per gli oggetti) trasformazioni affini (rotazione/scalatura/trasformazione obliqua) su due sfondi e 32 oggetti effetti grafici speciali: mosaico, additive blending, fade a nero/bianco suono: 6 canali 4 generatori di suoni del GameBoy originale: 2 di onde quadre, 1 di onde generiche e 1 generatore di rumore 2 canali “DirectSound” per suonare campioni e musica. Altro: 10 tasti (4 frecce direzionali, select/start, A e B, L e R) 14 interrupt hardware modalità multiplayer a 4 giocatori attraverso cavetto multiboot sensore opzionale a infrarossi, sensore di luce e giroscopio. Linguaggio di programmazione C (possibile anche il C++) e Assembly ma esistono anche tool per programmare in altri linguaggi. Dal punto di vista della programmazione, il GBA non ha un sistema operativo (a differenza delle console moderne) il che significa che quando programmiamo andiamo a scrivere direttamente nei registri del processore. Sezioni di memoria Area | indirizzo di inizio | indirizzo di fine | lunghezza | dimensione della porta | descrizione ROM | 0000:0000h | 0000:3FFFh | 16 kb | 32 bit | memoria del BIOS, non può vi si può accedere per leggere i dati ma solo per scriverli. EWRAM | 0200:0000h | 0203:FFFFh | 256 kb | 16 bit | External Work RAM. Disponibile per il codice e i dati, viene usata dal cavo multiboot. IWRAM | 0300:0000h | 0300:7FFFh | 32 kb | 32 bit | Internal Work RAM. Disponibile per codice e dati, è la sezione di memoria più veloce. IO RAM | 0400:0000h | 0400:03FFh | 1kb | 16 bit | Registri Input-Output, è la sezione dove si controllano la grafica, il suono, i tasti e altre caratteristiche. PAL RAM | 0500:0000h | 0500:03FFh | 1kb | 16 bit | memoria usata per 2 palette ciascuna di 256 colori con profondità 15 bit, la prima è per gli sfondi, la seconda per gli sprite. VRAM | 0600:0000h | 0601:7FFFh | 96 kbit | 16 bit | Video RAM dove vengono conservati i dati per gli sfondi e gli sprite. OAM | 0700:0000h | 0700:03FFh | 1 kb | 32 bit | Object Attribute Memory, permette di controllare gli Sprite. PAK ROM | 0800:0000h | variabile | variabile | 16 bit | Game Pak ROM. È dove si trova il gioco e dove inizia l’esecuzione se non si usa un cavo multiboot. Sebbene la dimensione sia variabile il limite è 32 MB. Cart RAM | 0E00:0000h | variabile | variabile | 8 bit | Cartridge RAM. È dove si trovano i dati di salvataggio. La dimensione totale è variabile ma si consiglia 64 kb. N.B. kb sta per kilobit non kilobyte. fonte: https://gbadev.net/tonc/hardware.html Strumenti Per programmare in C vi basta un qualunque editor di testo, va bene anche NotePad. Per la compilazione della ROM serve un tool specifico, chiamato devkitPRO e se siete su Windows anche la shell Msys. Potete trovare tutte le info qui se siete interessati: https://devkitpro.org/wiki/Getting_Started Il motivo per il quale non usiamo un ambiente di sviluppo come Eclipse, DevC++ ecc. è che il Makefile che dobbiamo usare è speciale, in quanto il GBA controlla che l’intestazione della ROM del gioco sia corretta, in caso contrario dà errore. La struttura della cartella in cui salveremo i file con il codice C è quella in figura: in "include" vanno i file *.h, in "source" i file *.c Come emulatore io uso mGBA ma va bene uno qualsiasi. Nozioni base del C Vi darò solo quelle essenziali che userò di volta in volta, altrimenti sarebbero troppe. XD Innanzitutto dovete sapere che ogni istruzione C deve terminare con il punto e virgola (tranne in alcuni casi specifici come il ciclo for/while e le direttive al preprocessore). La dichiarazione di una variabile ha questa forma: tipo_della_variabile nome_della_variabile; Esistono vari tipi, quelli che vedrete più spesso sono int, char e float ma ce ne sono altri che potete vedere su wikipedia se siete interessati. Attraverso int dichiariamo una variabile di tipo intero ossia un numero intero. Attraverso char dichiariamo una variabile che contiene un carattere (cioè una lettera). Attraverso float dichiariamo una variabile che contiene un numero con la virola. Ad esempio attraverso l’istruzione int a; dichiaro una variabile di tipo intero che chiamo a. Per assegnare un valore a questa variabile devo scrivere ad es. int a = 10; Comunque non vi preoccupate che appena li incontriamo vi spiego di volta in volta quali sono. Poiché il nostro file sarà diviso in file.h e file.c per includere le funzioni che andremo a scrivere nei file *.h usiamo la primitiva #include “file.h” (senza punto e virgola, ricordate? Ci sono delle eccezioni ). Un altro elemento che avete bisogno di conoscere è il vettore, che è sostanzialmente una collezione di elementi per farla semplice. Immaginate che sia uno scaffale dove dove sono riposti in ordine degli oggetti. Data una variabile intera dim (che rappresenta la lunghezza del vettore), definiamo un vettore ad es. di tipo intero in questo modo: int vettore[dim]; Sostituendo tra le parentesi quadre un numero indichiamo uno specifico elemento di quel vettore, ad es. int vettore[0]; indica il primo elemento del vettore. Aggiungendo un secondo indice, rappresentiamo una matrice (link a wikipedia). Ad es. int matrice[dim1][dim2]; dove dim1 e dim2 sono i numeri di righe e di colonne della matrice. Il mio primo programma per GBA: Hello World Per i veterani del C, sappiate che non avendo un sistema operativo, non possiamo usare printf() o le funzioni incluse in stdio.h per scrivere sullo schermo. Quindi il primo programma che ho fatto è stato quello per disegnare a schermo una barretta verticale, come quella del classico PONG. Inizio con il commentare il mio file header helloworld.h: typedef unsigned short u16; typedef unsigned int u32; typedef u16 color; #define MEM_IO 0x04000000 #define MEM_VRAM 0x06000000 #define REG_DISPCNT *((volatile u32*)(MEM_IO + 0x0000)) #define DCNT_MODE3 0x0003 #define DCNT_BG2 0x0400 #define SCREEN_W 240 #define SCREEN_H 160 #define WHITE_COLOR 0x7FFF typedef color m3_line[SCREEN_W]; #define M3_MEM ((m3_line *)MEM_VRAM) In questo file quello che faccio in sostanza è definire alcune costanti e alcuni tipi che mi serviranno nel programma principale. u16 e u32 sono due tipi interi che definisco, la u sta per unsigned cioè senza segno 16 e 32 sono i bit che occupano in memoria. Il tipo color lo uso semplicemente per ricordarmi che il GBA è in grado di rappresentare i colori in 16 bit (il sedicesimo non viene usato quindi in realtà sono 15). MEM_IO è l’indirizzo del registro di Input-Output in base esadecimale. MEM_VRAM è l’indirizzo della RAM video espresso in base esadecimale. REG_DISPCNT è il registro di controllo dello schermo (Display Control Register), è complicata da spiegare in parole semplici questa istruzione ma diciamo che serve per accedere direttamente al contenuto del registro. Per farvi meglio capire come è fatto il registro vi allego questa immagine presa qui: MEM_IO + 0x0000 = 0x04000000 ossia l’indirizzo 0400:0000 cioè l’indirizzo dell’IO RAM. Serve perché il valore di quella variabile potrebbe cambiare indipendentemente da quello che scriviamo nel codice, e stiamo dicendo al compilatore di ignorarla (volatile persuation). Non vado nel dettaglio perché è davvero complicato da spiegare. DCNT_MODE3 e DCNT_BG2 servono ad impostare la modalità dello schermo, di cui vi parlerò nel prossimo capitolo più nel dettaglio. SCREEN_W E SCREEN_H sono le dimensioni in pixel dello schermo. WHITE_COLOR è semplicemente il colore bianco espresso in base esadecimale. Per concludere le ultime due istruzioni mi servono a mappare i pixel dello schermo: con la prima creo un vettore di grandezza pari alla larghezza dello schermo e con la seconda indico l’indirizzo della Video RAM e siccome devo disegnare una linea deve essere dello stesso tipo con cui definisco le variabili a cui assegno un colore. Passiamo al file helloworld.c che ci serve a disegnare la barretta. #include "helloworld.h" int main(void) { u32 x = 10; u32 y = 10; REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; for (u32 colonna = x; colonna <= (x + 2); colonna++) { for (u32 riga = y; riga <= (2 * y); riga++) { M3_MEM [riga][colonna] = WHITE_COLOR; } } while(1); return 0; } int main(void) {…} è la funzione principale, che ci permette di eseguire le nostre funzioni che abbiamo eventualmente definito nei file *.h . x e y sono le coordinate che ci permettono di definire un punto sullo schermo, assegno a queste il valore 10 per far partire la barretta in una posizione più centrale poiché sullo schermo l’origine degli assi si trova in alto a sinistra. REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; mi serve per impostare i bit necessari ad attivare la modalità bitmap 3 e background2 sullo schermo. È arrivato il momento di disegnare la mia barretta, cosa che faccio attraverso due cicli for in modo tale da fissare il valore della coordinata x e far variare la coordinata y. L’istruzione M3_MEM [riga][colonna] mi permette di accedere alla posizione x,y sullo schermo per farla breve, nella pratica vado ad assegnare il valore “bianco” al registro della VRAM. While(1); serve per non far concludere il programma, poiché non essendoci un sistema operativo se il programma terminasse il comportamento non è definito. Non vi mostro il Makefile questa volta, perché già così sono un sacco di informazioni da assimilare, e inoltre in questo caso non mi è servito modificare il Makefile fornito da devkitPRO. XD A questo punto vado sulla shell scrivo cd /percorso/dove/hai/messo/la/cartella/del/tuo/programma faccio invio, e scrivo make questo è quello che uscirà scritto nella shell: Se è andato tutto a buon fine uscirà scritto "ROM fixed!". Aprendo la ROM questo è quello che apparirà a schermo: Per oggi è tutto, ci vediamo al prossimo capitolo. Se avete domande fatele pure, e fatemi sapere se vi interessa questa rubrica o se c'è qualcosa che non capite.
- 84 risposte
-
Questo lo conosco
-
Va bene
-
Ma forse lui li conosce già XD
-
Addio al complimento sugli intenditori mi sa Aggiungo anche questo alle cose da vedere u.u
-
Quel periodo l’ho avuto anche io intorno alle medie XD Infatti ho visto anche anime parecchio vecchi tipo kiss me licia e lamù, quello originale degli anni ‘80 XD mettendo ste sigle però me ne stai facendo conoscere anche tanti che non ho visto
-
Di nulla
-
Se sei tu a consigliarlo lo devo fare assolutamente
-
Ah ho capito io ranma lo conosco solo di nome, però deve essere bello; devo vederlo un giorno o l’altro
-
Vero… infatti ormai guardo praticamente solo serie anime XD Questo non lo ricordo
-
Lo aspetto anche io Sempre uguali noi
-
Peccato che non si è concluso lo adoravo da piccolo grazie
-
Vero Grazie per pensarlo
-
Anche io l’ho visto quello giapponese… ma chi? Io e te?
-
È che io ho sempre adorato i cartoni animati (come li chiamavo quando ero piccolo XD ora li chiamo anime)
-
Io la vedevo XD
-
Sala d'attesa tg espi
Diamaxus ha risposto a una discussione di evilespeon in CLUB DEL TG ESPI's Tg espi
Sì ma io intendevo non sono sicuro che le abbia vendute XD Sì l'importante è quello -
art gallery [evilespeon] LE F0LLI AVVENTURE DI ESPI
Diamaxus ha risposto a una discussione di evilespeon in Art Gallery
Di nulla senpai -
Sala d'attesa tg espi
Diamaxus ha risposto a una discussione di evilespeon in CLUB DEL TG ESPI's Tg espi
ah boh, non sono sicuro -
art gallery [evilespeon] LE F0LLI AVVENTURE DI ESPI
Diamaxus ha risposto a una discussione di evilespeon in Art Gallery
Entrambi -
Sala d'attesa tg espi
Diamaxus ha risposto a una discussione di evilespeon in CLUB DEL TG ESPI's Tg espi
Però io penso di detenere il record di castagne regalate -
Sala d'attesa tg espi
Diamaxus ha risposto a una discussione di evilespeon in CLUB DEL TG ESPI's Tg espi
Mi piace molto... per colpa mia temo... spero che si potranno di nuovo regalare
