Jour 8 - DS Hardware ← Précédent

UTILISEZ EFS_LIB plutot

EFS est synonyme de système de fichiers embarqués et cela vous permet de mettre d’autres fichiers “a l’interieur” d’une ROM NDS sans toutefois utilisé la rom comme un endroit de stockage mais seulement d’appel au fichiers. Pour des tutoriaux plus approfondies google est votre ami.

Tutoriel en francais Dev-fr

Jour 9 - Système de Fichiers de PA

Vue d'ensemble

Tout d’abord, qu’est-ce qu’un système de fichiers ? Pourquoi en a-t-on besoin ?

En fait, un système de fichiers, ce n’est pas grand chose, simplement une autre façon d’ajouter des fichiers à votre rom. Vous connaissez déjà la méthode simple : ajouter les fichiers lors de la compilation soit avec un fichier .c, ou en utilisant un fichier dans le dossier data (voir les exemples de gif/jpeg). Il existe une méthode qui consiste à ajouter les fichiers après la compilation. Oui, c’est possible, et ca présente quelques avantages :

  • On peut dépasser la limite de 4Mo, puisque le fichier n’est pas stocké dans la RAM, mais directement sur la rom de la carte flash gba (NdT : traduction approximative de on the gba flash cart’s rom).

Cela signifie aussi que de tels fichiers ne marcheront qu’avec une carte flash gba, mais ne fonctionneront pas avec WMB, CF ou autre... (J’ai fait une version qui marche avec les autres, mais il y a la limite de 4Mo...)

  • Si on peut ajouter des fichiers après la compilation, l’utilisateur pourra aussi ajouter des fichiers... Il y a beaucoup d’applications possibles, comme un lecteur de musique personnalisable (hehe, Kleevah !), un visionneur d’images, etc... nDoS utilise un tel système pour stocker et lire les contacts Outlook/Thunderbird... Je l’ai même utilisé dans un projet actuel pour supporter les skins avec des fichiers gifs (Kleevah l’a aussi fait avant moi :-P). Vous voyez donc que ça permet à l’utilisateur de personnaliser votre programme !

Il y a cependant quelques inconvénients...

  • Ça ne fonctionne pas du tout avec WMB (Comme je l’ai dit précédemment, on retrouve la limite de 4Mo...)
  • C’est un peu plus compliqué à utiliser que la méthode classique, bien que j’ai essayé de faire au plus simple

Le système de fichiers DS de PAlib s’appelle PAFS (PAlib File System). Vous pouvez aussi utiliser GBFS, qui existait pour PAlib avant que PAFS ne sorte, et qui fonctionne toujours pour des raisons de compatibilité...

Fichiers requis

A vos marques! Prêts ? Partez ! Comme vous pouviez le deviner, quelques fichiers sont requis pour faire marcher le système de fichiers. Commençons par regarder l’exemple PAFS/PAFS de PAlib, qui est le plus simple. Ouvrez le dossier, vous trouverez plus de fichiers que d’habitude...

  • PAFS.exe est le fichier principal. C’est celui qui ajoute les fichiers voulus à la rom, il est donc indispensable...
  • PAFS.log contient tout ce que PAFS a effectué ou rapporté, comme les fichiers ajoutés, leur taille, etc... (c’est un fichier de log)
  • PAFS.bat est important, ouvrez-le avec un éditeur de texte (bloc-note, etc.) : Il contient simplement PAFS PAFS.ds.gba. Mais à quoi ça sert ?
    • PAFS est l’exécutable à charger (PAFS.exe)
    • PAFS.ds.gba est le fichier auquel vous voulez ajouter des fichiers après compilation... Je les mets dans PAFS.ds.gba, parce que c’est le fichier dans lequel je mets ma carte flash, mais vous pouvez aussi les ajouter au .nds.
    • Après ça, vous pouvez ajouter d’autres options, comme le dossier dans lequel vos fichiers sont placés. Si vous ne précisez pas de dossier, comme dans l’exemple, les fichiers seront cherchés dans le dossier Files/.

Bon, vous voyez le dossier Files ? Il contient plusieurs fichiers texte. Ils ne servent qu’à vérifier que l’ajout de fichiers marche. Si ça marche, vous devriez pouvoir ouvrir ces fichiers depuis votre DS (comme un lecteur de livre !). Allons maintenant voir le code !

Vous pouvez aussi trouver une copie des fichiers PAFS.exe et .bat dans le dossier PAlibTools.

Important!!! Il y a des étapes à suivre pour que le programme ne plante pas au chargement des données:

  • Compiler votre code avec le build.
  • Changer dans le “PAFS.bat” le nom “PAFS.ds.gba” et “PAFS.nds” par les noms qui ont été créé par votre build.
  • Executer le “PAFS.bat”.
  • Ne plus utiliser le PAFS.nds mais le nouveau NewPAFS.nds qui s’est créé dans le même répertoire.

