mercredi 31 octobre 2012

Création de jeux sous MSX : Création de la librairie graphique



Aujourd'hui, on va mettre en place la seconde brique de notre librairie de jeu. Nous allons créer et compiler video.c.

Dans le répertoire TUTORIAL_TEST créez 2 fichiers, à savoir video.c et video.h.

Pour ce tutorial, nous allons créer les procédures :

    void screen_mode_2() : pour passer le MSX en mode vidéo 2 (mode graphique identique à celui de la COLECO)
    void put_vram(void* block,int vramaddr,int size) : pour écrire un bloc de la RAM vers la VRAM   
       
Un mot sur le mode 2 du MSX :

Le mode Vidéo 2 du MSX est le mode vidéo qui se rapproche le plus de celui de la Coleco. Ce mode vidéo est composé :

    - d'un écran de 32*24 caractères
    - de 3 tables de 255 caractères
    - de 3 tables de codes couleurs pour chaque caractères
   
Si on découpe l'écran en 3 de manière horizontale, la 1ere table de caractère est pour le tiers haut. (y = 0 à 7). La seconde table de caractère est pour le tiers du milieu, la troisième table de caractère est pour le tiers bas.

Par exemple, si on affiche le caractère 10 en position x=10,y=5, on se trouve dans le 1er tiers de l'écran, on affichera donc le dessin du caractère 10 stocké dans la 1ere table de caractère/couleur.
Si on affiche le caractère 10 en position x=10,y=20 , on se trouve dans le 3ème tiers de l'écran, on affichera donc le dessin du caractère 10 stocké dans la 3ème table de caractère/couleur.
   
Si le caractère 10 doit représenter le même caractères avec la même couleur partour sur l'écran alors sa définition doit être identique dans chaque table caractère/couleur.

Pour connaitre l'emplacement en mémoire VRAM (vidéo) de l'écran, du début des tables de caractères, et du début des tables de couleurs, il faut lire les adresses suivantes :

    0xF3C7 : Pour récupérer l'adresse de début de l'écran
    0xF3CB : Pour récupérer l'adresse de début des tables de définition des caractères
    0xF3C9 : Pour récupérer l'adresse de début des tables de définition des couleurs de caractères
   
Grâce à la commande peek_word que bous avons implémenté dans le précédent tuto, on va pouvoir récupérer les adresses ou écrire en vidéo.

    int adresse_ecran;
    int adresse_car;
    int adresse_col;
   
    adresse_ecran = peek_word(0xF3C7);
    adresse_car = peek_word(0xF3CB);
    adresse_col = peek_word(0xF3C9);

   
mais je tergiverse, implémentons, mes amis, implémentons.

Dans video.c, copiez collez le code suivant :

#include "video.h"

/*
GRPNAM 2 Adresse ou lire pour avoir l'adresse de la table des noms en mode 2
GRPCOL 2 Adresse ou lire pour avoir l'adresse de la table des couleurs en mode 2
GRPCGP 2 Adresse ou lire pour avoir l'adresse de la table des formes en mode 2
GRPATR 2 ou lire pour avoir l'adresse Adresse de la table des attributs de sprites en mode 2
GRPPAT 2 ou lire pour avoir l'adresse Adresse de la table des formes de sprites en mode 2
*/

#define GRPNAM 0xF3C7
#define GRPCGP 0xF3CB
#define GRPCOL 0xF3C9
#define GRPATR 0xF3CD
#define GRPPAT 0xF3CF

/* Passe en vidéo mode 2, 32 sprites actifs */
/**/
void screen_mode_2()
{
  __asm
  
   call 0x0072
  
  __endasm;
}

void put_vram(void* block,int vramaddr,int size)
{
   __asm
  
   ld l,4(ix);
   ld h,5(ix);
   ld e,6(ix);
   ld d,7(ix);
   ld c,8(ix);
   ld b,9(ix);
   call 0x005c;
  
   __endasm;
}



