La Place des Développeurs FUSION-C Codez en C pour MSX les doigts dans le nez !
ericb59
Membre non connecté
Conseiller Municipal
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.
ericb59
Membre non connecté
Conseiller Municipal
J'ai vérifié LMMM ne fonctionne que sur la première page de la VRAM
Si tu dois déplacer des éléments graphiques directement de la VRAM à la VRAM entre les pages , il faut utiliser fLMMMM
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
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 !
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 !
Quand j'utilise la commande :
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 !
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 !
ericb59
Membre non connecté
Conseiller Municipal
Correction dans le manuel Ok !
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
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
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 ?
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();
}
}
}
}
ericb59
Membre non connecté
Conseiller Municipal
@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 :
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); }
ericb59
Membre non connecté
Conseiller Municipal
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); }
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.
J'ai un morceau de code désactiver. C'est l'encrypteur.
Le decrypteur semble pas trop mal fonctionner.
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.
ericb59
Membre non connecté
Conseiller Municipal
Merci Monos c'est corrigé.
Bien le RLE, je n'y avait pas pensé.
Pour être plus rapide dans le décodage je ferai une mise à jour avec un module en assembleur.
Bien le RLE, je n'y avait pas pensé.
Pour être plus rapide dans le décodage je ferai une mise à jour avec un module en assembleur.
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie