vendredi 30 novembre 2012

Revival Chase

Ca y est, le site de Revival étant à jour, je peux en parler !! Dans le cadre du n° 50 de Revival, j'ai participé au "bonus" de ce n° à savoir un jeu PCEngine CD-ROM. Mais pour plus de détail voici tout d'abord le teaser de ce Revival 50 :


Ainsi qu'une fiche un peu plus détaillée du jeu à cette adresse : Revival Chase.

Pour encore plus de détail, un making-of croustillant, une seule solution, précommandez votre n° de Revival n° 50 !!!! :) :)

No News ... Good News ?

Un petit post pour dire que je n'ai pas abandonné les tutos MSX. Il y en à 2 autres à paraitre mais ils seront publiés quand j'aurais déménagé les précédents sur bfg-le-site.fr.

Je n'ai par contre, toujours pas trouvé comment adresser en C, les 32 ko octets de ROM possible, je suis toujours limité à 16ko, ce qui fait qu'il m'est impossible, pour le moment, de porter les jeux Coleco sur MSX. Dommage, car à part ce soucis, la conversion des jeux est possible à 100% avec excessivement peu de modifications ...

Et au passage, dans les jours qui arrivent attendez vous à une grosse annonce :)

Restez à l'écoute !! ;)

jeudi 22 novembre 2012

QuizWiz

J'ai découvert grace à allgamers, que CollectorVision distribuait la rom QuizWiz que j'avais commencé à développer. Il semblerait que si vous avez bon aux 30 questions, que vous pouvez gagner un cadeau ici  ...

Par contre il vend la chose en cartouche pour 30$ ... Soyons clair (mais il le précise dans son post), cette rom n'est pas terminée, c'est de l'alpha version, sans son, sans musique, sans animation, rien que 30 questions. Quand je vois sur le forum AtariAge des gens qui la commande en disant que ça à l'air d'être super cool, je crois que je vais commencer à développer des Pong au lieu de tenter de faire des bons trucs, car on à les mêmes encouragements dans tout les cas :) :) Sérieusement, n'achetez pas ce truc, c'est ridicule.

Sinon, la rom est disponible à cette adresse : http://bfg-le-site.fr/tele_quizz.html

mercredi 7 novembre 2012

Création de jeux sous MSX : Affichage de sprites.





Je vous sentais pressé d'afficher quelque chose sur l'écran ... héhéhéhé. Et bien, affichons des sprites !

Implémentation :

Pour rappel , un sprite est une image qui possède une transparence et qui peut être déplacée dans l'écran.
Nous allons, pour faire apparaitre ces sprites, implémenter les fonctions suivantes :

void setup_sprites(char spritesize, char zoom); : Va initialiser le type de sprite que l'on veut : de taille 8*8 ou 16*16, zoomé ou non ...

Hé oui, nous avons quasiment déja tout ce qu'il faut pour afficher des sprites !! Etonnant non ?!

Ouvrez le fichier video.c et ajouter la méthode suivante :


/* Définit les attribut général des sprites */
/* spritesize : SPRITE8X8
                SPRITE16X16
   zoom :       SPRITE_NO_ZOOM
                SPRITE_ZOOM    1            */
/**/
void setup_sprites(char spritesize, char zoom){
  __asm
 
  ld b,#0x00
  ld a,4(ix)
  and #0x0f
  cp #0x08
  jr z,$1
  set 1,b ; --- si 16x16 allume bit 1
$1:
  ld a,5(ix)
  cp #0x00
  jr z, $2
  set 0,b ; --- si sprite zoomé => allume bit 0
$2:
  ld hl,#0xf3e0 ;
  ld a,(hl)
  and #0xfc
  or b
  ld (hl),a
  call 0x007e ; --- Change le registre
 
  ld a,#0x01
  ld hl,#0xfcaf
  ld (hl),a
  call 0x0069 ; --- reset la table des attributs de sprites

  __endasm;
}


Alors sans entrer dans les détails, on va mettre certains bit de registre vidéo à 1 ou à 0 pour dire que les sprites font 8*8 ou 16*16 ou si ils sont zoomé ou non.

On modifie le video.h ainsi :

#ifndef ___MSXVIDEO_H___
#define ___MSXVIDEO_H___

#define SPRITE8X8      8
#define SPRITE16X16   32

#define SPRITE_NO_ZOOM 0
#define SPRITE_ZOOM    1

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

#endif


Et on le compile avec :

sdcc -mz80 -c video.c

Les sprites : la théorie

Les sprites sur Coleco/Msx, c'est 2 zone mémoires.

 1 Zone mémoire image, qui va contenir toute les représentations des sprites. Le début de l'adresse de cette zone est à peek_word(0xF3CF)
 1 Zone mémoire attribut qui va contenir pour chaque sprite : sa position x,sa position y,le n° de son image,sa couleur (0 à 15). Le début de l'adresse de cette zone est à peek_word(0xF3CD).

 Comme vous pouvez de suite le voir, un sprite = 1 seule couleur.

Les sprites : la pratique

Pour affiche un sprite à l'écran, on va donc les initialiser. Ici on va utiliser le cas le plus complexe, les sprites de 16*16. On décidera de ne pas zoomer.

setup_sprites(SPRITE16X16, SPRITE_NO_ZOOM);

Pourquoi le plus compliqué ? Pour calculer le n° d'image d'un sprite de 8*8 pixels c'est simple, si on veut l'image 0, c'est 0, si on veut l'image 1, c'est 1 ...
Un sprite de 16*16 est composé de 4 images de 8*8. Et donc le début de l'image 0 = 0, le début de l'image 1 = 1*4 = 4 et le début de l'image 2 = 2*4 etc etc ...

Dans ce tutorial, je vais vous donner le code de 3 images, un carré, un triangle et un rond. On apprendra à créer ces images dans un autre tutorial, à la main, et avec des utilitaires qui vont bien :)

// Size = 3 sprites * 4 caractères
//      = 3 sprites * (4*8) octets = 96 octets
//
// pattern de début Carré = image 0 * 4 = 0
// pattern de début Triangle = image 1 * 4 = 4
// pattern de début Rond = image 2 * 4 = 8
const unsigned char SPATTERN[] = {
  0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00,    // Carré
  0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,   // Triangle
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Rond
  0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


 Voilà, on va maintenant charger ces images de sprites à l'adresse mémoire des images de sprites :)

 int addr_sprite_pattern;

 addr_sprite_pattern = peek_word(0xF3CF);

 put_vram(SPATTERN,addr_sprite_pattern,96);


 Charger les images ne suffit pas ... Il faut pour afficher des sprites leur définir une image,une couleur et une position. (A savoir qu'une position de 204 en y par exemple positionne le sprite en dehors de l'écran et le rend donc invisible). ATTENTION, si par exemple le sprite 2 à une position y de 208, les sprites après le sprite 2 ne seront pas affiché !! La valeur 208 est une valeur spéciale.

 On sa créer une structure en C, et un tableau de 32 "sprites".

 typedef struct
{
 unsigned char y;
 unsigned char x;
 unsigned char pattern;
 unsigned char colour;
} sprite_t;

sprite_t sprites[32];


Et maintenant on va définir nos sprites en mémoire RAM :

// Carré
sprites[0].x=10;
sprites[0].y=10;
sprites[0].pattern=0; // Image 0*4
sprites[0].colour=2;
// Triangle
sprites[1].x=42;
sprites[1].y=42;
sprites[1].pattern=4; // Image 1*4
sprites[1].colour=3;
// Rond
sprites[2].x=42+32;
sprites[2].y=42+32;
sprites[2].pattern=8; // Image 2*4
sprites[2].colour=4;


Mais cela ne suffit pas ... Il faut maintenant copier cette table d'attribut en VRAM pour activer l'affichage.

addr_sprite_attr = peek_word(0xF3CD);
put_vram(sprites,addr_sprite_attr,4*32);


Compilez avec :

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

et

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

Voici le code source complet pour ceux qui sont un peu perdu :

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

// Size = 3 sprites * 4 caractères
//      = 3 sprites * (4*8) octets = 96 octets
//
// pattern de début Carré = image 0 * 4 = 0
// pattern de début Triangle = image 1 * 4 = 4
// pattern de début Rond = image 2 * 4 = 8
const unsigned char SPATTERN[] = {
  0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00,    // Carré
  0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,   // Triangle
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // Rond
  0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

typedef struct
{
  char y;
  char x;
  char pattern;
  char colour;
} sprite_t;

sprite_t bsprites[32];

void main(void)
{
    int addr_sprite_pattern;
    int addr_sprite_attr;   
   
    screen_mode_2();
    setup_sprites(SPRITE16X16, SPRITE_NO_ZOOM);
   
    addr_sprite_pattern = peek_word(0xF3CF);
    put_vram(SPATTERN,addr_sprite_pattern,96);
       
    // Carré
    bsprites[0].x=10;
    bsprites[0].y=10;
    bsprites[0].pattern=0; // Image 0*4
    bsprites[0].colour=2;
    // Triangle
    bsprites[1].x=60;
    bsprites[1].y=60;
    bsprites[1].pattern=4; // Image 1*4
    bsprites[1].colour=2;
    // Rond
    bsprites[2].x=42+32;
    bsprites[2].y=42+32;
    bsprites[2].pattern=8; // Image 2*4
    bsprites[2].colour=2;

    addr_sprite_attr = peek_word(0xF3CD);
    put_vram(bsprites,addr_sprite_attr,4*32);

   
    while(1){};
}


Lancez la rom dans un émulateur et ... admirez !!!!

Dans le prochain tuto, on va faire bouger tout ça... A la manette !!

mardi 6 novembre 2012

Pang Coleco en version RC2.0


C'est en se mouchant qu'on devient moucheron, c'est en codant, qu'on s'améliore :)

Fort de ma nouvelle expérience sur un jeu qui sera dévoilé certainement en Décembre, j'ai réussit à éliminer 99% des ralentissements sur la version Colecovision de Pang et ce en ... 5 lignes de codes !!!

La rom partait chez le fabricant en fin de semaine, et je viens de modifier, tester et envoyer la RC2.0, version optimisée de Pang sur Colecovision à CollectorVision !! Juste à temps.

Si seulement les patchs existaient sur cartouche, j'aurais pu utiliser la même technique sur Ozma Wars Coleco, hélas, à l'époque je ramait encore sur la machine ...

Il y à bien entendu encore des ralentissements en particulier sur le niveau en entête de ce message, mais ces ralentissement ne surviennent que dans un cas très particulier, qui je pense n'est même pas possible sans utiliser un cheat qui transformerait les 2 grosses balles directement en toutes petites. (Ce que j'utilise pour mon "stress" test :) ). En gros, quelqu'un qui joue normalement, ne devrait plus ressentir de ralentissements ! (En toute cas dans les 2 heures que je viens de passer à jouer, je n'ai rien ressentit de tel.)