Seuls les membres ayant 30 points peuvent parler sur le chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » gint : un noyau pour développer des add-ins
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

gint : un noyau pour développer des add-ins

Posté le 20/02/2015 17:30

Les SDKs classiques pour écrire des add-ins sont le fx-9860G SDK de Casio avec fxlib (pour Graph monochrome) et le PrizmSDK avec libfxcg (pour Prizm et Graph 90+E). Voici mon alternative : le fxSDK avec gint, pour toutes les plateformes.

Contrairement à fxlib et libfxcg, qui appellent les fonctions de l'OS pour faire leur travail, gint est un noyau indépendant de l'OS qui exploite seul le matériel et le met à disposition de votre add-in. Il vous offre plus de finesse sur le contrôle du matériel, notamment le clavier, l'écran et les horloges, de meilleurs performances sur le dessin, les drivers et la gestion de interruptions, et des choses entièrement nouvelles comme le moteur de gris.

Toutes les sources de gint sont publiques et accessibles sur la forge de Planète Casio :

» Dépôt Gitea Lephenixnoir/gint «

Voici plus précisément ce que gint vous offre de nouveau :

• Un contrôle détaillé du clavier pour les jeux, parfait pour les combos !
• Des timers avec une précision de 60 ns, d'autres à 30 µs
• Toutes vos images converties automatiquement sans code à copier (plus de Sprite Coder)
• Des polices personnalisées
• Des fonctions de dessin, d'images et de texte fulgurantes et optimisées la main
• Mesurer les performance de votre code à la microseconde près (avec libprof)
• Le contrôle du matériel et des interruptions
• Plein de petites choses pratiques comme dprint(1, 1, "x=%d", x)

• (Graph monochrome) Un moteur de gris pour faire des jeux en 4 couleurs !
• (Graph monochrome) La compatibilité SH3 et SH4, avec le même fichier g1a.

• (Graph 90+E) Une nouvelle police de texte, plus lisible et économe en espace
• (Graph 90+E) Le dessin en plein écran, sans les bordures blanches et la barre de statut !
• (Graph 90+E) Un driver écran capable de triple-buffering

Le coût de tout ceci, c'est que vous avez une copie du code de gint dans votre add-in. Cela prend environ 20 ko de place (selon la quantité de fonctions que vous utilisez), soit à peu près comme le sprintf() de fxlib qui fait 18 ko !

Et voici quelques photos et captures d'écran !





Tester gint sur votre machine

La fin du portage vers la Graph 90+E signera la sortie de gint v2. L'add-in de test de l'application est désormais gintctl :

» Dépôt Gitea Lephenixnoir/gintctl «

En plus de tester les fonctionnalités de gint, cet add-in contient quelques outils permettant d'inspecter la machine, la mémoire, et les registres. Je le développe au fur et à mesure, et je posterai un protocole de test complet avec la sortie de la v2 !

Utiliser gint pour développer des add-ins

Normalement, vous avez besoin du fxSDK pour développer avec gint. Le fxSDK est compatible avec Linux et Mac OS, et on peut réfléchir à un portage sous Windows s'il y a vraiment des intéressés. Il faut l'installer en premier (et avoir un cross-compilateur GCC).

La procédure de compilation et d'installation de gint est décrite sur le README du dépôt, c'est du configure - make tout à fait banal.

Une fois que gint est installé sur votre système, voyez les tutoriels de développement pour avoir un aperçu de son fonctionnement. La plupart des choses sont expliquées dans les en-têtes (fichiers .h) de la bibliothèque que vous pouvez consulter en ligne, sur votre copie locale du dépôt, ou dans les dossiers d'installation du compilateur.

Obtenir la dernière version de gint après une mise à jour

Je pousse régulièrement des mises à jour de gint sur le dépôt du projet. Pour les télécharger, tapez git pull, puis recompilez et réinstallez gint avec make et make install.


Fichier joint


Pages : Précédente1 ... , 24, 25, 26, 27, 28, 29, 30Suivante
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 15/11/2019 11:37 | #


Right, c'est un bug chez moi. Y'a des trucs subtils cachés partout

Je suis dessus...

Ajouté le 15/11/2019 à 13:32 :
C'est bon, j'ai corrigé ! Désolé, je manquais de tests... faut que je passe plus de temps sur ce projet
KikoodxHors ligneMembrePoints: 1614 Défis: 9 Message

Citer : Posté le 15/11/2019 14:52 | #


C'est bon pour moi ! Tout fonctionne merci
J'ai changé mon avatar pour la première fois en trois ans

2+2=5
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 15/11/2019 15:00 | #


Merci pour ta patience !
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 20/11/2019 15:40 | #


À quoi correspondent les différentes valeurs affichées lorsque il y a une Exception sur les graph monochromes ?
Par exemple, ici j'ai le cas suivant:
Exception! (SysERROR)
Read address error
PC :003034ba
TEA :003045f6
TRA :00000000 // à quoi correspondent PC, TEA, et TRA ?

The add-in crashed.
Please reset the calc

LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 20/11/2019 15:48 | #


PC c'est l'adresse de l'instruction responsable de l'erreur + 4 octets (car la calculatrice lit le code 4 octets en avance de son exécution). Ici ça doit donc être une instruction d'accès mémoire.

TEA c'est l'adresse à laquelle un accès invalide a été effectué. Ici elle n'est pas aligné à 4 octets, donc la première chose à regarder.

TRA c'est le numéro du trap, c'est utilisé uniquement quand l'exception est causée par l'instruction trapa, qui n'est utilisée que quand tu l'appelles exprès. (C'est fait pour implémenter des syscalls.)
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 20/11/2019 15:49 | #


Merci beaucoup pour cette explication
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 20/11/2019 15:53 | #


S'il y a d'autres informations que tu penses utile, je serai ravi de les ajouter. Sur la Graph 90+E, il y a largement la place. Sur la Graph mono, je peux utiliser le système que j'ai implémenté (et que tu avais motivé, il me semble) et avoir une System ERROR interactive.
YoustonesHors ligneMembrePoints: 317 Défis: 0 Message

Citer : Posté le 20/11/2019 16:15 | #


Lephenixnoir a écrit :
• (Graph monochrome) Un moteur de gris pour faire des jeux en 4 couleurs !
• (Graph monochrome) La compatibilité SH3 et SH4, avec le même fichier g1a.

• (Graph 90+E) Une nouvelle police de texte, plus lisible et économe en espace
• (Graph 90+E) Le dessin en plein écran, sans les bordures blanches et la barre de statut !
• (Graph 90+E) Un driver écran capable de triple-buffering

Cela veut dire si l'on crée un jeu et qu'on le publie, l'utilisateur doit aussi installer gint ?
Mon cerveau se répète tous les jours la mythique phrase : "Houston, je crois que nous avons un problème"
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 20/11/2019 16:19 | #


Lephenixnoir (juste après) a écrit :
Le coût de tout ceci, c'est que vous avez une copie du code de gint dans votre add-in. Cela prend environ 20 ko de place (selon la quantité de fonctions que vous utilisez), soit à peu près comme le sprintf() de fxlib qui fait 18 ko !

LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 20/11/2019 16:20 | #


Cela veut dire si l'on crée un jeu et qu'on le publie, l'utilisateur doit aussi installer gint ?

Non, gint est dans l'add-in en quelque sorte. Le fichier g1a ou g3a est exactement comme les add-ins habituels, on le met dans la calculatrice et c'est bon.
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 20/11/2019 16:53 | #


J'ai une question d'ordre pratique pour l'utilisation du clavier avec la nouvelle version.
voici un exemple

key_event_t event = pollevent();
while (event.type!=KEYEV_NONE)
{
    if (keydown(KEY_LEFT))
        camera.dh -= 0.1;
    if (keydown(KEY_RIGHT))
        camera.dh += 0.1;
[...]
    event=pollevent();
}

Si j'ai bien compris, ce code est supposé gérer la répétition des touches. Or, ce n'est pas le cas

Ai-je fait une erreur, ou y a-t-il un bug ?
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 20/11/2019 17:16 | #


Eh fait, non. Tu peux trouver une piste dans le message de commit associé :

* commit 95a334532643e5e0e82bfe97bae699630f22b7ee
| Author: Lephe <sebastien.michelland@protonmail.com>
| Date:   Sat Sep 28 19:22:47 2019 +0200
|
|     keyboard: add keydown() in the model
|
|     This change adds a keydown() function that is synchronized with events,
|     ie. it returns the key state as seen by previously read events.
|
|     It also completely eliminates low-level repeat events, which are not
|     very meaningul as the keyboard scan frequency goes up (and would be
|     meaningless if KEYSC interrupts were used), and adapts getkey() by
|     giving it access to the current driver time through pollevent().

Le problème des événements type répétition est qu'ils étaient cadencés sur la fréquence du clavier, et donc avaient cette quantification variable (128 Hz en général, mais pas toujours, et faut que ce soit suffisamment rapide sinon il y a des problèmes...).

J'ai donc changé de point de vue : j'ai placé le timer clavier à une valeur élevée (eg. 128 Hz) et je considère que la précision temporelle est infinie. Je pars donc du principe que tu es averti immédiatement (sous la forme d'un événement) quand la touche est pressée ou relâchée. Tu peux alors calculer toi-même les répétitions associées, soit avec un timer soit après coup (ou utiliser une fonction de haut niveau comme getkey() pour le faire).

Il n'y actuellement que getkey() qui renvoie des événements de genre répétition.

Ce que je peux te suggérer est plus stylé (et plus idiomatique pour les jeux vidéo). Quand tu dépiles tes events : soit la touche est pressée puis relâchée, et tu peux déplacer ta caméra d'une vitesse angulaire multipliée par le temps de pression ; soit la touche a été pressée mais pas encore relâchée, et tu peux déplacer ta caméra d'une vitesse angulaire multipliée par le temps écoule depuis que la touche a été pressée (ou plutôt, depuis que tu l'as observée pour la dernière fois).

Les événements ont un champ time qui sert exactement à ça, vois dans <gint/keyboard.h>.
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 20/11/2019 20:33 | #


J'étais complètement passé à côté de ce commit. En tout cas, tout est bon, ça marche !


Du coup, j'ai une question, on ne verra plus jamais d'events avec KEYEV_HOLD ?
Si c'est ça, je trouve ça top, ça allègerait le buffer.


LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 20/11/2019 20:34 | #


Milang a écrit :
Du coup, j'ai une question, on ne verra plus jamais d'events avec KEYEV_HOLD ?
Si c'est ça, je trouve ça top, ça allègerait le buffer.

Si, mais seulement quand getkey() les génère, et donc pas dans le buffer.

Et sur ce point, je suis entièrement d'accord avec toi.
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 22/11/2019 10:32 | #


J'ai encore une autre question :

Comment fait-on pour réglèr la vitesse d'éxécution d'un timer ?
Je sais que cela peut paraîtrre bête, mais je ne vois aucune différence à l'éxécution entre ces deux codes:
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/timer.h>

#include "world.h"

#include <gint/keyboard.h>

int callback(volatile void *arg)
{
    volatile int *has_ticked = arg;
    *has_ticked = 1;
    return 0;
}

int main(void)
{
    volatile int has_ticked = 1;

    timer_setup(0, timer_delay(0, 10000), timer_Po_4, callback, &has_ticked);
    timer_start(0);

    while(global_quit==0)
    {
        has_ticked=0;
        dclear(C_WHITE);
        world_update();
        dupdate();
    }

    timer_stop(0);
}

et celui là, qui devrait daire executer le jeu avec un rafraichissement 3x plus faible
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/timer.h>

#include "world.h"

#include <gint/keyboard.h>

int callback(volatile void *arg)
{
    volatile int *has_ticked = arg;
    *has_ticked = 1;
    return 0;
}

int main(void)
{
    volatile int has_ticked = 1;

    timer_setup(0, timer_delay(0, 3*10000), timer_Po_4, callback, &has_ticked);
    timer_start(0);

    while(global_quit==0)
    {
        has_ticked=0;
        dclear(C_WHITE);
        world_update();
        dupdate();
    }

    timer_stop(0);
}

LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 22/11/2019 10:34 | #


Eh mais... ton jeu tourne à fond là n'est-ce-pas ? Tu ne lis jamais la valeur de has_ticked.

Le but du timer c'est que tu arrêtes de t'exécuter jusqu'à ce que has_ticked devienne égal à 1. Donc ta boucle devrait ressembler à ça :

#include <gint/clock.h>

while(global_quit == 0)
{
    /* Sleep until the timer ticks */
    while(!has_ticked) sleep();
    has_ticked = 0;

    dclear(C_WHITE);
    /* etc */
}
MilangEn ligneMembrePoints: 393 Défis: 2 Message

Citer : Posté le 22/11/2019 10:35 | #


Oh le con
C'est moi qui ai supprimé le bout de code dans une manip xD
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 22/11/2019 10:39 | #


Tout va bien alors.

Soit dit en passant, selon la complexité de ton jeu tourner à fond peut aller beaucoup plus vite que si tu contrôles le timing (genre on peut monter assez facilement à 200 ou 300 FPS).
YatisEn ligneMembrePoints: 458 Défis: 0 Message

Citer : Posté le 26/11/2019 21:43 | #


Il y a fort longtemps, Lephenixnoir a écrit :

Milang a écrit :
Du coup, il y a finalement un dma sur les graph monochromes ou non ?

Pour l'instant non, il n'y en a pas.

Le DMA existe bel et biens sur monochrome et toute la documentation SH7724 semble lui correspondre. Seulement, Casio ne l'utilise qu'à de rares occasion (l'USB par exemple) et le reste du temps ils font "correctement" leur travail en "éteignant" le module (ce qui est, bien entendu, déconseillé dans la documentation de Renesas). Pour pouvoir y accéder il suffit de mettre le bit POWER.MSTPCRC0.DMA0 à 0 pour "allumer" le module
LephenixnoirEn ligneAdministrateurPoints: 16478 Défis: 140 Message

Citer : Posté le 26/11/2019 21:46 | #


Diaaaantre. Tu sais pas quoi ? Le driver de gint sauvegarde ce bit mais oublie de le mettre à 1 lorsqu'il s'initialise. Et du coup je suis passé à côté ! o(x_x)o

Désolé Milang pour la grosse confusion. Côté positif, ce memset de 65k pour ton z-buffer pourrait bien se faire accélérer finalement.

Ah je me sens con. xD
Shadow15510Hors ligneAdministrateurPoints: 4005 Défis: 16 Message

Citer : Posté le 08/12/2019 17:56 | #


Je voulais savoir si la transparence est gérée, ou pas ? Dans la version actuelle de Gint.

Merci d'avance !
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Moral
   95%
Pages : Précédente1 ... , 24, 25, 26, 27, 28, 29, 30Suivante

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 72 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