1

yop,


Le code, pour fixer les idées, il est ultra-basique :

J'utilise un timer basé sur l'AI1, pour un jeu qui accélère. Le truc, c'est que quand je mets un compteur à 8, j'ai une vitesse de jeu bonne pour débuter. Mais à 2, c'est la limite la plus basse, au-delà c'est injouable. Hors entre 8 et 2, la progression est hyper rapide. En clair, passer de 4 à 3 accélère le jeu de 30%, t de 3 à 2 de 50%. Mon problème est là. Comment avoir une accélération linéaire , par exemple par cran de 10% ?

(note : l'AI5 n'est pas une réponse)

2

C'est quoi ce post ??

Voici le code :
AI_1:	tst.w	d5
	beq.s	Ret
		subq.w	#1,d5
Ret:
AI_redirect:
	rte

3

La virgule fixe est ton amie tongue

Au lieu de diviser ta fréquence comme tu le fais, tu utilises une variable compteur que tu incrémentes à chaque interruption.
L'idée c'est que la valeur du compteur va représenter un nombre à virgule (avec un nombre fixe de chiffres après la virgule) au lieu d'une valeur entière. Mais comme les CPU utilisent nativement des entiers, tu vas en fait stocker cette valeur multipliée par un coefficient.

En base 10 ça donnerait par exemple ça, avec 2 chiffres après la virgule, donc une multiplication par 100 :
Imaginons que tu veuilles un jeu qui "avance" à 42% de la fréquence de l'interruption, soit un facteur de 0.42. À chaque interruption, tu vas ajouter 42 (0.42 * 100) à ton compteur.

Tu initialises le compteur à 0.
1ère interruption : le compteur vaut 42, c'est moins de 100, tu ne fais rien.
2ème interruption : le compteur vaut 84, c'est toujours moins de 100, tu ne fais toujours rien.
3ème interruption : le compteur vaut 126, c'est plus que 100, donc tu retranches 100 (ça donne 26) et tu fais "avancer" ton jeu d'un cran.
(note : si ton incrément est plus grand que 100, pour simuler une fréquence plus rapide, le total peut atteindre ou dépasser 200. Dans ce cas il faut retirer 100 autant de fois que nécessaire pour que le compteur reste entre 0 et 99, autrement dit calculer modulo 100).

Etc.

Si tu fais la moyenne, tu trouveras bien une fréquence d'avancement qui vaut 42% de la fréquence de l'interruption.

En binaire c'est encore plus simple : sur les 32 bits de ton registre, tu réserves n bits (supérieurs) pour la partie entière, et le reste pour la partie décimale. Pour récupérer la partie entière, il suffit d'un décalage à droite ; et pour calculer le modulo, d'un masquage.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

4

5

Ok, merci bien. Il me semble évident que en asm, je vais pas me fixer sur une valeur comme 100, mais plutôt 128 pour calculer les modulos rapidement. Et comme j'affiche mes sprites à la main, je suis déjà dans les div entiers et les modulos.

(en fait, je fais un tunnel bête comme choux, pour les enfants grin)

Merci bien !

6

Pourquoi pas 128, mais en fait on décide de la répartition en fonction du nombre max à placer dans la partie entière et de la précision souhaitée, c'est un compromis.
Si tu veux couper en deux un swap fait bien l'affaire cheeky (de mémoire)

7

Exact, le 16.16 est pas un mauvais choix dans le cas général, et présente l'avantage de pouvoir utiliser swap pour récupérer la partie entière en peu de cycles smile
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

8

D'aileurs que sur HW2, pour éviter que la vitesse du jeu dépende de l'état des piles, je pense que tu pourrais calculer ton ratio en mesurant la vitesse de l'AI1 avec l'AI5
avatar

9

Oué, je suis pas non plus au poil de couille près, je suis pas en train de réimplémenter une horloge atomique cheeky

10

Pour l'instant non, mais tu dois penser à la ré-utilisabilité embarrassed

11

C'est nul ça, ça supprime du code à écrire embarrassed

12

grin

13

Folco (./11) :
C'est nul ça, ça supprime du code à écrire embarrassed


make my day smile



GT calin Folco
avatar
Accrochez vous ca va être Cerebral !!

14

Joli, il faut que j'arrive à synthétiser pour en faire un motivational poster au boulot love
avatar

15

Folco (./9) :
Oué, je suis pas non plus au poil de couille près, je suis pas en train de réimplémenter une horloge atomique
Sans être au poil de couille près, il semble me souvenir que l'écart entre des piles neuves et usagés était quand même assez sensible.
avatar

16

Ouais, TI ne sait pas faire de bonnes consoles de jeu embarrassed
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

17

Uther (./15) :
Folco (./9) :
Oué, je suis pas non plus au poil de couille près, je suis pas en train de réimplémenter une horloge atomique
Sans être au poil de couille près, il semble me souvenir que l'écart entre des piles neuves et usagés était quand même assez sensible.

On est bien d'accord. C'est quelque chose que je devrais obligatoirement prendre en compte pour un soft de musique, par exemple. Mais là... on verra les enfants astucieux qui joueront _après_ les autres, ayant remarqué que la tension des piles jouent sur la fréquence de l'AI1. Il ne faut pas oublier que ce programme est avant tout didactif : le source défile en temps réel sur le côté de l'écran tripo

18

"didactif", hey, jamais j'aurais pensé que tu imposes comme ça ta littérature érotique à ta progéniture embarrassed
avatar

19

./4>
float voltage = (float)(conv * REF_VOLTAGE) / (float)CONV_MAX;
Cette fois, on va diviser un plus grand nombre, et les erreurs d’arrondis seront minimales.


ach mais nan ! /o\
ca serait vrai pour des entiers, ou justement pour des virgules fixes, mais absolument pas pour des floats, sauf pour des valeurs extremes, qui passeraient en denormal apres la division, donc auraient des bits de mantisse tronques.
mais l'inverse est vrai aussi: pour les tres grands nombres, faire la multiplication avant peut tout aussi bien provoquer une saturation en +/-inf.
Vous me suivez? Pour retrouver un nombre dans le bon format, il faut donc multiplier par D après la division.

heu. bah nan. surtout pas. La oui il faut multiplier avant de diviser :>
sinon il se passe ce qu'il disait qu'il se passait pour les floats mais qu'en fait il se passe pas embarrassed


enfin sinon c'est plutot pas trop mal explique ^^
avatar
HURRRR !

20

Tiens, ça serait intéressant d'avoir la critique de PpHd, il touche sa bibille aussi question flottants ^^

21

en relisant oui, y'a certains trucs que je devrais ré-expliquer mieux, mais en fait, je me suivais très bien moi même #modui#

22

Folco (./20) :
Tiens, ça serait intéressant d'avoir la critique de PpHd, il touche sa bibille aussi question flottants ^^
Je peux me tromper, mais pour autant que je sache, la virgule flottante (à opposer à la virgule fixe) essaie d'adapter la précision au mieux de ce qu'on lui demande de représenter.
Donc si la partie entière est grande, il reste moins de place pour le reste (la partie décimale).

23

Folco (./20) :
Tiens, ça serait intéressant d'avoir la critique de PpHd, il touche sa bibille aussi question flottants ^^

Mouiii ?
float voltage = (float)conv * ((float) REF_VOLTAGE / (float)CONV_MAX);
?

24

./22 : c'est un peu plus subtil que ça. En fait, c'est le même principe que la notation scientifique.

Par exemple, pour représenter 12345.6, la notation scientifique c'est 1.23456 x 104 : la partie entière est toujours comprise entre 1 et 9, et on multiplie par une puissance de 10 (l'exposant) pour compenser.

En virgule flottante binaire, c'est pareil, sauf que :
- on utilise des puissances de 2. Conséquence : à part pour la valeur zéro, la partie entière est comprise entre 1 et 1, donc elle vaut 1, du coup on n'a pas besoin de la stocker.
- la partie décimale a un nombre fixe de bits, ce qui revient à stocker un nombre fixe de chiffres après la virgule.
- idem pour l'exposant : le nombre de bits est fixe, donc il a un minimum et un maximum, ce qui fait qu'on ne peut pas stocker les nombres plus petits/plus grands qu'un certain seuil.

La conséquence de tout ça :
- en virgule fixe, l'écart entre deux nombres représentables est constant, autrement dit l'erreur d'arrondi maximum absolue est constante (c'est précis à 0.xxxx près)
- en virgule fixe, l'écart entre deux nombres représentables est variable et proportionnelle à la grandeur du nombre, autrement dit l'erreur d'arrondi maximum relative est constante (c'est précis à 0.xxxx % près)

(j'ai simplifié certains points, mais le principe est là)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

25

squalyl> ha il est de toi le tuto? hum merde ok grin

mais ouais, cf le post de 0^2 smile
Je peux me tromper, mais pour autant que je sache, la virgule flottante (à opposer à la virgule fixe) essaie d'adapter la précision au mieux de ce qu'on lui demande de représenter.Donc si la partie entière est grande, il reste moins de place pour le reste (la partie décimale).


oui, mais le nombre de bits pour les digits de ton nombre reste constant peu importe la "grandeur" de ta valeur.
sur un float ieee754 32 bits, t'as 23 bits pour les digits (plus un bit silencieux toujours a '1', sauf dans quelques rares cas (les "denormals" dont je parlais dans mon post au dessus), 8 bits pour l'exposant (qui est stocke avec un bias, mais c'est un detail), et un bit pour le signe.

peu importe si tu divise avant ou apres de multiplier, tu aura quand meme 23 bits de precision.
ce qui peut faire perdre ou gagner de la precision c'est par quel nombres tu multiplies ou divise, du a des erreurs d'arrondis au niveau 23 eme bit.
mais tu pourrais tres bien avoir un arrondi moins bon en multipliant avant qu'en divisant avant.

exemple bete de en quoi ca change rien:
1.75f => exposant = 0 (store dans le float en tant que 127), mantisse = (1)11000000000000000000000
on multiplie 1.75f par 2^80 => exposant = 80, mantisse = (1)11000000000000000000000, ie: exactement la meme
on divise par 2^100 => exposant = -20, mantisse = tjrs pareil

peu importe la "grandeur" de ton nombre, ce qui va determiner le gain ou perte de precision, c'est la mantisse, qui reste parfaitement fixe.

par contre c'est une toute autre histoire des que tu fais des add ou des mul.

un classique:

for (float t = 0; t < 1.0e+5f; t += 1.0e-4f) ;

=> boucle infinie

ca devrait iterer 1.0e+9 fois.
saut qu'il faut plus de 23 bits pour stocker '1.0e+5' plus ou moins un increment de '1.0e-4'
donc la boucle tourne et incremente 't', jusqu'au moment, quelquepart entre t=1.0e+2 et t=1.0e+3, ou un add provoque l'increment de trop de l'exposant de 't', qui fait que tous les add suivants n'auront aucun effet, et donneront juste 't'
donc la boucle tournera a l'infini, comme si on ajoutait 0 a t a chaque iteration.

mais la encore, pour les mul et les divs, le pbl n'a rien a voir smile
c'est les exposants qui s'additionnent et se soustraient, les mantisses sont combinees totalement independamment des exposants d'origine.

donc que tu multiplie 1.10111010100011101010011 exp 12345 avec 1.01010101110001010100101 exp -4567
OU 1.10111010100011101010011 exp 12345 avec 1.01010101110001010100101 exp 345667

ca te donnera exactement les memes bits de mantisse, donc la meme precision si tu le remultiplie ou divise apres par un autre nombre, juste un exposant different.
smile
avatar
HURRRR !

26

Des fois, on se demande si l'informatique a bien été faite par des humains pour des humains hypno

27

oui, c'est LOGIQUE !

Bear: pas de pbm, je sais accepter les critiques utiles grin

28

(d'un autre cote, c'est de l'enculage de mouches hein cheeky la critique est sur une demi phrase perdue au milieu de tout le reste qu'est cool grin)
avatar
HURRRR !