MSX Village forum

La Place des Développeurs FUSION-C Codez en C pour MSX les doigts dans le nez !

ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 17/02/2019 à 22h43

Reprise du message précédent

Je ne me souviens plus très bien, car j'ai surtout travaillé avec FLMMM.
Il me semble me souvenir que LMMM ne fonctionne que sur la Page VRAM Active. DOnc pas pour aller copier un élément graphique d'une autre page.
Je vérifie dans le code source demain, mais ça doit être ça.



banniere-ericb59e
Site web    
Monos Membre non connecté

Touriste

Rang

Avatar

Inscrit le : 28/09/2018 à 17h10

Messages: 101

Le 18/02/2019 à 05h08
J'avais fait des tests sur la page 0, c'est pareil ça n'avais pas fonctionné. Edité par Monos Le 18/02/2019 à 07h20


Il faut donner à manger à nos machines !
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 18/02/2019 à 07h38
J'ai vérifié LMMM ne fonctionne que sur la première page de la VRAM

Code C :
 
#include "fusion-c/header/VDP_graph2.h"
#include "fusion-c/header/msx_fusion.h"
 
 
/* ---------------------------------
               MAIN
-----------------------------------*/
void main(void)
{ 
    int x;
 
    Screen(8);
 
    Rect(10,10,80,80,16,FILL_ALL);       // Dessine un rectangle (10,10)-(80,80) en rouge
 
    LMMM( 10, 10, 80, 80, 10, 100, 0 );  // Copie le rectangle en (10,100)
 
    LMMM( 10, 10, 80, 80, 100, 10, 0 );  // Copie le rectangle en (100,10)
 
    WaitForKey();
 
 
    Screen(0);
    Exit(0);
}
 


Si tu dois déplacer des éléments graphiques directement de la VRAM à la VRAM entre les pages , il faut utiliser fLMMMM


banniere-ericb59e
Site web    
Monos Membre non connecté

Touriste

Rang

Avatar

Inscrit le : 28/09/2018 à 17h10

Messages: 101

Le 20/02/2019 à 06h20
Deux petits truc que nous avons remarqués hier soir avec un ami.

Les tableaux qui représente des "datas", bien les passer en CONSTANTE quand ce n'est pas dans le "main". SDCC n'aime pas ça. J'ai toujours eu l'habitude de ça mais pas mon ami qui a été bloqué avec ça xd. (Pour moi c'est une évidence mais pour certain qui utilise d'autre compilateur)

Deuxième point non testé en vrais machine ! Votre main, ne faite pas void main() mais int main() donc avec un return.
La vitesse du programme change ! Je pense que SDCC veux un int main et non un void !


Il faut donner à manger à nos machines !
Monos Membre non connecté

Touriste

Rang

Avatar

Inscrit le : 28/09/2018 à 17h10

Messages: 101

Le 20/02/2019 à 07h10
Quand j'utilise la commande :

Code :
Create("Test.bin");

Le fichier et bien créez (après avoir déclarer la structure édéquate) mais il ne me redonne plus la mains comme si cela se bloque.
En retirant cette fonction, j'arrive par contre avec Open, Write, Close... à écrire dans mon fichier binaire.
Page 89, tu as marqué open avec un o minuscule au début !


Il faut donner à manger à nos machines !
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 20/02/2019 à 07h45
Correction dans le manuel Ok !

Code C :
 
 
#include "fusion-c/header/io.h"
#include "fusion-c/header/msx_fusion.h"
 
/* ---------------------------------
               MAIN
-----------------------------------*/
void main(void)
{ 
     FCBlist *FCB = FCBs();   // Mandatory !
     int fh;
 
     char buffer[12]="Hello Guys!";
 
    fh = Create( "__TEST.TXT" );
 
    Write( fh, buffer, 12 );
 
    Close(fh);
 
    Exit(0);
}
 



pas de souci particulier détecté.

Pour les fichiers il y a un doublon de fonctions.
les fonctions du MSX-DOS qui commencent par "fcb_"

Et celle qui se trouve dans IO.H
Les deux sont censées faire la même chose... Je me suis interrogé si je devrais intégrer les 2 ou pas ....
Moi je préfère utiliser les routines fcb. Edité par ericb59 Le 20/02/2019 à 07h51


banniere-ericb59e
Site web    
Monos Membre non connecté

Touriste

Rang

Avatar

Inscrit le : 28/09/2018 à 17h10

Messages: 101