Tout d'abord, la routine screen_mode2 : on ne peux pas faire plus con, on appelle une routine du bios qui fait le travail. La routine du bios se trouve à l'adresse 0x0072.

La routine put_vram est un tout petit peut plus complexe. Cette routine va charger un tableau de données "block", à une adresse dans la vram "vramaddr", pour un nombre d'octet "size". Son implémentation fait également appel à une routine du bios MSX qui prend les paramètres suivants en entrée :

registres
HL             <-- Adresse de début des données à écrire
DE             <-- Adresse VRAM ou écrire ces données
BC             <-- Nombre d'octer à écrire
0x005c        <-- Adresse de la fonction BIOS put vram



Dans video.h copiez collez le code suivant :

#ifndef ___MSXVIDEO_H___
#define ___MSXVIDEO_H___

void screen_mode_2();
void put_vram(unsigned char* block,int vramaddr,int size);

#endif


Ce sont juste les signatures des fonctions que l'ont à créé.

Maintenant, on va compiler ça. Dans une ligne de commande lancez :

sdcc -mz80 -c video.c

Vous allez avoir de beaux message de WARNING (et pas d'erreur),

I:\CODING\Sources\MSX\TUTO_SOURCES>sdcc -mz80 -c video.c
video.c:40: warning 85: in function put_vram unreferenced function argument : 'block'
video.c:40: warning 85: in function put_vram unreferenced function argument : 'vramaddr'
video.c:40: warning 85: in function put_vram unreferenced function argument : 'size'


car le compilateur n'apprécie que moyennement le mélance C/Assembleur. Mais ça, si vous avez suivi le précédent tuto ... vous le savez déja.

Maintenant, on va tester si ça marche dans un programme !!

Créez un fichier main.c et copier/coller dedans le code suivant :

#include "tools.h"
#include "video.h"

void main(void)
{
    screen_mode_2();
    while(1){};
}


Maintenant, on va le compiler :

sdcc -mz80 --std-c99 --data-loc 0x8048 --code-loc 0x4020 --no-std-crt0 crt0.rel -main.ihx tools.rel video.rel main.c

Alors les paramêtres :

-mz80 --> Compile en assembleur z80
--std-c99 --> Type de vérification syntaxique du C (on s'en occupe pas de ce paramêtre)
--data-loc --> Adresse des datas en rom (J'ai mis en 8048h pour avoir accès aux 32 ko, ça fonctionne pour le tuto et ça semble fonctionner pour mon Lock'n Chase, stay tuned :) )
--code-loc --> Adresse du code en rom
--no-std-crt0 crt0.rel --> Spécifie de ne pas utiliser l'header par défaut, mais celui compilé dans le tuto n°1
-main.ihx --> Nom du fichier en sortie
Les derniers paramètres c'est la liste des fichiers qui vont former la rom, ici à savoir la version compilée de la librairie tools, la version compilée de la librairie video ainsi que le code source de notre programme principal (main.c)

Lancez la commande, il ne doit y avoir aucun message. Dans le répertoire vous devez trouver un fichier main.ihx. Nous allons maintenant transformer ce fichier en rom avec la commande :

objcopy --input-target=ihex --output-target=binary main.ihx result.rom

Pareil, pas de message, mais un fichier result.rom doit être généré.

Maintenant, téléchargez BlueMsx, et charger la rom dans un mode MSX ou MSX2. Lancer là. En base de l'écran BlueMsx, vous allez voir SCREEN n, n étant le mode écran qui est actuellement utilisé. Par exemple en MSX2, on passe de SCREEN 0 à SCREEN 6, et au final si tout c'est bien passé, cela doit afficher SCREEN 2.



Si c'est le cas, vous avez compilé et compilé votre premier programme MSX avec succès !!
Allez, dans le prochain tuto, on essayera d'affiche un sprite, ça sera plus excitant :)




Aucun commentaire:

Enregistrer un commentaire