Posté le 27/11/2019 15:12
Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 71 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 08/04/2022 16:41 | #
Ici path n'est pas alloué sur le tas (malloc()/new/new[]), c'est juste une variable locale allouée sur la pile. Comme le int index que tu as en paramètre ou le int sizeSTR de la fonction plus haut. Tu n'as pas besoin de la libérer.
Cheat sheet :
// Données (20 octets) sur la pile, pas de libération
char *path = malloc(20);
// Le pointeur (4 octets) est sur la pile, les données (20 octets) dans le tas
free(path);
char *path = new char;
// Le pointeur (4 octets) est sur la pile, la donnée (1 octet) dans le tas
delete path;
char *path = new char[20];
// Le pointeur (4 octets) est sur la pile, les données (20 octets) dans le tas
delete[] path;
Citer : Posté le 08/04/2022 16:44 | #
Ok, c'est beaucoup plus clair.
Du coup il n'y pas de delete, parfait. Merci !
Ajouté le 09/04/2022 à 19:48 :
Alors j'ai un souci j'ai ce code là:
unsigned char* DeserializeString(FILE* fp) {
int sizeSTR;
fread(&sizeSTR, sizeof sizeSTR, 1, fp);
unsigned char* str = new unsigned char[sizeSTR + 1]; // +1 ici
fread(str, sizeof * str, sizeSTR, fp);
str[sizeSTR] = '\0';
return str;
};
...
unsigned char* text = DeserializeString(fp);
if ((const char*)text=="Hello"){
//fait quelque chose
}
Sauf que ça marche pas alors que text est bien égale à "Hello".
Alors je suppose que c'est une question de pointer mais je ne sais pas comment le résoudre
Albert Einstein
Citer : Posté le 09/04/2022 19:53 | #
Tu es en train de comparer les adresses des pointeurs et non les contenus. Ton if demande si text est stocké en mémoire au même endroit que la chaîne statique "Hello" (laquelle est dans la ROM dans ton add-in), et la réponse est non parce que text est stocké dans le tas et le "Hello" est dans la région de la mémoire où ton add-in est chargé.
Pour comparer des chaînes de caractères, il faut aller lire les caractères, ie. vérifier que text[0] vaut bien "H", etc. Les opérateurs du C ne font pas ça pour toi, mais la lib standard le fait :
if(strcmp(text, "Hello") == 0) {
// égal
}
Attention au piège, strcmp() ne renvoie pas 1/0 pour la réponse "oui/non", mais renvoie en fait 0 en cas d'égalité et un nombre positif ou négatif sinon ; le signe de la valeur indique quelle chaîne est "plus petite" (dans l'ordre lexicographique), ce qui utile pour trier.
Citer : Posté le 09/04/2022 19:59 | #
Merci ça marche du tonnerre !
Ajouté le 10/04/2022 à 16:40 :
Est-ce qu'il est possible de créé un Timer sur Graph 90 ? (un chronomètre en gros)
Albert Einstein
Citer : Posté le 10/04/2022 16:52 | #
Vois ce tutoriel, section "Structure d'une boucle de jeu animée" !
Citer : Posté le 10/04/2022 17:03 | #
Ok merci.
Sinon deuxième question, est-ce qu'il est possible de charger une image bopti_image_t depuis un fichier car j'ai beaucoup d'images et ça va dépasser les 2 Mo malgré toutes les optimisations possibles
Albert Einstein
Citer : Posté le 10/04/2022 17:06 | #
Tu peux oui, mais dépasser les 2 Mo et en plus utiliser de la RAM pour les images va venir avec tout un paquet de conséquences désagréables...
Citer : Posté le 10/04/2022 17:17 | #
Mais si j'utilise l'image que peut de temps et après je la libère c'est moins dérangeant non ?
Albert Einstein
Citer : Posté le 10/04/2022 17:23 | #
Oui, mais si tu es obligé de la recharger depuis un fichier toutes les 3 secondes, tu vas payer assez fort en perfs (et il me semble que tu utilises gint sur la G90, avec lequel pour lire dans un fichier il faut interrompre pas mal de timers/communications/etc, ce qui peut gêner aussi).
Citer : Posté le 10/04/2022 17:29 | #
Pourquoi toutes les 3 secondes ?
En gros moi j'ai besoin de mettre des backgrounds de combats à l'extérieur du programme.
Ensuite lorsque que le joueur déclenche un combat, le jeu libère la Map (qui prend une grosse partie de la Ram) et charge l'image de Background qui se trouve dans un fichier.
lorsque le joueur termine le combat, l'image est libéré et le jeu recharge la Map.
Voilà en gros ce que je veux faire
Ajouté le 10/04/2022 à 17:37 :
Du coup, j'ai voulu faire ça, mais ça marche pas:
void Save_Image(unsigned char* path, bopti_image_t img)
{
FILE* fp = fopen((const char*)path, "w");
fwrite(img, sizeof * img,1, fp);
fclose(fp);
};
bopti_image_t Load_Image(unsigned char* path)
{
FILE* fp = fopen((const char*)path, "r");
bopti_image_t img;
fread(img, sizeof * img,1, fp);
fclose(fp);
};
Albert Einstein
Citer : Posté le 10/04/2022 17:47 | #
Si c'est un fond alors t'auras pas de problèmes, ok.
La taille d'une image bopti c'est pas juste sizeof *img ; c'est bien tenté mais la structure se termine par un tableau de pixels de taille variable (c'est une fourberie mais ça évite une indirection). Vois un bopti_image_t * comme un char * : tu dois noter sa taille à côté.
1. Au lieu de sizeof *img à l'écriture, calcules la taille avec cette fonction :
{
IMAGE_RGB565 = 0,
IMAGE_RGB565A = 1,
IMAGE_DEPRECATED_P8 = 2, /* Old P8 format */
IMAGE_P4_RGB565A = 3, /* Also the old P4 */
IMAGE_P8_RGB565 = 4,
IMAGE_P8_RGB565A = 5,
IMAGE_P4_RGB565 = 6,
};
size_t image_size_profile(int profile, int width, int height, int colors)
{
size_t size = sizeof(bopti_image_t);
if(profile == IMAGE_RGB565 || profile == IMAGE_RGB565A)
size += width * height * 2;
else if(profile == IMAGE_DEPRECATED_P8)
size += 512 + width * height;
else if(profile == IMAGE_P8_RGB565 || profile == IMAGE_P8_RGB565A)
size += 2 + 2 * colors + width * height;
else if(profile == IMAGE_P4_RGB565 || profile == IMAGE_P4_RGB565A)
size += 32 + ((width + 1) / 2) * height;
return size;
}
size_t image_size(bopti_image_t const *img)
{
int colors = -1;
if(img->profile == IMAGE_P8_RGB565 || img->profile == IMAGE_P8_RGB565A)
colors = img->data[0];
return image_size_profile(img->profile, img->width, img->height, colors);
}
2. Sauvegarde la taille avant l'image
3. À la lecture, lis la taille, alloue ton image avec malloc(), lis le reste et renvoie un pointeur
Citer : Posté le 10/04/2022 18:02 | #
Donc ce code là est bon ?
Pas de problème de pointer ou de truc comme ça ?
void Save_Image(unsigned char* path, bopti_image_t img)
{
FILE* fp = fopen((const char*)path, "w");
size_t size = image_size(&img);
fwrite(&size,1, sizeof size, fp);
fwrite(&img, size,1, fp);
fclose(fp);
};
bopti_image_t* Load_Image(unsigned char* path)
{
FILE* fp = fopen((const char*)path, "r");
int size;
fread(&size, sizeof size, 1, fp);
bopti_image_t* img = (bopti_image_t*)malloc(size);
fread(&img, size,1, fp);
fclose(fp);
return img;
};
Albert Einstein
Citer : Posté le 10/04/2022 18:05 | #
Tu ne peux pas passer un bopti_image_t par valeur, tu dois toujours toujours le passer par pointeur.
À part ça ouais ça devrait le faire.
Citer : Posté le 10/04/2022 18:09 | #
Alors j'ai rectifier avec ça
void Save_Image(unsigned char* path, bopti_image_t* img)
{
FILE* fp = fopen((const char*)path, "w");
size_t size = image_size(img);
fwrite(&size,1, sizeof size, fp);
fwrite(&img, size,1, fp);
fclose(fp);
};
puis j'ai testé avec ça :
Save_Image((unsigned char*)"testImg.bin", &img);
Et ma casio à crash avec un écran noir puis elle a reset
Albert Einstein
Citer : Posté le 10/04/2022 18:14 | #
Toujours un world switch avant d'utiliser le fs :
gint_world_switch(GINT_CALL(Save_Image, (unsigned char *)"testImg.bin", (void )&img));
Citer : Posté le 10/04/2022 18:16 | #
ça sert à quoi le world switch ?
Albert Einstein
Citer : Posté le 10/04/2022 18:18 | #
Ça rend le contrôle du matériel à l'OS temporairement.
Citer : Posté le 10/04/2022 18:22 | #
Et il faut le faire à chaque fois qu'on ouvre un fichier ?
Il faut aussi le faire avec le load ?
j'ai cette erreur là mais je penses que c'est des includes, mais du coups lesquels
error: void value not ignored as it ought to be
49 | gint_world_switch([red]GINT_CALL[/red](Save_Image, (unsigned char*)"testImg.bin", (void)&img));
Albert Einstein
Citer : Posté le 10/04/2022 18:26 | #
ll faut le faire chaque fois que tu ouvres un fichier oui.
Et pour l'erreur c'est (void *)&img, j'ai tapé trop vite.
Citer : Posté le 10/04/2022 19:05 | #
Ok du coup ça marche mais pas le Load, c'est à dire que j'ai voulu faire ça :
bopti_image_t* img = gint_world_switch(GINT_CALL(Load_Image, (unsigned char*)"testImg.bin"));
ça m'a donné ça :
error: invalid conversion from ‘int’ to ‘bopti_image_t*’ [-fpermissive]
50 | bopti_image_t* img = gint_world_switch(GINT_CALL(Load_Image, (unsigned char*)"testImg.bin"));
Albert Einstein
Citer : Posté le 10/04/2022 19:07 | #
Ah oui c'est que le typage est un peu chiant pour ça.
Pas de souci, tu peux juste forcer le cast :
En C++ on pourrait faire mieux et éviter tous les casts, il faudra que je supporte ça un jour.