Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Connexion avec identifiant, mot de passe et durée de la session

UserBox

Welcome, Guest.
Please login or register.
 
 
 
Mot de passe oublié?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Sujets - Monos

Pages: [1] 2 3 ... 22
1
Le Topic des joutes / CD de jeu à vendre ?
« le: 17 août 2018 à 12:36:40 »
Yop, dite ça botte de faire des CD de jeu à vendre au joute ?
Une compilation de jeu de fusion sur un CD.  (Il faut que les auteurs le veule bien).
Le petit bénef peut aller directement pour payer l'hebergement du site ou pourquoi pas nous permettre de faire d'autre CD dans le future ?


2
Jeux et Projets / En route pour PixnerIII
« le: 12 juin 2018 à 06:54:00 »
C'est partie les enfants pour Pixner III !

Nouvelle charte graphique avec les contraintes et palette du MSX ! (Pas la résolution)

- Jeux prévus en édition physique !!!  (Une 50en exemplaires)

*Les niveaux du premier pixner sont intégré au jeu.
*Des nouveaux niveaux sont prévus. (7 réalisés à l'heure actuel)


3
Les Événements / RGC 2018
« le: 07 juin 2018 à 04:51:52 »

Yeah, une semaine après les joutes du téméraire ! Meaux accueille la RGC, une convention de jeu vidéo rétro et pas que. Une plus grande PGR. J'y serrais normalement.
Je vais voir si on peux pas exposer des jeux PC aussi. 

4
QG du Comptoir / Cookies du site !
« le: 03 juin 2018 à 15:53:04 »
Le site et le forum du comptoir du clickeur utilise des cookies pour vous loguer au forum.
Nous ne réalisons aucun commerce avec vos données personnels même si j'aimerais bien, ça me ferrais du pognon hum hum.

Si vous ne voulez pas être fliqué par des cookies, ba quittez le net et retournez dans sur minitel !
Bref voila.


5
Les Événements / PGR 2018
« le: 21 mai 2018 à 07:10:56 »
Ce week end c'était la pgr 2018 à pinon.
Cela peut être sympathique l'année prochaine de monter un petit stand fusion.

Sinon voici des photos.

Mon "petit" stand avec Pixner sur la ouya. Little Sokoban et Prisonnier II sur Master System (oui le sokoban est sur une megadrive mais en mode émulation master system.)


Voici alekmaul qui à adapté rick dangerous II sur Megadrive, Il  à porté Sydney hunter sur la SNES et  Teenage Queen aussi...


Kikiche à gauche, Michel louvet au centre et alekmaul à droite.
M.Louvet à développé pas mal  d'hombrew sur Colecovision et tien une chaine youtube.
Lien


Le Stand de Twin Dragon, un homebrew sur NES.


Et son créateur Antoine Gohin.
Lien du site du jeu

C'est aussi l'occasion de voir du vieux matériel !

Comme un mac classique en monochrome.



Des vieux MSX et MSXII


Un exeltel


Le Stand Colecovision de Michel Louvet. Il a apporté ses homebrew et d'autre jeu.




Une vetrex, une console qui affiche des graphismes avec des dessins vectoriels.


Nous avons eu le droit à un feu d'artifice aussi.




Une rétro pétanque. (La c'est une Game Boy qui fonctionne plus du tout et qui fait des voltiges ! )







6
Le Topic des joutes / Les joutes 2018
« le: 12 mai 2018 à 12:04:43 »
Salut les clickeurs en herbe, j'ai chopé les dates pour les prochaines joutes du téméraire et semblerais être le week end du 20 et 21 octobres 2018.

Oui en octobre. Pour le moment je n'ai pas encore été contacté officiellement.
Voilou.

Mise à jour le 7/08/2018
Matériel emporté :

Monos :
Sega Master System 1 avec Prisonnier en Cartouche (TV Techwood)
Sega Master System 1 avec Everdrive jeu ?
Sega Master System 2 avec Everdrive jeu ?

Sega Master System 2 Cartouche.... (Très certainement en secoure)

PCE Engine Everdrive avec un jeu de Dark Maul
Nes avec Twin Dragon en boite. (Anthonie ne vient pas)

Colecovision => Everdrive soit un jeu à moi ou un jeu de michel louvel.

PC Fixe avec les niveaux de Pixner Forever

5 moniteurs crt à retrouver ! Waou xd


7

Chapitre 9 : Importer des graphismes

Aller, nous allons commencer à passer au chose sérieuse. Nous allons importer des graphismes réalisé sur un logiciel externe, dans la master system... Pour notre première exemple, nous allons importer une image réalisé avec photoshop. Mias vous pouvez faire la même chose avec d'autre logiciel de création d'image. Il faut juste exporter en png indexer sur 16 couleurs.

Voici pour l'exemple, l'image que nous allons faire bouffer à la machine.

J'ai juste réduit l'image en 256*192, indexer en 16 couleurs et puis c'est tout.

Maintenant il faut télécharger un petit logiciel qui se nomme bmp2tiles.
Lien
Ce logiciel à une interface graphique, ceci dit sur certain pc ce n'est pas complet et possède des problèmes. C'est mon cas. Donc pas le choix, on va devoir passer en mode ligne de commande. Aller dans le dossier Demo et poser votre graphisme. Ouvez le make data avec not pad++, on va placer des commandes dedans et je vais vous expliquer ce qu'il faut mettre.

Comme à mon habitude, j'aime bien effacer les fichiers.

donc

del *.bin
del *.inc
del *.pscompr
del *.psgcompr

ensuite on va découper l'image avec le bmp2tiles. mon image se nomme duck.png.
Notons que les dimenssions de l'image doit être un multiple de 8.

..\bmp2tile.exe duck.png      -removedupes -nomirror -savetiles tilesduck.binAlors le logiciel qui se trouve dans le dossier avant va chercher le fichier image duck. On va retirer les tiles qui peuvent faire doublon, et pas de miroir. On sauvegarde les tiles en tant que tilesduck.bin. Donc un fichier binaire.

après on va faire une tile map ! pour ça c'est -savetilemap tilemap.bin  et ebfub on va sauvegarder la palette de couleur avec -palsms   -savepalette palette.bin     -exit
Ce qui fait :

..\bmp2tile.exe duck.png      -removedupes -nomirror -savetiles tilesduck.bin            -savetilemap tilemap.bin            -palsms   -savepalette palette.bin     -exit

pause

maintenant dans votre projet, créer un dossier data. placer dedans les trois fichier qui viennent  d'êtres générés ici même.
Ensuite vous allez devoir placer dans le dossier de votre projet, le fichier exe filder2c que vous pouvez trouver dans le dossier de devkitsms.
Et on va créer un nouveau fichier batch pour compiler les datas avec ceci.
@echo off
echo Build data.c from data folder
folder2c data data
sdcc -c -mz80 --std-sdcc99 data.c
pause
trois fichier important sont réalisés.
Un fichier data.C que nous avons compiler pour donner un data.rel
Un fichier data.header
Placer le fichier .rel dans le dossier rel pour pas qu'il soit effacé plus tard.
le fichier .h dans le dossier header qui se trouve dans source. On va en avoir besoin.

Petite précision  sur folder2c data data
Le premier data, c'est le dossier qui sera traité, et le 2nd c'est le nom des fichiers avant extensions qui sera généra.
Si vous écrivez folder2c data ressource
il va générer un fichier ressource.c et ressource.h.

et dans le comp-link nous allons linker le data.rel avec les autres et le rajouter.
sdcc -o sms.ihx -mz80 --no-std-crt0 --data-loc 0xC000 rel/crt0_sms.rel  rel/data.rel main.rel SMSlib.lib
maintenant dans votre main, on va appeller le fichier data.header.
#include "header/data.h"
ouvez le data.h pour voir ce qu'il a dedans. Vous avez le nom de la palette, des tiles et du tilemap.
Ensuite vous avez un macro qui permet surtout de connaitre la taille des tiles.
11,456 ko l'image...

Bon on va mettre en place l'image et on va commencer par charger en mémoire la palette et voir une nouvelle commande pour charger une palette entière.
SMS_loadBGPalette(palette_bin);pratique non ?

Maintenant nous allons charger les tiles en mémoire.
SMS_loadTiles(tilesduck_bin, 0, tilesduck_bin_size);C'est traditionel. Le tilesduck_bin_size c'est tous simplement le macro de la taille des tiles qui se trouve dans le header généré par les datas.

Et enfin on va afficher l'image avec le tilemap après le retour d'un balayage d'écran.
SMS_loadTileMap (0,0,(unsigned int *)tilemap_bin,tilemap_bin_size);Le  0,0 est la position de l'image. tilemap_bin le nom de la map, et après bien sur c'est ça taille.
Tester un peu et magie ! votre image apparait !


voici le code complet de l'exemple :

// Intégration du fichier SMSlib.h
// la bibliotheque du DevKitSMS.
#include "header/SMSlib.h"
#include "header/data.h"
 
// En tête de la rom pour que cela soit lisible sur Master System.
SMS_EMBED_SEGA_ROM_HEADER(0,0);
SMS_EMBED_SDSC_HEADER(0,0,2018,01,02,"Monos","Duck","Test") ;



 
 
// ****************************************************************
// ** Fonction main qui est la fonction initiale du programme... **
// ****************************************************************
void main (void)
{

SMS_loadBGPalette(palette_bin);

  SMS_loadTiles(tilesduck_bin, 0, tilesduck_bin_size);
// Allumage de l'écran
SMS_displayOn();
    SMS_waitForVBlank ();
 
  SMS_loadTileMap (0,0,(unsigned int *)tilemap_bin,tilemap_bin_size);

        // ************************
        // ** Une boucle infinie **
        // ************************
        while (1)
        {


}
}


Retrouvez le dossier complet ici même

Allons plus loin :
11,456 ko l'image, nous pouvons compresser notre image. Pour cela dans l'utilitaire pour découper l'image, que de sauvegarde l'image en .bin, nous le sauvegardon en .psgcompr ce qui fait donc :
..\bmp2tile.exe duck.png      -removedupes -nomirror -savetiles tilesduck.psgcompr            -savetilemap tilemap.bin            -palsms   -savepalette palette.bin     -exit

pause
Le reste de la compilation est identique. Ceci dit pour charger les tiles compressé on utilise la fonction   
  SMS_loadPSGaidencompressedTiles (nom_du_tableau, Tiles);dans mon exemple cela fait :
SMS_loadPSGaidencompressedTiles (tilesduck_psgcompr, 0);
La taille des donnés compressé passe à 8,568 ko. 3ko de gagné sur la cartouche. Ce qui peut être important pour les machines qui ont peux de mémoire.

Note : Pour importer seulement des planches de tiles pour la composition de votre jeu : Je conseille de remplacer   -removedupes  par  -noremovedupes

8

Chapitre 8 : La manette de jeu et le déplacement du sprite


Voici la manette du jeu de la Master System. Elle possède deux boutons, et un pad à 4 boutons soit 6 boutons.

(Haut)(Bas)(Gacue)(Droite)(1 start)(2)

Notons aussi que la Master System possède un bouton Pause programmable et la Master System 1 un bouton Reset qui est aussi programmble au niveau logiciel. (Ce n'est pas du Hard)

La Master System possède deux emplacement pour brancher la manette de jeu. Port A et Port B.

Le SDK permet de tester de 4 manière si la manette de jeu est utilisé.
Si une touche est pressé. Si une touche est relaché, si une touche continue à être enfoncé. Et le statut d'une touche.

Nous allons préparer le sprite à être déplacé complétement en variable. On va déclarer la variable Y, et on remplace tous les "Y" de l'update et affichage du tiles par  Position_Y.

// Déclaration de la variable Position_X
unsigned char Position_Y = 0 ;

SMS_addSprite (Position_X, Position_Y, 256);

SMS_updateSpritePosition (0, Position_X, Position_Y);


Pour continuer un peu l'apprentissage du C avec vous, on va se créer une fonction qui va contenir le code qui va updater le sprite. Vu qu'elle ne renvois rien, ça sera void. Pour modifier le sprite, il faut trois arguement, l'id du sprite, la position X et la position Y : On va déclarer ses trois nouvelle variable directement dans la fonction comme ceci :

void Update_Sprite(unsigned char ID_Sprite,unsigned char Position_X,unsigned char PositionY)
{

}


Ensuite à l'interrieur, nous allons placer le code adéquate et remplacer le 0 de la fonction uptade par ID_Sprite ce qui fait :

void Update_Sprite(unsigned char ID_Sprite,unsigned char Position_X,unsigned char Position_Y)
{
// Retour du balayage écran
SMS_waitForVBlank();

// Modification de la position du sprite 0 en fonction de la variable

SMS_updateSpritePosition (ID_Sprite, Position_X, Position_Y);

// On affiche les sprites à l'écran
SMS_copySpritestoSAT ();
}


On place le morceau de code en dessous  de la fonction main.
Maintenant il faut déclarer la fonction. Pour cela vous placez au début du fichier au dessus de main, le nom de la fonction et les déclarations et vous ajoutez un ; comme ceci.

void Update_Sprite(unsigned char ID_Sprite,unsigned char Position_X,unsigned char Position_Y);
Et maintenant dans la boucle on va appeller la fonction et lui passer les paramètres voulus.

Update_Sprite(0,Position_X, Position_Y);
Cela donne ça :
       while (1)
        {
// Modification de la variable
Position_X = Position_X+1;
Update_Sprite(0,Position_X, Position_Y);

}
Si vous testez, le sprite va toujours bouger c'est normale.
Voila vous avez vu la création d'une petite fonction. Attention, vous ne pouvez pas modifier les variables qui sont déclarés dans le main, dans cette fonction.
Même si Position_X est identique que Position_X du main, ce n'est pas la même variable, ce n'est pas la même case mémoire. Mais ça on y reviendra beaucoup plus tard...

maintenant pour éviter les problèmes de variable, nous allons retravailler dans le main pour la gestion du pad et nous allons voir une partie fondamentale de la programmation... Les conditions. Les conditions permet de réaliser des actions quand la condition est remplis. Exemple dans notre cas.

Si le joueur utilise la touche droite de la manette alors on va ajouter 1 à la variable Position_X.  En C une condition s'écrit comme ça :

if (condition)
{
// code
}


La fonction pour tester en continu le pad de la master system c'est :
SMS_getKeysStatus() et nous allons assossier ça à un mot clef pour test. poiur le pad gauche c'est : 
PORT_A_KEY_RIGHTet on assemble ça avec un &

On assemble tout çe maintenant et on modifie la Position X de 1.

if (SMS_getKeysStatus()& PORT_A_KEY_RIGHT)
{
Position_X = Position_X + 1 ;
}

On fait pareil avec Gauche, Haut et Bas. Attention pour Haut et Bas on touche la variable Position_Y et plus X.

Ce qui nous fait dans la boucle While...


while (1)
        {
// Modification de la variable

if (SMS_getKeysStatus()& PORT_A_KEY_RIGHT)
{
Position_X = Position_X + 1 ;
}

if (SMS_getKeysStatus()& PORT_A_KEY_LEFT)
{
Position_X = Position_X - 1 ;
}

if (SMS_getKeysStatus()& PORT_A_KEY_UP)
{
Position_Y = Position_Y - 1 ;
}

if (SMS_getKeysStatus()& PORT_A_KEY_DOWN)
{
Position_Y = Position_Y + 1 ;
}


Update_Sprite(0,Position_X, Position_Y);

}


Avec cette méthode nous pouvons nous déplacer aussi sur les diagonales. Ceci dit si vous utilisé avant les autres if, le mot clef else, on testera dans la chaine de condition, 1 et 1 seul condition. Une fois la condition testé, on passe à la fin de la chaine de if. Donc plus de diagonale.

if (SMS_getKeysStatus()& PORT_A_KEY_RIGHT)
{
Position_X = Position_X + 1 ;
}

else if (SMS_getKeysStatus()& PORT_A_KEY_LEFT)
{
Position_X = Position_X - 1 ;
}

else if (SMS_getKeysStatus()& PORT_A_KEY_UP)
{
Position_Y = Position_Y - 1 ;
}

else if (SMS_getKeysStatus()& PORT_A_KEY_DOWN)
{
Position_Y = Position_Y + 1 ;
}

Maintenant, notre sprite peut sortir de l'écran. Et si nous évitons tout ça ? C'est simple, nous allons faire une double condition. Débutons sur la droite. Pour que le sprite se déplace à droite, il faut que sa position X soit inférieur à 256- vu que c'est la taille de l'écran. (En partant de 0) et ba on placer ça aussi dans la condition avec un ET de condition. Et cette fois si c'est &&

Ce qui fait :
if ( ( SMS_getKeysStatus()& PORT_A_KEY_RIGHT ) && ( Position_X < 256 ) )
{
Position_X = Position_X + 1 ;
}

Nous pouvons voir que le sprite est quand même mangé. On va rectifié ça en retirant aussi ça taille qui est de 8. Donc un 256-8.
if ( ( SMS_getKeysStatus()& PORT_A_KEY_RIGHT ) && ( Position_X < 256-8 ) )
{
Position_X = Position_X + 1 ;
}


Réalisons la même opération pour les autres directions. Plus grand c'est  le signe >
if ( ( SMS_getKeysStatus()& PORT_A_KEY_RIGHT ) && ( Position_X < 256-8 ) )
{
Position_X = Position_X + 1 ;
}

else if ((SMS_getKeysStatus()& PORT_A_KEY_LEFT) && ( Position_X > 0 ) )
{
Position_X = Position_X - 1 ;
}

else if ((SMS_getKeysStatus()& PORT_A_KEY_UP) && ( Position_Y > 0 ) )
{
Position_Y = Position_Y - 1 ;
}

else if ((SMS_getKeysStatus()& PORT_A_KEY_DOWN) && ( Position_Y < 192-8 ) )
{
Position_Y = Position_Y + 1 ;
}

Faite bien attention au parenthèse.  Toute les conditions sont dans une première parenthèse et prenez le plie de mettre aussi des parenthèse pour chaque sous condition.

Voici les symbole à connaitre pour tester les conditions :

==  est égale. (Attention c'est bien un double égale, piège à con ça, et beaucoup erreur à ce niveau la)
> est supérieur à
< est inférieur à
>= Supérieur ou égale
<=inférieure ou égale
!= différent de.

et pour lier les conditions :
nous avons vu le ET représenté par
&& ET il faut que les conditions soit vrais.
|| Ou, si une des conditions est Vrais alors le code sera joué.

Pour aller plus loin.
SMS_getKeysStatus c'est donc pour connaitre le statut de la touche en gros c'est quand la touche est pressé dans notre exemple et que ça continue.

si vous remplacez par SMS_getKeysPressed, l'action ne sera pas répété car c'est au moment ou la touche est pressé que l'action va se faire.

et SMS_getKeysReleased, l'action va se faire quand la touche sera relâché.

Voila, vous savez utiliser le pad de la master system et déplacer un sprite.
La prochaine étape sera d'importer des graphismes via photoshop par exemple et les intégrer dans la mémoire vidéo. Nous réaliserons un écran titre au début, puis nous importerons des "tiles/sprites" et des palettes dans de future chapitre. Ouf plus besoin d'encoder à la main...

9
Vos créations / Programmer la Master System. Chapitre 7 : les sprites
« le: 18 janvier 2018 à 07:04:56 »

Chapitre 7 : Les sprites

Bon nous savons poser un tile comme ça sur la background, nous allons attaquer maintenant les sprites, afficher un sprite.
Mais qu'elle est la différence entre un sprite et un tile ?

Le sprite on le pose ou nous le voulons sur master system, un tile c'est obligatoirement sur une grille !

Ceci dit il y a des limitations technique au sprite. La Master system ne peux afficher simultanément que 64 sprites à l'écran. Ce qui est pas mal.
(Un sprite c'est comme un tile, c'est 8px sur 8px).
Sur Master system, il n'y a pas contrainte de couleur sur un sprite. Le sprite peut avoir les 15 couleurs de sa palette tous comme un tile. C'est la différence entre la master system et la Nes par exemple.

Ceci dit tous comme la nes, il y a une limitation technique. Nous ne pouvons pas afficher plus de 8 sprites sur la même ligne. (64 pixel de sprites).
C'est pour ça que sur certain jeu, il y a des effets de clignotement. On alterne l'affichage de sprite pour en avoir plus de 8 sur la même ligne voir depasser les 64 sprites à l'écran.

On passe au code les gens !
Nous allons utiliser notre caré pour représenter notre sprite, on va changer de couleur !

Premier étape c'est de définire la palette des sprites, au lieu d'utiliser :
SMS_setBGPaletteColor, nous allons utiliser SMS_setSpritePaletteColor.


SMS_setSpritePaletteColor (0,0);
SMS_setSpritePaletteColor (1,12);

Pour notre exemple on va quand même utiliser un carré plein. Voici les graphismes du carré plein.

const unsigned char Data_Spriset[]=
{
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00
};


Maintenant on va injecter les données de notre carré mais à partir du tiles 256. Car avec ce SDK, c'est à partir ici que c'est potentiellement un sprite.
SMS_loadTiles (Data_Spriset, 256,32);
Bon maintenant voyon une façon d'afficher le sprite.
Il faut trois choses.

SMS_initSprites ();Cela permet d'initialiser tous les sprites. (On repart à 0)

SMS_addSprite (Position_X, Position_Y,Id_Tiles);Cette fonction permet de créer le sprites à la position X et Y et en pixel cette fois si. et enfin aller chercher le tiles.
Il n'y a pas d'id de sprite à configurer. C'est dans l'ordre.
SMS_copySpritestoSAT ();Envois les sprites à l'écran.

Voici le fichier main en entier.

// Intégration du fichier SMSlib.h
// la bibliotheque du DevKitSMS.
#include "header/SMSlib.h"
 
// En tête de la rom pour que cela soit lisible sur Master System.
SMS_EMBED_SEGA_ROM_HEADER(0,0);
SMS_EMBED_SDSC_HEADER(0,0,2018,01,02,"Monos","Carré","Test") ;


// Le Tableau de graphismes dans le même fichier main
const unsigned char Data_Tilset[]=
{
0xFF,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00
};
 
 const unsigned char Data_Spriset[]=
{
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00
};
 
// ****************************************************************
// ** Fonction main qui est la fonction initiale du programme... **
// ****************************************************************
void main (void)
{
   
     
       
// Mise en place de la palette de couleur
SMS_setBGPaletteColor (0,0x00);
SMS_setBGPaletteColor (1,0x0F);

SMS_setSpritePaletteColor (0,0x00);
SMS_setSpritePaletteColor (1,12);
       
// Chargement du tiles en mémoire vidéo
        SMS_loadTiles (Data_Tilset, 1,32);
SMS_loadTiles (Data_Spriset, 256,32);
       
// Attente de la syncro verticale
        SMS_waitForVBlank();

// Affichage du tile 1 à l'écran
        // SMS_setTileatXY(0,0,1)

// Allumage de l'écran
SMS_displayOn();
 
// Affichage du sprite
SMS_initSprites ();
SMS_addSprite (20, 16, 256);
SMS_copySpritestoSAT ();
        // ************************
        // ** Une boucle infinie **
        // ************************
        while (1)
        {
                // ******************************************************
                // Fonction pour attendre le retour du balayage écran. **
                // ******************************************************
                SMS_waitForVBlank();

}
}
 

 
 Voici notre beau sprite à l'écran au pixel près.
 
 Maintenant nous allons le faire déplacer automatiquement de gauche à droite.
 Pour cela on va avoir besoin d'une valeur qui peut être modifié. C'est ce que nous appellons une variable. Nous allons en déclarer une qui à pour nom Position_X
 En C il faut dire au compilateur qu'elle taille la variable va occuper dans la machine. C'est le typage. Vous l'avez déja vu avec les tableaux. Nous pour l'exemple nous avons besoin d'injecter une valeur entre 0 et 255.Doncun octet. On va utiliser un unsigned char. Car si on ne place pas le mot unsigned, le compilateur SDCC va comprendre que c'est un octet signer, va travailler seulement avec 7 bits de la variable et la 8em pour savoir si c'est dans les négatives ou les positives.
 
 Voici les typages pour SGCC.
 Un Bool (true/false) 1 bit.
 
 unsigned char et char (1 octet) 0,255 :  signed Char -128 , +127
 unsigned short et int(2 octet) 0,65535 : Short et int -32768, +32767
 unsigned long (4 octet)0,4294967295 : long -2147483648, +2147483647
 
 Float aussi qui existe qui prend 4 octets  et qui va  1.175494351E-38,
3.402823466E+38. Ceci dit sur des machines 8 bits.

Notons que c'est pour le compilateur SDCC. Ce genre de donnée change d'un compilateur à un autre voir d'une version à une autre. La version 3.0.0 du SDCC , le char par exemple est  signé nativement.
Pour éviter les problèmes, placez unsigned et signed devant le typage adéquate.
 
 
 

On va déclarer la variable comme ceci  juste après l'acollade de main:
unsigned char Position_X = 0 ; leur initiale à une variable car la variable peut être déclaré sur une ancienne case qui contient déja une valeur)

Maintenant dans la fonction pour mémoriser le sprite je peux remplacer la partie qui représente la position X du sprite par le nom de cette variable. Position_X
ce qui fait :  SMS_addSprite (Position_X, 16, 256);
Si vous testez par grand chose va se faire. Le sprite sera à 0px.

Dans la boucle infinie pour notre exemple on va s'amuser à aditioner 1 à cette variable.

donc
Position_X = Position_X + 1 ; Ce qui est bien c'est arrivé à 255 la prochaine valeur passe à 0 vu que c'est 1 octet.
Maintenant on va attendre le retour du balayage écran avec :
SMS_waitForVBlank(); Et on va modifier les donnés de notre sprite avec la fonction
SMS_updateSpritePosition (Id_Sprite, Position_X, Position_Y);Bon l'id du sprite c'est 0. Car on a injecté un seul sprte. Position_X on garde la variable Position_X et pour Y on reprend pour notre exemple, notre valeur qui est 16.
Et enfin on utilise la commande
SMS_copySpritestoSAT ();
pour afficher le sprite à l'écran.

Ce qui fait pour notre boucle :

Notre boucle :
  while (1)
        {
// Modification de la variable
Position_X = Position_X+1;

// Retour du balayage écran
SMS_waitForVBlank();

// Modification de la position du sprite 0 en fonction de la variable
// Position_X
SMS_updateSpritePosition (0, Position_X, 16);

// On affiche les sprites à l'écran
SMS_copySpritestoSAT ();
}

Et voila vous avez un sprite qui se déplace de gauche à droite.

Le prochain chapitre, on va apprendre à déplacer le sprite avec le pad de la master system, nous verrons donc les fonctions lié au commande, et on va créer aussi notre propre fonction pour sortir un peu de main, et aussi sur les conditions en C !

Télécharger la programmation finale de ce chapitre

10
Vos créations / Programmer la Master System. On passe au code
« le: 17 janvier 2018 à 07:01:38 »

Chapitre 6 : on passe en code

Pour commencer nous allons juste nous amuser à placer un carré jaune d'un seul tiles sur l'écran de la master system. Nous allons garder la couleur 0 à noir et la couleur 1 sera une teinte ajune.

Nous allons utiliser le couleur 15 soit $0F qui est un rouge pur.
Petite aparté. $0F c'est une valeur hexadécimale. Il existe plusieurs manière de dire à un lecteur que nous parlons en hexadécimale. le dollars, le 0x comme en C voir le # qui peut se voir de temps en temps.
Autre rapelle avant que je perde du monde ici. Nous la majeur partie on compte de 0 à 9. Quand on fait +1 à 9, on reppart à 0 et on ajoute 1 à la valeur qui se trouve à gauche. Dans ce cas la ça fait 10. Quand on est à 19 on passe à 20.
99 ? ba ça fait 0 pour le chifre de droite on ajoute 1 au chiffre de gauche. et comme c'est un 9 ba ça passe à 0 et on ajoute +1 au chiffre à gauche de lui. Donc 1 car je suis à 0 donc 100.

En valeur héxadécimale c'est la même chose sauf que la plage avant de rebouter le chiffre et d'ajouter 1 au chiffre de gauche n'est pas de 0 à 9 mais de 0 à 15.  Et a partir de 10 on utilise tous simplement des lettres pour représenter les chiffre au dela de 9. Donc cela fait :
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

Quand on fait +1 à F, ça passe à 0 et on fait +1 à la valeur de Gauche donc 10. (Mais ce n'est pas notre 10 mais 16...)

C'est pareil avec les valeurs binaire. Sauf que la plage est compris entre 0 et 1. Quand on ajoute +1 à 1. On passe à 0 et on ajoute +1 à la valeur de gauche.

Voilou.

Bon revenons à nos mouton.
Nous avons vu dans la decortication du code une fonction pour modifier l'index d'une palette de couleur.
  SMS_setBGPaletteColor(1, RGB(2,2,2)); // couleur 1cette fonction permet de modifier la palette dit de Background, valeur 1 que nous remplaçons en RGB(2,2,2)

RGB(R,V,B) est un macro pour aider à retrouver la couleur.
Il y a aussi d'autre macro comme RGB8 et RGB24.
Sinon et je conseille cette méthode c'est d'utiliser directement la bonne valeur. Pour notre jaune pur on a trois façon de faire.

SMS_setBGPaletteColor (1,0x0F);SMS_setBGPaletteColor (1,15);SMS_setBGPaletteColor (1,0b00001111);
Pour le noir, c'est tous simplement 0 ou 0x00 ou 0b00000000

Encodage de notre tiles
Nous allons encoder notre tiles à la main. (Rassuré vous plus tard on utilisera des logiciels pour faire ce travaille à notre place.)
Nous voulons notre carré ! de 8px. Voici donc linérairement notre carré pour le réprésenter avec notre index de palette.

11111111
10000001
10000001
10000001
10000001
10000001
10000001
11111111

Bon maintenant il faut encoder tout ça en bit plan. Par chance nous allons faire ça que pour la premier ligne et 2em ligne. Le reste c'est identique.

La première ligne c'est :
1111111

Il faut donc créer les 4 octets pour représenter tout ça. Etant donner que nous voulons la palette 1. en binaire 1 c'est %0001. Il faut inverser donc %1000
Et maintenant on recompose nos 8 bits de la premier ligne.
11111111
00000000
00000000
00000000

On va convertir ça en hexadécimale ce qui fait 0xFF,0x00,0x00,0x00
Un petit site sympathique pour les conversions

Regardon un peu la 2nd ligne maintenant.

10000001 la c'est la représentation graphique en mode linéaire. Encore une fois notre exemple est facile.

Ce qui fait
10000001
00000000
00000000
00000000

On va convertir ça en hexadécimale.
Ce qui fait

0x81,0x00,0x00,0x00

Notre carré est donc encodé comme ceci :

0xFF,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00

Maintenant nous allons charger tout ça en mémoire dans la master system dans la position 1 des tiles.
La position 0 c'est ce qu'il y a déja au fond de l'écran.

La fonction pour charger des tiles en mémoire la voici.

void SMS_loadTiles (void *src, unsigned int tilefrom, unsigned int size);
C'est une fonction void qui donc ne renvois rien.
Cette fonction attend trois paramètre.

Le premier void *src : c'est une adresse mémoire. La ou se trouve les données sur la cartouche. Un pointeur pour être exacte. Mais ne fait pas attention à cela pour le môment, garder en tête que c'est ici qu'il faut marquer le nom du tableau qui contient les données.

Le 2nd, unsigned int filefrom : attend le tile de départ ou va être mémorisé les données. Pour notre exemple, nous voulons le mémoriser au 1er tile.

Le 3em et dernier paramètre c'est la taille en octet du tableau tout simple.
Nous mémorisons seulement 1 tiles, et 1 tiles c'est 32 octets. Donc on va placer 32 octets.

Ce qui fait par exemple :
SMS_loadTiles (Data_Tilset,1,32);

Maintenant nous allons nous occuper du tableau !

const unsigned char Data_Tilset[]=
{
0xFF,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00
};


Ne vraiment pas oublier le const pour bien indiquer au compilateur que c'est en mode lecture seulement et surtout que cela doit se loger dans la cartouche et non dans la ram de la console.

Et maintenant la petite fonction pour afficher le tile à l'écran :
SMS_setTileatXY(x,y,tile)donc X et Y en Case en partant de 0. Et tile ba le numéro du tiles.
Donc la 1.
On assemble tout ça dans notre fichier main, on compile et c'est partie !
Voici donc un exemple de code et se qui faut marquer dans le fichier compilation.


// Intégration du fichier SMSlib.h
// la bibliotheque du DevKitSMS.
#include "header/SMSlib.h"
 
// En tête de la rom pour que cela soit lisible sur Master System.
SMS_EMBED_SEGA_ROM_HEADER(0,0);
SMS_EMBED_SDSC_HEADER(0,0,2018,01,02,"Monos","Carré","Test") ;


// Le Tableau de graphismes dans le même fichier main
const unsigned char Data_Tilset[]=
{
0xFF,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0x81,0x00,0x00,0x00,
0xFF,0x00,0x00,0x00
};
 
 
 
// ****************************************************************
// ** Fonction main qui est la fonction initiale du programme... **
// ****************************************************************
void main (void)
{
   
     
       
// Mise en place de la palette de couleur
SMS_setBGPaletteColor (0,0x00);
SMS_setBGPaletteColor (1,0x0F);
       
// Chargement du tiles en mémoire vidéo
        SMS_loadTiles (Data_Tilset, 1,32);
       
// Attente de la syncro verticale
        SMS_waitForVBlank();

// Affichage du tile 1 à l'écran
        SMS_setTileatXY(0,0,1)

// Allumage de l'écran
SMS_displayOn();
 
        // ************************
        // ** Une boucle infinie **
        // ************************
        while (1)
        {
                // ******************************************************
                // Fonction pour attendre le retour du balayage écran. **
                // ******************************************************
                SMS_waitForVBlank();
    }
}
 


Et le fichier de compilation.
@echo off

echo ----------------------------
echo -- Compilation et linkage --
echo ----------------------------
sdcc -c -mz80 --peep-file peep-rules.txt source/main.c

sdcc -o sms.ihx -mz80 --no-std-crt0 --data-loc 0xC000 rel/crt0_sms.rel main.rel SMSlib.lib

echo ------------------------------
echo -- Creation du fichier .sms --
echo ------------------------------
ihx2sms sms.ihx out/sms.sms

echo -------------------------------------------
echo -- Destruction des fichiers asm et autre --
echo -------------------------------------------
pause

del *.sym
del *.ihx
del *.lk
del *.noi
del *.rel
del *.lst
del *.asm
del *.map


echo ----------
echo -- Fin --
echo ---------
pause

Pour cette exemple nous n'avons pas eu besoin de fichier externe, donc  j'ai zapé la compilation du font.c et bien sur du font.rel !


Code Source

Bon la création d'un carré est simple.
Voici donc un exercice à faire ! Réaliser un carré de 16 pixel !
Donc il faut assembler 4 tiles.
Les placer en mémoire.
Et les assembler !

Le prochain chapitre sera consacré au sprite, (ou Lutin en bon français).

11

Chapitre 5 : Un monde de tiles et de couleur

La première chose que nous aimons savoir d'une console rétro c'est sa capacité graphique. Se qu'il est capable de cracher à l'écran !

La Master System est pas mal de se coté la. Au niveau de sa palette de couleur, elle possède 64 teintes en mémoire et nous pouvons dire que c'est bien coloré.

Attention le rendu sur machine réel peut être un peu différente, mais c'est une bonne  base de travaille.

La nes pour information, concurente de la master system d'après wiki c'est une palette de 53 couleurs, l'atari 7800 c'est 256 couleurs et la GX-4000 4096 couleurs.
mais l'histoire des machines de 3em génération retient seulement la bataille entre la nes et la master system chez nous. (Sega vs Nintendo)

Les deux palettes programmables
La master system permet d'utiliser en même temps deux palettes. Une palette dédié au tiles, et une palette dédié au sprite en sachant que les tiles peuvent aussi utiliser cette palette. Chaque palette peut mémoriser 16 couleurs sur les 64 disponibles de la Séga. Ce qui fait que nativement la master system peut afficher 32 couleurs à l'écran.

Les palettes fonctionnes par index !
Exemple :
Palette des tiles :

Couleur 0 : Noir
Couleur 1 : Rouge
Couleur 2 : Vert
Couleur 3 : Jaune
Couleur 4 : Rose Bonbon
Couleur 5 : Bleu nuit
Couleur 6 : Gris
Couleur 7 : Blanc
Couleur 8 : Vert pomme
Couleur 9 : Maron claire
Couleur 10 :Bleu utramarine
Couleur 11 :Rouge foncé
Couleur 12 :Bleu EDF
Couleur 13 :Mauve
Couleur 14 :Cyan
Couleur 15 :Orange

(Note pour expliquer j'ai juste placé des nom comme ça au couleur)

La premier étape sera donc de mémoriser la palette de couleur en mémoire avec la couleur couleur à son emplacement donc son indexe.
Dans la création du tiles, la machine va regarde le valeur du 1er point à poser, (exemple 13) va regarder l'index de la palette à la position 13 et va donc poser dans notre exemple abstrait, la couleur Mauve à l'écran. Il va regarder le 2nd pixel de la première ligne, va chercher l'index de couleur et va poser la couleur adéquate ! Cela marche comme ça aussi pour les sprites (Sauf que la couleur 0 est transparente donc ne sera pas afficher à l'écran)

Donc simulon une ligne de couleur de 8px pour notre tiles !
12,11,2,1,5,15,2,2

Ce qui veux dire : Bleu EDF | Rouge Foncé | Vert | Rouge | Bleu Nuit | Orange | Vert | Vert

Bon je pense que vous avez compris pour savoir ce qui est un index de couleur.

Taille d'un tiles
Aller zou on complique un peu les choses !
Un tiles dans un système informatique, c'est un morceau de graphismes qui à pour tailles un carré de  8 points (ou pixel).
ce qui veux dire que pour afficher un tile sur Master System il faut connaitre  8*8 indexe de couleur. 8 par lignes et il y a 8 lignes soit 64 valeurs !

On pourrais donc se dire chouette on va répéter notre sequence  8 fois est on a notre tiles !

12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2
12,11,2,1,5,15,2,2

On entre ça  dans la mémoire vidéo est le tour est joué !!!
Malheuresement non ! Pas sur Master system. Cette idée fonctionne sur mégadrive vu que l'encodage d'un tiles et liénaire, (c'est pratique) mais sur Master System, la console fonctionne en Bit Plane ! Tous comme beaucoup de console et de micro ordinateur comme l'amiga par exemple.

Allons y j'explique :
On encoder une ligne pour cette exemple. Une ligne de tiles sur Master System est encodé sur 4 octets. (Et comme il y a 8 lignes sur un tile nous retrouvons les 32 octets).

1 octets c'est 8 bits. Donc une valeur entre 0 et 255 en décimal, 0 à F en Hexadécimale, 00000000 à 11111111 en valeur binaire. Nous allons travailler en binaire pour l'explication.  8 bits => 8 points
le bit tout à gauche est belle et bien le pixel le plus à gauche du tile, et le bits tout à droite, est belle et bien le pixel le plus à droite du tile. et ce qui est cool c'est que cela se suit bien. Le 2nd bit, c'est le 2nd pixel .... nikel.

Maintenant nos 8 bits sont répété 4 fois sur 4 octets et pour connaitre l'index de la palette de notre pixel, on regarde les bits de chaque ligne, en fonction de leurs position, on les assembles, et on en sort une nouvelle valeur qui correspond à l'index vouleur ! Exemple

Octet 1 :10110010
Octet 2 :10011010
Octet 3 :11100001
Octet 4 :10010101

Nous avons recomposer une ligne d'un tiles.
Voyons voir le premier pixel ! Le premier bit de :
octet 1 = 1
octet 2 = 1
octet 3 = 1
octet 4 = 1

On assemble ça avec l'octet en partant de la fin. (en gros 4em octet - 3em octet - 2em octet - 1 octet) = 1111 = 15 en décime donc index 15, orange pour notre exemple. (La il y a que des 1)

Voyon voir le 4em pixel pour mieux comprendre le system :
octet 1 = 1
octet 2 = 1
octet 3 = 0
octet 4 = 1

donc 1011 = 11 en décimale donc rouge foncé.

... Voila le mystème des bits plan !!!

Regardons un peu rapidement notre font.c
Nous allons regarder cette ligne.
// Tile index ,0x006
0x1E ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
Nous avons 32 valeurs. Donc un tiles.
La première ligne est codé sur 4 octets donc :
0x1E ,0x00 ,0x00 ,0x00.

Ce qui fait pour la premier ligne :

00011110
00000000
00000000
00000000

Donc

Les 3 premiers pixels ont index 0.
Les 4 autres ont pour valeur binaire 0001 donc index 1.
Et enfin le dernier index 0.

(en linéaire : 00011110)
Je vous laisse recomposer ce tableau pour voir la lettre qui s'y trouve ! (facile car j'utilise que deux couleurs)

Et la palette ?
Vous pensez bien qu'il ne faut pas nommer les couleurs par leurs nom.
Voici le lien pour avoir les informations et récupérer les codes de la palette.
Lien

Vous pouvez voir le tableau avec une zone SMS  colour index. Le Hex c'est la valeur Hexadécimale de la couleur, ensuite la valeur décimale et en binaire. Nous pouvons avoir la couleur en RGB et le code HTML.

Exemple le jaune en "15" ou en $0f est un jaune pure. #ffff00

Le prochain chapitre sera consacré au code en lui même pour modifier la palette couleur dans la SMS et injecter un premier tiles dans la mémoire vidéo !

12
Vos créations / Chapitre 4 : Décryptage du premier programme
« le: 16 janvier 2018 à 06:13:09 »

Chapitre 4 : Décryptage du premier code source !

Le compilation se passe bien, vous avez lancé le fichier binaire dans un émulateur, vous avez un hello world à l'écran. Mais vous avez rien bitté au deux fichier c. Le main et le font ! Pas de panic nous allons en parler, et en même temps commencer à apprendre le langage C. Enfin la Base, car je ne suis pas un spécialiste. Mais je vais vous apprendre ce que je sais faire ! Après ça sera à vous de continuer sur le chemin de la création, en vous documentant bien comme il le faut sur les différents site, livre, et autre pour vous améliorer dans ce langage.

Histoire du C
Le C est un langage de programmation des années 70. Il fut inventé pour réécrire unix. (Wiki est mon ami). C'est un peu le papa de beaucoup de langage. Son auteur est Dennis Ritchie est possèdes plusieurs norme. ANSI C,C89,C11... Pour faire simple, une norme c'est la façon d'écrire le C

Le C est un langage structuré,procédural et impératif. Ce qui veux dire en gros, qu'il faut bien structurer sa programmation avec divers fichiers, des conditions, des boucles et éviter de se balader d'un point à un autre avec la fonction GOTO qui rend son code illisible. (Ah le Basic chez les débutants).
Procédural car on va construire son programme avec des sous programmes qui peuvent être appellé de n'importe ou.
(Je simplifie bien sur la vision)
La C contrairement à son petit fréro, le C++ ou d'autre langage de programmation comme le C#, le ruby, le javascript, le java... n'est pas un langage object.
Un sous programme, si on lui passe pas des paramètres, ne va pas intégrer les données d'un autre sous programme comme ça...

Le C à la falculté de travailler directement dans la mémoire de l'ordinateur. C'est un langage dit Bas niveaux pour cette partie. Proche des éléments éléctronique de l'ordinateur. Moins que l'assembleur mais quand même. Avec le C on manipule beaucoup la mémoire,et les adresse mémoire de la machine cible. Les pointeurs. Ce qui permet d'économiser de la mémoire dans ses programmes.

Le C permet donc pour ça de choisir des "Variables" de différente taille. Allant d'un octet pour les variables dit de type Char à  8 octets ,16,32... Ce n'est pas le seul langage à proposer ça. Pour information, l'amos sur Amiga, une variable numérique c'est 4 octets, il n'y pas beaucoup de typage de variable, c'est pareil avec Second Basic pour créer des jeux avec le langage Basic sur Megadrive !

Le C est donc un langage de choix sur les petits systèmes et donc adapté pour les machines rétro que nous voulons programmer.  Le choix du C est beaucoup utilisé pour les SDK amateur de nos vielle machine.

Fichier main.c
// Intégration du fichier SMSlib.h
// la bibliotheque du DevKitSMS.
#include "header/SMSlib.h"

Débutons avec ceci. La fonction #include permet d’intégrer un fichier dans un autre fichier.
La pour notre exemple quand on va passer les fichiers à la moulinette avec le compilateur, le contenu du fichier SMSlib.h qui se trouve dans le dossier header, sera ajouté dans ce fichier même.
En principe un fichier.h contient des tas de choses importante comme indiquer au compilateur: attention je vais utiliser cette espace mémoire pour pouvoir utiliser une fonction qui va permettre de déplacer mon sprite ! Le compilateur est prévenu, il va donc bloquer une plage mémoire dans son programme pour ça ! Je simplifie bien sur mais l'idée est la.

 // En tête de la rom pour que cela soit lisible sur Master System.
SMS_EMBED_SEGA_ROM_HEADER(0,0);
SMS_EMBED_SDSC_HEADER(0,0,2018,01,02,"Monos","Hello_World","Test") ;
Voici deux fonctions de notre bibliotheque adoré. C'est tous simplement l'entete du fichier binaire obligatoire pour la master system.

On reviendra  dessus plus tard !

 void main (void)
{
…….
}

Voici la fonction la plus importante du programme.  C'est quoi une fonctions ? C'est tous simplement un morceau d'un programme (ici main) avec du code dedans, qui peut être appelé ! On peux lui injecter des donnés et une fonction peut retourner une résultat. (Un et un Seul!!!)
Le petit mot en bleu void veux dire "Rien", "néant" "nada", placer devant le nom, veux dire le type de donné que la fonction va retourner, et renvoyer. La c'est rien, la fonction main ne vas rien renvoyer ! On parle aussi dans ce cas la de Procédure.  Le void entre parenthèse veux dire aussi qu'il n'attend rien comme donnée quand on appelle main ! …
La fonction main est un peux spécial, c'est le début du programme, il est obligatoire.
Ensuite nous avons les deux accolades. { }
En C, une fonction/procedure doit avoir une accolade ouvrante qui marque le début et une accolade fermente qui merque la fin ! C'est un "bloc". A vrais dire beaucoup d'instruction sont comme ça. Ah ah.

 
extern unsigned char Font_Namco[];Alors la il est placé dans main ! Au début du main.
Extern veux dire : va cherche le truc à l'extérieur de ce fichier pour que je puisse l'utiliser. C'est une variable Global ! La philosophie du C c'est d'éviter au maximum ce genre de variable quand nous le pouvons.

Unsigned char c'est un typage de variable.   char veux dire que la variable va prendre une case mémoire. Donc 1 octet. Une valeur entre 0 et 255 soit 256 possibilité. Si on ne place pas le mot unsigned, ba le compilateur va comprendre grosse merdo une valeur entre -127 et 127. Un bit pour indiquer le signe et 7 bites pour la valeur. Le unsigned élimine tout ça et permet de gérer les  8 bits de la case.
 Font_Namco[] c'est tout simplement le nom d'un tableau ! Une série de variable tous simplement. C'est la série de valeur contenu dans le fichier font.c, on va donc le placer ici pour qu'il soit lisible dans le programme main !

SMS_setBGPaletteColor(0, RGB(0,0,0)); // couleur 0
SMS_setBGPaletteColor(1, RGB(2,2,2)); // couleur 1
Ayez on entre dans le domaine de la Master System.
On va appeler deux fois une fonction de la bibliotheque devkitsms "SMS_setBGPaletteColor(a,b)"
cette fonction, permet tout simplement de remplacer la couleur à une position voulu avec la couleur voulu, dans la palette dédié au Background ! (Donc palette tiles).

La master System possède deux palettes, une pour les tiles, et une pour les sprites. Chaque palette permet de mémoriser 16 couleurs. (De 0 à 15).
La on mémorise l'index 0 et l'index 1 de la palette des tiles !
Notons qu'une instruction doit se terminer par un ;
C'est un piège à con et une source d'erreur monumentale donc faite bien attantion.

SMS_loadTiles (Font_Namco, 1, 0x38*32); Cette fois si on va injecter dans la mémoire vidéo de la master system, les graphismes voulu qui sont présent dans le tableau Font_Namco. Nous allons débuter à la position 1, et le 0x38*32 c'est la taille en octet des données.
Il y a 0x38 tiles de 8*8 pixelq .le 0 x c'est pour annoncer au compilateur que nous allons parler en Hexadécimal. Ce qui fait 56 tiles à mémoriser. Et *32 car un tile à pour taille, 32 octets. Ce qui fait donc  1792 octets, (1,8ko). On peux remplacer  0x38*32 par 1792 ou  0x1792 ou 0b11100000000
0b c'est pour annoncer que nous injectons une valeur en langage binaire.

SMS_displayOn();Une fonction pour "allumer" l'écran de la master system. Le Off permet de l'éteindre.
 

SMS_setTileatXY(7,7,18) // H
SMS_setTileatXY(8,7,15) // E
SMS_setTileatXY(9,7,22) // L
SMS_setTileatXY(10,7,22)// L
SMS_setTileatXY(11,7,25)// P

SMS_setTileatXY(13,7,33)// W
SMS_setTileatXY(14,7,25)// O
SMS_setTileatXY(15,7,28)// R
SMS_setTileatXY(16,7,22)// L
SMS_setTileatXY(17,7,14) // D

SMS_set_TileatXY(x,y,id)
C'est une fonction qui permet d'afficher le numéro du tile(id) en mémoire à la position X et Y de l'écran.
Mais attention, les positions X et Y sont exprimés en Case et non en pixel. 
Dans mon exemple, le W de World, il est posé à la  13em case en Largeur (X) et 7em case en hauteur (Y) . Enfin pour être exacte c'est la 14em cases en X et 8em cases en Y,  la première case débute à 0. Enfin 33, c'est la place en mémoire ou se trouve l'élément graphique qui représente le W.

Ah, j'avais dit qu'il fallait des ; à chaque fin d'instruction. Le "SMS_set_TileatXY(x,y,id)" qui se trouve dans la bibliothèque estune Défine.  Ce n'est donc pas une "fonction" a proprement parlé mais un morceau de code qui sera remplacer par une vrais fonctions ou un autre morceau de code. Et l'auteur a placé un ; dans le morceau remplacé. donc pas besoin de ; à la fin de cette "fonction".

Pour information le "SMS_set_TileatXY(x,y,id)" sera remplacé à la compilation par :
SMS_setAddr(XYtoADDR((x),(y)));
SMS_setTile(tile); Qui sont aussi des défine (ou macro) qui sera remplacé par autre chose bref un tas de noeux, mais sans trop d'importance...

while (1)
{
SMS_waitForVBlank();
 }

Ah une boucle. While() c'est une boucle. Nous avons toujours les accolades d'ouverture et de fermeture. En gros quand on va à l'accolade de fermeture dans une boucle, on repart au début ! Il y a  un petit test et si c'est vérifié, on continu à exécuter la boucle.
Ici nous avons un 1 entre parenthèse. Ce qui veux dire que c'est toujours vrais !
Donc la boucle va se jouer à l'infini !  C'est une boucle infini quoi.
Attention c'est le MAL ! Source de bug xd mais bon nous sommes sur console et comment on quitte un jeu sur console ? Ba avec le bouton power off ! Donc si c'est la boucle principale (ou boucle du jeu) du programme sur console, nous pouvons faire ça, pour 99% des autres cas, c'est bien sur déconseillé !

SMS_waitForVBlank();Cette fonction permet tout simplement d'attendre que le balayage de l'écran reviennent en haut pour continuer le programme !
(Tips : Sur Master System on le place aussi avant d'afficher des graphismes, chose que je n'ai pas fais ici... bouhhh)

Fichier font.c
Aller un petit tour dans le fichier font.c
 
const unsigned char Font_Namco[]={….} ;Alors plusieurs chose la pour débuter.
Const : c'est tous simplement un petit mot qui veux dire constante donc que nous allons mémoriser ça dans la ROM. Cela protège en "écriture" Et sur console par exemple cela évite que les données partent dans la Ram de travaille.

Unsigned char, c'est le typage de notre tableau. Unsigned veux dire non signé, donc on va pas dans les valeurs négative. Et char c'est tous simplement pour dire que chaque élément aura pour taille 1 octet donc 8 bits.

Font_Namco veux dire ceci est un tableau qui à pour nom Font_Namco.
[] : Normalement on doit intégrer le nombre d'élément du tableau mais ça marche bien sans les mettre pour sdcc.
={} ;  ne pas oublier le égale, les accolades et le point virgule dans les tableaux.

Dans le tableau en lui même nous avons des valeurs et des virgules.
0x1C ,0x00 , ….
Chaque élément du tableau est séparé par une virgule.
Et le 0xValeur veux tous simplement dire que c'est une valeur héxadécimale.

Le tableau Font_Namco contient tous simplement les graphismes représentant une police de caractère que j'ai vite fait arrangé pour que cela soit lisible pour notre exemple.

Voilà pour le décryptage des fichier. Nous reviendrons bien sur sur les éléments avec plus de détaille et d'explication car la ce n'est qu'un survole du petit code source.

Pour le prochain tuto, je parlerais des couleurs de la master system, et comment encoder notre premier tiles de 8 pixel dans la mémoire! Car c'est peut être le truc le plus important et le plus dure à comprendre au départ.
Rassurez vous, un peu plus tard nous aurons pas besoin d'encoder à la main les graphismes du jeu !

13

Chapitre 3 : Afficher un Hello World à l'écran de la master system !

Reprennez le dossier réalisé au chapitre deux, et nommer le Hello_Word par exemple. Pour ce premier programme test, je ne vais pas trop parler du code en lui même et de la bibliotheque, c'est un chapitre pour voir si votre machine va vraiment compiler et afficher du texte à l'écran sur votre master system, (ou l'émulateur) pour enfin passer à la suite.

Pour commencez vous allez créer un nouveau fichier que vous allez nommer "main.c" dans le dossier source.(mais pas dans le header).
Maintenant vous aller copier/coller ce morceau de code. Il est un peu commenté pour débuter la compréhension !

// Intégration du fichier SMSlib.h
// la bibliotheque du DevKitSMS.
#include "header/SMSlib.h"

// En tête de la rom pour que cela soit lisible sur Master System.
SMS_EMBED_SEGA_ROM_HEADER(0,0);
SMS_EMBED_SDSC_HEADER(0,0,2018,01,02,"Monos","Hello_World","Test") ;

// ****************************************************************
// ** Fonction main qui est la fonction initiale du programme... **
// ****************************************************************
void main (void)
{
// **************************************************
// ** Intégration d'un tableau du fichier externe. **
// **************************************************
extern unsigned char Font_Namco[];

// *************************************************************
// ** Configuration des deux premières couleurs de la palette **
// ** prévue  pour les tiles.                                 **
// *************************************************************
SMS_setBGPaletteColor(0, RGB(0,0,0)); // couleur 0
SMS_setBGPaletteColor(1, RGB(2,2,2)); // couleur 1


// **************************************************************************
// ** Chargement dans la mémoire vidéo, la police contenue dans le tableau **
// ** 1 = Numéros du tiles de départ,                                      **
// ** 0x38*32 c'est le nombre de tiles mutiplié par 32 1 tile = 32 octets  **
// **************************************************************************
SMS_loadTiles (Font_Namco, 1, 0x38*32);

// ***********************************
// ** Commande pour allumer l'écran **
// ***********************************
SMS_displayOn(); // On allume l'écran.

// ***************************************************************************
// ** Commande pour afficher un tile à l'écran                              **
// ** Position X,Position Y, numéro du tiles.                               **
// ** La position du tile est exprimé en case. (8*8 pixel).                 **
// ** Pas besoin de ";" à la fin de la fonction car c'est un défine (macro) **
// ** et ça intègre le ; dans ce qu'il remplace.                            **
// ***************************************************************************
SMS_setTileatXY(7,7,18) // H
SMS_setTileatXY(8,7,15) // E
SMS_setTileatXY(9,7,22) // L
SMS_setTileatXY(10,7,22)// L
SMS_setTileatXY(11,7,25)// P
SMS_setTileatXY(13,7,33)// W
SMS_setTileatXY(14,7,25)// O
SMS_setTileatXY(15,7,28)// R
SMS_setTileatXY(16,7,22)// L
SMS_setTileatXY(17,7,14) //D
 
// ************************
// ** Une boucle infinie **
// ************************
while (1)
{
// ******************************************************
// Fonction pour attendre le retour du balayage écran. **
// ******************************************************
SMS_waitForVBlank();
    }
}

maintenant vous allez faire un 2nd fichier font.c
Et placez ce morceau de code dedans.

const unsigned char Font_Namco[]={
// Tile index ,0x000
 0x1C ,0x00 ,0x00 ,0x00 ,0x26 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x32 ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x001
 ,0x0C ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x3F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x002
 ,0x3E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x07 ,0x00 ,0x00 ,0x00 ,0x1E ,0x00 ,0x00 ,0x00 ,0x3C ,0x00 ,0x00 ,0x00 ,0x70 ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x003
 ,0x3F ,0x00 ,0x00 ,0x00 ,0x06 ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x1E ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x004
 ,0x0E ,0x00 ,0x00 ,0x00 ,0x1E ,0x00 ,0x00 ,0x00 ,0x36 ,0x00 ,0x00 ,0x00 ,0x66 ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x06 ,0x00 ,0x00 ,0x00 ,0x06 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x005
 ,0x7E ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x006
 ,0x1E ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x007
 ,0x7F ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x06 ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x008
 ,0x3C ,0x00 ,0x00 ,0x00 ,0x62 ,0x00 ,0x00 ,0x00 ,0x72 ,0x00 ,0x00 ,0x00 ,0x3C ,0x00 ,0x00 ,0x00 ,0x4F ,0x00 ,0x00 ,0x00 ,0x43 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x009
 ,0x3E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3F ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x06 ,0x00 ,0x00 ,0x00 ,0x3C ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x00A
 ,0x1C ,0x00 ,0x00 ,0x00 ,0x36 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x00B
 ,0x7E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x00C
 ,0x1E ,0x00 ,0x00 ,0x00 ,0x33 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x33 ,0x00 ,0x00 ,0x00 ,0x1E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x00D
 ,0x7C ,0x00 ,0x00 ,0x00 ,0x66 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x66 ,0x00 ,0x00 ,0x00 ,0x7C ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x00E
 ,0x3F ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x3F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x00F
 ,0x7F ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x010
 ,0x1F ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x67 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x33 ,0x00 ,0x00 ,0x00 ,0x1F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x011
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x012
 ,0x3F ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x3F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x013
 ,0x03 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x014
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x66 ,0x00 ,0x00 ,0x00 ,0x6C ,0x00 ,0x00 ,0x00 ,0x78 ,0x00 ,0x00 ,0x00 ,0x7C ,0x00 ,0x00 ,0x00 ,0x6E ,0x00 ,0x00 ,0x00 ,0x67 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x015
 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x3F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x016
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x77 ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x6B ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x017
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x73 ,0x00 ,0x00 ,0x00 ,0x7B ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x6F ,0x00 ,0x00 ,0x00 ,0x67 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x018
 ,0x3E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x019
 ,0x7E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x01A
 ,0x3E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x6F ,0x00 ,0x00 ,0x00 ,0x66 ,0x00 ,0x00 ,0x00 ,0x3D ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x01B
 ,0x7E ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x67 ,0x00 ,0x00 ,0x00 ,0x7C ,0x00 ,0x00 ,0x00 ,0x6E ,0x00 ,0x00 ,0x00 ,0x67 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x01C
 ,0x3C ,0x00 ,0x00 ,0x00 ,0x66 ,0x00 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x01D
 ,0x3F ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x01E
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x01F
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x77 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x08 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x020
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x6B ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x36 ,0x00 ,0x00 ,0x00 ,0x22 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x021
 ,0x63 ,0x00 ,0x00 ,0x00 ,0x77 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x77 ,0x00 ,0x00 ,0x00 ,0x63 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x022
 ,0x33 ,0x00 ,0x00 ,0x00 ,0x33 ,0x00 ,0x00 ,0x00 ,0x12 ,0x00 ,0x00 ,0x00 ,0x1E ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x023
 ,0x7F ,0x00 ,0x00 ,0x00 ,0x07 ,0x00 ,0x00 ,0x00 ,0x0E ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x38 ,0x00 ,0x00 ,0x00 ,0x70 ,0x00 ,0x00 ,0x00 ,0x7F ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x024
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x025
 ,0x1C ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x1C ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x10 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00
// Tile index ,0x026
 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x10 ,0x00 ,0x00 ,0x00 ,0x20 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x027
 ,0x81 ,0x00 ,0x00 ,0x00 ,0x42 ,0x00 ,0x00 ,0x00 ,0x24 ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x24 ,0x00 ,0x00 ,0x00 ,0x42 ,0x00 ,0x00 ,0x00 ,0x81 ,0x00 ,0x00 ,0x00
// Tile index ,0x028
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x029
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x02A
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x02B
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x3E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x02C
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x02D
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x02E
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x02F
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x030
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x031
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x032
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x033
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x034
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x035
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x036
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
// Tile index ,0x037
 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00

};

maintenant à la racine de votre dossier du projet, (Racine veux dire des que nous entrons dans le dossier en question, vous allez faire un nouveau fichier compile.bat par exemple.
Et voici le code à mettre dedans.

@echo off

echo ----------------------------
echo -- Compilation et linkage --
echo ----------------------------
sdcc -c -mz80 --peep-file peep-rules.txt source/main.c
sdcc -c -mz80 --peep-file peep-rules.txt source/font.c
sdcc -o sms.ihx -mz80 --no-std-crt0 --data-loc 0xC000 rel/crt0_sms.rel main.rel font.rel SMSlib.lib

echo ------------------------------
echo -- Creation du fichier .sms --
echo ------------------------------
ihx2sms sms.ihx out/sms.sms

echo -------------------------------------------
echo -- Destruction des fichiers asm et autre --
echo -------------------------------------------
pause

del *.sym
del *.ihx
del *.lk
del *.noi
del *.rel
del *.lst
del *.asm
del *.map


echo ----------
echo -- Fin --
echo ---------
pause

Nous y sommes, nous allons voir si tous fonctionne bien ! Double cliquez dessus et normalement,

Dans votre dossier, vous devez avoir un fichier  qui se nomme sms.sms que vous pouvez lancer dans un émulateur master system et voir afficher un beau Hello World.


Nous allons décrypter le fichier bat. (Attention sur un autre os que windows, cela ne doit pas être un fichier bat, mais un truc propre à votre os.)

=> @echo off :Permet tous simplement de cacher les "commandes" envoyez à votre OS. Vous pouvez retirer cette ligne pour voir ce que cela fait. Mais c'est moins lisible je trouve.

=> sdcc -c -mz80 --peep-file peep-rules.txt source/main.c
=> sdcc -c -mz80 --peep-file peep-rules.txt source/font.c

Deux mêmes fonctions mais sur deux fichiers séparé. (main.c et font.c)
En gros on demande à sdcc de créer pour chaque fichier  un fichier .rel du même nom. Un fichier en .sym et assembleur.

=> sdcc -o sms.ihx -mz80 --no-std-crt0 --data-loc 0xC000 crt0_sms.rel main.rel font.rel SMSlib.lib
Maintenant nous allons rassembler tout ça pour créer un seul fichier, le  sms.ihx.
Donc pour chaque fichier.c que nous avons dans le programme, il faut ajouter son .rel dans la ligne !

Et enfin ihx2sms
=> sms.ihx out/sms.sms
Permet de passer du fichier sms.ihx => sms.sms qui est un fichier binaire lissible par la master system. Le fichier dans cette exemple sera créer dans le répertoire out. Vous pouvez changer le nom du répertoire mais il doit exister avant la création du fichier binaire.
Vous pouvez aussi changer le nom du fichier binaire par ce que vous voulez.
Le fichier binaire à pour nom aussi de ROM. Non pas les Tziganes mais l'acronyme de Read Only Memory. (Mémoire en lecture seul !) ou mémoire Morte. Interdiction écrire dessus, du coup c'est le nom donnée au fichier binaire des cartouches.

del *.sym
del *.ihx
del *.lk
del *.noi
del *.rel
del *.lst
del *.asm
del *.map

Permet d'effacer tous les fichiers et éviter  éviter de polluer votre dossier. Il y a une pause avant cette fonction si vous voulez les récupérer.

Voilà voila pour un petit décryptage du fichier bat. Si ça marche bravos vous venez d'utiliser un logiciel en ligne de commande !

Maintenant  nous allons voir les donnés de la fenêtre de commande.

*** sverx's …… ***
Bon ça osef, c'est le nom du bidul chouette, cela n'a pas d'importance capitale.

Info : 3331 bytes used/32769 totale [10,17 %] - size output Rom is 32kb.
Une bonne information, cette phrase dit que nous utilisons 3331 bytes pour notre programme !
Ou Octets. Donc cela fait un programme de 3,33ko. Oui Bytes et Octets sont synonymes.  Il ne faut pas confondre Bytes = 1 octet = 8 bits…
nous avons 10,17 % aussi dans cette phrase. C'est le pourcentage "utilisé" pour le type de cartouche . La une cartouche de 32768 octets ce qui fait a la sortie nous avons belle et bien une cartouche de 32 Ko.  Quand on arrive à plus de 100 % de la cartouche, on passe à une version supérieur.  (Donc la une cartouche de 64ko,128ko…)
Attention aussi, 32ko qui est belle et bien 32,000 Kilos octets est une approximation du nombre d'octet disponible. 1Ko = 1024 octets. Donc une cartouche de 32ko mémorise bien 32768 octets !
On en discutera plus tard de la mémoire !
(Ceci dit pour débuter, il est peut être bon de ne pas dépasser les 32ko)

Prochaine ligne d'information : SEGA header found, checksum updated !
Tout s'est bien passé. La console Sega Master a besoin d'un en tête pour faire fonctionner le jeu, et quand cette phrase apparaît cela veux dire que le fichier binaire peut être lu sur une vrais console !

Voilou pour cette article, le prochain on décrypte le programme en C ! Car la pour pas mal de monde c'est obscure !

Télécharger le dossier Hello World

14

Chapitre 2 : Installation du devKitSMS et un petit mot sur le processeur !

Installation du SDK, du compilateur et d'autre outil
Pour programmer la Master System, nous avons besoin de plusieurs programmes sur votre ordinateur et le plus important, un compilateur* qui va permettre de transformer votre code en fichier binaire lisible par la master System. Vous avez besoin aussi d'un éditeur de texte. (Note Pad ++ par exemple) , d'un émulateur master system et un kit de développement. Pour le kit de développement , le devKitSMS est sympathique, il permet de coder en C avec des fonctions utiles pour la master system sans trop mettre la main dans l'assembleur*. Pour le compilateur, il utilise  "SDCC", et l'emulateur, vous prenez celui que vous voulez. (Kega Fusion est pas mal pour tester, Meka est pas mal, permet de voir les palettes de couleur, ce qu'il y a dans la mémoire vidéo et bien d'autre encore. )
Notons que le devKitSMS permet de créer des jeux pour Master System/Sega Mark III, Game Gear et Sega Mark I (La SG100).

En premier lieu, télécharger le DevKit à cette adresse : https://github.com/sverx/devkitSMS En haut à droit, il y a Clone or Dowload, cliquez dessus et utilisé Download Zip.
Déziper l'archive.

Télécharger et installer SDCC qui se trouve à cette adresse dans snapshop.
http://sdcc.sourceforge.net/snap.php
Télécharger la version adéquate à votre OS. Sur Windows, je vous conseille d'installer ça dans le disque dure / partition ou est installé votre OS. (Souvent le C mais ça peut changer)

Maintenant copier/coller ihx2sms.exe  dans le dossier bin de SDCC (Si vous n'êtes pas sur Windows, il faut re-compiler le logiciel pour votre os)
Faite de même avec assets2banks.exe  et older2c.exe. (Dans le fichier bin)
Le fichier SMSlib.lig  lui se place dans le dossier lib/z80.

Voici une organisation  parmi tant d'autre de votre dossier du projet.

-Faite un nouveau dossier avec le nom de votre projet, dedans :
--Faite un Dossier out qui va recevoir le fichier binaire compilé.
--Faite un Dossier rel Placez le fichier crt0-sms.rel dedans
--Faite un Dossier source, vous aller placer vos fichier en .c ici comme main.c
----Dans le dossier source, faite un dossier header, placez le fichier SMSlib.h
--Créer le fichier .bat de compilation dans la racine du dossier du projet. (Nous verrons plus tard ça)
--Placer le fichier ijx2sms.exe
--Placer le fichier peep-rules
--Placer le fichier SMSlib.lib
 
Voila un bon début. Vous pouvez télécharger un exemple ici :

Télécharger le Zip

Note : si il manque un fichier, le compilateur va vous le dire de toute façon.
Avec un peu plus de connaissance, vous allez pouvoir organiser tout ça comme bon vous semble.

Pour l'écriture de votre jeu, vous pouvez utiliser un simple fichier texte renommé en . C ou .H suivant ce que vous aller faire. En mode simple, je vous conseille quand même un éditeur de text un peu plus évolué.
Notepad++ est pas mal à ce petit jeu. Lien
Mais il en existe d'aute bien sur. (Code Block,Eclipse,et j'en passe)
Pour l'émulateur, vous pouvez faire un tour sur planetemu. Lien
Il y a d'autre outil à télécharger, mais nous verrons tout ça en temps utile.


Le Processeur c'est quoi  vraiment ? :

* Compilateur, Assembleur ?
Pour le moment si vous suivez le mode d'emploi, tout devrait bien se passer. Cette outil de développement pour la master system pour s'installe facilement. Même pour une personne qui si connaît pas trop. Mais  deux mots sont la, Compilateur et Assembleur… J'ai du perdre du monde la. C'est le point culture du tuto !

Chaque type de machine informatique est construite de la même manière depuis la nuit des temps enfin presque. Que cela soit votre console préfère, votre smartphone de dernière génération, votre PC, la vielle console nes, la Master System, l'amstrad CPC pour rester dans le rétro ,elles Continnent les mêmes organes pour fonctionner ! (Bon maintenant c'est beaucoup plus puissant mais on reste toujours sur la même base)



*De la mémoire vive dit RAM qui permet de mémoriser les informations. (8 ko exploitable sur la Master System, 2Ko sur le nes, 128ko sur l'amstrad CPC 6128, 16Go pour mon PC Fixe à l'heure actuel.  1,5Go pour mon téléphone Samsung galaxy S5 mini. 3Go pour l'iphone 10..


*Un module graphique avec des fois de la mémoire dédiés, des fois non. Le CPC c'est le Gate Array qui s'occupe de balancer les images à l'écran mais n'a pas de mémoire dédiés. Elle est partagé avec la Ram centrale. Sur les PC actuel se sont les cartes Graphiques comme les G-force, Saphyre…  avec des résolutions de ouf geudin par apport au passé (Carte VGA par exemple)La Master System c'est la carte TMS9918 qui permet d'afficher et gérer les image à l'écran les deux palettes de 16 couleurs, et possède une mémoire interne de 16ko sans bouffer sur la ram de la console !


*Le 3em composant indispensable se sont les entrées  pour communiquer avec le système informatique. Clavier, manette de jeu, stylo optique, écran tactile…

*Le 4em élément sont les sorties ! Cela peut être une TV, une imprimante, un petit écran lcd sur les consoles voir rien du tout juste brancher sur d'autre pièce eletronique/mecanique pour faire des actions reçu en entrée.


*Et enfin le plus important, il faut un maître d'oeuvre, un chef d'orchestre. Et ça c'est le rôle du processeur ! Les I7/I5/Duale core, pantium4 pour les PC  en passant aussi par les game des AMD, ceci dit c'est la même famille de processeur. (X86), nous avons les processeurs de type ARM, les vieux 68000 de motorola qui équipe les Amiga, Megadrive, premier Mac, Néo Géo, les Z80 de la Master System,  Le fameux 6502 de la NES Atari 2600,du T800 !

Le processeur et le chef d'orchestre du system informatique, c'est lui qui donne les ordres comme par exemple : bon la dans ma petite mémoire interne je vais placer la valeur 50, et maintenant le contenue de cette valeur je vais la placer dans cette case mémoire, puis je vais additionner le contenu de cette case mémoire par la valeur contenu dans une autre case mémoire interne au processeur.  Maintenant toi carte graphique, tu peux lire le contenu de cette casse mémoire pour la placer chez toi dans le case mémoire numéro X ou X la valeur contenu dans ma case mémoire pointé par le contenu de cette case mémoire interne à mon processeur. (ouf dure cette phrase xd).
Bref voila le rôle du processeur ! Jouer avec les nombres ! Et faire des actions que nous appelons des instructions ! Et vous savez quoi ? Un processeur sait lire que 10 valeurs !  Soit 0, soit 1.
(Heu ça fait que deux ça ?) .
Oui, pardon seulement deux valeurs. Votre processeur ne reconnais que des 0 et 1. C'est le langage "Binaire". Avec ça on fait plein de truc. Quand on assemble plusieurs des 0 et 1 (Un bit), cela permet d'avoir  de multiple possibilité. La norme c'est de placer 8 bits à la suite pour former entre 0 et 255 possibilité(s). Ce qui fait 1 Octet. 

Maintenant concrètement que fait votre processeur avec ça ? Ba il va lire séquentiellement (la liste octet du fichier. Les décoder en interne et faire une action qui se rapporte à l'octet ou plusieurs car il  existe des instructions qui  codés sur 1-2-3 voir plus d'octets).

Exemple concret :
Octet 1 : 00111110
Octet 2:  00001111

C'est un vrais code qui fonctionne ! Décryptage.
Le proco arrive, lit l'octet 1 qui est 00111110 en binaire.  (62 en décimale)
Sans entrer dans les détaille, il sait qu'il va devoir mémoriser dans sa mémoire interne la valeur du prochain octet. Il va lire l'octet 2 qui est de 00001111 (15) et va le mémoriser dans sa mémoire interne. (Enfin une mémoire interne car il en possèe plusieurs.)

Tous programme informatique, votre os, votre jeu préféré, vos vidéos préférés, tous, tous, tous fonctionne comme ça. Et c'est le seul langage que votre ordinateur connaît. C'est ce que nous appelons le langage machine !

Sauf que écrire des programmes en 0 et en 1 c'est pas facile, c'est pas lisible du tout pour un être humain. Alors les programmeurs se sont dit, bon on va simplifier l'écriture de nos programme pour notre machine et on va associer des termes qui est facile à retenir pour les instructions de notre machine.
Donc    00111110, 00001111 devient LD A,%000011110 (ou) LD A,$F,($F =%0001111=15, c'est une valeur Hexadecimale).
Le nouveau logiciel va tous simplement remplacer LD A par 00111110, 15/$F par sa valeur binaire et continue comme ça. C'est une "compilation". Ou un assemblage. (Je pense faire un abus de langage mais bon) et voila le langage Assembleur est née !
Sauf que ! Notre LD A n'est valable que sur les processeur de la famille des Zilog 80. Sur un Windows PC, cela veut dire très certainement autre chose pour le processeur… C'est pour cela qu'un logiciel PC n'est pas compatible en lui même sur un téléphone mobile car les instructions ne sont pas les mêmes. Un programme Master Systeme ne peux pas fonctionne sur une NES. Ceci dit un programme NES peut être lu avec les mêmes jeu d'instruction sur une Atari 2600 ceci dit l'interprétation des donnés ne sera pas le même ! Idem avec le CPC d'amstrad et la master System. C'est le même processeur donc le même "langage" mais l'interprétation n'est pas la même.
Le CPC qui à une mémoire partagé avec la ram, aura le même code d'instruction, pour placer la valeur 255 à la case mémoire numéros 49152 et affichera un petit trait à l'écran, alors que sur Master System, la mémoire vidéo n'est pas branché sur cette case mémoire et ça sera une simple "variable"  dans la console…

Maintenant passons un peu à nos moutons, nous avons installé un compilateur SDCC. C'est quoi ? C'est tous simplement une passerelle qui va permettre de créer un fichier binaire plus ou moins lisible avec les processeur de la famille des Z80. Il en existe d'autre mais notre ami DevKitSMS fonctionne avec celui la…

Qu'allons nous faire concrètement. Nous allons écrire notre programme dans un langage de programmation autre que celui de l'assembleur du Z80. Nous allons le faire en C.
Le compilateur va lire les fichier que nous avons  écrire, et vas en gros les transformer en "langage machine" propre  au Z80 puis assembler tous ça et nous créer un nouveau fichier binaire lisible sur une master system  pour notre cas. Cool non ?

Un compilateur c'est ça, transformer notre code source dans un fichier lisible par la machine ciblé.

  Dans le prochain chapitre nous allons compiler notre premier programme test complet pour voir si nous avons bien installé notre outil de développement.
(Vous pouvez quand même cliquez sur le fichier .bat du dossier télécharger, mais le fichier sms ne contient pratiquement rien)  L'heure de vérité approche.

15

Programmer la master system

Chapitre 1 : Introduction et Présentation de la machine

Sega Mark III, la console initiale au japon

La master system est  la dénomination hors du japon d'une console 8 bits de chez Sega. Le nom japonais est la Sega Mark III.  La Master System / Mark III arrive le 20 octobre 1985 au japon, septembre 1985 au USA, début 1987 au royaume unis et Septembre 1987 chez nous !


La Master System


La Master System est une console bien présente sur le marché européen et Brésilienne.
La Master system à connus deux version de la console chez nous. La master System 1 et la Master System II.  La 2nd version de la console corrige un bug d'affichage de sprite et autorise deux autres mode d'affichage, elle se trouve plus compacte que sa grand sœur. Elle perd aussi la possibilité d'utiliser des Sega Cartes, le slot d’extension, et le bouton Reset (Qui est un bouton software pour information).

La Master System II


La Master System possède un jeu en rom incorporé qui dépend des "versions".
(Sonoc, Alex kid, Hang On…)


Alex kid

La Sega Master system possède deux ports  pour brancher une manette de jeu. La manette de jeu standard possède un pad de direction (Haut, Bas, Gauche,Droite) et deux boutons. C'est branché en port DB9. (Alias les fameux port Atari que nous retrouvons sur pas mal de console et beaucoup de micro ordinateur 8/16 bits). Mais il possible de brancher d'autre manette et même de programmer une manette de type Megadrive pour utiliser les 6 boutons.


Une manette de jeu pour la Master system

La Manette ne possède pas comme la NES de bouton Start et Pause. Le bouton Start est associé au bouton 1 et Pause sur la console en elle même. (Ceci dit les développeur du jeu Wonder Boy 3, on eu la bonne idée d'utiliser la 2nd manette pour ajouter la fonctionnalité pause et aller au menu du jeu pour les inventaire évitant de se lever pour appuyer sur le bouton de la console.)


Une boite, la cartouche et le livret d'un jeu Master system

Au niveau des caractéristiques technique de la console :

La Master System est équipe du processeur Zilog Z80 cadencé à 3,54 Mhz en Pal/Secam et 3,57 en NTSC. Le Zilog Z80 est un processeur beaucoup utilisé à cette époque. C'est un proco de la famille des 8bits avec un adressage de la mémoire en 16bits. (Ce qui veux dire que le processeur est capable de lire une adresse mémoire entre  0 et 65535. (Les fameux 64ko…)
Le Z80 équipe des consoles comme la Colecovision, La Game Boy,et Game Gear par exemple. Et des micros ordinateur comme le CPC d'amstrad, les ZX Spectrum, la norme MSX...

La master system est équipe de 8 ko de Ram pour mémoriser les données du programmes volatile. (Mémoriser les variables du jeu).

Pour les données du jeu en lui même, la master system peut lire 48ko en même temps d'une cartouche et possède une fonction pour échanger les 16 derniers ko de la cartouche par une autre zone. (La Bank Switching, ou échange de plage mémoire). Ce qui permet d'avoir des cartouches avec une capacité de stockage supérieur de 48ko.

Au niveau graphismes, la master system est équipe du TMS9918 derived VDP de Texas instruments. Elle possède un espace de 16ko pour la mémoire vidéo, peut afficher en même temps deux palettes de 16 couleurs programmables sur un nuancier de 64 couleurs. (Une palette pour les tiles, et une palette pour les sprites). (Les tiles peuvent aussi prendre la palette des sprites)

La palette aproximative de la master system car il peut y avoir des différences entre émulateur, master system 1, master system 2, mégadrive, et les types de sortie de la console...

La résolution d'affichage standard de la master system est de 256 pixels horizontalement et 192 pixel verticalement.

Il est possible de  cacher 8  pixels sur le coté gauche pour pouvoir réaliser des scrolling latérale, et de passer en 224px sur la hauteur ou 240px pour les versions pal. (A partir de la master system II et Mégadrive)
La mémoire vidéo possède un espace réservé de 14336 octets pour mémoriser les tiles (8px sur 8px). Un tile est codé sur 32 octets ce qui fait que la mémoire vidéo permet de mémoriser en même temps 1792 tiles/sprites de 8px soit 448 tiles de 16px.  (Un chipset de Rpg Maker 2000/2003 c'est 480 tiles de 16px).  Il n'y a pas de contrainte de couleurs sauf la palette bien sur.

La master system peut afficher 64 sprites à l'écran avec une limitation de 8 sprites sur une ligne. (64 pixels dédiés au sprites sur la même ligne maximum). Pour dépasser les  8 sprites, il faut alterner les affichages. (Les fameux clignotement de sprite présent sur les 8bits).

La Master System gère le scrolling dans les 4 directions au niveau hardware, et collision de sprite (Très peux utilisé ça ne detecte pas qui est en collision avec qui)

 Le modèle du processeur sonore de la Master System (PSG pour Paris heu Programmable Sound Generator) est le SN76489 de chez Texas instrument. Il permet de gérer 4 canaux (Sortie Mono malheuresement). 3 générateurs de son sur 4 octaves et 1 générateur de bruits blanc.
 
 "Petite" différence avec "la 2nd version" de la Séga Mark III au japon.  Cette dernière intègre une puce FM pour le son de chez Yamaha ce qui améliore la qualité sonore des jeux qui sont programmé pour utiliser cette puce. (Il y a une 40en de jeu)

Le Chapitre II parlera de l'installation du SDK...

Pages: [1] 2 3 ... 22
Powered by EzPortal