Le 23/02/2019 à 07h55
Re eric,
je me casse les dents sur le ayfx !

Alors j'intègre bien le fichier h
Je fais bien le MMalloc du nombre d'octet du fichier sur afbdata (d'ailleurs ça peut être cool d'ajouter ça dans la doc que c'est sur afbdata )

afbdata=MMalloc(152);

j'init bien le psg et le fx comme l'exemple
je charche bien le fichier fxdata.afb dans mon exemple.

j'utilise bien PlayFX(1); pour lancer le son 1 et UpdateFX(); a la fin de la boucle.
J'ai même utilisé comme toi le testFX et Jiffy xd

Mais le son du logiciel n'est pas le même dans le msx.
j'ai testé avec un son pré fabriqué c'est pareil.
J'ai loupir un truc ?

Code :
/*******************************************************
* Nom ......... : title_screen.c
* Role ........ : Gestion de l'écran titre et option
********************************************************/

// =====================
// ** Fichier include **
// =====================
#include "header/game.h"
#include "header/ayfx_player.h"
#include "header/io.h"

// * Define de placement de texte *
#define CADRE_X 0
#define CADRE_Y 120-8


#define OPTION_PY CADRE_Y+8

#define TP1_PX CADRE_X+8
#define TP1_PY CADRE_Y+24

#define TP2_PX TP1_PY 
#define TP2_PY TP1_PY+8


extern s_player player[2];


// ============================
// ** Procedure Title screen **
// ============================
void title_screen()
{
    static unsigned char c1=0; // Paramètrage des commandes du joueur 1
    static unsigned char c2=1; // Paramètrage des commandes du joueur 2
    unsigned int id_files = 0;
    FCBlist *FCB = FCBs();
    afbdata=MMalloc(152); 
  SpriteOff();

    // ==================================
    // * Chargement du fichier sound fx *
    // ==================================
 id_files=Open("fxdata.afb",O_RDWR);
    Read(id_files,afbdata,152);
    Close(id_files);
        InitPSG();
  InitFX();
    
    
    Cls();
    PutText(60, 0 ,"PRISONNIER III");

    create_windows(CADRE_X,CADRE_Y,32,8,0);
    

    PutText(CADRE_X+80, OPTION_PY,"GAME OPTION");     
    PutText(CADRE_X+8, CADRE_Y+40,"(3) Credit");
    PutText(CADRE_X+8, CADRE_Y+48,"(Space) Start the Game");
    
    PutText(160,192-8,"Offgame 2019");
    PutText(0,192-8,"V D0.0.1");
    

    
    
    ShowDisplay();
    // -----------------------------------
    // * Boucle de la scene Title Screen *
    // ------------------------------------
    while(scene_get() == SCENE_TITLE_SCREEN)
    {
        
    

    
    
        
        // ============
        // * Player 1 *
        // ============
        
        switch(c1)
        {
            case 0:
                PutText(CADRE_X+8, CADRE_Y+24,"(1)Player 1 :...Keyboard");
            break;
        
            case 1:
                PutText(CADRE_X+8, CADRE_Y+24,"(1)Player 1 :.....Port 1");
            break;
        
            case 2:
                PutText(CADRE_X+8, CADRE_Y+24,"(1)Player 1 :.....Port 2");
            break;
            
            case 3:
                PutText(CADRE_X+8, CADRE_Y+24,"(1)Player 1 :...Computer");
            break;
        }
        
        // ============
        // * Player 2 *
        // ============
        switch(c2)
        {
            case 0:
                PutText(CADRE_X+8, CADRE_Y+32,"(2)Player 2 :...Keyboard");
            break;
        
            case 1:
                PutText(CADRE_X+8, CADRE_Y+32,"(2)Player 2 :.....Port 1");
            break;
        
            case 2:
                PutText(CADRE_X+8, CADRE_Y+32,"(2)Player 2 :.....Port 2");
            break;
            
            case 3:
                PutText(CADRE_X+8, CADRE_Y+32,"(2)Player 2 :...Computer");
            break;
        }
        
        
        
        
      // ======================
            // * Gestion du clavier * 
            // ======================
            switch(Inkey())
            {
                        
                // ---------------------
                // * Touche (1) ou (&) *
                // ---------------------
                
                case (49):
                    case (38):
                    c1++;
                     PlayFX(1);
                    
    
                break;
                
            
                //     c1++;
            //     break;
                
                // ---------------------
                // * Touche (2) ou (é) *
                // ---------------------
                case (50):                    
                case (130):
                    c2++;
                     PlayFX(1);
                break;
            
              // ---------------------
                // * Touche (3) ou (") *
                // ---------------------
                case (51):                    
                case (34):
                 
                    scene_set( SCENE_CREDIT);
                break;
            }        
            // ===================================
            // * Test de dépassement de c1 et c2 *
            // ===================================
            if (c1>3)
            {
                c1=0;
            }
            
            if (c2>3)
            {
                c2=0;
            }
            
        
          // ==========================
      // * Lancement de la partie *            
            // ==========================
            if (TriggerRead(0)==255)
          {    
                player[0].id_controle = c1;
                player[1].id_controle = c2;
            scene_set( SCENE_GAME);
        }
            
            
             if (TestFX()==1)
 {
      if (JIFFY!=0)
      {
       JIFFY=0;
        UpdateFX();
      }
  }
            
            
            }
    
    
    
    
}







