Planète Casio - Vos tutoriels et astuces - Flux RSS http://www.planet-casio.com Programmes Casio, Jeux, Cours pour Calculatrices Casio fr-FR https://www.planet-casio.com/images/logo.gif Planète Casio - Vos tutoriels et astuces - Flux RSS http://www.planet-casio.com 55 50 Programmes Casio, Jeux, Cours pour Calculatrices Casio. Mon, 21 Apr 2025 18:43:48 GMT Mon, 21 Apr 2025 18:43:48 GMT contact@planet-casio.com (Planet Casio) contact@planet-casio.com (Planet Casio) 5 Application invisible https://www.planet-casio.com/Fr/forums/topic18687--.html Salut ! je suis à la recherche d'un moyen de faire un programme en quelques sortes invisibles ou un add-in invisible dans les onglets seulements accessible via un raccourci genre H (J'ai cherché des pistes sans trouver de réponses) Tue, 01 Apr 2025 23:14:48 +0200 Achieve 250+ FPS on your Graph 90+E/Graph Math+! https://www.planet-casio.com/Fr/forums/topic18686--.html This tutorial is intended for overclocking enthusiasts who wish to push their Graph 90+E/Graph Math+ towards the hardware limits. If you are new to overclocking, this article from Lephenixnoir is a good starter ;) The short answers In Ptune4: :here: Press and [+] to raise TRC to 6. :here: Press / to enter BSC settings. Switch to WCR mode by [F5]/[⇥], and set WW/HW registers in CS5AWCR section to 0/0.5 cycles respectively. :here: Press +/ to enter Ptune4 settings. Select "Bus Clock Max" and raise the limit by [+]/. You can now push the PLL to x32 or more to gain even more FPS than the current F5 preset for Graph 90+E/Graph Math+. :D What are the magic sauces? Culprit 1: Spread spectrum Spread spectrum is enabled in Graph 90+E/Graph Math+ by default. This not only slightly slows down the performance, but also causes problems when PLL is above x32, where x33 has the same performance as x1. This caused Ptune3's maximum PLL to be hardcoded to x32 as a result, when spread spectrum was not known at the time of fx-CG50/Graph 90+E launch. Ptune4 automatically disables spread spectrum when you enter the add-in, so that you can raise PLL to the maximum value of x64 like Ptune2. 👍 However, if you plan to do benchmarks (especially on Casio Basic and Casio Python) with speed presets in Ptune4, make sure you indicate the state of spread spectrum (or before/after using Ptune4) for your results. This is because the results you get after using Ptune4 are under the condition of spread spectrum being off, which is faster than the default state after waking up from hibernation and RESTART. There is currently no way to re-enable it in Ptune4 because of the way gint's clock calculation function works. Culprit 2: Default SDRAM timings are suboptimal If you take a closer look at the registers in CS3WCR, you may recognize that most of them are the common SDRAM timings used in the PC overclocking community. Timings are one of the major factors that determine the maxmium frequency you can achieve. Suitable timings allow the RAM kits to go even further and boost performance, whereas inappropriate settings cause instability and crash your system. Typically, they are indicated in `CL-tRCD-tRP-tRAS` format. In our case, the first three timings are all 2 cycles by default. tRAS is not available for modification, but we can calculate it based on this formula: `tRAS = CL + tRCD`. There is also a formula for calculating recommended minimum value of tRC which is modifiable in Ptune4: `tRC = tRP + tRAS`. This is where the problem lies. tRC defaults to 4 cycles, but using the above formulas the minimum value should be 6 cycles. Setting tRC to 6 extends the maximum bus frequency to 130+ MHz, as indicated by Ptune4's SDRAM test: https://i.imgur.com/Df7mUTh.png Culprit 3: Slower LCD timings LCD timings are managed by CS5ABCR and CS5AWCR. Here we only concern IWW, WW and HW registers as they affect the performance the most. The default values for fx-CG10/20 are IWW=1, WW=0 and HW=0.5. However, Graph 90+E/Math+ use WW=1 and HW=1.5 instead, which hinders the screen update. By using the same settings as the previous generation, we see a 38.1% improvement from the normal preset. With IWW=0 the percentage increase goes even further to 67.9%, but it is not recommended to tighten IWW along with WW and HW because such settings cause screen glitches when the bus frequency is 105 MHz or above. Important! LCD timings will be reset once you turn off your calculator. This is dangerous because they are known to limit the maxmium bus frequency that LCD (not the RAM itself!) can withstand. If you set a bus frequency that is inappropriate for the default values, the screen may become distorted the next time you wake up your calculator. If that happens, press the RESTART button on the back to reset the bus frequency to its default value. Closing remarks There are more BSC registers that can improve the performance, but they are quite minor when comparing to the above culprits. If you are keen to extract a bit more speed, you can take a look at my overclocking notes on the Planète Casio bible server. Most of them will also be present in the Ftune/Ptune Wiki once I finished porting the rest of the Ftune/Ptune editions to gint. :here: https://bible.planet-casio.com/calcloverhk/overclocking-notes/ As a side note, I propose the following CPG and BSC parameters (shown in the screenshot below) as the new F5 preset for Graph 90+E/Graph Math+. You can try this experimental configuration starting from Ptune4 v0.06, by pressing +[F5] (Graph 90+E) or + (Graph Math+) in the main menu. If it causes system error, please let me know! https://imgur.com/WByUQCd.png Have fun overclocking and feel free to share your results in the comment section! 8-) Tue, 01 Apr 2025 12:51:39 +0200 Peut-on transférer des fichiers entre le 5800p et une calculatrice graphique Casio moderne ? https://www.planet-casio.com/Fr/forums/topic18667--.html Ce serait bien de pouvoir sauvegarder les données de mon 5800p sur une calculatrice avec interface USB... Tue, 11 Mar 2025 04:42:31 +0100 Guide for using Cahute and fxlink on WSL 2 https://www.planet-casio.com/Fr/forums/topic17875--.html This tutorial guides you to enable USB communication in WSL 2 for Cahute and fxlink, which is not supported natively by WSL as of this writing (updated 2025-3-6). Pre-requisites As the title suggests, this guide is intended for developers using WSL 2. This is because `usbipd-win` and `WSLg` do not support WSL 1 distros. It is also not applicable to Windows on ARM computers as the author of `usbipd-win` has no plans to support ARM64. Although there is a non-production solution for ARM64 PCs, this article only covers `usbipd-win` for now as the writer does not have any ARM64 device for verifying. For Windows 10 users, you must be running version 21H2 or higher, which is the minimum requirement for `WSLg` to work. Setting up WSL 2 If you are new to WSL, open PowerShell as administrator and execute the following commands to enable it: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart Restart your PC to apply these changes. The latest release of WSL 2 (v2.4.11) does not come with USB mass storage modules. Only pre-releases v2.3.11-2.3.14 provide them for now. Set the default install version for new distros to WSL 2: wsl --set-default-version 2 You can type `wsl --list --online` and select your preferred distro from the list by `wsl --install <distro> --web-download`, or install other third-party WSL distros like ArchWSL. The guide will be using Ubuntu 24.04 LTS for demonstration. Installing Cahute and fxlink Make sure to `sudo apt update && sudo apt upgrade` to have the latest libraries before going through all these instructions. Go to the README of GiteaPC and install it. Since we will be using the full version of fxlink, install the following dependencies: % sudo apt-get install cmake python3-pil libusb-1.0-0-dev libudev-dev libsdl2-dev libpng-dev libncurses-dev libudisks2-dev libglib2.0-dev Then continue with the remaining instructions as usual. Lastly, follow these instructions to install Cahute. Instructions for using `usbipd-win` The following instructions are for CLI users. If you prefer GUI, you can take a look at this GUI application or this VSCode integration. On the Windows host, go to the release page for the `usbipd-win` project and download the latest .msi installer. After installing `usbipd-win`, connect your calculator with USB and select any connection mode. Then open PowerShell/Command Prompt as administrator and run `usbipd list` (no admin privilege required here). The list should look like the following: https://i.imgur.com/4y7hcdh.png Look for the USB device with a VID of `07cf` (highlighted in yellow). This is Casio's vendor ID used for their products with USB. Jot down its corresponding bus ID (highlighted in green) for later use. Click any one of the spoilers according to the version of `usbipd-win` you are using. This version adds the policy option that allows you to attach your calculators to WSL without manually binding them in advance. The usage is `usbipd policy add -e Allow -o 'AutoBind' [-b <bus-id> / -i <VID>:<PID>]` (admin privilege required). You can execute either `usbipd policy add -e Allow -o 'AutoBind' -b 1-7` or `usbipd policy add -e Allow -o 'AutoBind' -i 07cf:6103`. The former option assigns a particular USB port to WSL (suitable if you want to attach other USB devices to WSL through this port as well), while the latter one allows Casio devices in any port with a PID of 6103. Once the policy is successfully configured, the Casio USB device will have `Allowed` state instead: https://i.imgur.com/WdjR0l1.png If you want a no-brainer solution to allow all Casio graphing calculators and their protocols, execute the following commands: usbipd policy add -e Allow -o 'AutoBind' -i 07cf:6101 usbipd policy add -e Allow -o 'AutoBind' -i 07cf:6102 usbipd policy add -e Allow -o 'AutoBind' -i 07cf:6103 Copy its bus ID and bind the calculator with `usbipd bind -b <bus-id>`. Note that you have to repeat the bind command for each connection mode as they have different PIDs. While your WSL instance is active, attach your calculator by `usbipd attach -w -b <bus-id>`. To let your calculator always connect to WSL instance instead of the host, add `-a` flag after `usbipd attach`. This will start an endless attach loop until you press Ctrl+C to terminate it. For `usbipd` 4.4.0+, the `-u` flag allows you to start the attach loop, even if your calculator is not connected to that port. Note that this flag requires `-a` and `-b`. For calculators that use CESG502, type `p7 info` in WSL terminal to confirm that Cahute can detect the calculator connection. If your calculator is in USB Flash mode, enter `lsblk` to see if its storage appears under `sdx` directory. Possible issues and workarounds 1. If you have installed `USBPcap` in Windows (which is used for debugging with Cahute), `usbipd` will prompt you: usbipd: warning: USB filter 'USBPcap' is known to be incompatible with this software; 'bind --force' will be required. If you prefer not to force bind your calculator to WSL instance, do not use both components simultaneously. 2. If `usbipd-win` cannot automatically load `vhci_hcd` module, edit the module config file: % sudo nano /etc/modules-load.d/modules.conf Add `vhci_hcd` module at a new line, save the config file and restart your WSL session. 3. Since fxlink is installed in your home directory, `fxsdk build-cg -s` may not work properly as it requires sudo privileges. In this case, execute the following workaround in WSL terminal: % which fxlink Copy its path and enter the following command at your fxSDK project directory as sudo: % sudo /full/path/to/fxlink -sw <your-addin>.g3a Another way (but not recommended) is to start as root and install fxSDK there instead. 4. If `p7screen` prompts you: Segmentation fault (core dumped) You probably have encountered the bug that has been upstreamed to libsdl's bug tracker (thanks Cakeisalie5 for the report). For now to work around it, create a `WSLg` config file: % sudo nano /etc/tmpfiles.d/wslg.conf Save the config file with the following content and restart your WSL session: # Type Path Mode UID GID Age Argument L+ /tmp/.X11-unix - - - - /mnt/wslg/.X11-unix Sun, 15 Sep 2024 20:32:52 +0200 Tutoriel d'utilisation de libMicrofx https://www.planet-casio.com/Fr/forums/topic17848--.html Pour que le tutoriel soit plus visible que dans le repo de mon jeu de pong ( https://git.planet-casio.com/mibi88/pong/src/branch/master/TUTORIAL_fr.md ), je le poste ici aussi. J'ai utilisé https://rtxa.github.io/mdtobb/ pour la conversion du markdown vers du BBCode. J'ai réécrit la table à la main. J'ai aussi réécrit les listes. Tutoriel d'utilisation de libMicrofx Dans ce tutoriel nous allons coder un jeu de pong en C avec libMicrofx. Préréquis Des connaissances solides du C sont requises. Pour pouvoir suivre ce tutoriel, vous avez besoin du fxsdk, car libMicrofx réquis sh-elf-gcc etc. et fxgxa. Vous avez donc besoin d'un système d'exploitation UNIX-like compatible avec celui-ci. Vous avez bien sûr besoin d'une calculatrice CASIO monochrome sh-4 pour pouvoir tester l'add-in. Quelques infos utiles Le coin en haut à gauche est l'origine du repère. Le pixel en haut à gauche est aux coordonnées 0;0 et le pixel en bas à droite aux coordonnées 127;63, car l'écran fait 128x64 pixels. Création du projet Clonez le dépot libMicrofx (branche master). Faites une copie du dossier template, c'est un exemple de projet. Renommez votre copie de ce dossier avec le nom de votre nouveau projet (par exemple: pong). Lancez make dans ce dossier. Si vous n'avez pas d'erreurs et obtenez un add-in fonctionnel, vous pouvez continuer. Dans le dossier du projet, crééz un dossier assets pour y mettre les graphismes, ainsi qu'un dossier inc pour les headers. Structure du projet Nous allons structurer le projet comme ceci: main.c Lancement du jeu et boucle du jeu. game.c et game.h logique du jeu et rendu. game.h contiendra toutes les structures. ball.c et ball.h mouvement, collisions et rendu de la balle. paddle.c et paddle.h gestion des collisions entre la balle et la raquette, mouvement et rendu de la raquette. fixed.h Calculs à virgule fixe (si vous ne savez pas ce que c'est, c'est pas grave, j'en parlerais plus tard). Créez ces fichiers, les fichiers .c dans src et les fichier .h dans inc. Dans assets, créez un écran de titre (title_img.png) pour le jeu. Il doit avoir une dimension de 128x64 (la taille de l'écran). Vous pouvez aussi prendre celui du dépôt du tutoriel. Pour pouvoir l'utiliser depuis le code, il faut le convertir en code source. Vous pouvez utiliser sprite coder pour cela (https://tools.planet-casio.com/SpriteCoder/index.php). Vous devriez avoir un dossier comme ça : $ tree . ├── assets │ ├── title_img.c │ └── title_img.png ├── icon.png ├── inc │ ├── ball.h │ ├── fixed.h │ ├── game.h │ └── paddle.h ├── lib │ ├── fx98xx.ld │ ├── include │ │ └── microfx │ │ ├── ext │ │ │ ├── img.h │ │ │ └── strtools.h │ │ ├── keycodes.h │ │ └── microfx.h │ └── libMicrofx.a ├── Makefile └── src ├── ball.c ├── game.c ├── main.c └── paddle.c Makefile Ajoutez les fichiers .c à SRC, changez NAME et ajoutez -Wall -Wextra -Wpedantic à la ligne $(CC) -c $< -o $@ -Os -Ilib/include/ -std=c89 pour avoir plus de warnings, pour rendre le débogage plus facile. Ajoutez aussi -Iinc, pour ne pas avoir à écrire le chemin vers les headers. Si vous n'avez pas l'habitude du C ANSI enlevez -std=c89. Code Nous sommes enfin prêts à coder le jeu. - main.c, la boucle du jeu Nous allons commencer par faire la boucle du jeu. Pour que notre jeu soit agréable à jouer, nous allons limiter le nombre d'images par seconde à lequel il peut tourner, car la calculatrice est en mesure de l'exécuter très très vite. Nous allons quitter la boucle si EXIT est appuyé, ce que nous pouvons voir avec kcheck(KCEXIT). J'ai donc choisi de limiter le framerate à 50fps (cela vous rapelle peut être les jeux vidéos PAL des années 80). libMicrofx propose une variété de fonctions pour controller le temps. Nous allons utiliser treset, tgetticks et tiselapsed, car ils nous offrent la meilleure précision que libMicrofx est capable de fournir (1/128 secondes). Si vous avez besoin d'une plus grande précision, utilisez gint. tgetticks permet d'obtenir le temps écoulé depuis minuit. tiselapsed permet de savoir si X milisecondes se sont écoulés depuis un certain nombre de ticks. Nous allons nous en servir pour attendre de 20ms s'écoulent depuis le début de l'image. treset permet de réinitialiser le comptage du temps. On en a besoin, car au bout de 24h le temps est remis à zéro, ce qui pourrait faire crasher notre jeu. Nous allons donc d'abord réinitialiser le RTC et ensuite utiliser tgetticks pour obtenir le temps écoulé. Nous allons ensuite exécuter une image du jeu, puis, dans une boucle, utiliser tiselapsed pour attendre que 20ms soient écoulées. sclear efface l'écran et supdate met à jour l'écran donc mettez les entre tgetticks et tiselapsed. Essayez par vous même, et regardez ensuite mon implémentation. while(!kcheck(KCEXIT)){ /* Reset RTC to avoid a crash if it gets midnight. */ treset(); /* Get the current time. */ ticks = tgetticks(); /* Run a frame of the game. */ sclear(); /* A game frame. */ supdate(); /* Wait that 20ms are elapsed to let the game run at 50fps (PAL). */ while(!tiselapsed(ticks, 20)); } Testez. Si vous arrivez bien à quitter le jeu en appuyant sur EXIT, continuez. - game.h, les structures Maintenant que nous avons une boucle de jeu, nous pouvons commencer à coder le jeu en lui même. Nous allons créer trois structures, Game, qui rassemble toutes les informations sur le jeu, Ball, qui représente la balle, et Paddle qui représente une raquette. Nous allons mettre toutes les structures dans game.h (pour éviter le cross referencing). Nous allons commencer par créer la structure Paddle, c'est celle qui nous intéressera en premier. Celle pour la balle sera plus compliquée. Nous avons juste besoin de stocker la position de la raquette. /* A structure representing a paddle (used in paddle.c) */ typedef struct { /* The position of the paddle. */ int x; int y; } Paddle; Ensuite nous allons créer la structure Game avec deux raquettes. /* A structure storing all the informations about the game. */ typedef struct { /* The player's paddle */ Paddle paddle1; /* The computer's paddle */ Paddle paddle2; } Game; - paddle.c et paddle.h, gestion des raquettes. Maintenant que nous avons crée toutes les structures, il est temps de coder le mouvement et l'affichage des raquettes. - Initialisation d'une raquette. Dans paddle.h, écrivez, comme vous en avez sûrement l'habitude #ifndef PADDLE_H #define PADDLE_H #include <game.h> #endif Dans paddle.c, nous allons commencer par coder inclure paddle.h. Nous allons aussi inclure microfx/microfx.h. #include <paddle.h> #include <microfx/microfx.h> Nous allons créer une fonction paddle_init pour initialiser la raquette: void paddle_init(Paddle *paddle, int x) { /* TODO */ } Dans cette fonction, nous allons mettre paddle->y à SHEIGHT/2: SWIDTH et SHEIGHT sont définis par microfx/microfx.h et SWIDTH contient la largeur de l'écran. SHEIGHT contient sa hauteur. paddle->x sera égal à x. void paddle_ini(Paddle *paddle, int x) { paddle->x = x; paddle->y = SHEIGHT/2; } Mettez le prototype de cette fonction dans paddle.h. - Mouvement d'une raquette. Nous allons ensuite créer une fonction paddle_move pour pouvoir bouger la raquette. void paddle_move(Paddle *paddle) { /* TODO */ } Comme nous l'avons fait précédemment, nous allons utiliser kcheck pour récupérer les entrées clavier. KCUP est la flèche vers le haut et KCDOWN est la flèche vers le bas. Dans paddle.h nous allons définir la vitesse du paddle, ansi que sa taille. #define PADDLE_SPEED 1 #define PADDLE_WIDTH 3 #define PADDLE_HEIGHT 16 Nous n'allons pas bêtement incrémenter et décrémenter la position du paddle, car il ne doit pas sortir de l'écran. Mon implémentation : void paddle_move(Paddle *paddle) { /* Move the paddle up if the up arrow key is pressed. */ if(kcheck(KCUP)){ if(paddle->y-PADDLE_SPEED >= 0){ paddle->y -= PADDLE_SPEED; }else{ paddle->y = 0; } } /* Move the paddle down if the down arrow key is pressed. */ if(kcheck(KCDOWN)){ if(paddle->y+PADDLE_SPEED < SHEIGHT-PADDLE_HEIGHT){ paddle->y += PADDLE_SPEED; }else{ paddle->y = SHEIGHT-PADDLE_HEIGHT-1; } } } Mettez le prototype de cette fonction dans paddle.h. - Dessin d'une raquette Maintenant que notre raquette peut être initialisée et bougée, nous devons la dessiner. Nous allons dessiner un rectangle. Nous allons donc créer une fonction pour dessiner une raquette, et dessiner un rectangle à la position de la raquette, avec void srect(int x1, int y1, int x2, int y2); Mon implémentation : void paddle_draw(Paddle *paddle) { /* Draw a rectangle to represent the paddle. */ srect(paddle->x, paddle->y, paddle->x+PADDLE_WIDTH, paddle->y+PADDLE_HEIGHT); } Mettez le prototype de cette fonction dans paddle.h. - game.c et game.h, initialisation, rendu et logique Maintenant nous avons grand besoin de tester si tout ce que nous avons codé fonctionne. Nous allons donc créer trois fonctions: game_init pour initialiser le jeu. game_logic pour la logique du jeu. game_draw pour le rendu. - Initialisation du jeu. Dans game_init nous allons créer une première raquette avec une abscisse de 16 et une deuxième avec une abscisse de SWIDTH-16-PADDLE_WIDTH. Mon implémentation : void game_init(Game *game) { /* Initialize the paddles on the two sides of the screen. */ paddle_init(&game->paddle1, 16); paddle_init(&game->paddle2, SWIDTH-16-PADDLE_WIDTH); } Ajoutez le prototype de cette fonction à game.h. - Logique du jeu. Dans game_logic nous allons appeler paddle_move pour la première raquette. Mon implémentation : void game_logic(Game *game) { /* Let the player move his paddle. */ paddle_move(&game->paddle1); } Ajoutez le prototype de cette fonction à game.h. - Rendu Dans game_draw nous allons dessiner les raquettes avec paddle_draw. Mon implémentation : void game_draw(Game *game) { /* Draw the paddles. */ paddle_draw(&game->paddle1); paddle_draw(&game->paddle2); } Ajoutez le prototype de cette fonction à game.h. - main.c, appel des fonctions de game.c Avant de pouvoir tester, nous devons appeler toutes ces nouvelles fonctions. Créez une variable game, et au début de main, et initialisez la avec game_init. Ensuite, dans la boucle du jeu, après sclear et avant supdate, appelez game_logic puis game_draw. Mon implémentation de main : Game game; int main(void) { int ticks = 0; /* Wait for the user to release all the keys */ while(kisdown()); /* Initialize the game. */ game_init(&game); /* Main game loop. */ while(!kcheck(KCEXIT)){ /* Reset RTC to avoid a crash if it gets midnight. */ treset(); /* Get the current time. */ ticks = tgetticks(); /* Run a frame of the game. */ sclear(); game_logic(&game); game_draw(&game); supdate(); /* Wait that 20ms are elapsed to let the game run at 50fps (PAL). */ while(!tiselapsed(ticks, 20)); } /* Add-ins should return 1 on success (yes, it's weird). */ return 1; } - game.h et fixed.h, la balle et les nombres à virgule fixe. - Opérations à virgule fixe. Comme vous le savez sûrement déjà, l'écran de la calculatrice fait 128x64 pixels. Si l'on dessine un pixel à (0;0), et qu'on le déplace de 1 pixel sur l'axe des abscisses 50 fois par seconde, le pixel traverse l'écran en 2,56 secondes. C'est très rapide. Nous avons donc besoin de bouger le pixel de moins d'un pixel par image, mais comment faire ? C'est très simple: nous allons stocker sa position comme un nombre réel, et l'incrémenter d'un nombre plus petit que 1 (ex: 0,1), ce qui nous permet de gérer la vitesse de son déplacement plus précisément. Pour trouver ses coordonnés à l'écran, nous ne prendrons que les chiffres avant la virgule. Intuitivement, vous utiliseriez des floats mais la calculatrice n'a pas de FPU (une puce qui permet de faire des calculs à virgule flottante rapidement), donc tout est effectué sur le CPU ce qui rend les calculs avec des float très lent. De plus cela rend l'add-in plus volumineux (ce que nous ne voulons pas). Nous allons donc utiliser des entiers : nous allons garder quelque bits pour les chiffres après la virgule. C'est ce que l'on appelle les nombres à virgule fixe. Exemple: 19,2 comme entier 16 bit non signé avec une précision de 8 bits après la virgule : Avant la virgule Après la virgule 00010011 00110011 Si l'on reconvertit ce chiffre en float, on obtient environ 19,199, car nous avons perdu en précision, mais ce n'est pas grave dans un jeu vidéo (19,199 c'est quand même très proche de 19,2 !). Maintenant, codons quelque macros pour convertir des nombres en nombres à virgule fixe, et d'autres pour la multiplication et la division (nous pouvons faire les additions et les soustractions comme d'habitude). La conversion est très facile, il suffit d'effectuer des décalages de bits. /* The precision of the fixed point numbers. */ #define PRECISION 8 /* Convert a float to a fixed point number. */ #define TO_FIXED(num) (int)((num)*(1<<PRECISION)) /* Convert a fixed point number to an integer. */ #define TO_INT(num) ((num)>>PRECISION) Note : Je multiplie num par (1*PRECISION) pour pouvoir passer des floats à la macro. Les macros pour la multiplication et la division sont très simples, elles aussi : /* Multiply two fixed point numbers together. */ #define MUL(a, b) ((a*b)>>PRECISION) #define DIV(a, b) ((a<<PRECISION)/b) Nous allons finir par définir un type fixed_t, pour que notre code soit plus lisible : /* The fixed point type (to make the code easier to read). */ typedef int fixed_t; - Structure Ball. Dans game.h, nous pouvons donc créer une structure pour la balle, qui va contenir sa position, sa direction (sous forme de vecteur) et sa vitesse. /* The ball structure (used in ball.c). */ typedef struct { /* The position of the ball. */ fixed_t x; fixed_t y; /* How the ball position is increased on each frame. */ fixed_t x_inc; fixed_t y_inc; /* The speed of the ball. */ fixed_t speed; } Ball; Nous allons aussi l'ajouter à la structure Game: /* The ball */ Ball ball; - ball.c, ball.h et game.c, le dessin et le mouvement de la balle. - Initialisation de la balle. Avant de faire quoi que ce soit avec la balle, nous devons l'initialiser. Nous allons donc créer une fonction ball_init dans ball.c. Elle aura pour paramètres la direction et la vitesse de la balle. Elle sera placée au milieu de l'écran. Mon implémentation : void ball_init(Ball *ball, fixed_t x_inc, fixed_t y_inc, int speed) { /* Set the ball position to the center of the screen. */ ball->x = TO_FIXED(SWIDTH/2); ball->y = TO_FIXED(SHEIGHT/2); /* Set the increase on the x and y axis and the speed of the ball. */ ball->x_inc = x_inc; ball->y_inc = y_inc; ball->speed = speed; } Ajoutez le prototype à ball.h et appelez cette fonction depuis game_init, pour l'initialiser au lancement du jeu. - Dessin de la balle Mainenant que nous avons initialisé la balle, nous pouvons la dessiner. Nous allons tout simplement récupérer ses coordonnés à l'écran, et dessiner un rectangle de 3x3 que nous allons remplir (vu que l'intérieur ne fait qu'un pixel, nous allons utiliser spixel), pour qu'elle soit assez visible. void ball_draw(Ball *ball) { /* Get the position of the ball on screen. */ int screen_x = TO_INT(ball->x); int screen_y = TO_INT(ball->y); /* Draw a rectangle and fill it to make the ball more visible. */ srect(screen_x-1, screen_y-1, screen_x+1, screen_y+1); spixel(screen_x, screen_y, SBLACK); } Nous allons appeler cette fonction dans game_draw. Vérifiez que tout fonctionne, et si tout est bon, vous pouvez continuer. Sinon relisez votre code et le tutoriel. - Mouvement de la balle Mainenant que nous dessinons la balle, nous pouvons la faire bouger. Nous allons créer une nouvelle fonction char ball_move(Ball *ball); et commencer par calculer la position qu'elle atteindra à l'écran : /* The destination coordinates (on the screen) */ int dest_x = TO_INT(ball->x+MUL(ball->x_inc, ball->speed)); int dest_y = TO_INT(ball->y+MUL(ball->y_inc, ball->speed)); Nous allons tout d'abord vérifier si la balle sortira du côté droit ou gauche de l'écran, pour pouvoir donner un point au joueur qui a marqué. /* If dest_x > SWIDTH the player should get a point. */ if(dest_x > SWIDTH) return 1; /* If dest_x < 0 the computer should get a point. */ if(dest_x < 0) return 2; Nous pouvons aussi vérifier si elle doit rebondir sur les bords de l'écran, et nous allons la faire rebondir si besoin : /* Make the ball bounce on the sides of the screen. */ if(dest_y < 0){ ball->y_inc = -ball->y_inc; ball->y = TO_FIXED(0); } if(dest_y >= SHEIGHT){ ball->y_inc = -ball->y_inc; ball->y = TO_FIXED(SHEIGHT-1); } Nous allons finir par faire bouger la balle : /* Move the ball. */ ball->x += MUL(ball->x_inc, ball->speed); ball->y += MUL(ball->y_inc, ball->speed); Mon implémentation : char ball_move(Ball *ball) { /* The destination coordinates (on the screen) */ int dest_x = TO_INT(ball->x+MUL(ball->x_inc, ball->speed)); int dest_y = TO_INT(ball->y+MUL(ball->y_inc, ball->speed)); /* If dest_x > SWIDTH the player should get a point. */ if(dest_x > SWIDTH) return 1; /* If dest_x < 0 the computer should get a point. */ if(dest_x < 0) return 2; /* Make the ball bounce on the sides of the screen. */ if(dest_y < 0){ ball->y_inc = -ball->y_inc; ball->y = TO_FIXED(0); } if(dest_y >= SHEIGHT){ ball->y_inc = -ball->y_inc; ball->y = TO_FIXED(SHEIGHT-1); } /* Move the ball. */ ball->x += MUL(ball->x_inc, ball->speed); ball->y += MUL(ball->y_inc, ball->speed); return 0; } Appelez cette fonction depuis game_logic, et récupérez ce qu'elle retourne, on en aura besoin. Si la balle sort, réinitialisez la, pour pouvoir tester ce que nous venons de coder. - paddle.h et paddle.c, collisions avec la balle et paddle de l'ordinateur - Collision avec le paddle Maintenant que nous avons une balle qui bouge, nous devonss pouvoir vérifier lorsqu'elle touche le paddle. Pour la simplicité de ce tutoriel, je garderais les collisions très simple, mais n'hésitez pas à les améliorer (en vérifiant pour une collision des deux côtés du paddle). Créez une fonction paddle_will_collide_with_ball qui a pour paramètres la raquette et la balle. Elle vérifiera si, lors du prochain mouvement de la balle, elle entrera en collision avec le paddle. Nous allons commencer par calculer la position de la balle sur l'axe des abscisses après son mouvement : /* Get the position on the x axis the ball will go to. */ fixed_t dest_x = ball->x+MUL(ball->x_inc, ball->speed); Ensuite nous allons vérifier si la balle passera d'un côté à l'autre du côté gauche du paddle. Si c'est le cas, nous retournons 1 : /* Check if the ball would go through the paddle (on the X axis). */ if((ball->x > TO_FIXED(paddle->x) && dest_x <= TO_FIXED(paddle->x)) || (ball->x < TO_FIXED(paddle->x) && dest_x >= TO_FIXED(paddle->x))){ /* Check if the ball is on the paddle on the Y axis. */ if(ball->y >= TO_FIXED(paddle->y) && ball->y < TO_FIXED(paddle->y+PADDLE_HEIGHT)){ /* The ball will hit the paddle. */ return 1; } } Sinon, retournez 0. Appelez cette fonction depuis game_logic et inversez y_inc lors d'une collision pour pouvoir tester les collisions : if(paddle_will_collide_with_ball(&game->paddle1, &game->ball)){ game->ball.y_inc = -game->ball.y_inc; } if(paddle_will_collide_with_ball(&game->paddle2, &game->ball)){ game->ball.y_inc = -game->ball.y_inc; } - Mouvement du paddle de l'ordinateur Nous pouvons maintenant faire bouger le paddle de l'ordinateur en fonction de la position de la balle, maintenant que nous pouvons la renvoyer. Créez une fonction paddle_computer_move qui prend pour paramètres le paddle à bouger et la balle. Si la position à l'écran, sur l'axe des ordonnées, de la balle est plus petite que la position de la raquette, nous allons la monter, et si elle est plus grande nous allons la monter. Sinon nous allons rien faire vu que la raquette est en face de la balle. void paddle_computer_move(Paddle *paddle, Ball *ball) { /* Move the paddle up if the ball y position is smaller than the paddle y * position. */ if(TO_INT(ball->y) < paddle->y+PADDLE_HEIGHT/2){ if(paddle->y-PADDLE_SPEED >= 0){ paddle->y -= PADDLE_SPEED; }else{ paddle->y = 0; } }else if(TO_INT(ball->y) > paddle->y+PADDLE_HEIGHT/2){ /* Move the paddle down if the ball y position is bigger than the paddle * y position. */ if(paddle->y+PADDLE_SPEED < SHEIGHT-PADDLE_HEIGHT){ paddle->y += PADDLE_SPEED; }else{ paddle->y = SHEIGHT-PADDLE_HEIGHT-1; } } } - game.c et game.h, affichage des scores. - Initialisation et affichage des scores. Nous avons déjà (presque) un jeu fonctionnel, mais nous devons compter le score, pour pouvoir savoir qui a gagné et qui a perdu. Nous allons commencer par ajouter deux variables à la structure Game pour le stocker : /* The player's score */ unsigned char score1; /* The computer's score */ unsigned char score2; Nous allons ensuite l'initialiser dans game_init : /* Reset the score. */ game->score1 = 0; game->score2 = 0; Pour l'afficher, nous allons utiliser itoa pour convertir le score en chaine de caractères et stext pour l'afficher à l'écran. Les scores sont des unsigned char, donc un tableau de 4 caractères sera suffisant. Pour afficher le score, nous allons d'abord appeler itoa pour obtenir une chaine de caractères : itoa(game->score1, score_buffer); Ensuite nous pouvons l'afficher avec stext : stext(SWIDTH/2-8-5*3, 8, score_buffer, SBLACK); Les deux premiers arguments sont la position à laquelle afficher le texte, le troisième, le texte à afficher et le dernier argument est la couleur (SWHITE ou SBLACK). Nous allons faire de même pour le score de l'ordinateur ce qui nous donne /* Convert the score to a string. */ itoa(game->score1, score_buffer); /* Display the score */ stext(SWIDTH/2-8-5*3, 8, score_buffer, SBLACK); /* Do the same with the score of the computer. */ itoa(game->score2, score_buffer); stext(SWIDTH/2+8, 8, score_buffer, SBLACK); - Incrémentation des scores. Le nombre retourné par ball_move va enfin nous être utile ! Si il retourne 1 le joueur obtient un point, sinon c'est l'ordinateur qui obtient un point : move = ball_move(&game->ball); if(move == 1){ /* Player 1 got a point. */ game->score1++; /* Put the ball in the middle and send it to the computer */ ball_init(&game->ball, TO_FIXED(1), TO_FIXED(1), TO_FIXED(DEFAULT_SPEED)); } if(move == 2){ /* Player 2 got a point. */ game->score2++; /* Put the ball in the middle and send it to the player */ ball_init(&game->ball, TO_FIXED(-1), TO_FIXED(1), TO_FIXED(DEFAULT_SPEED)); } - game.c, écran de titre et écran de fin du jeu. - Mise en place Lorsque le joueur ou l'ordinateur atteint un certain score, il faut que la partie se termine et que le joueur puisse recommencer. Nous avons donc besoin d'ajouter un écran de fin. Nous allons aussi ajouter un écran de titre. Nous allons définir une énumération dans game.h qui liste les différents écrans : /* The screens. */ typedef enum { S_TITLE, S_INGAME, S_END, S_AMOUNT } State; Nous allons stocker l'écran actuel dans la structure Game : /* What we're currently displaying */ unsigned char state; Ensuite, nous allons l'initialiser dans game_init : /* Display the title screen. */ game->state = S_TITLE; Nous allons créer un grand switch dans game_logic et game_draw pour effectuer des actions différentes selon l'écran affiché. Nous allons mettre le code que nous y avons actuellement dans le cas S_INGAME. Dans game_logic : switch(game->state){ case S_TITLE: break; case S_INGAME: /* Let the player move his paddle. */ paddle_move(&game->paddle1); /* Let the computer move his paddle. */ paddle_computer_move(&game->paddle2, &game->ball); /* If the ball hits the player paddle, make it bounce off of it. */ if(paddle_will_collide_with_ball(&game->paddle1, &game->ball)){ game->ball.y_inc = -game->ball.y_inc; } /* If the ball hits the computer paddle, make it bounce off of it. */ if(paddle_will_collide_with_ball(&game->paddle2, &game->ball)){ game->ball.y_inc = -game->ball.y_inc; } move = ball_move(&game->ball); if(move == 1){ /* Player 1 got a point. */ game->score1++; /* Put the ball in the middle and send it to the computer */ ball_init(&game->ball, TO_FIXED(1), TO_FIXED(1), TO_FIXED(DEFAULT_SPEED)); } if(move == 2){ /* Player 2 got a point. */ game->score2++; /* Put the ball in the middle and send it to the player */ ball_init(&game->ball, TO_FIXED(-1), TO_FIXED(1), TO_FIXED(DEFAULT_SPEED)); } break; case S_END: break; default: /* This should never happen, but if it happens we go to the title * screen. */ game->state = S_TITLE; } Dans game_draw : switch(game->state){ case S_TITLE: break; case S_END: /* Coming soon */ case S_INGAME: /* Convert the score to a string. */ itoa(game->score1, score_buffer); /* Display the score */ stext(SWIDTH/2-8-5*3, 8, score_buffer, SBLACK); /* Do the same with the score of the computer. */ itoa(game->score2, score_buffer); stext(SWIDTH/2+8, 8, score_buffer, SBLACK); /* Draw the paddles. */ paddle_draw(&game->paddle1); paddle_draw(&game->paddle2); /* Draw the ball. */ ball_draw(&game->ball); default: /* This should never happen, but if it happens we go to the title * screen. */ game->state = S_TITLE; } Note : Je n'ai pas mis de break à la fin de S_END, et je l'ai mis avant S_INGAME dans game_draw pour toujours afficher l'écran de jeu lorsque la partie est terminé. On écrira juste du texte en plus ("GAME OVER" ou "YOU WIN"). - Écran de titre Nous allons commencer par ajouter l'écran de titre. Dans game_draw nous allons juste dessiner l'image de l'écran de titre : /* Show the title image. */ simage(0, 0, 128, 64, (unsigned char*)title_img, SNORMAL); Les deux premiers paramètres de simage indiquent la position à laquelle l'image doit être dessinée. Les deux prochains sont la taille de l'image, le cinquième un pointeur vers les données de l'image et le dernier comment l'image doit être dessinée : SNORMAL : On dessine le noir aussi bien que le blanc SINVERTED : On inverse les couleurs. STRANSP : le blanc est dessiné comme du noir et le noir n'est pas dessiné. Utile pour faire de la transparence. SNOWHITE : On ne dessine pas le blanc. SNOBLACK : On ne dessine pas le noir. Dans game_logic nous allons réinitialiser le jeu (pour tout remettre à zéro) et aller vers l'écran S_INGAME, si la touche SHIFT est pressée : /* We wait for the user to press shift to go to the in game screen. */ if(kcheck(KCSHIFT)){ /* Reset the game. */ game_init(game); game->state = S_INGAME; } - Écran de fin de la partie. Nous allons ensuite coder l'écran de fin de la partie. Dans game_draw, nous allons afficher "GAME OVER" ou "YOU WIN!" selon le score. Pour l'afficher au milieu, j'ai ajouté quelque defines en haut de game.c : #define WIN "YOU WIN!" #define GAME_OVER "GAME OVER" /* The position of the game over text. */ #define GAME_OVER_X (SWIDTH/2-5*sizeof(GAME_OVER)/2) /* The position of the win text. */ #define WIN_X (SWIDTH/2-5*sizeof(WIN)/2) Dans game_draw il suffit d'appeler stext selon le score obtenu par le joueur : if(game->score1 > game->score2){ /* The player won, so we display it. */ stext(WIN_X, END_Y, WIN, SBLACK); }else{ /* The player lost, so we display it. */ stext(GAME_OVER_X, END_Y, GAME_OVER, SBLACK); } Ensuite, dans game_logic nous allons attendre que SHIFT est pressé, puis attendre que cette touche soit relachée pour que l'écran de titre ne soit pas sauté. /* Check if shift is pressed. If shift is pressed, go to the title * screen. */ if(kcheck(KCSHIFT)){ game->state = S_TITLE; /* Wait for shift to be released, to avoid directly going to the * ingame screen after going to the title screen. */ while(kcheck(KCSHIFT)) csleep(); } Ensuite, nous devons aller à l'écran de fin au score maximal, lorsqu'on change le score : if(move == 1){ /* Player 1 got a point. */ game->score1++; /* Put the ball in the middle and send it to the computer */ ball_init(&game->ball, TO_FIXED(1), TO_FIXED(1), TO_FIXED(DEFAULT_SPEED)); /* If the player got the max score he won, so we go to the end screen. */ if(game->score1 >= MAX_SCORE) game->state = S_END; } if(move == 2){ /* Player 2 got a point. */ game->score2++; /* Put the ball in the middle and send it to the player */ ball_init(&game->ball, TO_FIXED(-1), TO_FIXED(1), TO_FIXED(DEFAULT_SPEED)); /* If the computer got the max score he won, so we go to the end screen. */ if(game->score2 >= MAX_SCORE) game->state = S_END; } - ball.c, ball.h et game.c, rebond de la balle sur la raquette. Pour l'instant, le rebond de la balle n'est pas très fidèle à celui de pong. Je trouve que faire l'interpolation linéaire entre y_inc = -1 et y_inc = 1 de la position de la balle par rapport à la raquette est assez fidèle à l'original. Nous allons donc créer une fonction ball_bounce qui a pour paramètre la balle et le paddle, dans laquelle nous allons calculer le nouveau y_inc comme je l'ai décrit ci-dessus. Mon implémentation : void ball_bounce(Ball *ball, Paddle *paddle) { /* Linear interpolation to calculate the new angle of the ball. */ int pos_on_the_paddle = ball->y-TO_FIXED(paddle->y); fixed_t angle_inc = DIV(TO_FIXED(ANGLE_RANGE), TO_FIXED(PADDLE_HEIGHT)); /* Fix the position of the ball on the paddle. */ if(pos_on_the_paddle < 0) pos_on_the_paddle = 0; if(pos_on_the_paddle > TO_FIXED(PADDLE_HEIGHT)){ pos_on_the_paddle = TO_FIXED(PADDLE_HEIGHT); } /* Perform the linear interpolation. */ ball->y_inc = TO_FIXED(ANGLE_TOP)+MUL(angle_inc, pos_on_the_paddle); ball->x_inc = -ball->x_inc; /* Increase the ball speed because we hit a paddle. */ if(ball->speed < TO_FIXED(MAX_SPEED)){ ball->speed += TO_FIXED(SPEED_INC); } } Ajoutez son prototype à ball.h et appelez la lors d'une collision, là où on a précedemment fait game->ball.y_inc = -game->ball.y_inc;. Améliorations possibles Améliorez les collisions, essayez de rendre le jeu le plus petit possible, cela vous entrainera bien. Vous pouvez aussi ajouter un mode deux joueurs ou un mode robot contre robot. Vous pouvez aussi rendre possible la séléction du score maximal (libMicrofx propose des fonctions de saisie de nombres et de texte). Étendre vos connaissances de libMicrofx Pour étendre vos connassances de libMicrofx je vous conseille de lire les headers dans lib/include/microfx. La plupart des fonctions sont dans microfx.h. Il y a des fonctions très utiles à la création de jeux vidéos dans les headers dans le dossier ext. C'est la fin de ce tutoriel Voilà ! Vous avez fini de lire ce tutoriel (ou presque). J'espère que ce tutoriel vous a plu et que vous vous amuserez bien avec libMicrofx ! Sun, 25 Aug 2024 13:22:10 +0200 Tutoriel d'optimisation et d'overclock pour le jeu OpenJazz (Graph 90+E) https://www.planet-casio.com/Fr/forums/topic17776--.html Attention ! Ceci n'est pas un tutoriel sur l'overclock (Si vous en voulez un, je vous conseille de commencer par ceci, C'est déjà un très bon début, à ma connaissance.). Je ne suis pas un fin connaisseur, juste un tripatouilleur. Ces réglages ont été faits pour le jeu Jazz Jackrabbit , je ne garantis pas qu'ils auront le même effet sur d'autres jeux. C'est tout, on peut commencer. Pour commencer, qu'est-ce que l'overclock. En gros, c'est une accélération matérielle ou logicielle des composants de l'appareil qu'on cible (RAM, CPU, GPU, VRAM, etc.). On peut aussi underclocker (ralentir la vitesse de ces composants). Ici, ce qu'on va faire, c'est d'augmenter les FPS (nombre d'images par secondes, ça joue énormément sur la fluidité) en accélérant le matériel. Je vous préviens tout de même : l'overclock peut diminuer la durée de vie de votre appareil. Voilà, vous êtes prévenu. Mais loverclock ne cassera pas votre calculatrice, ne vous en faites pas (du moins, il n'y a aucun cas répértorié de ce genre.). Une chose qu'il fera à coup sûr, par contre... C'est de consommer plus. C'est à dire que vos piles se videront plus vite . Donc, pour ce tutoriel, vous aurez besoin d'une Casio Graph 90+E, de OpenJazz d'installé sur votre calculatrice, et de Ptune 3, l'outil qui va vous permettre d'overclocker votre calculatrice. Tout est prêt ? Bien. Lançons Ptune3. Conseil : si vous voulez afficher les fps en jeu, une fois dans OpenJazz, appuyez sur F1. Si le compteur bug et affiche 1 en permanence, relancez le jeu. https://www.planet-casio.com/storage/forums/Overclock1-17776.bmp Ça, c'est le paramètre de base de votre calculatrice. En gros, il va faire tourner OpenJazz à 28/20 fps. Généralement 25. Si vous le modifiez et que vous souhaitez y revenir, appuyez sur la touche F1. https://www.planet-casio.com/storage/forums/Overclock3-197286.bmp Ça, c'est le paramètre F4. Il vous permettra de jouer à 35 fps, voir 30. c'est suffisant pour un jeu comme celui-là. https://www.planet-casio.com/storage/forums/Overclock2-197285.bmp Celui-là, c'est le paramètre F5. Il vous permettra de jouer à plus de 40 fps (47/48) constants, parfois même à 50. Mais si vous voulez aller plus loin, vous pouvez faire ceci : Appuyez sur la touche [^]. Cela pourrait vous faire gagner un ou deux FPS. Vous pouvez aussi monter la variable PLL, cela vous fera encore gagner quelques FPS. https://www.planet-casio.com/storage/forums/overclock4-197287.bmp Note: les paramètres F2 et F3 sont des paramètres d'underclock. Ils n'augmenteront pas vos fps. Voilà, cela vous donnera peut-être quelques bases pour faire vos réglages. ^^ Merci d'avoir lu, et bonne journée :) Thu, 30 May 2024 15:27:22 +0200 chiffres 1 à 9 en python extra sur graph 35+ EII https://www.planet-casio.com/Fr/forums/topic17771--.html Avec python extra je me suis amusé ce matin à coder les chiffres de 0 à 9 de 5 pixels de haut et 4 pixel de large. from gint import * c=[[[1,1,1,1],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,1,1,1]],[[0,0,0,1],[0,0,0,1],[0,0,0,1],[0,0,0,1],[0,0,0,1]],[[1,1,1,1],[0,0,0,1],[1,1,1,1],[1,0,0,0],[1,1,1,1]],[[1,1,1,1],[0,0,0,1],[0,1,1,1],[0,0,0,1],[1,1,1,1]],[[1,0,0,1],[1,0,0,1],[1,1,1,1],[0,0,0,1],[0,0,0,1]],[[1,1,1,1],[1,0,0,0],[1,1,1,1],[0,0,0,1],[1,1,1,1]],[[1,1,1,1],[1,0,0,0],[1,1,1,1],[1,0,0,1],[1,1,1,1]],[[1,1,1,1],[1,0,0,1],[0,0,0,1],[0,0,0,1],[0,0,0,1]],[[1,1,1,1],[1,0,0,1],[1,1,1,1],[1,0,0,1],[1,1,1,1]],[[1,1,1,1],[1,0,0,1],[1,1,1,1],[0,0,0,1],[1,1,1,1]]] dclear(0) for n in range(10): for y in range(5): for x in range(4): if c==1:dpixel(x+n*8+0,y,3) dupdate() k=getkey() voici ce que ça donne : https://imgur.com/yZ9EthZ.png ça n'a pas trop d''intérêt si ce n''est pour comprendre les listes... Sat, 18 May 2024 10:50:38 +0200 Coder un add-in en Python! https://www.planet-casio.com/Fr/forums/topic17719--.html Salut tout le monde :D , Comme on le sait tous, un add-in se fait coder en C ou en C++. Aujourd'hui j'ai découvert un site web qui permet de transformer un code python en un code C avec de l'IA! le site web est ici: https://www.codeconvert.ai/python-to-c-converter . Si vous utilisez gint, vous pouvez simplement mettre les fonctions Python comme ce que vous aurez fais avec Python Extra, et ensuite entré ces lignes au début du code: #include <gint/keyboard.h> #include <gint/display.h>Et c'est fais! Normalement les résultats sont très impressionnant et correct. Si il y a une erreur tout de même, vous pouvez toujours poster un commentaire ;) . Voilà voilà! Tuper Fri, 15 Mar 2024 18:37:37 +0100 Question en C https://www.planet-casio.com/Fr/forums/topic17613--.html Salut tout le monde! Je voulais savoir est ce que c'est possible de définir une variable dès la première ligne. Et est ce que on est obligé d'utiliser "void" car le projet initiale que le donne le sdk est un long paragraphe et je ne sais pas où commencer. Merci pour vos réponses ^^ Wed, 10 Jan 2024 09:33:09 +0100 Demande de conseil sur l'introduction d'une double condition dans un prog pour fx 8500 G https://www.planet-casio.com/Fr/forums/topic17586--.html SUR UNE FX 8500 G JE VOUDRAIS DANS UN PROGRAMME METTRE DEUX CONDITIONS POUR LANCER UNE BOUCLE: Soit M résultat d'un calcul A > 0 ET B > 0 entraîne GOTO 1 A > 0 ET B < 0 entraîne GOTO 2 A < 0 ET B < 0 entraîne GOTO 3 LBL 1 M LBL 2 M + 100 LBL 3 M + 200 Il n'y a pas de fonction AND prête à servir ans la FX 8500 G Je suis preneur de tout conseil, merci d'avance et bonne année. Tue, 02 Jan 2024 20:16:34 +0100