Voila ça marche!!!.

Charger un fichier

Restez dans le même exemple, et ouvrez main.c. Voici ce que vous devriez avoir dans votre fonction principale :

PA_InitText(0, 0);  // Initialise the text system on the bottom screen	
PA_InitText(1, 0);  // Initialise the text system on the top screen
	
PA_OutputText(1, 0, 0, "Loading PAFS...");
	
 
u32 FileNumber = PA_FSInit(); // Inits PA File System, and returns the number of files
 
PA_OutputText(1, 0, 1, "  Files   : %d    ", FileNumber);		
			
// For each file, we'll draw it's name on the bottom screen...
s32 i;	
for (i = 0; i < FileNumber; i++){
	PA_OutputText(0, 0, i, "%s.%s   Size : %d, %d", PA_FSFile[i].Name, PA_FSFile[i].Ext, PA_FSFile[i].Length, PA_FSFile[i].FilePos);
}
	
// Output the first file text on the top screen, just to test...
PA_OutputText(1, 0, 5, "File 0 : %s", PA_PAFSFile(0));
PA_OutputText(1, 0, 7, "File 1 : %s", PA_PAFSFile(1));
PA_OutputText(1, 0, 9, "File 2 : %s", PA_PAFSFile(2));	
 
// Infinite loop to keep the program running
while (1)
{ 
	PA_WaitForVBL();
}

Nous commençons avec 2 inits des textes, un pour chaque écran, et un texte simple “Loading PAFS...”

Ensuite, vient la partie importante:

  • u32 FileNumber = PA_FSInit(); PA_FSInit est la fonction qui initialise le système de fichiers. Si vous ne l’employez pas, vous ne pourrez lire aucun de vos fichiers… Pour l’information, il y a des scans fait rapidement par votre ROM pour rechercher le système de fichiers… et alors il lit l’information sur les différents dossiers. Cette fonction renvoie le nombre total de dossiers, et stocke cela dans la variable FileNumber.