Il faut donner à manger à nos machines !
Anata Membre non connecté

Vagabond

Rang

Avatar

Inscrit le : 19/02/2019 à 01h38

Messages: 4

Le 23/02/2019 à 17h31
ericb59 : comment fais tu pour creer une palette a l'aide de la struct Palette pour le Screen 5 ?

J'ai beau essayé pas mal de chose, j'arrive a rien ^^
   
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 23/02/2019 à 19h46
@Anata : Alors, il y a une erreur dans la doc, car les structures nécessaires sont déjà déclarées.

Il faut faire comme ceci :
Code C :
 
#include "fusion-c/header/msx_fusion.h"
#include "fusion-c/header/vdp_graph2.h"
 
 
void main(void)
{ 
    int i,x,y;
 
    char mypalette[] = 
    {
        0, 0,0,0,
        1, 2,1,1,
        2, 6,5,4,
        3, 5,4,3,
        4, 5,5,3,
        5, 6,5,3,
        6, 7,6,4,
        7, 3,2,1,
        8, 7,5,2,
        9, 6,4,2,
        10, 4,3,2,
        11, 6,0,1,
        12, 5,3,2,
        13, 3,3,2,
        14, 3,1,0,
        15, 6,6,6
    };
 
    Screen(5);
    SetColors(0,0,0);
    SetSC5Palette((Palette *)mypalette);
 
    x=10;
    y=10;
 
    for ( i = 0; i < 16; ++i)
    {
        Rect( x*i, 100, x*i+15, 140, i, FILL_ALL);
    }
 
WaitForKey();
Screen(0);
Exit(0);
 
}
 
 


banniere-ericb59e
Site web    
Anata Membre non connecté

Vagabond

Rang

Avatar

Inscrit le : 19/02/2019 à 01h38

Messages: 4

Le 23/02/2019 à 22h57
Nickel, merci bien
   
Anata Membre non connecté

Vagabond

Rang

Avatar

Inscrit le : 19/02/2019 à 01h38

Messages: 4

Le 26/02/2019 à 12h20
Pour le screen 5 , aurais tu par hasard des fonctions pour charger les fichier SC5 suivant la page , comme pour le SC8 ?
   
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 26/02/2019 à 15h50
Anata :
Pour le screen 5 , aurais tu par hasard des fonctions pour charger les fichier SC5 suivant la page , comme pour le SC8 ?


Tu veux dire pour charger des images ?

C'est le même principe sauf qu'en screen 5, un octet lu, est équivalent à la couleur de 2 pixels contigus...

Alors j'ai fait cet example qui n'est pas très rapide... Sans doute quelqu'un pourrait optimiser Lecture dans le fichier et écriture en VRAM pour 2 pixels ?

Fichier Image : mona.SC5.zip


Code C :
 
#include "fusion-c/header/msx_fusion.h"
#include "fusion-c/header/vdp_graph2.h"
#include <string.h>
 
static FCB file;
 
 
unsigned char LDbuffer[2200];
 
 void FT_SetName( FCB *p_fcb, const char *p_name ) 
{
  char i, j;
  memset( p_fcb, 0, sizeof(FCB) );
  for( i = 0; i < 11; i++ ) {
    p_fcb->name[i] = ' ';
  }
  for( i = 0; (i < 8) && (p_name[i] != 0) && (p_name[i] != '.'); i++ ) {
    p_fcb->name[i] =  p_name[i];
  }
  if( p_name[i] == '.' ) {
    i++;
    for( j = 0; (j < 3) && (p_name[i + j] != 0) && (p_name[i + j] != '.'); j++ ) {
      p_fcb->ext[j] =  p_name[i + j] ;
    }
  }
}
 
