Day.png);">
Apprendre


Vous êtes
nouveau sur
Oniromancie?

Visite guidée
du site


Découvrir
RPG Maker


Apprendre
RPG Maker

Tutoriels
Guides
Making-of

Dans le
Forum

Section Entraide

News: Les actualités de fin d'année / Jeux: Glixel en version complète / Jeux: Izac 1 / News: Des jeux d'hiver sous la couette / Scripts: Système de vol pour RPG Maker (...) / Chat

Bienvenue
visiteur !





Désactiver
la neige


publicité RPG Maker!

Statistiques

Liste des
membres


Contact

Mentions légales

249 connectés actuellement

30835134 visiteurs
depuis l'ouverture

2401 visiteurs
aujourd'hui



Barre de séparation

Partenaires

Indiexpo

Akademiya RPG Maker

Blog Alioune Fall

Fairy Tail Constellations

RPG Maker VX

Lumen

Alex d'Or

Le Comptoir Du clickeur

Tous nos partenaires

Devenir
partenaire



[Master System] Programmer la Master System. Chapitre 4. Décryptage du premier programme

-Décryptage du hello world !

Ecrit par Monos le 16/01/2018


❤ 0

image
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

Portion de code : Tout sélectionner

1
2
3
// 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.

Portion de code : Tout sélectionner

1
2
3
// 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 !

Portion de code : Tout sélectionner

1
2
3
4
5
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.


Portion de code : Tout sélectionner

1
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 phylosophye 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 !

Portion de code : Tout sélectionner

1
2
        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.

Portion de code : Tout sélectionner

1
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.

Portion de code : Tout sélectionner

1
        SMS_displayOn();


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


Portion de code : Tout sélectionner

1
2
3
4
5
6
7
8
9
10
11
12
13
 
        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 (image 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...

Portion de code : Tout sélectionner

1
2
3
4
5
6
 
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é !

Portion de code : Tout sélectionner

1
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

Portion de code : Tout sélectionner

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



Gaetz - posté le 16/01/2018 à 22:59:24 (2394 messages postés)

❤ 0

...passe...

Monos, tu bosses dans l'informatique ? Parce que si c'est pas le cas tu devrais.

Lije : démo 0.5 | Powered by Geex


Monos - posté le 17/01/2018 à 05:18:09 (57322 messages postés)

❤ 0

Vive le homebrew

Désolé Gaetz, j'ai pas changé de métier depuis la dernière fois que tu es venu à la maison, j'ai même un CDI depuis 4 ans dans les vignes !

Citation:

Parce que si c'est pas le cas tu devrais.


Coucou, je veux bosser dans l'informatique mais programmer les vielles machines.
Non merci monsieur, nous sommes sur la switch./ps4/Xboxone avec des langages objets.

Ok merci ! Bon je retourne tailler mes pieds de vigne. :p

Signer du nez ?


winterskill - posté le 17/01/2018 à 13:00:47 (927 messages postés)

❤ 0

Empereur des bons gros meuh

:lol

mais pourquoi un "unsigned char", et pas un "char" tout court? les codes des caractères sont tous positifs non?

"pommes de rainette et pommes d'API, API API Rest-e" | "A combattre sans périls, on triomphe sans gloire" - le cid ; (oui mais on gagne quand même non?...) | à soutenir absolument : https://www.kickstarter.com/projects/1264023666/bushido-the-way-of-men


Monos - posté le 17/01/2018 à 17:50:41 (57322 messages postés)

❤ 0

Vive le homebrew

Citation:


const unsigned char Font_Namco[]={….} ;


Attention, le tableau ce n'est pas le "code" du caractère c'est l’encodage graphique.

Ensuite avec SDCC, les variables sont signés nativement. Donc Char c'est une valeur entre -128 et +127.

La place des variables en passant :
Bool : 1 bit
char : 1 octets
short et int : 2 octets
long : 4 octet
float : 4 octet IEEE754 (je ne sais pas ce que c'est)

pointeur de 1 à 4 octet.

Signer du nez ?


Gaetz - posté le 17/01/2018 à 20:57:00 (2394 messages postés)

❤ 0

...passe...

Il y a beaucoup de gens qui bossent avec des vieilles machines dans l'informatique. Après, pas des machines de jeu, c'est sûr.

En tout cas, je suis admiratif de ta capacité à travailler avec ce genre de code, et si un jour tu veux des conseils pour faire du code ton métier, hésite pas à m'en parler. Quand on vieillit, être devant un ordi au bureau est moins fatigant que bosser aux champs :)

Lije : démo 0.5 | Powered by Geex


Monos - posté le 18/01/2018 à 05:14:46 (57322 messages postés)

❤ 0

Vive le homebrew

Merci.

Citation:

En tout cas, je suis admiratif de ta capacité à travailler avec ce genre de code,


Ba c'est pas compliqué. Quand on a les "fonctions" et que nous savons à quoi sa correspond xd.

Signer du nez ?


Monos - posté le 18/01/2018 à 06:24:06 (57322 messages postés)

❤ 0

Vive le homebrew

Monos a dit:


Citation:


const unsigned char Font_Namco[]={….} ;


Attention, le tableau ce n'est pas le "code" du caractère c'est l’encodage graphique.

Ensuite avec SDCC, les variables sont signés nativement. Donc Char c'est une valeur entre -128 et +127.

La place des variables en passant :
Bool : 1 bit
char : 1 octets
short et int : 2 octets
long : 4 octet
float : 4 octet IEEE754 (je ne sais pas ce que c'est)

pointeur de 1 à 4 octet.



Heu j'avais une vielle version, de SDCC, qui signe automatiquement les char, que les nouvelles versions les char sont non signés.

Signer du nez ?

Suite à de nombreux abus, le post en invités a été désactivé. Veuillez vous inscrire si vous souhaitez participer à la conversation.

Haut de page

Merci de ne pas reproduire le contenu de ce site sans autorisation.
Contacter l'équipe - Mentions légales

Plan du site

Communauté: Accueil | Forum | Chat | Commentaires | News | Flash-news | Screen de la semaine | Sorties | Tests | Gaming-Live | Interviews | Galerie | OST | Blogs | Recherche
Apprendre: Visite guidée | RPG Maker 95 | RPG Maker 2003 | RPG Maker XP | RPG Maker VX | RPG Maker MV | Tutoriels | Guides | Making-of
Télécharger: Programmes | Scripts/Plugins | Ressources graphiques / sonores | Packs de ressources | Midis | Eléments séparés | Sprites
Jeux: Au hasard | Notre sélection | Sélection des membres | Tous les jeux | Jeux complets | Le cimetière | RPG Maker 95 | RPG Maker 2000 | RPG Maker 2003 | RPG Maker XP | RPG Maker VX | RPG Maker VX Ace | RPG Maker MV | Autres | Proposer
Ressources RPG Maker 2000/2003: Chipsets | Charsets | Panoramas | Backdrops | Facesets | Battle anims | Battle charsets | Monstres | Systems | Templates
Ressources RPG Maker XP: Tilesets | Autotiles | Characters | Battlers | Window skins | Icônes | Transitions | Fogs | Templates
Ressources RPG Maker VX: Tilesets | Charsets | Facesets | Systèmes
Ressources RPG Maker MV: Tilesets | Characters | Faces | Systèmes | Title | Battlebacks | Animations | SV/Ennemis
Archives: Palmarès | L'Annuaire | Livre d'or | Le Wiki | Divers