Logicielsmoto.com

Nous sommes le 22 Oct 2020, 16:37

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 10 messages ] 
Auteur Message
 Sujet du message: Sprites en BM16
MessagePosté: 09 Aoû 2020, 00:31 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1265
Localisation: Brest
Pour répondre à Bentoc sur un sujet dédié pour ne plus polluer celui sur mission:liftoff

La démo rends vraiment bien. Bravo!

L'idée d'un générateur de code externe pour les sprites est une excellente idée car de toute façon on a de la place dans les banques mémoire pour mettre pas mal de code sur TO8.

J'ai regardé le code ASM que tu as eu la bonne idée de mettre dans l'archive. Je vois que tu n'accèdes aux données de l'écran qu'avec des offsets négatifs. Il y a une raison que je n'ai pas vue ? Parce que tu pourrais avancer S (LEAS) de 8 lignes en 8 lignes au lieu de tous les 4 max en utilisant à la fois les offsets positifs et négatifs: de -120,S à 120,S (ce qui reste un décalage de 1 octet par rapport à S donc ne change pas la taille du code.)

Autre chose: je vois que tu utilises X pour lire/écrire 2 octets d'un coup quand il n'y a pas de masquage. Mais lors des masques, tu travaille octet par octet uniquement avec le registre A. Or tu pourrais aussi bien travailler les masques sur A et B et faire des LDD / STD pour le même coût que LDX/STX. Tu gagnerais même pas mal dans la mesure ou tu peux faire un truc genre:
Code:
; lecture ecran
    LDD  offset,S   ; 6
; sauvegarde pour restauration ecran
    STD  sauvegarde ; 5
   
; au choix: 4 cas exclusifs les uns des autres

; cas 1: masque sur A et B
    ANDA #masque1   ; 2
    ANDB #masque2   ; 2
    ADDD #image     ; 4

; cas 2: masque sur A
    ANDA #masque1   ; 2
    ORA   #image1   ; 2
    LDB   #image2   ; 2

; cas 3: masque sur B
    LDA   #image1   ; 2
    ANDB  #masque2  ; 2
    ORB    #image2  ; 2

; cas 4: aucun masque
    LDD  #image12   ; 3

; mis à jour de l'écran
    STD  offset,S   ; 6 total = entre 20 et 25 cycles si je ne me suis pas trompé

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 09 Aoû 2020, 07:03 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 18
Localisation: Var
Merci pour ces deux très bonnes idées !
Je vais essayer d'implémenter ça dans le générateur.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 12 Aoû 2020, 15:36 
Hors ligne

Inscription: 21 Fév 2020, 11:38
Messages: 94
Samuel Devulder a écrit:
Pour répondre à Bentoc sur un sujet dédié pour ne plus polluer celui sur mission:liftoff

La démo rends vraiment bien. Bravo!

L'idée d'un générateur de code externe pour les sprites est une excellente idée car de toute façon on a de la place dans les banques mémoire pour mettre pas mal de code sur TO8.

J'ai regardé le code ASM que tu as eu la bonne idée de mettre dans l'archive. Je vois que tu n'accèdes aux données de l'écran qu'avec des offsets négatifs. Il y a une raison que je n'ai pas vue ? Parce que tu pourrais avancer S (LEAS) de 8 lignes en 8 lignes au lieu de tous les 4 max en utilisant à la fois les offsets positifs et négatifs: de -120,S à 120,S (ce qui reste un décalage de 1 octet par rapport à S donc ne change pas la taille du code.)

Autre chose: je vois que tu utilises X pour lire/écrire 2 octets d'un coup quand il n'y a pas de masquage. Mais lors des masques, tu travaille octet par octet uniquement avec le registre A. Or tu pourrais aussi bien travailler les masques sur A et B et faire des LDD / STD pour le même coût que LDX/STX. Tu gagnerais même pas mal dans la mesure ou tu peux faire un truc genre:
Code:
; lecture ecran
    LDD  offset,S   ; 6
; sauvegarde pour restauration ecran
    STD  sauvegarde ; 5
   
; au choix: 4 cas exclusifs les uns des autres

; cas 1: masque sur A et B
    ANDA #masque1   ; 2
    ANDB #masque2   ; 2
    ADDD #image     ; 4

