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.


Messages - Monos

Pages: [1] 2 3 ... 139
1
Citer
Super Pixner est un jeu qui fonctionne avec pas beaucoup d'objet actif par niveau,
Heum dans ma mémoire chaque tiles de 16px c'est une image active. Petite résolution certe  mais il y a de l'active et c'est pas si bien programmé que ça.

Citer
Quand je parlais de RPG, j'ai utilisé ce terme grossièrement, j'avais surtout en tête les RPG style les premiers Final Fantasy qui ont des map assez grande avec pas mal d'actif à gérer, et dont là le problème de puissance risque de se faire sentir sur les plateformes mobile / navigateurs, à contrario des supports PC !
Afficher la map entière c'est une connerie sur tous logiciel de toute façon. Le mieux c'est d'afficher la map visible, et quand tu déplaces ton perso à droite par exemple, tu affiches ta bande à droite hors écran, et tu déplaces ta map à gauche !

Tu ne déplaces pas ton sprites PJ qui reste la ou il est est ! Le tour est joué xd

Et oué de la vrais programmation ou vrais technique de programmation sur Fusion ! Cela facilite la tache dans énormément de truc.

2
Citer
Va essayer de faire un mini-RPG sur téléphone avec Fusion...
Cela fonctionnera à merveille. Pixner fonctionne, je ne vois pas pourquoi un rpg ne fonctionnera pas.

3
Il faut prendre Fusion comme un langage interprété.  La runtime est déjà un programme en lui même qui va juste décoder des "actions" pour en réaliser d'autre. Il n'y a pas de 2nd compilation en binaire xd C'est déja fait.

C'est pour ça que ça peut être "lent".
Par contre quand on exporte sous android, flash, ios... C'est autre chose. La runtime c'est plus vraiment un interpréteur mais une série de script déjà codé. Et fonction pré créer.(Bon ça revient au même mais voila) on  transforme tout ça en fichier de programmation du langage cible, et c'est pour ça qu'il faut "compiler" cette fois avec les logiciels de compilation dédié à la cible pour re faire le fichier binaire lisible sur la machine voulu. Pareil avec le module XNA pour PC on recompile ça pour du X86 avec d'autre couche. mais bon. 

Normalement fusion III sur PC sa devrait être du native à ce que j'ai compris.

4

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

5
Enfin c'est pas tout à fait photoshopt, c'est importer des ressources, il arrive je le poste la pour toi

6
Vos créations / Re : Programmer la Master System. On passe au code
« le: 19 janvier 2018 à 17:52:33 »
 SMS_setBGPaletteColor(1, RGB(255,0,0)); // J'ai un warning 158 et ça m'affiche le carré
RGB c'est encodé si je ne dis pas de bétise de 0 à 3.  (Ce qui fait 4 Rouge, 4 Vert,4 Bleu donc
4*4*4  = 64 teintes le compte est bon.
RGB8 que tu dois utiliser je pense pour trouver la couleur approximative en utilisant une valeur entre 0 et 256. (1 octet  par composante)

 


7
Vos créations / Re : Programmer la Master System. On passe au code
« le: 19 janvier 2018 à 17:38:51 »
La vache xd, si tu places directement 3 ça doit donner rouge ? Je corrige ça.

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
La Taverne / Re : Programmer les consoles rétro.
« le: 18 janvier 2018 à 20:03:53 »
Nom du jeu : Sokoban pour la game Jam 2018 n
Support : Séga Master System
Programmeur : Jean Monos
Graphismes : Jean Monos
Musique et son : Jean Monos.
Moteur : DevkitSMS
Type : Petit Puzzle.
Lien :Lien sur itch.io


Yopla voici un Sokoban sur Sega Master pour la Game Jam de chez Gamecodeur. Enfin je dois être hors concours mais pas grave.



Lien

Le jeu est un proto qui marche sur Master System de chez Sega. Les sources sont dedans.
Codé en C.
Il y a 9 niveaux.

C'est sans  grande prétention mais ça ma permis de voir un peu le DevkitSMS qui est fort sympathique.
Voilou bon test.

10
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

11
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).

12

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 !

13
Vos créations / Re : Chapitre 4 : Décryptage du premier programme
« le: 16 janvier 2018 à 17:37:40 »
Merci ça me fais plaisir. C'est un peu le but ! A vrais dire j'explique comme si j'aimerais qu'on m'explique les choses.  Ce n'est pas du "c" académique mais osef.
Citer
michel louvet
Maitre Louvet xd Oui, il explique bien.  C'est grace à lui que j'ai compris un peu le compilateur C du Z80 quand il a fait ses vidéos sur le CPC. Cela à débloqué le bouzin.

14
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 !

15

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

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