Page 1 of 3

Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 01 May 2016, 18:29
by grosged
Hé bien , je vous expose un mini-projet qui me trottait dans la tête depuis un bon moment:
pouvoir afficher des sprites depuis le Basic, et (pourquoi pas?) pouvoir les définir depuis le Basic!
Je vous avoue que j'ai dû faire pas mal de concessions!
N'ayant qu'1 KiloOctets de disponible pour y loger les Datas (en $e30800 : cursor image Ram),
et opérant en mode graphique 16bpp (étant donné qu'on reste en Basic, on n'a pas trop le choix) je me suis alors restreint au format 10 pixels sur 10, afin de pouvoir stocker jusqu'à 5 sprites.
J'ai eu l'idée d'ajouter un 6ème sprite (non modifiable) , le sprite d'effaçage n° 0.
J'ai aussi inclu la possibilité d'effacer entièrement l'écran (en noir).
à noter que par souci de commodité, j'ai décidé d'opter pour une palette de 16 couleurs.
Ainsi, il nous est facile de définir , dans nos programmes Basic, pixel-par-pixel, chacuns des 5 sprites (en utilisant la notation hexadécimale: 0123456789ABCDEF)

Voici, par exemple, comment définir le sprite n°1:

Image
Sans oublier ces 2 dernières lignes (lesquelles étaient hors-écran) :
Code: Select all
:Ans+"FFFFFFFFFF
:Asm(prgmSPRITE

Voilà, c'est tout ! :D
Vous remarquerez qu'en entête, les 3 caractères suivant le n° de sprite peuvent être des espaces, ou 3 virgules, ou ce que vous voulez : ils ne sont là que pour pouvoir ajuster la 1ère ligne aux suivantes ;)

Maintenant , vous voulez l'afficher ? Rien de plus simple :
Code: Select all
{n°de sprite , coord.X , Coord.Y ...suivi , bien entendu, d' Asm(prgmSPRITE

(Merci à Mateo & PT pour l'astuce du Ans stocké sous forme de liste ;) )
N° de sprite de 0 à 5 (le sprite n° 0 , non redéfinissable, permet d'effacer)
Coord.X de 0 à 309
Coord.Y de 0 à 229

On veut, par exemple, afficher le sprite n°1 en coordonnées 99,99 :
Code: Select all
{1,99,99:Asm(prgmSPRITE

Ce qui nous donne...
Image


On souhaite obtenir un écran noir (effaçage rapide) , il nous suffit d'un double guillement:
Code: Select all
"":Asm(prgmSPRITE


Voilà pour le moment! Un peu plus tard, je vous parlerai aussi des 16 couleurs de la palette.
(elles sont pour l'instant fixes, mais , pourquoi pas , à l'avenir, prévoir une fonction de définition? ;) )

N'hésitez pas à faire des suggestions, commentaires, rapports d'éventuel bug.. ;)

Ah , j'oubliais ! La routine est téléchargeable ici : archives_voir.php?id=510643
Pour les curieux, voici le code source:
Code: Select all
.nolist
#include "ti84pce.inc"
.list
.org userMem-2
.db tExtTok,tAsm84CeCmp
.assume ADL=1

SPRITE: call    _RclAns
        dec     a
        jr      z,AffSpr
DefSpr: call    _RclVarSym
        ld      a,(de)
        or      a,a
        jr      z,ClrScr
        inc     de
        inc     de
        ld      a,(de)
        sub     a,49
        ret     c
        cp      a,5
        ret     nc
        ld      b,200
        ld      c,a
        mlt     bc
        ld      hl,$e30800
        add     hl,bc
        inc     de
        inc     de
        inc     de
        ld      bc,$6430
        ld      ix,DatCol
CodHex: inc     de
        ld      a,(de)
        sub     a,c
        cp      a,17
        jr      c,bon
        sub    a,7
bon:    add     a,a
        ld      (OffsC+2),a
        inc     a
        ld      (OffsD+2),a
OffsC:  ld      a,(ix+0)
        ld      (hl),a
        inc     hl
OffsD:  ld      a,(ix+0)
        ld      (hl),a
        inc     hl       
        djnz    CodHex
        ret
ClrScr: ld      hl,$e40000
        ld      de,$d40000
        ld      bc,153600
        ldir
        ret
AffSpr: push    de
        push    de
        ld      hl,3
        call    _GetLToOP1
        call    _ConvOP1
        ld      d,160
        mlt     de
        ld      hl,$350000
        add     hl,de
        add     hl,hl
        add     hl,hl
        pop     de
        push    hl
        ld      hl,2
        call    _GetLToOP1
        call    _ConvOP1
        pop     hl
        add     hl,de
        add     hl,de           ; now, HL=addr on screen
        pop     de
        push    hl
        sbc     hl,hl
        inc     l
        call    _GetLToOP1
        call    _ConvOP1
        jr      z,Spr0ef
        ld      d,200
        mlt     de
        ld      hl,$e30800-200
        add     hl,de
Spr0bk: pop     de              ; =addr on screen
        ld      bc,20
        ld      a,c
        ld      (SvOlSp+1),sp
        di
        ld      sp,620
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
        ex      de,hl
        add     hl,sp
        ex      de,hl
        ld      c,a
        ldir
SvOlSp: ld      sp,0
        ret
Spr0ef: ld      hl,$e40000
        jr      Spr0bk
DatCol: .db $00,$00,$10,$10,$18,$18,$04,$04,$4b,$4b,$07,$07,$7f,$7f,$60,$60
        .db $70,$70,$84,$84,$b5,$b5,$f7,$f7,$e0,$e0,$f8,$f8,$e7,$e7,$ff,$ff

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 01 May 2016, 18:56
by Clément.7
Impressionnant ! Par contre la question qui me titille est : Est-ce que les performances tiennent le coup ?

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 01 May 2016, 19:37
by Epharius
Enfin, il l'a fait !

J'ai téléchargé le programme et ça rend bien ! Seul problème : le sprite est malheureusement un peu petit pour être vraiment utilisable. On a des pixels assez fins. Alors que sur monochrome 10 pixels est énorme, ici on ne peut pas en faire grand chose.

J'ai fait un programme qui déplace le sprite 10 par 10 (sinon, c'est un peu lent, mais c'est la faute au basic), cependant, j'ai trouvé dommage que l'"effaçage" soit en noir, et non en blanc. Disons que la plupart des jeux ne seront pas pas en noir à mon avis, il vaut mieux soit mettre en blanc, soit proposer à l'utilisateur grâce à 0=noir et 1=blanc (pas forcement ces nombres là, mais c'est l'idée).

Bon, j'ai exposé les défauts mais en dehors de ça, c'est super bien ;)
Ensuite, permettre à l'utilisateur de définir sa palette au début, serait en effet très utile et permettrait plus de liberté. Et quant à la peur de "DCE le fera" (si j'ai bien compris) : de deux choses l'une :
- je n'ai pas vraiment envie d'installer un programme aussi lourd juste pour jouer avec les sprites en basic x)
- ça oblige les utilisateurs à installer eux aussi DCE, là il leur suffit de télécharger juste prgmSPRITE

Bref, bon courage pour la suite =D

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 01 May 2016, 19:52
by grosged
ça me paraît correct...pour du Basic :)
On pourraît peut-être encore améliorer le temps d'exécution:
-au niveau de l'asm, implanter la routine d'affichage directement en zone "cursor image ram"
histoire de booster son exécution (mais alors, on sacrifierai un sprite , puisqu' actuellement n'y restent que 20 octets de libre)
-au niveau du Basic, simplifier encore la transmission des paramètres : 1 seul valeur dans Ans , regroupant à la fois n°de sprite+X+Y (au lieu de la liste dans Ans, plus lourde à gérer) simplifierait/accélèrerai la routine ASM.

EDIT:
Merci pour tes encouragements & suggestions, Epharius !
re-EDIT: trouver un moyen sûr et permanent d'allouer de la ram (afin de passer en 12x12...16x16)

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 01 May 2016, 21:36
by Wistaro
Excellent ! Les 5 sprites sont modifiables? J'ai pas trop compris cette partie..

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 02 May 2016, 17:24
by grosged
oui, oui :)
Une version améliorée de la routine est en cours...

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 02 May 2016, 18:19
by Ti64CLi++
Super.
Cela serait nettement mieux si tu pouvais définir les couleurs, et la couleur d’effaçage comme l'a précisé Epharius ;)
Sinon, très bon programme :bj:

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 03 May 2016, 05:55
by DoOmnimaga
Salut, si cet outil permet l'affichage de sprites à partir de donnée de sprites stockée dans un programme comme je peux probablement constater, alors ce serait très utile pour les programmeurs TI-BASIC.