; cas 2: masque sur A
    ANDA #masque1   ; 2
    ORA   #image1   ; 2
    LDB   #image2   ; 2

; cas 3: masque sur B
    LDA   #image1   ; 2
    ANDB  #masque2  ; 2
    ORB    #image2  ; 2

; cas 4: aucun masque
    LDD  #image12   ; 3

; mis à jour de l'écran
    STD  offset,S   ; 6 total = entre 20 et 25 cycles si je ne me suis pas trompé


Salut Samuel,

Je pense qu'il a utilisé la même méthode que moi pour les masque, c'est à dire sans utiliser de masque (d'une part, ça gaspille beaucoup de RAM (256 octets) aloprs que peu (31 octets) ne sont utilisé et d'autres part, ma méthode utilise moins de 30 cycles d'horloge contre 43 pour la tienne (gain de 33% quand même) dans le cadre d'un masque sur 1 octet
Mais bon là je n'arrive même pas à afficher un Sprite en Assembleur...

En tous cas, c'est un chouette moteur, mais perso, je préfère utiliser les outils Thomson et DCMoto de Daniel Coulomb, qui permet de faire des copier coller très pratiques pour les éduiteurs Pascal, Assembleur. En plus, ça permet de travailler jusqu'à 10 fois la vitesse des Thomson (Pas le choix mon TO8 est en panne depuis des lustres, par contre, le MO5 lui fonctionne)


Dernière édition par Neotenien le 12 Aoû 2020, 22:24, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 12 Aoû 2020, 19:43 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1265
Localisation: Brest
Je suis un peu perdu. De quel code de 41 cycles vs 33 du parles? A mon avis les deux codes en questions ne font pas la même chose car j'ai du mal à croire que j'aurais proposé un code inefficace (si tu parles du code que tu cite, n'oublie pas que les cas 1,2,3,4 sont exclusifs les uns des autres et figurent dans le code généré. On ne peut pas faire plus rapide.)

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 13 Aoû 2020, 07:30 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 18
Localisation: Var
La remarque de Samuel est très pertinente :

Dans mon générateur, dès que je rencontre un octet contenant donc deux pixels dont l'un est transparent, je n'utilise que le registre A.
Je ne cherche pas à savoir si juste après j'ai un autre octet à traiter.
L'idée de Samuel est de traiter la gestion des pixels transparents sur A et B à la place de A uniquement, ce qui permet de réduire le nombre de cycles puisque je travaille avec le registre D.

Je vais en profiter pour reprendre tout le code du générateur de sprite, car celui-ci est mal foutu. Il y a plein d'aspects que j'ai découvert en chemin et qui sont venu se greffer, ou d'autres fonctionnalités abandonnées qui sont restées ...


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 26 Sep 2020, 23:33 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 18
Localisation: Var
La nouvelle version du générateur de sprite compilé est bien avancée.
Le principe est toujours le même, on réalise en un passage la sauvegarde du fond et l'écriture du sprite.
Le code d'effacement du sprite charge les données sauvegardées et repositionne le fond (juste les pixels utiles).

Avec la nouvelle méthode j'obtiens un gain de 16% en cycles par rapport à l'ancienne version.
J'ai également remplacé la sauvegarde du fond par auto-modification de code en une sauvegarde dans un tableau de données.
Le code du sprite ne nécessite plus d'être dupliqué en cas d'instance multiples du sprite (comme dans la version précédente), on a juste besoin d'une zone mémoire pour stocker les données de fond.

U pointe sur le tableau de sauvegarde des données de fond
S pointe sur la zone écran

Le code est plus complexe à lire compte tenu des différentes optimisations en jeu, il est beaucoup moins séquentiel qu'avant.
Je donnerai un peu plus de détail sur le fonctionnement dans les jours à venir si ça vous intéresse.

Je suis preneur de vos retours, si vous voulez que je passe une image dans le générateur, postez là je vous donnerai l'équivalent en code.

en pj un exemple de code généré (toujours la même image)


Fichiers joints:
HIR0.rar [6.39 Kio]
Téléchargé 16 fois
Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 27 Sep 2020, 10:36 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 18
Localisation: Var
Voici les étapes pour la construction du sprite compilé (on peut le faire à la main aussi) :
Image de départ :
Image

On divise l'image en deux, une partie pour la RAM A et une autre pour la RAM B
Voici une représentation des données pour la RAM A :
Code:
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
....cc..........................................................................
....cc..........................................................................
...dccc.........................................................................
....ddac........................................................................
....ddaa........................................................................
....ddaa........................................................................
....cdaa........................................................................
....dcca........................................................................
....dcbc........................................................................
...cdcba........................................................................
...ddcbb........................................................................
..dddcbb........................................................................
....dcbb........................................................................
....dcbb........................................................................
....ddab0.......................................................................
....dd2b0.......................................................................
....dd22........................................................................
....d022........................................................................
...cdd33........................................................................
....dd0e........................................................................
.....d32........................................................................
....c222........................................................................
....2322........................................................................
....2d22........................................................................
....3b13........................................................................
....eadd........................................................................
....d9d0........................................................................
.....a.d........................................................................
.....9.d........................................................................
.......d........................................................................
.......d........................................................................
.......d........................................................................
.....a9a........................................................................
.....909........................................................................
.....0aa........................................................................
.....1b0........................................................................
....e1f21.......................................................................
....e1ffe1......................................................................
....e0ee00..


Les points sont des pixels transparents
L'image est complétée sur 80 pixels de large pour respecter l'aspect continu de la zone mémoire et faciliter les calculs.
De l'espace vide est présent en haut de l'image car le sprite est issu d'une planche, ça n'a pas d'importance pour l'exemple.

Etape 1
La lecture commence en haut à gauche et on cherche des motifs, a chaque motif est attribué un code correspondant.
On trouve donc :
motif XX (ligne 1) , motif XX (ligne 2), motif _XXX (ligne (3) , motif X_ (ligne 3), ...

Le motifs sont attribués dans l'ordre en utilisant les moins couteux d'abord en terme de cycles.
On fait ça pour toute l'image.

Etape 2
Chaque motif utilise soit un adressage indexé (LD offset,S), soit un adressage immédiat (PULS) pour la lecture du fond à sauvegarder.
On va donc constituer des "noeuds" ou groupes autour des motifs utilisant un adressage immédiat.
On cherche ensuite à rattacher des motifs à adressage indexé dans la limite -128 +127 pour ne pas être pénalisé par le cout de l'offset (ici seulement +1).
Une fois qu'on a fait ça, on recherche les motifs qui ne sont pas rattachés à des noeuds et on en constitue des nouveaux.

ça donne pour l'image de référence :

Noeud 1
(index:position:offset:pattern)
(0:362:-120:Pattern_11)
(1:402:-80:Pattern_11)
(2:441:-41:Pattern_0111)
(3:443:-39:Pattern_10)
(4:482:0:Pattern_1111)
(5:522:40:Pattern_1111)
(6:562:80:Pattern_1111)
(7:602:120:Pattern_1111)

Noeud 2
(index:position:offset:pattern)
(8:642:0:Pattern_1111)

Noeud 3
(index:position:offset:pattern)
(9:682:-119:Pattern_1111)
(10:721:-80:Pattern_0111)
(11:723:-78:Pattern_11)
(12:761:-40:Pattern_0111)
(13:763:-38:Pattern_11)
(14:801:null:Pattern_111111) Adressage immédiat
(15:842:41:Pattern_1111)
(16:882:81:Pattern_1111)
(17:922:121:Pattern_1111)
(18:924:123:Pattern_10)

Etape 3
On a maintenant une liste de motifs ou "patterns", on va parcourir cette liste et générer le code ASM.
On prends le premier noeud et on calcule le LEAS à partir de la position actuelle du sprite à l'écran (chargée dans S)

Etape 4
La suite se complique un peu ...
On va prendre chaque motif et quand c'est possible, dissocier le code de sauvegarde du fond de celui de l'écriture du sprite.
C'est possible sur un motif :
Code:
LDX -20,S
PSHU X
LDX #$ddac
STX -20,S


On peut executer
Code:
LDX -20,S
PSHU X
dans n'importe quel ordre dans le noeud, car S ne bouge pas, il faut juste qu'on écrive la sauvegarde du fond avant l'écriture du sprite ;-)

ça ne fonctionne pas pour les motifs avec gestion de transparence par contre...

L'idée est donc constituer des sous-groupes dans le noeud qui ont la même "empreinte".
Par exemple si on a deux motifs d'écriture (avec la même valeur) de :
Code:
LDX #$ddac
STX -20,S


Etape 5
mais pourquoi ?
Car on va ensuite tester tous les agencements de sous-groupes pour le noeud, en modifiant leur ordre.
S'il y a moins de 10 groupes on test toutes les combinaisons possibles, sinon on teste les combinaisons hasard dans une limite de qq millions.
Pour chaque combinaison on évalue le cout en cycles et on garde la meilleure proposition.
Les variations en terme de cout sont liées aux optimisations lors de la génération du code.

Etape 6
Otpim 1 : sur la sauvegarde du fond, on regroupe les registres a sauvegarder sur un PSHU commun
Optim 2 : sur l'écriture de l'image, on réutilise les registres déjà chargés
Optim 3 : sur le rétablissement du fond, on regroupe les registres sur les PUL/PSHU
Optim 4 : on sauvegarde S au milieu des données de l'image, et ce une seule fois pour tout le noeud ... le rétablissement se fait donc uniquement par PUL, PSH et STD indexé, S étant rechargé par PUL/PSHU, donc pas besoin de LEAS

Pour le noeud 1, la meilleur solution trouvée est la suivante :
Rappel des patterns du noeud
(0:362:-120:Pattern_11)
(1:402:-80:Pattern_11)
(2:441:-41:Pattern_0111)
(3:443:-39:Pattern_10)
(4:482:0:Pattern_1111)
(5:522:40:Pattern_1111)
(6:562:80:Pattern_1111)
(7:602:120:Pattern_1111)

Code de sauvegarde du fond et de l'écriture de l'image :

Code:
10  4+4   A011 32   E9 01E2         LEAS 482,S
12  4+1   A015 A6   E8 88           LDA -120,S      * Lecture fond Pattern 0
13  4+1   A018 E6   E8 B0           LDB -80,S      * Lecture fond Pattern 1
14  5+1   A01B AE   E8 78           LDX 120,S      * Lecture fond Pattern 7
15  6+0   A01E 10AE E4              LDY ,S         * Lecture fond Pattern 4
16  5+6   A021 36   36              PSHU Y,X,B,A   * Sauvegarde Fond Pattern 4, 7, 1, 0 (Optim 1)
17  5+1   A023 EC   E8 28           LDD 40,S      * Lecture fond Pattern 5
18  5+1   A026 AE   E8 50           LDX 80,S      * Lecture fond Pattern 6
19  5+4   A029 36   16              PSHU X,D      * Sauvegarde Fond Pattern 6, 5 (Optim 1)
20  5+1   A02B EC   E8 D7           LDD -41,S      * Lecture fond Pattern 2
21  5+2   A02E 36   06              PSHU D         * Sauvegarde Fond Pattern 2
22  2     A030 84   F0              ANDA #$F0      * Masque de transparence Pattern 2
23  2     A032 8A   0D              ORA #$0d      * Ecriture pixel couleur d
24  2     A034 C6   CC              LDB #$cc      * Chargement pixel Pattern 2, 0 et 1 couleur cc
25  5+1   A036 ED   E8 D7           STD -41,S      * Ecriture pixel Pattern 2
26  4+1   A039 E7   E8 88           STB -120,S      * Ecriture pixel Pattern 0
27  4+1   A03C E7   E8 B0           STB -80,S      * Ecriture pixel Pattern 1
28  3     A03F CC   DDAC            LDD #$ddac      * Chargement pixel Pattern 4 couleur ddac
29  5+0   A042 ED   E4              STD ,S         * Ecriture pixel Pattern 4
30  2     A044 C6   AA              LDB #$aa      * Chargement pixel Pattern 5 couleur ddaa (Optim 2)
31  5+1   A046 ED   E8 28           STD 40,S      * Ecriture pixel Pattern 5 (Optim 2)
32  5+1   A049 ED   E8 50           STD 80,S      * Ecriture pixel Pattern 6 (Optim 2)
33  2     A04C 86   CD              LDA #$cd      * Chargement pixel Pattern 5 couleur cdaa (Optim 2)
34  5+1   A04E ED   E8 78           STD 120,S      * Ecriture pixel Pattern 7 (Optim 2)
35  4+1   A051 A6   E8 D9           LDA -39,S      * Lecture fond Pattern 3
36  5+3   A054 36   42              PSHU S,A      * Sauvegarde Fond Pattern 3 et position du noeud S (Optim 4)
37  2     A056 84   0F              ANDA #$0F      * Masque de transparence Pattern 3
38  2     A058 8A   C0              ORA #$c0      * Chargement pixel couleur c
39  4+1   A05A A7   E8 D9           STA -39,S      * Ecriture pixel Pattern 3


Code de rétablissement du fond :

Code:
563  5+3   A522 37   42              PULU A,S      * lecture données fond Pattern 3 et position du noeud S (Optim 4)
564  4+1   A524 A7   E8 D9           STA -39,S      * Ecriture fond pixel Pattern 3
565
566  5+6   A527 37   36              PULU D,X,Y      * lecture données fond Pattern 2, 5 et 6 (Optim 3)
567  5+1   A529 ED   E8 D7           STD -41,S      * Ecriture fond pixel Pattern 2
568  5+1   A52C AF   E8 28           STX 40,S      * Ecriture fond pixel Pattern 5
569  6+1   A52F 10AF E8 50           STY 80,S      * Ecriture fond pixel Pattern 6
570
571  5+6   A533 37   36              PULU A,B,X,Y   * lecture données fond Pattern 0, 1, 7, 4 (Optim 3)
572  4+1   A535 A7   E8 88           STA -120,S      * Ecriture fond pixel Pattern 0
573  4+1   A538 E7   E8 B0           STB -80,S      * Ecriture fond pixel Pattern 1
574  5+1   A53B AF   E8 78           STX 120,S      * Ecriture fond pixel Pattern 7
575  6+0   A53E 10AF E4              STY ,S         * Ecriture fond pixel Pattern 4


Dernière édition par Bentoc le 27 Sep 2020, 13:20, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 27 Sep 2020, 11:36 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1265
Localisation: Brest
Whaou, la vache! Ca c'est de l'optim. Tu as du passer pas mal de temps à peaufiner l'algorithme de génération de code.

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 27 Sep 2020, 13:39 
Hors ligne

Inscription: 21 Avr 2019, 21:48
Messages: 18
Localisation: Var
Effectivement j'ai passé beaucoup de soirées sur le sujet depuis fin aout !
J'ai complété les explications ci dessus pour que ce soit le plus clair possible.

Le générateur peut être modifié relativement facilement pour ajouter de nouveaux patterns ou en retirer.
On peut implémenter également d'autres optimisations sans avoir a tout réécrire.

J'ai encore qq idées pour le générateur, mais je vais passer à la suite, le résultat étant déjà satisfaisant.
Je vais travailler sur la modification de la démo et intégrer :
- Une gestion du chargement des sprites et des données d'animations en mémoire au travers d'un concept de "niveaux" de jeu
- Une compression/décompression des données par Exomizer (il me semble que vous avez bien bossé sur le sujet il y a quelque temps, si ça ne vous dérange pas je compte réutiliser du code.)

L'objectif est, dans un jeu ou dans une démo, de pouvoir appeler le niveau suivant, ce qui provoque le chargement de tous les éléments nécessaires pour ce niveau en RAM (juste les images et animations, les zones mémoires nécessaires à la sauvegarde de fond des sprites (qui dépend du nombre d'instances de chaque sprite), les données d'apparition des sprites ... et tout code ASM nécessaire pour le niveau courant). Tout ça étant décrit dans un config.properties.

Je dois aussi développer le code ASM pour gérer les apparitions de sprites ennemis, ...

Bref bcp de travail encore ;-)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Sprites en BM16
MessagePosté: 27 Sep 2020, 14:36 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1265
Localisation: Brest
Bentoc a écrit:
(il me semble que vous avez bien bossé sur le sujet il y a quelque temps, si ça ne vous dérange pas je compte réutiliser du code.)
Vas-y, c'est fait pour ca!

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 10 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 6 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages
Vous ne pouvez pas joindre des fichiers

Rechercher:
Aller à:  
Développé par phpBB® Forum Software © phpBB Group
Traduction par phpBB-fr.com