1

Salut à tous,

Je maitrise très bien la prog C avec les fonctions de TIGCC. Je précise que je suis partisan du nostub.
Comme je n'ai pas envie de me retaper toujours la même chose à chaque nouveau projet (désactiver les auto_int, mettre en place les écrans virtuels, portSet pour les niveau de gris etc..), j'ai cherché une libraire qui fasse tout ce boulot assez chiant.
De plus le double buffering par memcopy est tout de même relativement lent.

J'ai donc recensé 4 noms de librairies :
GraphX
ExtGraph
GenLib
Xlib.

ExtGraph ne m'a pas vraiment convaincu, cela simplifie l'utilisation des niveaux de gris mais la fonction FastScreenCopy censée accélérer le double buffering n'est pas plus rapide qu'un memcopy.
GraphX est déjà nettement plus convaincante, la technique de double buffering est très rapide est la librairie est dans l'ensemble très simple à utiliser. Seul bémol, l'utilisation des sprites autres que 32x32 semble merder (à moins que ce soit l'outil livré avec qui ne les génère pas correctement). De plus je n'ai pas réussi à utiliser les fonctions de base comme DrawLine, DrawPixel, DrawCircle, sachant que cette librairie n'en propose aucune (hormis DrawPixel).
GenLib m'a paru très complète, du moins sur la papier, car dans la pratique je n'ai jamais réussi à la faire fonctionner avec TIGCC (j'ai suivi la procédure d'install et j'ai copié l'exemple dans la doc, mais j'obtiens une erreur "Library calls are not supported in this mode". Au passage, si quelqu'un sait d'où ça vient je suis preneur.
Xlib j'ai lu son nom sur ce forum mais impossible de la trouver sur le net.

Bref hormis si qqn sait comment faire fonctionner GenLib, je suis assez perdu dans mon choix de librairie.
J'en suis presque à me demander si il vaut mieux ne pas en utiliser. Le seul pb, je le rappelle, est la lenteur du double-buffering par memcpy face auquel je ne vois pas vraiment de solution, sauf à éviter d'en faire (je pense à une solution qui consisterait à changer l'adresse de la mémoire vidéo de la TI pour switcher entre deux écrans, mais je ne sais pas du tout si c'est faisable et je n'y connais rien en ASM).

Voilà donc si vous avez des conseils je suis preneur top

@+

2

Hum, normalement cette étape n'est pas ce qui prend le plus de temps dans un jeu...
15 Hz sont suffisants pour l'affichage. Au pire 30 Hz...
Moi je te conseille genlib. Je ne sais pas trop pourquoi ça n'a pas fonctionné. Il faut dire que comme l'équipe de TIGCC ne s'investit pas beaucoup pour maintenir les fonctionnalités "kernel", il faut peut-être un peu bricoler pour que ça fonctionne...
!call PpHd
--- Call : PpHd appelé(e) sur ce topic ...
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

3

4

PS : La fonction FastScreenCopy est tout de même plus rapide qu'un simple memcpy, ton problème de lenteur vient peut-être d'ailleurs.
PPS : les bibliothèques GraphX et Xlib ne sont plus du tout maintenues. Les seules bibliothèques à jour sont genlib et extgraph.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

5

ok pour genlib en plus il me semble que GraphX n'est pas compatible Titanium.
Mais il faudrait juste réussir à l'utiliser lol.
J'ai vu dans un autre post que quelqu'un avait le même problème avec TIGCC v.0.95, alors qu'il ne se posait pas avec TIGCC v.0.94.
Le seul truc c'est que je n'arrive pas à mettre la main sur cette version grin
Si quelqu'un l'a en stock je suis pas contre.

6

7

oui je suis sous windows, TIGCC v.0.95

8

9

ouais j'suis généralement pas chaud pour les v. bêta mais je peux essayer pour voir si ça change qq chose.

10

11

Pas de changement avec TIGCC v.0.96.
C'est bizarre comme problème.
En fait dans la doc ils disent juste de copier genlib.a dans le répertoire lib & Archive et le header qui va bien.
Ensuite je mets cette fonction dans le code :

#include <genlib.h>
void gl_main()
{

}

Résultat : Library calls are not supported in this mode.
Si je rajoute gl_init(); et gl_quit(); dans la fonction main, il me sort Unsolved reference to gl_init() et gl_quit().
Je rajoute donc gennlib.a (avec deux "n") dans lib et dans archive et je reteste.
Dans le premier cas (fonction vide), idem, "Library calls..."
Et dans le deuxième cas, avec gl_init() et gl_quit(), le plus curiseusement du monde ça compile, mais la calto (enfin l'émulateur) se crashe directement.

Je comprends rien et vous ?

12

Il y a peut être des options à configurer dans TIGCC aussi ?
J'utilise les options par défaut, et mon fichier .C est vide (hormis le code que j'ai posté).

13

Compile en mode kernel.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

14

djflex (./1) :
GenLib m'a paru très complète, du moins sur la papier, car dans la pratique je n'ai jamais réussi à la faire fonctionner avec TIGCC (j'ai suivi la procédure d'install et j'ai copié l'exemple dans la doc, mais j'obtiens une erreur "Library calls are not supported in this mode". Au passage, si quelqu'un sait d'où ça vient je suis preneur.

Tu as compilé ton programme en mode 'nostub' et tu essayes de faire un call à une librarie kernel.
La solution est d'inclure gennlib.a qui définit un wrapper nostub pour charger genlib.
genlib.a est pour lié en kernel. gennlib.a pour le nostub.

genlib est trop grosse et a trop de fonctionnalités liées pour être statique (Même Kevin à abandonner, c'est te dire wink).
djflex (./11) :
Résultat : Library calls are not supported in this mode.
Si je rajoute gl_init(); et gl_quit(); dans la fonction main, il me sort Unsolved reference to gl_init() et gl_quit().
Je rajoute donc gennlib.a (avec deux "n") dans lib et dans archive et je reteste.
Dans le premier cas (fonction vide), idem, "Library calls..." Et dans le deuxième cas, avec gl_init() et gl_quit(), le plus curiseusement du monde ça compile, mais la calto (enfin l'émulateur) se crashe directement.

gennlib.a est ce qu'il fallait pour faire fonctionner en nostub mais ...
Le mode 'nostub' de genlib (gennlib) n'est plus supporté.
J'ai fait un sondage et la majorité s''en foutait ( topics/43486-genlib-nostub-do-you-use-it ) , alors je n'ai pas eu envie de perdre du temps à supporter ce mode (Surtout que c'était lourd à faire).
Si tu veux essayer de le refaire marcher, c'est le fichier 'load.c' dans /genlib/src/static de l'archive qui est à modifé et à adapter aux recents AMS / hardware.

PS: Sympa le double call smile

15

Les gens qui conseillent genlib, on dirait que vous ne savez pas lire:
djflex (./1) :
Je précise que je suis partisan du nostub.

PpHd (./14) :
genlib est trop grosse et a trop de fonctionnalités liées pour être statique (Même Kevin à abandonner, c'est te dire wink).

Je n'ai pas abandonné, je n'ai pas le temps, c'est différent. (Et le problème n'est pas que ce ne serait pas possible en librairie statique (évidemment que c'est possible!), mais que ton code n'est pas maintenable. tongue)

Au passage, je signale que gennlib.a n'est pas du vrai _nostub, mais un hack pour reloger la librairie kernel (une sorte de kernel intégré, quoi), c'est pour ça que ça n'intéresse personne.

Quant à la question de départ:
J'en suis presque à me demander si il vaut mieux ne pas en utiliser. Le seul pb, je le rappelle, est la lenteur du double-buffering par memcpy face auquel je ne vois pas vraiment de solution, sauf à éviter d'en faire (je pense à une solution qui consisterait à changer l'adresse de la mémoire vidéo de la TI pour switcher entre deux écrans, mais je ne sais pas du tout si c'est faisable et je n'y connais rien en ASM).

Le double-buffering par plane switching est déjà intégré à TIGCCLIB! Cf. http://tigcc.ticalc.org/doc/gray.html. Donc tu n'as besoin d'aucune librairie pour faire ce que tu veux.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

16

Le double-buffering par plane switching est déjà intégré à TIGCCLIB

J'ai cru voir ça effectivement. Mais est-ce que c'est compatible avec le mode non-grayscale (noir & blanc) ?
Donc tu n'as besoin d'aucune librairie pour faire ce que tu veux.

Ouais je pense que je vais me faire un template, ça sera plus simple.

17

Pour les "grandes" librairies graphiques maintenues et utilisables, il ne reste en effet plus qu'ExtGraph et Genlib.
Même si leurs fonctionnalités se recoupent évidemment, et que Genlib est une souce d'inspiration pour ExtGraph, elles n'occupent pas le même "segment" de "marché". En gros:
* Genlib: lib dynamique kernel-based, philosophie principale "une routine pour plusieurs usages" (philosophie qui vient largement du fait que c'est une lib dynamique, pour laquelle le footprint sur la calculette doit être aussi limité que possible);
* ExtGraph: lib statique neutre (même si personne ne doit l'utiliser en kernel-based grin), philosophie principale "une routine pour un usage".


> ExtGraph ne m'a pas vraiment convaincu, cela simplifie l'utilisation des niveaux de gris mais la fonction FastScreenCopy censée accélérer le double buffering
FastCopyScreen(_R) n'accélère pas le double buffering.
FastCopyScreen(_R) fait de la copie bourrine de plans, sans synchronisation avec les routines de grayscale. C'est pas pareil grin
Le vrai "bon" doublebuffering se fait avec les fonctions fournies par les routines de grayscale, et il peut même être plus rapide que l'utilisation de FastCopyScreen(_R), puisqu'il n'y a pas double copie des données.

> n'est pas plus rapide qu'un memcopy.
Si. Vu les instructions qu'utilise FastCopyScreen(_R) (pour transférer 32 bits, 8 clocks + l'overhead du décodage de l'instruction movem.l), et vu celles qu'utilise memcpy (pour transférer 32 bits, 12 clocks + l'overhead du décodage de l'instruction move.l), FastCopyScreen(_R) est plus rapide que memcpy. Ton bench est certainement faux.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

18

djflex (./16) :
J'ai cru voir ça effectivement. Mais est-ce que c'est compatible avec le mode non-grayscale (noir & blanc) ?

Non, mais à part ExtGraph, les librairies citées sont toutes pour les niveaux de gris elles aussi.

Il faut savoir que (à part pour les vieilles HW1) pour écrire sur l'écran, il faut forcément une recopie quelque part, parce que l'écran ne va plus lire ses données en RAM depuis les HW2, mais intercepte les écritures dans sa plage d'adresses et effectue les mêmes écritures dans sa mémoire interne. Donc le plane switching n'est pas possible en noir&blanc. En niveaux de gris, c'est la routine de gris qui recopie alternativement l'un ou l'autre plan, le plane switching change l'adresse source de cette recopie périodique (et évite donc une deuxième recopie par dessus).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

19

FastCopyScreen(_R) est plus rapide que memcpy. Ton bench est certainement faux.


C'est un bench à vu de nez (une balle qui rebondit sur l'écran).
La vitesse semblait équivalent entre les deux méthodes.

Concernant le GrayDBufToggle proposé par TIGCC, j'ai vu qu'il existait une version Sync, mais je saisis pas réellement la différence. J'ai cru lire à quelque part que la version Sync était bcp plus lente que la non-sync. Cependant d'après la doc la version non-sync peut produire des effets indésirables sur l'image.
Du coup je ne sais pas vraiment laquelle choisir (on dirait un dilemne entre vitesse et qualité).

Qqn pour m'éclairer sur le sujet ? confus

Merci

20

AMHA, sauf si tu synchronises manuellement, la version sans synchro n'est tout simplement pas une option à envisager.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

21

J'ai cru lire à quelque part que la version Sync était bcp plus lente que la non-sync

Si je prends la version Sync comme tu le préconises, ça reste quand même plus rapide qu'un memcpy ? Sinon tout ce qu'on raconte ne sert à rien finalement...

22

> C'est un bench à vu de nez
Donc c'est pas un bench wink
L'écran est trop lent / les fonctions sont trop rapides pour que tu _voies_ la différence. Mais elle est mesurable.
FastCopyScreen(_R) et toutes les routines de grayscale, sur HW2+, utilisent cette méthode de recopie de données, parce qu'elle est plus rapide que memcpy. A la louche, d'après ce que j'ai marqué plus haut, 1 appel à FastCopyScreen(_R) prend environ les deux tiers du temps que prend un appel équivalent à memcpy.



La version Sync est plus lente que la version non-Sync parce que ces macros sont définies ainsi:
#define GrayDBufToggle() ((void)(__gray_dbl_offset=(__gray_dbl_offset?0:8)))
#define GrayDBufToggleSync() ({short __ishw2=_GrayIsRealHW2();if(__ishw2)GrayWaitNSwitches(1);GrayDBufToggle();if(!__ishw2)GrayWaitNSwitches(1);})
#define GrayWaitNSwitches(n) ({unsigned long __w=__switch_cnt+(n);while(__switch_cnt<__w);})

GrayWaitNSwitches fait de l'attente active. Si on refait sa définition, on peut faire quelques traitements en attendant que le plane switch soit fini.


> Si je prends la version Sync comme tu le préconises, ça reste quand même plus rapide qu'un memcpy ?
Très difficile à dire... En effet, ça dépend de:
* la quantité de données qu'il reste à copier avant le prochain plane switch;
* le temps qu'il reste jusqu'à la prochaine interruption 1 (utilisée par la routine de grayscale).
Et ça, ça dépend des traitements que fait ton programme.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

23

Donc c'est pas un bench

J'ai jamais dit que c'en était un, c'est toi qui a introduit ce terme.
Très difficile à dire... En effet, ça dépend de:
* la quantité de données qu'il reste à copier avant le prochain plane switch;
* le temps qu'il reste jusqu'à la prochaine interruption 1 (utilisée par la routine de grayscale). Et ça, ça dépend des traitements que fait ton programme.


En fait si je comprends bien, j'ai l'impression qu'il vaut mieux continuer à faire du memcpy ou du FastScreenCopy ça a l'air drôlement moins chiant que de se prendre la tête avec ces histoires de syncro.

24

> j'ai l'impression qu'il vaut mieux continuer à faire du memcpy ou du FastScreenCopy ça a l'air drôlement moins chiant que de se prendre la tête avec ces histoires de syncro.
Le programme est un poil plus facile à écrire (franchement, pas beaucoup wink ), mais moins agréable pour l'utilisateur: même si certaines personnes y sont moins sensibles que d'autre, ne pas faire des affichages synchrones se voit habituellement assez facilement à l'oeil nu.

L'idéal serait que les traitements de ton programme soient suffisamment découpables pour que tu puisses écrire GrayDBufToggleSync et GrayWaitNSwitches inline, en remplaçant l'attente active "while(__switch_cnt<__w);" par "while(__switch_cnt<__w ) { /* un petit bout du traitement */ };".
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

25

Le programme est un poil plus facile à écrire (franchement, pas beaucoup ), mais moins agréable pour l'utilisateur: même si certaines personnes y sont moins sensibles que d'autre, ne pas faire des affichages synchrones se voit habituellement assez facilement à l'oeil nu.

Si je comprends bien même avec FastScreenCopy, ce problème n'est pas résolu.
L'idéal serait que les traitements de ton programme soient suffisamment découpables pour que tu puisses écrire GrayDBufToggleSync et GrayWaitNSwitches inline, en remplaçant l'attente active "while(__switch_cnt<__w);" par "while(__switch_cnt<__w ) { /* un petit bout du traitement */ };".


en fait c'est presque un algorithme de jeu vidéo classique ce dont tu parles.
ça pourrait se résumer ainsi :

Tant que Temps_non_écoulé
Executer_Traitements();
Fin
Affichage();


Sachant que Temps_non_écoulé représenterait ici le temps de l'attente entre 2 switches. Mais, à moins que je ne me trompe, ce temps restant avant le prochain cycle ne sera pas toujours le même lorsqu'on atteindra la fonction Executer_Traitements(). Ce qui signifie que de manière aléatoire, cette fonction pourra être executée 1 fois, 5 fois, 10 fois, x fois, en fonction du temps restant avant le prochain cycle.
On risque donc d'avoir un programme saccadé non ?

26

27

(Note: je n'ai pas une grande expérience en programmation de jeux wink )

> > Le programme est un poil plus facile à écrire (franchement, pas beaucoup ), mais moins agréable pour l'utilisateur: même si certaines personnes y sont moins sensibles que d'autre, ne pas faire des affichages synchrones se voit habituellement assez facilement à l'oeil nu.
> Si je comprends bien même avec FastScreenCopy, ce problème n'est pas résolu.
Oui, ce problème n'est pas résolu, puisque FastCopyScreen(_R) ne prend pas plus en compte la synchro que memcpy. Je n'ai jamais écrit que FastCopyScreen(_R) prenait en compte la synchro wink

> ça pourrait se résumer ainsi :
> Tant que Temps_non_écoulé
> Executer_Traitements();
> Fin
> Affichage();
Dans mon esprit, pas exactement. En fait, ce que j'ai écrit plus haut est assez loin d'être complet...
Pour utiliser au max le processeur, je penserais à un truc du genre:
short state;


state = 0;
if (__switch_cnt<__w ) {
// bout 1 du traitement
state = 1; // Fini le premier bout

if (__switch_cnt<__w) {
// bout 2 du traitement
state = 2; // Fini le deuxième bout

if (__switch_cnt>=__w) {
// bout 3 du traitement
state = 3; // Fini le troisième bout

while (__switch_cnt<__w); // une attente active si par hasard, on finit le traitement avant que le plane switch soit fini;

}
}
}

if (state == 0) {
// faire bout 1 du traitement
state = 1;
}
if (state == 1) {
// faire bout 2 du traitement
state = 2;
}
if (state == 2) {
// faire bout 3 du traitement
}


> Mais, à moins que je ne me trompe, ce temps restant avant le prochain cycle ne sera pas toujours le même lorsqu'on atteindra la fonction Executer_Traitements().
Tu ne te trompes pas smile

> Ce qui signifie que de manière aléatoire, cette fonction pourra être executée 1 fois, 5 fois, 10 fois, x fois, en fonction du temps restant avant le prochain cycle.
Si on s'y prend mal ou si on désire faire du frameskip, oui.
L'attente active à la fin du traitement que j'ai mis plus haut resychronise avec l'affichage.

> On risque donc d'avoir un programme saccadé non ?
C'est possible que ce soit plus saccadé que la solution proposée par Martial, même si cette solution n'offre pas un framerate exactement constant non plus (de toute façon, il n'y en a pas, puisqu'il n'y a pas de timer synchrone avec le frame sync sur les TI-68k).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

28

Pour apporter une précision sur GraphX : Oui, elle avait été conçue pour être hyper simple tout en étant très rapide. C'était un projet assez intéressant je pense, et la doc était très claire, très didactique. Mais les sources ont été perdues.
Xlib était un peu dans le même style, avec l'avantage d'être plus complète. Les sources de Xlib ne sont pas perdues, mais personne ne souhaite visiblement reprendre le flambeau.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

29

Euh, si je me rappelle bien, les sources de Xlib ont aussi été perdues.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

30

Lionel Debroux (./27) :
> On risque donc d'avoir un programme saccadé non ? C'est possible que ce soit plus saccadé que la solution proposée par Martial, même si cette solution n'offre pas un framerate exactement constant non plus (de toute façon, il n'y en a pas, puisqu'il n'y a pas de timer synchrone avec le frame sync sur les TI-68k).


L'interruption des nvg n'est pas plus ou moins synchrone avec le frame sync ?
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.