void FT_errorHandler(char n, char *name)
{
  InitPSG();
  Screen(0);
  SetColors(15,6,6);
  switch (n)
  {
      case 1:
          Print("\n\rFAILED: fcb_open(): ");
          Print(name);
      break;
 
      case 2:
          Print("\n\rFAILED: fcb_close():");
          Print(name);
      break;  
 
      case 3:
          Print("\n\rStop Kidding, run me on MSX2 !");
      break; 
  }
Exit(0);
}
 
void FT_SC5Data( char *buffer, int y, int nbl)
{
    int i,s;
 
        s=0;
        for ( i = 0; i < nbl*128; ++i)
        {
            Vpoke(y*128+s,buffer[i]);
            s=s+1;
 
        }
}
 
int FT_LoadSc5Image(char *file_name, unsigned int start_Y, char *buffer)
    {
        int rd=2304;
        int nbl=0;
        InitPSG();
        FT_SetName( &file, file_name );
        if(fcb_open( &file ) != FCB_SUCCESS) 
        {
          FT_errorHandler(1, file_name);
          return (0);
        }
        fcb_read( &file, buffer, 7 );  // Skip 7 first bytes of the file
        while(rd!=0)
        {
 
            rd = fcb_read( &file, buffer, 2176 );
                if (rd!=0)
                {
 
                  nbl=rd/128;
                  //HMMC(buffer, 0,start_Y,256,nbl ); // Move the buffer to VRAM. 17 lines x 256 pixels  from memory
                  FT_SC5Data( buffer, start_Y, nbl);
                  start_Y=start_Y+nbl; 
              }
        }
      if( fcb_close( &file ) != FCB_SUCCESS ) 
      {
         FT_errorHandler(2, file_name);
          return (0);
      }
 
return(1);
}
 
 
void main(void)
{ 
    char a,l,r;
    int i;
    char mypalette[] = {
    0, 0,0,0,
    1, 2,1,1,
    2, 6,5,4,
    3, 5,4,3,
    4, 5,5,3,
    5, 6,5,3,
    6, 7,6,4,
    7, 3,2,1,
    8, 7,5,2,
    9, 6,4,2,
    10, 4,3,2,
    11, 4,3,1,
    12, 5,3,2,
    13, 3,3,2,
    14, 3,1,0,
    15, 5,2,0
    };
 
    Screen(5);
    SetColors(15,0,0);    
 
    FT_LoadSc5Image("mona.sc5",0,LDbuffer);
 
    SetSC5Palette((Palette *)mypalette);
 
 
    WaitForKey();
    Screen(0);
    Exit(0);
 
}
 
 


banniere-ericb59e
Site web    
Monos Membre non connecté

Touriste

Rang

Avatar

Inscrit le : 28/09/2018 à 17h10

Messages: 101

Le 03/03/2019 à 09h05
J'ai retrouvé une coquille sur le livre que j'ai. (Je ne sais plus si j'ai déja dit ou pas désolé)
Page 65.
Vpoke.
Il manque une partie de la fonction pour connaitre le data à envoyer à l'adresse.


Il faut donner à manger à nos machines !
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 03/03/2019 à 16h57
@Monos : Exact je viens de corriger. Merci ;)


banniere-ericb59e
Site web    
Monos Membre non connecté

Touriste

Rang

Avatar

Inscrit le : 28/09/2018 à 17h10

Messages: 101

Le 03/03/2019 à 18h21
Page 90, write, dernière ligne qui doit être un copier coller du read , la fonction juste au dessus.
Je supose que c'est write au lieu de read.

Il me semblais qu'il y avait une fonction pour ajouter une valeur binaire à la suite des autres d'un fichier; J'ai pas trouvé ça tout à l'heure.

Sinon ce matin j'ai travaillé sur une fonction pour passer en VRAM une compression RLE.

Code :

/*************************************************************
    rle_write_vram
    
    Décompression du buffer et mémorisation en Vram de la page.
===============================================================
    Versions du 3 fevrier 2019
===============================================================
**************************************************************/

// ===================
// * Fichier Include *
// ===================
#include "header/msx_fusion.h"

// ==========
// * Define *
// ==========
#define ADR_VRAM 0x0000

// ============================
// * Signature de la fonction *
// ============================