Après arrive ce bout de code PA_OutputText(1, 0, 1, " Files : %d “, FileNumber); En esperant que vous avez lu le tutorial a propos du texte ! Il affiche juste le nombre de fichiers donnés par PA_FSInit… Maintenant, la partie intéressante commence :

s32 i;	
for (i = 0; i < FileNumber; i++){
	PA_OutputText(0, 0, i, "%s.%s   Size : %d, %d", PA_FSFile[i].Name, PA_FSFile[i].Ext, PA_FSFile[i].Length, PA_FSFile[i].FilePos);
}

Qu’est-ce que cela fait ? Pour chaque fichier (le premier étant le fichier 0, et FileNumber indicant le nombre de fichiers), il produira sur l’écran le nom du fichier (sans l’extension, exemple : .txt, .dat, . jpg) et sa position dans le système de fichiers. Vous n’emploierez pas beaucoup ces 2 dernières informations, mais le nom et son extension seront beaucoup utilisés plus tard…

  • Le nom, parce qu’il permettra à l’utilisateur d’indiquer quel fichier charger, par exemple.
  • Et l’extension, parce que vous ne traiterez pas un fichier de la même manière si c’est un son, du texte, une image, ou autre chose…

Comme vous pouvez le voir, c’est simple pour obtenir toute cette information. Tout se trouve dans la fonction PA_FSFile, PA_FSFile[n] pour le numéro du fichier (attention, il commence par le fichier0, non 1). .Name, .Ext, .Length et .FilePos sont les 4 variables possibles.

La dernière chose que vous voyez (il n’y a rien dans la boucle infinie !), est PA_OutputText(1, 0, 5, “File 0 : %s”, PA_PAFSFile(0));. C’est la chose la plus importante à se rappeler, alors ouvrez grand vos yeux !

  • PA_PAFSFile(File Number) est un indicateur vers le fichier réel avec un nombre de fichiers donné. Pour faire n’importe quoi avec ce fichier, vous devrez employer ceci… ça remplace le nom du fichier, comme si vous employiez mollusk.gif appelé par GIF (dans l’exemple de GIF…), ici vous devrez le donner dans PAFS… Dans cet exemple, nous avons employé l’indicateur dans un texte… pourquoi ? Simplement parce que les fichiers que nous avons mis étaient des fichiers textes, et ainsi nous pouvons montrer le texte sur l’écran… Si vous essayiez de montrer le contenu d’un autre type de fichier (une vidéo, une musique), vous ne pourriez pas lire n’importe quoi sur l’écran…

Ok, maintenant que nous avons vu le code, vous pouvez compiler… Avant de mettre la ROM sur Nintendo DS, n’oubliez d’ajouter les fichiers! Pour ce faire, ouvrez PAFS.bat qui se trouve dans le dossier avec build.bat, qui inclura tous les fichiers. Essayez, vous devriez voir les textes sur votre écran de DS !

Yup, ceci est déjà fini ! Mais le tutorial pas encore. Il y a encore quelques trucs à voir, comme lire la structure des fichiers, ou utiliser PAFS avec une carte WMB ou CF… Il y a également quelques exemples de PAFS employé pour charger des dossiers, de la musique ou des images, et vous les trouverez dans C:\devkitPro\PAlibExamples\PAFS.

Utiliser des dossiers

Je reconnais que ce n’est pas si utile que ça d’avoir des dossiers dans un système de fichiers, mais ça pourra aider pour la lecture des fichiers. Par exemple, on peut demander à l’utilisateur de mettre ses musiques dans Files/Music, et ses images dans Files/Images, etc ...

Vu que ce n’est pas si intuitif (désolé, j’ai fait de mon mieux !), je vais expliquer en détail comment les utiliser.

L’exemple PAlib est PAFS Folders. Je ne vais pas détailler toutes les fonctions PAFS que nous avons vu juste avant, donc j’espère que vous avez déjà mémorisé tout ça! Si ce n’est pas le cas, jetez y un coup d’œil à nouveau et vérifiez quelques détails si vous n’êtes pas sûrs.

Cet exemple est un peu plus compliqué que ce que nous avons vu avant, mais je vais faire de mon mieux pour rendre ça aussi facile que possible. Il contient deux fonctions, la classique fonction main, et WriteFolders. En fait, ce n’est pas vraiment une fonction qu’on va utiliser avec PAFS, mais c’est utilisé ici pour afficher les informations à propos du dossier.

Le code principal est exactement le même que celui qu’on vient de voir, on a juste rajouté WriteFolders(0); à l’intérieur. Cette fonction lit le contenu (sous-dossiers et fichiers) du dossier numéro 0. Si vous ne savez pas combien de dossiers il y a, vérifiez juste la valeur de PA_FSSys→Nfolders, et vous saurez (ça compte les dossiers ET les sous-dossiers ensemble). Le dossier 0 est en fait le dossier Files.

void WriteFolders(u16 N){ // Recursive function to write the number of folders
 
u16 Nfolder = N;	
	// Write the folder's name...
PA_OutputText(1, indent, foldery, "%s : %d folders, %d files", PA_FSFolder[Nfolder].Name, PA_FSFolder[Nfolder].NFolders, PA_FSFolder[Nfolder].NFiles); 
	foldery++;	
	
	if (PA_FSFolder[Nfolder].NFolders > 0){ // For every subfolder, check their subfolders
		indent+=2; // Indents for the subfolders	
		s32 k;		
		for (k = 0; k <  PA_FSFolder[Nfolder].NFolders; k++){  
			// Note : PA_FSFolder[i].FirstFile stores the number of the first file, 
			//so the files go from 
			//PA_FSFolder[i].FirstFile to PA_FSFolder[i].FirstFile + PA_FSFolder[i].NFiles
			WriteFolders(PA_FSFolder[Nfolder].FirstFolder + k); // Check the subfolders
		}
		indent -= 2;
	}
}

Pour rester aussi simple et clair que possible, je ne vais pas décrire toutes les lignes de code de cette fonction. Il faut juste savoir qu’elle affiche les dossiers et sous-dossiers et différents niveaux sur l’écran, pour montrer quel dossiers contient quels autres...

Tout ce qu’il faut comprendre est ce qui est contenu dans le tableau de structure PA_FSFolder. Il contient les informations sur les différents dossiers, et voila les variables :

  • PA_FSFolder[Nfolder].Name est le nom du dossier, Files par exemple.
  • PA_FSFolder[Nfolder].NFolders est le nombre de dossiers qu’il contient.
  • PA_FSFolder[Nfolder].FirstFolder est le numéro du premier dossier qu’il contient. Donc si vous avez 3 sous-dossiers, et que le premier est le numéro 2, vos trois dossiers ont pour numéro 2, 3, et 4.
  • PA_FSFolder[Nfolder].NFiles est le nombre de fichiers qu’il contient, un peu comme pour les dossiers.
  • PA_FSFolder[Nfolder].FirstFile est comme pour les dossiers, le numéro du premier fichier. Vous ajouez juste 1 pour avoir le fichier suivant, etc...

Et voila !

Faites juste comme avant, compilez, utilisez PAFS.bat, et regardez le résultat sur votre DS.

Je ne vais pas donner plus de détails que ça, et on va passer à l’utilisation de PAFS sur émulateur (comme dualis) et WMB.

PAFS dans la Ram

J’ai dit au début que PAFS stockait les fichiers dans la rom au lieu de la ram, mais vous pouvez forcer le stockage des fichiers dans la ram. Grâce à ça, cela marchera sur les émulateurs, WMB, et n’importe quel type de linker...même si ça a quelques limitations, la première étant la taille maximum de 4MB pour la rom, et la seconde étant que vous devez spécifier dans votre code combien de mémoire vous voulez donner à l’utilisateur. Si vous ne spécifiez pas assez, ça ne marchera pas. Le code est vraiment simple, même s’il y a deux choses de plus que le code PAFS classique. Ouvrez PAFS_Ram et regardez !

// Includes
#include <PA9.h>       // Include for PA_Lib
 
 
PA_FSRam(100000);  /* Ceci définit la taille de la mémoire que vous allouez au maximum pour les fichiers  ... Je l'ai mise à 100ko, ici.
Vous pouvez en utiliser plus (comme 2 Mo, mais pas beaucoup plus) ou aussi peu de Ko si vous n'avez pas besoin d'en mettre beaucoup plus ...*/
 
 
// Function: main()
int main(int argc, char ** argv)
{
	PA_Init();    // Initialisation PA_Lib
	PA_InitVBL(); // Initialise une norme VBL
	
	PA_InitText(0, 0);  // Initialise le système de texte sur l'écran du bas	
	PA_InitText(1, 0);  // Initialiser le système de texte sur l'écran du haut
	
	PA_OutputText(1, 0, 0, "Chargement PAFS...");
 
	PAFSStart = (char*)PA_FileSystem; // Dit l'utilisation du RAM ...
	u32 FileNumber = PA_FSRamInit(); // Inits PA Ram File System, et retourne le nombre de fichiers

Je n’ai donné que le début du fichier et l’initialisation de PAFS, tout le reste est identique aux autres exemples de PAFS.

  • La première chose que vous remarquerez est que nous avons ajouté quelque chose juste après l’include de PAlib ! PA_FSRam(100000); est important, car il dit à PAFS combien de mémoire vous lui donnez. Dans cet exemple, j’alloue seulement 100kb, ce qui n’est pas beaucoup, car un fichier .mod (NDT : désolé, pas réussi à traduire) peut être beaucoup plus grand que ça.
  • Par défault, PAFS cherche vos fichiers dans la rom... Pour qu’il regarde au bon endroit, il faut préciser que c’est dans la ram. C’est là que PAFSStart = (char*)PA_FileSystem; intervient. Ca peut ne pas sembler intuitif, mais ça signifie “PAFS démarre dans la ram”
  • Et pour finir, vous allez voir que l’initialisation est légèrement différente : FSRamInit. C’est une initialisation spéciale pour que PAFS recherche directement dans la ram.

Voila, c’est tout ! Nous avons déja vu tout le reste, donc vous pouvez compiler, ajouter les fichiers, et tester sur dualis (c’est ce que je fais) pour voir si ça marche réellement :-p

Utiliser le DLDI

Le DLDI est un systeme que Chishm a mis en place pour pouvoir utiliser des fichiers qui se trouvent sur le linker. Plus d’infos : ici

Le seul problème de cette méthode est que ça ne marche pas avec certains linkers. Et il faut aussi patcher la rom avec les fichiers *.dldi correspondant à son linker, on peut les trouver sur le site de Chishm. Mais maintenant la majorité des linkers patchent automatiquement la rom donc vous n’aurez pas à vous en soucier pour la plupart d’entre vous.

Voilà maintenant quelques explications sur l’utilisation :

Avant d’utiliser une fonction de la lib fat, vous devez l’initialiser :

fatInitDefault();

Vous pouvez maintenant vous servir des fonctions standard de manipulation de fichier.

Voici un exemple qui charge un fichier jpg dans un buffer:

     
fatInitDefault(); //Initialise la fat
 
FILE* imgFile = fopen ("Zelda.jpg", "rb");//ouvre le fichier zelda.jpg en mode lecture
 
	
if(imgFile){//regarde si le fichier c'est bien ouvert
	
//on cherche la taille du fichier, cela sert apres pour le buffer
u32 imgSize;
fseek (imgFile, 0 , SEEK_END);
imgSize = ftell (imgFile);
rewind (imgFile);//on retroune au debut du fichier
	
// on alloue suffisamment de mémoire et on stocke l'adresse dans buffer
char * buffer;
buffer = (char*) malloc (sizeof(char)*imgSize);
fread (buffer, 1, imgSize, imgFile);
	
 
fclose (imgFile);//on ferme le fichier
 

Il existe d’autres fonctions spécifiques à la fat qui permettent de chercher les fichiers sur la carte et ainsi de permettre à l’utilisateur de choisir un fichier, mais ceci sera mis ici ultérieurement.

Suivant → Jour 10 - Fonctions 3D

 
day9.txt · Dernière modification: 20/02/2010 18:05 par 79.88.143.132
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki