1

J'avais besoin d'une routine de sessin de sprite spécifique pour mon je de zelda et j'ai programmé celle-là (une version pour ti 89 et une version pour ti92+/v200). J'aimerais avoir votre avis. | Assembly Source File | Created 26/08/2003; 23:34:07 .global sprite_draw_masked_89 .data | dessine un sprite avec du clipping | J'ai décidé de faire une version différente selon la machine car c'était le moyen d'avoir le code le plus rapide | étant donné les différences de l'affichage du jeu entre la ti89 et les TI92+ et V200 | void sprite_draw_masked(void *plane0, void *plane1, short x, short y, const unsigned short *sprite_data); sprite_draw_masked_89:      |illegal      movem.l %d0-%d7/%a0-%a6,-(%sp)      | lecture de x et de y      move.w 72(%sp),%d0 | je stocke la variable x dans d0      moveq.l #0,%d1 | la partie haute de d1 sera ansi vide      move.w 74(%sp),%d1 | et y dans d1      | Teste la visibilité.      | si le sprite est complètement hors de la zone visible, la routine se termine immédiatement      cmpi.w #-16,%d0 | test de x par la gauche      jble _sprt_msk_89_end      cmpi.w #160,%d0 | test de x par la droite      jbge _sprt_msk_89_end      cmpi.w #-16,%d1 | test de y par le haut      jble _sprt_msk_89_end      cmpi.w #100,%d1 | test de y par le bas      jbge _sprt_msk_89_end      | Tous les tests ont été passés, donc on peut continuer normalement      move.l 64(%sp),%a0 | Je stocke plane0 dans a0      move.l 68(%sp),%a1 | et plane1 dans a1      move.l 76(%sp),%a2 | Je stocke sprite_data dans a2      moveq.l #16,%d2 | J'initialise le compteur de la boucle dans d2 (je fais ça maintenant car c'est nécéssaire)      | Si y est négatif, je dois commencer à dessiner plus bas      tst.w %d1      jbge _sprt_msk_89_y_test_2 | je saute directement au deuxième test      add.w %d1,%d2 | Il faut garder en mémoire que d1 ne sera jamais plus petit que -15 donc d2 sera tjrs positif      neg.w %d1      lsl.w #1,%d1 | Multiplication par 2 puisque le sprite fait 2 octets par ligne      adda.l %d1,%a2 | J'augmente le pointeur du sprite (la hauteur du dessin a diminué)      moveq.l #0,%d1 | Je mets d1 (y) à 0 pour le calcul des addresses dans les plans      jbra _sprt_msk_89_calculate_addresses | Le test suivant n'est pas nécéssaire, daonc on le saute      | Si le sprite dépasse un peu en bas, je dois diminuer la hauteur du dessin _sprt_msk_89_y_test_2:      cmpi.w #85,%d1 | 85 + 16 = 101 et 101 > 100      jblt _sprt_msk_89_calculate_addresses      move.l %d1,%d3 | d3 était inutilisé jusqu'à maintenant (utilisation temporaire)      sub.w #84,%d3      sub.w %d3,%d2 | Je diminue le compteur      | Partie suivante: calcul du décalage par rapport aux adresses des plans _sprt_msk_89_calculate_addresses:      moveq.l #0,%d3      mulu #30,%d1 | d1 est obligatoirement positif, donc mulu convient très bien      move.l %d1,%d3      move.l %d0,%d1      lsr #3,%d1 | divise x par 8 pour obtenir l'adresse de l'octet qui contient le premier pixel du sprite      bclr.b #0,%d1 | S'assure d'obtenir une adresse paire (pour pouvoir utiliser des longs...)      add.w %d1,%d3      | Ajoute le décalage calculé dans d3 aux pointeurs plane0 et plane1      adda.l %d3,%a0      adda.l %d3,%a1      | Calcule les adresses des deux autres "plans" du sprite (foncé et masque) - on peut se passer de ça et faire autrement (utiliser 32(%a2) et 64(%a))      movea.l %a2,%a3      adda.l #32,%a3      movea.l %a3,%a4      adda.l #32,%a4      | Calcule le nombre de bits à décaler vers la gauche      move.w %d0,%d1 | Je dois toujours préserver d0, donc je le copie dans d1      and.w #0xF,%d1      neg.w %d1      addi.w #16,%d1 | Le calcul du nombre de décalages vers la gauche est ausi simple que ça :)      | Teste si le sprite dépasse vers la gauche      tst.w %d0      jbge _sprt_msk_89_x_test_2      move.l #0xFFFF,%d3 | Masque pour ne pas endommager les autres données placé dans d3      | Teste si le sprite dépasse vers la droite _sprt_msk_89_x_test_2:      cmpi.w #145,%d0      jblt _sprt_msk_89_drawnormal      move.l #0xFFFF0000,%d3 | Le masque est mis dans d3 _sprt_msk_89_out_of_screen:      moveq.l #0,%d5 | Efface d5 en entier      move.l %d5,%d6      move.l %d6,%d7      | Charge une ligne complète du sprite et la décale vers la gauche      | Puis lui applique le masque contenu dans d3      move.w (%a2)+,%d5      lsl.l %d1,%d5      and.l %d3,%d5      move.w (%a3)+,%d6      lsl.l %d1,%d6      and.l %d3,%d6      move.w (%a4)+,%d7      lsl.l %d1,%d7      and.l %d3,%d7      not.l %d7 | Inverse d7      | Traîtement du light plane      move.l (%a0),%d4      and.l %d7,%d4      or.l %d5,%d4      move.l %d4,(%a0)      adda.l #30,%a0      | Traîtement du dark plane      move.l (%a1),%d4      and.l %d7,%d4      or.l %d6,%d4      move.l %d4,(%a1)      adda.l #30,%a1      subq #1,%d2      bne _sprt_msk_89_out_of_screen      jbra _sprt_msk_89_end _sprt_msk_89_drawnormal:      moveq.l #0,%d5 | Efface d5 en entier      move.l %d5,%d6      move.l %d6,%d7      | Charge une ligne complète du sprite et la décale vers la gauche      move.w (%a2)+,%d5      lsl.l %d1,%d5      move.w (%a3)+,%d6      lsl.l %d1,%d6      move.w (%a4)+,%d7      lsl.l %d1,%d7      not.l %d7 | Inverse d7      | Traîtement du light plane      move.l (%a0),%d4      and.l %d7,%d4      or.l %d5,%d4      move.l %d4,(%a0)      adda.l #30,%a0      | Traîtement du dark plane      move.l (%a1),%d4      and.l %d7,%d4      or.l %d6,%d4      move.l %d4,(%a1)      adda.l #30,%a1      subq #1,%d2      bne _sprt_msk_89_drawnormal _sprt_msk_89_end:      movem.l (%sp)+,%d0-%d7/%a0-%a6      rts
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

2

je ne vois pas trop de quelle différence tu parles entre 89 et 92+? (je ne suis pas assez expérimenté pour bien comprendre ton code)
Tu veux ne pas dépasser de l'écran 89 quand tu es sur 89? La mem écran étant de la même taille, j'ai du mal à comprendre...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

3

Sur ti 92, j'ai un comportement différent. Par exemple (j'ai modifié légèrement le jeu pour prendre cette image):
zelda_sprite.png
Là, le sprite de link est tronqué puisqu'il dépasse de la zone du jeu mais sur ti89, la zone de jeu est l'écran
Là c'est la version ti89, mais c'est pas ça qui est important. Je voudrais savoir si c'et assez optimisé où si c'est à revoir.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

4

pour la mm écran, tu peux te limiter a 2000 si tu veux économiser de la ram ... mais ca te contraint a ne pas utiliser toutes les ROM_CALLs

5

Me limiter à 2000 ? c'est à dire ?
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

6

ousp, dsl, la taille de l'écran virtuel ...

7

Bon, j'ai pas tout regardé, mais il y a des petits détails optimisables : par exemple, dès le début, tu testes la visibilité du sprite ; ce serait plus malin de faire ces tests plus tard, par exemple, pour le test y<=-16 il vaut mieux le faire après avoir remarqué que y est négatif. Comme en général les sprites sont affichés à des coordonnées positives, ça fera que ce test ne sera fait que dans quelques cas minoritaires. Et c'est comme ça pour chacun de tes tests de visibilité du début.
Ensuite, ta multiplication par 30 peut être remplacée par des décalages + additions qui seraient plus rapides.
Sinon, j'ai vu pas mal d'instructions (ou suites d'instructions) optimisables, comme adda.l #30,a0 en adda.w #30,a0, voire en lea.l 30(a0),a0. lsl.w #1,d1 en add.w d1,d1. move.l #$FFFF0000,d0 en moveq.l #-1,d3 ; clr.w d3 (je n'ai pas vérifié, mais c'est certainement plus rapide). Et quelques autres...

Ton format de sprite n'est pas pratique, tu devrais mieux adopter un format entrelacé.

Enfin, tu devrais passer tes arguments directement dans les registres plutôt que d'utiliser la pile.

Sinon, une question, pourquoi tu effaces la partie haute de d1 au début ?

8

> voire en lea.l 30(a0),a0
lea 30(a0),a0 est plus rapide que adda.w #30,a0

> move.l #$FFFF0000,d0 en moveq.l #-1,d3 ; clr.w d3 (je n'ai pas vérifié, mais c'est certainement plus rapide).
Pareil pour move.l #$FFFF,d0 -> moveq #0,d0 ; not.w d0

Et enfin tu peux utiliser un dbf pour ta boucle, ça t'économiserait 4 cycles par boucle.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

9

6 & 7>Merci smile. Je vais essayer tout ça.
Ton format de sprite n'est pas pratique, tu devrais mieux adopter un format entrelacé.

Je peux pas à cause de mon éditeur grin
Sinon, une question, pourquoi tu effaces la partie haute de d1 au début ?

Il me semble que c'était pour la multiplication que je faisais ça.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

10

81: moveq.l #0,%d5 | Efface d5 en entier
82: move.l %d5,%d6
83: move.l %d6,%d7

heu moveq tout court.
apres je comprend pas trop ce que tu fais, pkoi pas 3 moveq?

11

./9 C'est inutile pour la multiplication de faire ça.

./10 Ça revient au même.

12

A oui tiens, j'avais mal lu. Je croyais qu'il fallait effacer la partie supérieure, mais en faît c'est pas la peine.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

13

./11 ct surtout le .l au niveau du reproche

14

jackiechan :
move.l #$FFFF0000,d0 en moveq.l #-1,d3 ; clr.w d3 (je n'ai pas vérifié, mais c'est certainement plus rapide).

En tout cas, ça économise 2 octets.
Pollux
: Et enfin tu peux utiliser un dbf pour ta boucle, ça t'économiserait 4 cycles par boucle.

Et gaspille 2 octets:
subq.w #1,%dn
label:
...
dbf.w %dn,label

-> 6 octets (dbf.s n'existe pas)

label:
...
subq.w #1,%dn
bne.s label

-> 4 octets
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é

15

Si ni dbf.s ni dbf.l existent, inutile de mettrre dbf.w, Kevin tongue

Et puis tu es hors-sujet ! GoldenCrystal a besoin d'optimisation en vitesse.
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.

16

D'ailleurs, vu la taille de la fonction, quelques octets de plus, ça me dérange pas grin
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

17

j'avais pas vu:
mulu #30,%d1 #eurk#

18

couic Arg 70 cycles ! Je pensais pas que c'était autant. J'aurais du regarder la doc.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

19

Mais c'est de loin le plus efficace en taille.

Et Thibaut, je te signale que le message de départ ne parlait pas du tout d'optimisation, et que le message ./3 ne précisait pas ce qu'il voulait optimiser.
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é

20

Tu peut quand même supposer que pour un jeu je préfère optimiser en vitesse, non ?
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

21

Non.
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é

22

Le genre d'optimisation qu'il demandait (taille ou vitesse ?) est évident.

Programme-nous un jeu de ce style en optimisant en taille plutôt qu'en vitesse !
On va bien rire du résultat gni

tsss...
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.

23

Ce n'était pas du tout évident. Plein de jeux sont compilés en -Os. Duke68k pour n'en citer qu'un. (Il aurait dépassé les 64 KO sinon.)
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é

24

Pour éviter de dépasser 64 ko il vaut mieux bien choisir ses switch de compilation ou changer des algo, utiliser des représentations de données plus compactes, etc... que d'essayer de grapiller 10 octets dans les routines critiques en perdant 25% de la vitesse du prog roll

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

25

Clair !
Mais bon, laissons Kevin... on verra le résultat quand il programmera un jeu de plateforme.
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.

26

comment peut-on vouloir optimiser en taille une routine de sprite?
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

27

bein si:
move.w d1,d2
divu.w #16,d1
mulu.w #30,d0
add.w d1,d0
add.w d0,a0
moveq #15,d1
and.w d1,d2
LOOP:
moveq #0,d0
move.w (a1)+,d0
lsl.l d2,d0
eor.l d0,(a0)
lea 30(a0),a0
dbf d1,LOOP
rts

ca c'est top rapide d'ailleur Xlib utilise ca tongue
(ct une blague pour ceux qui comprendraient pas!)

28

on epu encore optimiser en taille il me sembletongue

29

de toutes façons c pas la taille qui compte !


dehors

30

Jackosking> ton divu prend plus de place qu'un lsr roll
Et ta fonction est incorrecte. Teste la pour voir.
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. »