/*
        *buffer     : Pointeur sur le tableau de donné crompressé
        size        : Taille en octet du tableau
        position_x  : Départ en Position X de la page à copier les donnés.
        position_y  : départ en Position Y de la page à copier les donnés.
        page_number : Numéros de la page (0-1)
*/

void rle_write_vram_sc8 (unsigned char *buffer,signed int size,unsigned char position_x, unsigned char position_y, unsigned char page_number);


// =================
// * Donnée divers *
// =================
/* Simuation de RLE ! */
const unsigned char test[]={
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
255,255,
    
};

/*
void rle_load_vram_sc8(unsigned char *buffer,signed int size,unsigned char position_x, unsigned char position_y, unsigned char page_number)
{
    unsigned char compteur = 1;
    unsigned char octet = 0;
    unsigned char octet_temps = 0;
    unsigned char i;
    unsigned char index;
    // --------------------
    // * Page Destination *
    // --------------------
    SetActivePage(page_source); 
    
    // ========================================
    // * Adresse de départ en fonction X et Y *
    // ========================================
    VpeekFirst(ADR_VRAM+((position_y<<8)+position_x)); 
    
    
    // Premier octet
    octet = VpeekNext();
    
    // Boucle 
    
    for (i=1;i<size;i++)
    {
        octet_temps = VpeekNext();
        if (octet_temps!= octet)
        {
            
            buffer[index] = compteur;
            buffer[index+1] = octet;
            index = index +2;
            
            octet = octet_temps ;
            compteur = 1;
        }
        
        else if (octet_temps == octet)
        {            
            compteur ++;
        }
    }
    
    
    // Lire le premier octet.
    // Le placer dans une variable temporaire
    // Acrémenter un compteur
    
    // Lire le nouveau octet.
    
    // Si le nouveau octets est identique, acrémenter le compteur
    // Sinon : mémoriser le compteur dans un tableau, mémoriser le variable temp dans le tableau+1, mémoriser dans la variable temporaire l'octet, passer le compteur à 1
    
    
    
    
}

*/


// ===========================
// * Fonction rle_write_vram *
// ===========================
void rle_write_vram_sc8 (unsigned char *buffer,signed int size,unsigned char position_x, unsigned char position_y, unsigned char page_number)
{
    // -------------------------------------
    // * Déclaration des variables locales *
    // -------------------------------------
    unsigned int index=0; // index du tableau buffer qui contient les donnés compressés.
    unsigned char nb; // Nombre de fois que l'octet N+1 sera dupliqué en Vram
    unsigned char i,j; // Variable de la boucle de décryptage.
    unsigned int boucle; // Nombre de tour à faire ! 
    unsigned char octet_copy; // Valeur de l'octet à copier en VRAM !
    
    // --------------------
    // * Page Destination *
    // --------------------
    SetActivePage(page_number); 
    
    // -------------------------------------------------------------------------------
    // * Calcule de l'adresse de départ en fonction de la position X et Y de la page *
    // -------------------------------------------------------------------------------
    VpokeFirst(ADR_VRAM+((position_y<<8)+position_x)); 

    // ------------------------------------------------------
    // * Calcule du nombre de boucle à effectuer (size / 2) *
    // ------------------------------------------------------
    boucle = size >> 1 ; 
    
    // -----------------------
    // * Boucle de travaille *
    // -----------------------
    for (j=0;j<boucle;j++)
    {    
        nb = buffer[index]; // Récupérer le nombre de fois que l'octet va se dupliquer.
        octet_copy = buffer[(index+1)] ; // Mise en mémoire de l'octet à coller en vram
        for (i = 0 ; i<nb ; i++)
        {
             VpokeNext(octet_copy); // Duplication de l'octet et incrémentation de l'adresse vram        
        }
    
        index = index + 2 ; // Passage au décryptage des deux octets suivants.
                
    }
    

}

// ==========================
// * Main exemple de l'algo *
// ==========================
void main()
{
                Screen(8); 
                VDP50Hz(); 
                Cls();
                rle_write_vram_sc8 (test,32,0,64,0);
                
                while(1){}
    
    
}


J'ai un morceau de code désactiver. C'est l'encrypteur.
Le decrypteur semble pas trop mal fonctionner.


Il faut donner à manger à nos machines !
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 04/03/2019 à 18h21
Merci Monos c'est corrigé.

Bien le RLE, je n'y avait pas pensé. :tchin
Pour être plus rapide dans le décodage je ferai une mise à jour avec un module en assembleur.


banniere-ericb59e
Site web    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie