Bonjour à tous,
J'ai écrit un outil de développement pour TO8 (mode bitmap 16) que je souhaite partager avec vous.
Il permet de gérer :
- la génération d'une image fd
- le boot en assembleur
- les animations de sprites en double buffering
- la génération de sprites compilés a partir de planches d'images
- la routine d'effacement de sprite
- la routine de positionnement de sprite par pas de 2 pixels
- l'organisation optimisée de sprites en page mémoire
- le chargement des données de sprites en page mémoire
- la conversion d'une image en données prête à l'affichage
- la génération de la palette de couleur
Il fonctionne en java et prend en entrée un fichier de config.
L'outil permet de faire un build a partir de votre code source assembleur en y intégrant des images compilées et des données d'animation.
Le résultat est une image de disquette fd et sd
Utilisé dans un IDE comme Eclipse, il permet de builder et de tester sous emulateur en un clic.
Vous trouverez en pièce jointe l'outil et une démo.
La démo montre un jeu de plateforme, mais il est possible d'implémenter n'importe quel style de jeu, l'outil à pour vocation d'être principalement un moteur d'animation.
Voici en exemple, le fichier de config de la demo livrée avec l'outil :
Code:
# Configuration du BuildDisk
# **************************
# le fichier bootfile contient le code assembleur qui sera encodé dans le secteur d'amorçage
bootfile=./input/CODE/BOOT.ASM
# le fichier mainfile contient le code assembleur qui sera chargé depuis
# la disquette par le code d'amorçage et implanté dans la mémoire vive pour y être exécuté
mainfile=./input/CODE/MAIN.ASM
# le fichier outputfile est le nom qui sera donné aux fichiers .fd et .sd qui seront produits en sortie
outputfile=./output/DISK
# indique l'executable à utiliser pour la compilation du code pour Thomson TO8
compiler=c6809.exe
# indique le tag utilisé dans le fichier mainfile pour positionner les scripts d'animation
animation.tag=<ANIMATION_TABLE>
# Liste les pages réservées pour les sprites compilés (la page impaire suivant chaque page paire est également occupée)
# Lors du build, la log affiche les pages réellement occupées et celles disponibles suite à la compilation des sprites
memorypages=4;6;8;10;12;14;16;18;20;22;24;26;28;30
# Fichier PNG de type couleurs indexées 8Bits, Index de palette : Transparence=0, couleurs=1-16
# animation.image.n=asmtag;tag;pagegroup;subgroup;file(png);images(nb);flipH(0|1)
animation.image.1=HERO_IDLE_L;HIL;1;0;./input/SPRITES/HERO_IDLE-R.png;1;1
animation.image.2=HERO_IDLE_R;HIR;1;0;./input/SPRITES/HERO_IDLE-R.png;1;0
animation.image.3=HERO_WALK_L;HWL;1;0;./input/SPRITES/HERO_WALK-R.png;12;1
animation.image.4=HERO_WALK_R;HWR;1;0;./input/SPRITES/HERO_WALK-R.png;12;0
animation.image.5=HERO_RUN_L;HRL;1;0;./input/SPRITES/HERO_JOG-R.png;10;1
animation.image.6=HERO_RUN_R;HRR;1;0;./input/SPRITES/HERO_JOG-R.png;10;0
animation.image.7=HERO_JUMP_L;HJL;1;0;./input/SPRITES/HERO_JUMP-R.png;10;1
animation.image.8=HERO_JUMP_R;HJR;1;0;./input/SPRITES/HERO_JUMP-R.png;10;0
# animation.script.n=asmtag;frameDuration;nbFrames;ABS(nbFrames absolue)|GSP(nbFrames relatif a la vitesse);tagRef;Image;...;GO|RET;asmtag cible;image cible;image retour
animation.script.1=HERO_IDLE_L;24;ABS;HIL:0;GO;HERO_IDLE_L;0;0
animation.script.2=HERO_IDLE_R;24;ABS;HIR:0;GO;HERO_IDLE_R;0;0
animation.script.3=HERO_WALK_L;6;GSP;HWL:0;HWL:1;HWL:2;HWL:3;HWL:4;HWL:5;HWL:6;HWL:7;HWL:8;HWL:9;HWL:10;HWL:11;GO;HERO_WALK_L;0;0
animation.script.4=HERO_WALK_R;6;GSP;HWR:0;HWR:1;HWR:2;HWR:3;HWR:4;HWR:5;HWR:6;HWR:7;HWR:8;HWR:9;HWR:10;HWR:11;GO;HERO_WALK_R;0;0
animation.script.5=HERO_RUN_L;6;GSP;HRL:0;HRL:1;HRL:2;HRL:3;HRL:4;HRL:5;HRL:6;HRL:7;HRL:8;HRL:9;GO;HERO_RUN_L;0;0
animation.script.6=HERO_RUN_R;6;GSP;HRR:0;HRR:1;HRR:2;HRR:3;HRR:4;HRR:5;HRR:6;HRR:7;HRR:8;HRR:9;GO;HERO_RUN_R;0;0
animation.script.7=HERO_JUMP_L;4;GSP;HJL:0;HJL:1;HJL:2;HJL:3;HJL:0;HJL:1;HJL:4;HJL:5;HJL:0;HJL:1;HJL:6;HJL:7;HJL:0;HJL:1;HJL:8;HJL:9;GO;HERO_JUMP_L;0;0
animation.script.8=HERO_JUMP_R;4;GSP;HJR:0;HJR:1;HJR:2;HJR:3;HJR:0;HJR:1;HJR:4;HJR:5;HJR:0;HJR:1;HJR:6;HJR:7;HJR:0;HJR:1;HJR:8;HJR:9;GO;HERO_JUMP_R;0;0
# l'image PNG est celle affichée au lancement du programme. Fichier PNG de type couleurs indexées 8Bits, Index de palette : couleurs=1-16 ne doit pas contenir de pixel avec couleur 0
init.video=./input/BACKGROUND/GHZ_BACKGROUND.png
On y retrouve :
- Le fichier ASS qui contient le code de boot (BOOT.ASS)
- le fichier ASS qui contient le programme principal (MAIN.ASS)
- La balise qui permet de positionner la déclaration des données d'animation
- L'image de disquette générée
- l'image de fond a charger au démarrage du programme
- Les pages mémoires qui sont réservées à la génération des sprites compilés. A noter que les pages impaires (5, 7, ...) doivent être libres car utilisées dans le cadre du double buffering.
- les planches d'images: elles contiennent des images de tailles identiques organisées horizontalement. les colonnes "pagegroup" et "subgroup" ne sont pas utilisées pour le moment. Il faut indiquer le nombre d'images (pour la découpe). On peut demander un flip horizontal de l'image, ce qui évite de devoir faire des planches en double pour la symétrie. le tag ASM est celui qui sera intégré dans le code source, le tag est celui référencé dans le script d'animation.
Remarques: Pour chaque image les codes couleurs de palette sont affichées à l'écran, il faut choisir une de ces palettes et intégrer le code manuellemet dans le fichier MAIN.ASS
Les images doivent être au format PNG indexé 8bit, avec en position 0 la couleur transparente, puis les 16 couleurs utiles de 1 à 16.
- les scripts d'animation permettent de définir les images d'une animation, la durée de chaque image, si la durée de chaque image est proportionelle a la vitesse du sprite, l'enchainement des animations (branchement, retour, ...).
Dans votre code assembleur en fonction des mouvements de manette et de l'intelligene du jeu, un sprite pourra être amené a changer d'animation. il suffira d'appeller
Code:
LDX #HERO_WALK_R
STX HERO_ANIMATION_ADR
Le moteur d'animation se chargera en permanence d'afficher la bonne image du sprite au bon moment.
Exemple : si vous souhaitez remplacer toutes les images de la démo par une seule, effectuez les changements suivants dans le fichier de config. Il n'y a aucune ligne de code assembleur a modifier, le personnage se déplace selon le même moteur physique, il n'y a qu'une image chargée en mémoire et sur la disquette.
Cela permet une grande latitude dans la conception en ajustant les animations en fonction des ressources mémoire, sans avoir a refaire tout le code. Evidement dans cet exemple c'est un peu extrême ;-)
Code:
# Fichier PNG de type couleurs indexées 8Bits, Index de palette : Transparence=0, couleurs=1-16
# animation.image.n=asmtag;tag;pagegroup;subgroup;file(png);images(nb);flipH(0|1)
animation.image.1=HERO_IDLE_R;HIR;1;0;./input/SPRITES/HERO_IDLE-R.png;1;0
# animation.script.n=asmtag;frameDuration;nbFrames;ABS(nbFrames absolue)|GSP(nbFrames relatif a la vitesse);tagRef;Image;...;GO|RET;asmtag cible;image cible;image retour
animation.script.1=HERO_IDLE_L;24;ABS;HIR:0;GO;HERO_IDLE_L;0;0
animation.script.2=HERO_IDLE_R;24;ABS;HIR:0;GO;HERO_IDLE_R;0;0
animation.script.3=HERO_WALK_L;24;ABS;HIR:0;GO;HERO_WALK_L;0;0
animation.script.4=HERO_WALK_R;24;ABS;HIR:0;GO;HERO_WALK_R;0;0
animation.script.5=HERO_RUN_L;24;ABS;HIR:0;GO;HERO_RUN_L;0;0
animation.script.6=HERO_RUN_R;24;ABS;HIR:0;GO;HERO_RUN_R;0;0
animation.script.7=HERO_JUMP_L;24;ABS;HIR:0;GO;HERO_JUMP_L;0;0
animation.script.8=HERO_JUMP_R;24;ABS;HIR:0;GO;HERO_JUMP_R;0;0
L'outil est fonctionnel, mais il manque encore pas mal de choses. Les évolutions a venir sont :
- Une organisation des pages mémoires en "tableaux" ou "niveaux" de jeu, pour pouvoir changer le set de sprites et de fond d'ecran facilement
- Un moteur d'animation pour plusieurs sprites et non un seul !
- Une optimisation du générateur de sprite compilés actuel
- Le choix entre plusieurs méthodes pour la génération de sprite compilés, en particulier une version sans la gestion de l'effacement intégrée
- l'intégration des données de palette en automatique
- Correction du comptage des cycles et taille du code compilé en log
... La liste est longue, a vous de donner votre avis !
Si vous voulez participer au projet, n'hésitez pas.
Complément:
J'ai bien avancé sur une application indépendante qui permet de travailler sur un ensemble d'images, d'établir automatiquement une palette commune avec un nombre fixe et réduit de couleurs (en passant par le référentiel CIE Lab).
On peut ensuite enregistrer toutes les images réindexées en une fois. A suivre donc ... je pense que c'est interressant dans le cas d'adaptation de jeux existants.
Mode opératoire :
1. Installer OpenJDK 12 ou supérieur si ce n'est pas déjà fait (ex:
https://jdk.java.net/14/)
Ajouter le chemin complet du répertoire bin du jdk dans le PATH
2. Ajouter c6809.exe dans le répertoire racine de l'outil (dans le même répertoire que config.properties)
3. Pour lancer le build, utiliser la ligne de commande suivante dans le répertoire racine de l'outil
java.exe -classpath ".\bin" fr.bento8.to8.build.BuildDisk config.properties
Si vous n'avez pas d'erreur, vous trouverez l'image de disquette dans le répertoire output
Pour lancer la démo, appuyer sur B !
Je n'ai jamais pris la peine de remercier tous les contributeurs des différents forum, alors je prend le temps de le faire :
Un grand merci à vous tous pour tous les conseils et le code que vous publiez sans relache depuis tant d'années !
Sans vous j'en serai resté au basic ... il y a 30 ans.
PS : Le moteur d'animation et la gestion du personnage de la demo ont été insiprés du code asm de Sonic.
http://info.sonicretro.org/Disassemblieshttp://info.sonicretro.org/Sonic_Physics_GuidePS : si vous voulez discuter en particulier du générateur de sprites compilés, un fil est déjà ouvert ici
http://www.logicielsmoto.com/phpBB/viewtopic.php?f=3&t=619(Update 18/09/2021)
Dernière version du projet :https://github.com/wide-dot/thomson-to8-game-engineArchive obsolète :