Problème d'écriture avec Bfile
Posté le 14/05/2021 16:20
Hello !
J'essaye d'écrire dans un fichier (mémoire de stockage) de ma calto 35+E
tweakée. Je l'avais déjà fait pour mon jeu
Chess Link. Mais cette fois-ci, rien à faire, ça ne fonctionne pas.
J'ai changé la méthode par rapport à Chess Link : J'utilise maintenant un tableau à deux dimensions
. Après écriture, je lis le fichier crée avec un éditeur hexadécimal : il ne contient que des 0xff.
Je pense avoir tout dit. Voici le code :
if(Sauvegarder_partie()){
Bfile_DeleteFile(PathName);
Bfile_CreateFile(PathName,101);
handle=Bfile_OpenFile(PathName,_OPENMODE_WRITE);
if(handle>=0){
for(i=0;i<10;i++) for(j=0;j<10;j++){
Bfile_SeekFile(handle,10*i+j);
Bfile_WriteFile(handle,&PlateauDuJeu[i][j],1);
}
Bfile_CloseFile(handle);
ML_rectangle(25,27,98,38,1,ML_BLACK,ML_WHITE);
dispStr("Partie sauvegard\x89""e",28,29);
ML_rectangle(25,27,98,38,1,ML_BLACK,ML_XOR);
}
else{
ML_rectangle(25,27,98,38,1,ML_BLACK,ML_WHITE);
dispStr("ERREUR",40,29);
ML_rectangle(25,27,98,38,1,ML_BLACK,ML_XOR);
}
GetKey(&key);
}
Le fichier :
const FONTCHARACTER PathName[]={'\\','\\','f','l','s','0','\\','S','t','r','a','t','e','g','o','.','s','a','v',0};
Et le tableau:
char PlateauDuJeu[10][10];
Il est bien sûr rempli de nombres quelconques (entre -12 et 12, donc dans les limites du
char)
La calto m'affiche "Partie sauvegardée", mais le fichier crée est rempli de 0xff
Merci d'avance pour toute idée !
Citer : Posté le 14/05/2021 16:28 | #
C'est normal que ça ne fonctionne pas sur la Graph35+E parce qu'il y a une limitation sur l'écriture des données. Si tu veux arriver à écrire correctement, tu dois avoir : 1) l'adresse du tableau de donnée que tu envoies a Bfile_WriteFile() multiple de 2, pareil pour la taille que tu envoies.
Basiquement :
uint8_t salut = 0xde;
uint16_t tmp = 0xcad0;
Bfile_WriteFile(handle, &salut, 1); // <-- ne fonctionne pas parce que salut et/ou la taille n'est pas multiple de 2
Bfile_WriteFile(handle, &tmp, 2); // <-- fonctionne parce que les deux arguments sont multiple de deux
Citer : Posté le 14/05/2021 16:31 | #
Donc il me faut un tableau de short ?
Citer : Posté le 14/05/2021 16:33 | #
Ou alors tu copies chaque entrée dans un short avant de l'écrire (dans ce cas il te faut 202 octets dans le fichier) :
short v = PlateauDuJeu[i][j];
Bfile_SeekFile(handle,2*(10*i+j));
Bfile_WriteFile(handle,&v,2);
}
Ou alors tu écris deux valeurs à la fois. Ou alors tu écris tout le tableau d'un coup (ce qui est possible parce que la tableau dans la mémoire est juste toutes les cases mises bout à bout) :
Note que Bfile_SeekFile() n'est pas nécessaire souvent, parce que quand tu ouvres le fichier tu commences à la position 0 au début du fichier et tu avances tout seul durant l'écriture, donc enchaîner les Bfile_WriteFile() suffit pour que les données soient correctement écrites en séquence.
Citer : Posté le 14/05/2021 16:54 | #
J'ai remplacé par ceci ,
compilé, balancé, testé, re-balancé, ouvert dans un éditeur hexadécimal : le résultat est le même !
...Et c'est absolument certain, PlateauDuJeu n'est absolument pas rempli de tels caractères !
Je teste toutes les autres techniques...
Citer : Posté le 14/05/2021 16:58 | #
Les 0xff sont les contenus initiaux du fichier. Regarde la valeur de retour de Bfile_WriteFile pour voir ?
Citer : Posté le 14/05/2021 17:31 | #
Elle retourne '-31', erreur qui correspond, je crois, à IML_FILEERR_ENUMRATEEND
Donc elle n'a pas fonctionné... Mais pourquoi ?
Au passage, pourquoi 0xff sont les octets originaux du fichier crée ? Pourquoi pas 0x00 ?
Edit:
Non, en fait, cela correspond à l'erreur IML_FILEERR_DEVICEERROR, d'après filebios.h
Citer : Posté le 14/05/2021 17:36 | #
C'est un code d'erreur utilisé quand la recherche ("enumeration") se termine sans trouver le fichier ("end"), typiquement utilisé par Bfile_FindNext(). Je suis pas sûr de comprendre ce qui t'arrive, il faudra que je teste.
Edit : Toujours mystérieux avec l'autre code. Tu as essayé de faire de place et optimiser la mémoire de stockage ?
0xff c'est à cause du principe de la mémoire Flash. Quand tu effaces un secteur initialement tous les bits sont à 1 pour des raisons physiques. Ensuite quand tu écris les bits peuvent devenir 0, mais les bits 0 ne peuvent plus repasser à 1 sauf tu effaces de nouveau tout le secteur. C'est pour ça que dans les add-ins on a tendance à effacer les fichiers et à les recréer en permanence, parce qu'ils ne peuvent être écrits qu'une fois.
Ce comportement semble être absent sur la Graph 35+E II et la Graph 90+E, mais je ne serais pas surpris que Bfile ait juste été modifié pour automatiquement effacer les secteurs quand c'est nécessaire. Les écritures sont si lentes sur ces modèles, Bfile a le tend de faire du café à chaque appel donc pourquoi pas effacer des secteurs.
Citer : Posté le 14/05/2021 17:41 | #
Euh, j'ai 265 936 octets libres dans ma mémoire de stockage
Edit : J'ai initialisé le tableau (0 partout) , lancé ce code :
Bfile_CreateFile(PathName,101);
handle=Bfile_OpenFile(PathName,_OPENMODE_WRITE);
if(handle>=0){
ML_clear_vram();
afficher_nombre_betterfont(Bfile_WriteFile(handle,PlateauDuJeu,100),1,1);
GetKey(&key);
}
... Et même l'émulateur du SDK m'affiche '-31'
Re-Edit: Avec le code original (sans les SeekFile), seul le deuxième appel à Bfile_WriteFile retourne 1, tous les autres retournent -31
Re-Re-Edit: Avec ta méthode, Lephé, (en passant par un short) (avec les SeekFile) La fonction retourne 2 à chaque passage dans la boucle. Or elle retourne la position du curseur... !!
Au fait, même sans SeekFile, elle retourne 2 ...
4x-Edit: Avec la méthode précédente, le fichier contient 0x00 excepté les deux derniers octets qui sont 0xff. Je croyais qu'il a écrit dans le fichier seulement à la 2ème position, parce qu'il retournait 2 ?!
Citer : Posté le 14/05/2021 20:51 | #
C'est quel type de variable ton handle pendant que j'y suis ?
Je vois vraiment pas ton problème, j'ai collé ça dans le SDK et ça marche immédiatement.
{
FONTCHARACTER const path[] = {
'\\', '\\', 'f', 'l', 's', '0', '\\', 'S', 't', 'r', 'a',
't', 'e', 'g', 'o', '.', 's', 'a', 'v', 0x00
};
char TableauDuJeu[10][10];
int x, y, handle, key;
for(y = 0; y < 10; y++)
for(x = 0; x < 10; x++)
TableauDuJeu[y][x] = 10 * y + x;
Bfile_DeleteFile(path);
Bfile_CreateFile(path, 100);
handle = Bfile_OpenFile(path, _OPENMODE_WRITE);
Bfile_WriteFile(handle, TableauDuJeu, 100);
Bfile_CloseFile(handle);
GetKey(&key);
return 1;
}
Citer : Posté le 14/05/2021 21:33 | #
Bin oui, en effet, le code fonctionne : j'ai testé avec un nouveau projet (au cas où mon SDK beuguait). Mais j'intercale ce code exactement au début de mon prog, et ça ne fonctionne pas ! Le fichier crée est vide (rempli de 0xff).
Du coup, plus le choix, je vais reprendre ce bout de code à zéro. Ca va me prendre... disons... quelques jours !
Merci Lephé
Je reviens une fois le bug vaincu !
Citer : Posté le 14/05/2021 21:50 | #
Attends c'est pas dit que ce soit ton code lol. Si tu as merdé sur le système de fichiers ça peut avoir des conséquences au-delà de l'exécution d'un seul add-in. Commence par supprimer le dossier Debug du projet et/ou recréer un projet dans le SDK, ce sera plus rentable.
Citer : Posté le 14/05/2021 22:30 | #
J'ai recrée un nouveau projet, ça ne marche toujours pas. Le fichier est toujours vide
Citer : Posté le 14/05/2021 23:04 | #
C'est littéralement impossible !
Je copie-colle le code que tu m'as donné, qui fonctionne, a début de mon programme. Il contient les mêmes variables, tout pareil, à la virgule près !
Et cependant, il ne fonctionne pas !!
Je te donne les deux progs, parce que là, je suis désespéré...
Mon Stratego Link ne fonctionne pas, tandis que le 'A', projet test, fonctionne
Comme j'ai une limite de taille, je te les joins en deux messages différents
Citer : Posté le 14/05/2021 23:05 | #
Et le projet test:
Citer : Posté le 14/05/2021 23:26 | #
Argh ce code c'est... je ne sais pas ce que c'est mais quand je supprime tout et que je garde que le main ça marche (sinon ça ne marche pas comme tu l'as vu).
Oublie ce que j'ai dit c'est bien ton code le problème... si possible quand tu le réécris prends une approche plus rigoureuse qui sépare la logique, le dessin, etc. Le fichier fait crasher l'éditeur du fx-9860G SDK sur certaines sélections à la souris.
Ah et aussi renvoyer des char ça sert à rien, ça ne prend pas moins de place. Les char c'est utile que si c'est dans gros tableau ; sinon int ou bool (et comme le SDK est limité au C89 qui ne supporte pas bool c'est int).