Par contre, une suggestion que j'ai serait de permettre l'affichage et le stockage de plusieurs sprites avec une seule commande Asm(prgmSPRITE . La commande Asm() est lente d'exécution car la TI doit chercher dans la VAT pour trouver le programme ASM et le copier dans la SafeRAM je crois. Si par exemple tu permettais la syntaxe {sprite1,x,y,sprite2,x,y,sprite3,x,y,sprite4,x,y,sprite5,x,y , alors tu pourrais permettre d'afficher 33 sprites en même temps si, par exemple, 255 éléments étaient permis à la fois comme avec CE Textlib.

Avec cette habilité de chaining je crois que beaucoup de gens sur CodeWalrus serait content, vu la quantité de gens là-bas qui sont intéressés par le Basic étendu. :P J'utilise déja les sprites avec CE Textlib mais ce n'est pas nécéssairement le truc le plus éfficace. :P


Et comme deuxième suggestion: affichage des sprites zoomés. Par exemple, il y aurait 4 arguments et le 4ème définirait si tu veux afficher le sprite 2 fois plus gros, 3 fois plus gros, etc. Ce serait pratique.

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 03 May 2016, 15:57
by grosged
C'est vrai que la commande Asm( n'est pas très rapide!
C'est une bonne idée le fait de combiner plusieurs sprite à afficher en une seule requête :)
Dans la prochaine version, la routine d'affichage sera relogée en mémoire $e30800 (Cursor Image Ram) ainsi , lors d'un Asm(prgmSPRITE, la TI cherchera dans la VAT un programme très court de 6 octets seulement: 2 octets d'entête, suivis d'un simple "JP $e30800" (afin de rediriger vers la zone mémoire $e30800). Au fait, connais-tu un moyen de faire baisser ce temps de recherche dans la VAT ? Peut-être en fonction du nom du programme?..de l'ordre de création (tout 1er crée, trouvé tout de suite?)
Par contre, l'effet zoom ,avec un 4ème paramètre , ça risque ( en chaining) de faire de longues lignes de commande . On pourrait garder cette idée de zoom, mais en 2nde routine complémentaire (sans chaining) qu'on pourrait appeler...ZSPRITE .... ou SPRITEXL par exemple
Avec Epharius, on est actuellement en train de regarder comment optimiser ces lectures de paramètres ... ;)

Re: Sprite10x10 pour Basic [TI83PCE]

Unread postPosted: 03 May 2016, 18:44
by TheMachine02
Normalement le VAT est trié par ordre alphabétique, donc le programme se nommant A devrait être trouvé en premier. Par contre, la taille du programme, ça change rien, la VAT contient juste un pointeur vers le programme.