1

Je viens de tester avec mes sprites à moi... Je sens que ça va m'énerver. Ça marche très bien, et très vite (aussi vite qu'en RAM ?), merci Fafa pour le tuto, mais :

1) on est toujours obligé d'allouer un buffer pour la réception ROM->RAM de taille 1024 ? A moins de se servir de ce buffer pour tous les chargements... ?
2) pas possible d'avoir plus de 16 "objets" en ROM ? Lynxer.ttp me plante en beauté sous MagiC si j'inclus plus de 16 (environ ?) fichiers externes -> va falloir que je le recode en GFA, pour que ça soit plus rapide et pas buggé.
3) si j'ai bien pigé... le FileStartBlock étant sur 1 octet -> 256 valeurs -> x1024 : on ne peut pas adresser des cartouches de 512 Ko alors ?

J'ai 125 sprites à stocker (et ya pas encore les décors), la plupart font 250 octets, bonjour le gaspi avec le callage à 1024... à moins que je puisse accéder à un OLB ou lieu d'une multitude de SPR dans la ROM ? ou faire un savant calcul pour accoler sans tenir compte de l'alignement de 1024 ?

Sinon, un petit peu de GFA, pour recoder MAKE_LNX... en LYX2LNX. Avant, ça prenait 3 minutes pour avoir le LNX, et maintenant 3 secondes... Sur Atari ST... Paske ça serait trop facile avec un PC tongue

2

1) tu peux en effet réutiliser le même buffer de lecture, rien ne s'y oppose
2) à vrai dire, je ne sais pas... Lynxer.ttp, c'est un soft flacon je suppose ?
3) les cartouches de grande taille, y'a une "bidouille" parce que le bit d'adresse "fort" est en fait un signal "audio in" (qui est digital et non analogique)

Pour tes sprites, tu peux envisagerle mode compact si la place est vraiment un problème. D'autre part le groupement n'est pas un problème, dans la rom, tu stocke ce que tu veux sous la forme que tu veux sachant qu'il y a une contrainte à la lecture et que l'écriture du LNX peut s'avérer un peu tordue.
avatar
Webmaster du site Ti-FRv3 (et aussi de DevLynx)
Si moins de monde enculait le système, alors celui ci aurait plus de mal à nous sortir de si grosses merdes !
"L'erreur humaine est humaine"©Nil (2006) // topics/6238-moved-jamais-jaurais-pense-faire-ca

3

Oki, merci pour les réponses smile

Lynxer.ttp est la version recompilée pour Atari du pack BLL pour PC... Je vais regarder ce matin, mais Bastian a pas dû prévoir dans son code plus de 16 objets : j'ai de belles bombes si ça dépasse.

EDIT : hum... je sens qu'un petite table avec offsets/adresses des objets va être précieuse, que ce soit en RAM ou en ROM.

4

Bon, même en ayant réécrit le lynxer en GFA (ce qui donne un truc plus rapide, plus léger, et très stable) : toujours la limite de 16 fichiers dans le .MAK, l'insert.o et le programme.o inclus.
En fait, ça dépend moins du lynxer.ttp que du loader26.o : en éditant ce dernier fichier, on remarque à la fin un emplacement vide de 16*8 octets... qui vont être remplis par lynxer pour adresser ces 16 blocs en ROM. Pour anecdote, 42Bastian a aussi mis sa signature en dur dans ce fichier.

Donc la limite de 16 est constitutive du BLL... Se faire sa propre table d'adresses/offsets est donc indispensable.
Va falloir aussi étudier comment sont adressés les fichiers dans un OLB... ça pourrait être utile.

5

Oui, tout ça quoi (je sais, je fais dans la réponse courte)

Lynxer est vraiment limité à 16 objets d'après la doc. C'est pourquoi je ne mets que les écran de fond en ROM, tous les sprites sont inclus dans le source roll
Si tu veux faire mieux, je crois qu'il va te falloir passer au compilo de karri qui est beaucoup plus souple de ce coté, mais qui n'utilise pas la syntaxe de la lib BLL (c'est pourquoi je n'ai pas franchi le pas). En particulier, tu pourras même charger/décharger des portions de code (un peu comme des modules quoi).

(réponse plus détaillée demain au besoin)
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

6

oki, merci Fadest, Ô Grand Guru du code Lynx smile

Je me sents pas vraiment de porter le compilo de Karri sur ST, mais ça coûte rien d'étudier son compilo.
Pour info, j'ai déjà 125 sprites à caser donc ça rentrera pas dans la RAM... J'ai toujours pas les décors... donc obligé de taper en ROM. Le chargement est très rapide à ce que j'ai vu smile

7

Ouh là, tu vas vite en besogne, je ne gouroutise rien du tout moi grin

125 sprites, effectivement, ça commence à chiffrer.
Concernant l'histoire du bloc de 1024, il y a dans les routines BLL un début de code permettant d'accéder à un fichier qui ne serait pas aligné (donc gérer des offsets), mais les commentaires disent bien que c'est expérimental et buggé. En fait, on n'en a pas trop l'utilité car le nombre de fichier étant limité à 16 (ou plutôt 14 max en enlevant insert.o et ton prog principal), on n'a pas trop besoin de ne pas être aligné.
Pour la vitesse, efefctivement, c'est pas trop mal, j'avais fait un petit test de dessin animé en chargeant 14 images en boucles, ça saccadait un peu mais pas trop.
Evidemment, le temps de chargement dépend de la taille (enfait surtout du nombre de blocs).

Quelques pistes pour gérer ton problème / réduire le nombre de sprites (tu y as probablement déjà pensé, mais ça peut être utile pour des débutants qui liraient ce sujet)
- je ne sais pas si on peut charger/décharger un olb, mais effectivement, tu dois pouvoir regrouper tes sprites par blocs de x sprites dans un seul fichier. Lire ce fichier et dispactcher les sprites dans tes zones mémoires (le plus simple serait encore de les aligner sur une taille fixe genre 300 octets dans ton cas, histoire de ne pas trop confler ton programme avec une gestion trop poussée, car il est limité à une quarantaine de ko au max). Je crois que Duranik ou Sage doivent même avoir un compacteur pour gagner de la place en ROM.

- pour diminuer le nombre de sprites, il y a plusieurs truc :
- jouer avec l'effet miroir. par exemple, sur un jeu vu de dessus avec un perso ayant 8 directions différentes, on peut se contenter de 3 sprites. Les 5 autres sont obtenus par utilisation des flags miroir horizontal/vertical dans la structure du SCB
- jouer sur la palette du sprite : c'est déjà plus sioux et demande beaucoup de boulot au graphiste pour avoir quelque chose de spectaculaire. Dans chaque SCB, on définit l'ordre de la palette, donc, le même sprite peut-être affiché en bleu ou rouge par exemple, il suffit de remplacer la valeur correspondant au bleu par celle du rouge dans le SCB (attention : on ne touche pas à la palette de la Lynx, juste à l'ordonnancement de celle du sprite).

Pour mieux illustrer mes propos, prenons l'exemple d'un clone de IK+
Il y a 3 combattants. Admettons qu'il y ait besoin de 300 sprites (3 x 100 sprites par personnage)
Déjà, on divise le nombre de sprites par 2 avec la gestion du miroir horizontal.
On peut diviser ensuite le nombre par 3 en utilisant la gestion des palettes.
Le premier est blond, kimono blanc, ceinture rouge. C'est le seul déssiné.
Pour le second, on dit que l'index blond correspond à la teinte brun maintenant, le blanc devient du bleu, le rouge du noir
Pour le troisième, on dit que l'index blond correspond à la teinte noir maintenant, le blanc devient du rouge, le rouge du noir.

Si tu as un graphiste très doué (et très sympa), il peut même prévoir 2 coupes de cheveux différentes (genre court et en pétard) en utilisant 2 couleurs différentes. Pour tes 2 premiers karatéka, la partie pétard de la coiffure est transparente, pour le 3°, elle est de la même couleur que le reste de la coiffure.

avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

8

Sisi, Grand Guru smile

- Je pensais hier soir regrouper en effet tous les sprites en un seul fichier et y accéder via une fonction qui joue avec le LoadCartBlock + une table décrivant les offsets dans ce fichier. La taille des sprites est effectivement vers 250-300 octets, quoique certains (pas beaucoup) tournent vers les 500-700. Merci pour l'idée de l'alignement dans ce même fichier, ça va être effectivement plus simple wink

- pour le mirroring, ben c'est déjà cogité. Sur les 125 sprites, certains devront être mirrorés pour la direction de droite. En fait, il s'agit plus de sprites animés : 3 en général, et de différents types (à la course, sur une fusée, en hélico, sur ressort)... Je peux certes virer les sprites où le road-runner marche, mais pour le reste, ça perdrait son charme.

- bonne idée pour les couleurs, quoique pour ce jeu, le coyote doit rester marron et le piaf bleu grin

Me demande comment ils ont réussi à caser tout ça dans Shadow of ze beast ou toutes les animations dans Skweek.

9

Oh, le 2° jeu auquel j'ai joué sur ST (le premier étant Winter "Alpine" Games) y ressemblait beaucoup grin

Pour les couleurs, tu peux utiliser le truc pour des ennemis/objets, histoire d'apporter un peu de variété à moindres frais. Ou ne pas t'en servir dans ce cas et la recycler plus tard...

Les jeux commerciaux n'utilisaient pas BLL... Et étaient probablement codés en assembleur... Mais je ne pense qu'il y ait une limite sur la Lynx concernant le nombre d'objets. Comme tu le dis, ça doit venir de BLL. C'est sur que je ne pense que Bastian envisageait qu'un petit français aurait besoin de 500 sprites 10 ans après qu'il ait cogité son truc, on ne peut trop pas lui en vouloir.

avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

10

Ben, c'était mon 1er jeu, cadeau de la boutique lors de l'achat de mon 1er Atari (520STF). Pour info, j'ai pu ripper tous les sprites du jeu ST pour en faire une conversion Lynx. Pas possible d'avoir les décors par contre. On va essayer de bidouiller ça comme on peut.
Déjà que voir la version 2600 à l'Astérisque Connexion m'a bien motivé...

11

Le jeu était bien sympa en effet...

Pas grand chose à voir, mais lis tu tes mini-messages ?
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

12

mini-message lu wink

Pour terminer ce thread : je vais 'étendre' le lynxer.ttp à quelques fonctions... Vu que la création d'un programme mergeant les objets et me donnant une table, ça ferait double emploi avec le lynxer.ttp, il vaut mieux bidouiller directement dans ce lynxer. En goupillant, on veut avoir une syntaxe compatible avec les anciens fichiers .MAK

Donc il y avait :
- fichier à déclarer
- alignement au prochain multiple de 1024 octets

Je vais rajouter :
- fichier non déclaré dans les FileEntry du loader26.o. '@' ou '#' devant le nom du fichier. Si '@' alors on accolle brutalement le fichier à ce qui est avant, si '#' alors on fait ça intelligemment : on regarde si avec la taille, ça peut-être casé dans les octets avant le nouveau Block de 1024, et si c'est pas le cas, on saute aux prochain Block ->
- alignement au prochain multiple de xxx octets (style #ALIGN=256, le #ALIGN tout court étant de 1024 par défaut)

Et surtout, un fichier de log qui me sort la table. Sous DOS, vous pouvez sortir ça facilement, mais ze peux pas sous TOS tongue

13

Pari réussi, vais pouvoir continuer le code, enfin plutôt le kit de dev ST et le code smile
Donc je me suis bricolé un Lynxer.ttp comme ci-dessus : fichiers déclarés et ceux non déclarés commençant par @ (accolage brutal après le dernier fichier) ou # (accolage intelligent, après le dernier fichier, si c'est à cheval entre deux blocs de 1024 octets, alors j'aligne au multiple de 1024).

Pour le fichier .MAK
insert.o
tst_spr2.o
#ALIGN
sprites\brun1.spr ; fichier déclaré, on accèdera aux autres avec LoadCartDir(2)
#sprites\brun2.spr
#sprites\brun3.spr
#sprites\btongue1.spr
#sprites\btongue2.spr
#sprites\btongue3.spr
#sprites\bwalk1.spr
#sprites\bwalk2.spr
#sprites\bwalk3.spr
#sprites\bwalk4.spr
#sprites\bback1.spr
#sprites\bback2.spr
#sprites\bfront1.spr
#sprites\bfront2.spr
#sprites\bnod1.spr
#sprites\bnod2.spr
#sprites\bmock1.spr
#sprites\bmock2.spr
#sprites\bdrink1.spr
#sprites\bdrink2.spr
#sprites\bjump1.spr
#sprites\bburnin1.spr
#sprites\bburnin2.spr
#sprites\bburnin3.spr
;--8<----------------------------
#sprites\van22.spr
#sprites\van31.spr
#sprites\van32.spr


Le lynxer avec la commande "[-l [log_file]]" me fournit un fichier texte en C qui me décrit les localisations des fichiers :
struct file {
	uchar	fileEntry;		// with LoadCardDir(F)
	uchar	blockOffset;		// + N blocks of 1024
	int	byteOffset;		// + O bytes
	};

struct filePosition fpos[127] = {
	{0,	0,	0},		// 2346 bytes for insert.o
	{1,	0,	0},		// 3620 bytes for tst_spr2.o
	{2,	0,	0},		// 270 bytes for sprites\brun1.spr
	{2,	0,	270},		// 264 bytes for #sprites\brun2.spr
	{2,	0,	534},		// 278 bytes for #sprites\brun3.spr
	{2,	1,	0},		// 274 bytes for #sprites\btongue1.spr
	{2,	1,	274},		// 266 bytes for #sprites\btongue2.spr
	{2,	1,	540},		// 278 bytes for #sprites\btongue3.spr
	{2,	2,	0},		// 258 bytes for #sprites\bwalk1.spr
	{2,	2,	258},		// 266 bytes for #sprites\bwalk2.spr
	{2,	2,	524},		// 264 bytes for #sprites\bwalk3.spr
	{2,	3,	0},		// 260 bytes for #sprites\bwalk4.spr
	{2,	3,	260},		// 252 bytes for #sprites\bback1.spr
	{2,	3,	512},		// 254 bytes for #sprites\bback2.spr
	{2,	4,	0},		// 262 bytes for #sprites\bfront1.spr
	{2,	4,	262},		// 264 bytes for #sprites\bfront2.spr
	{2,	4,	526},		// 252 bytes for #sprites\bnod1.spr
	{2,	5,	0},		// 252 bytes for #sprites\bnod2.spr
	{2,	31,	400},		// 100 bytes for #sprites\n0900.spr
	{2,	31,	500},		// 102 bytes for #sprites\n1000.spr
//--8<----------------------
	{2,	32,	0},		// 592 bytes for #sprites\van01.spr
	{2,	33,	0},		// 602 bytes for #sprites\van02.spr
	{2,	34,	0},		// 546 bytes for #sprites\van11.spr
	{2,	35,	0},		// 556 bytes for #sprites\van12.spr
	{2,	36,	0},		// 514 bytes for #sprites\van21.spr
	{2,	37,	0},		// 534 bytes for #sprites\van22.spr
	{2,	38,	0},		// 518 bytes for #sprites\van31.spr
	{2,	39,	0}		// 532 bytes for #sprites\van32.spr
	};


Ce fichier va être intégré dans le source C, en enlevant les 2 premiers fichiers de la table...
#include <lynx.h>
#include <lynxlib.h>
#include <stdlib.h>

// Bug in cc65? Needs real code before C++ comments occur?

extern char FileEntry[ 8];

struct fileCache {
	uchar entry;
	uchar block;
	int		offset;
	char  *address;
	char 	buffer[ 1024];
	};

struct fileCache cache;

struct fileLocation {
	uchar	fileEntry;		// with LoadCardDir(F)
	uchar	blockOffset;		// + N blocks of 1024
	int	byteOffset;		// + O bytes
	};

struct fileLocation fpos[ 125] = {
	{2,	0,	0},		// 270 bytes for sprites\brun1.spr
	{2,	0,	270},		// 264 bytes for #sprites\brun2.spr
	{2,	0,	534},		// 278 bytes for #sprites\brun3.spr
	{2,	1,	0},		// 274 bytes for #sprites\btongue1.spr
	{2,	1,	274},		// 266 bytes for #sprites\btongue2.spr
	{2,	1,	540},		// 278 bytes for #sprites\btongue3.spr
	{2,	2,	0},		// 258 bytes for #sprites\bwalk1.spr
	{2,	2,	258},		// 266 bytes for #sprites\bwalk2.spr
	{2,	2,	524},		// 264 bytes for #sprites\bwalk3.spr
	{2,	3,	0},		// 260 bytes for #sprites\bwalk4.spr
	{2,	3,	260},		// 252 bytes for #sprites\bback1.spr
	{2,	3,	512},		// 254 bytes for #sprites\bback2.spr
	{2,	4,	0},		// 262 bytes for #sprites\bfront1.spr
	{2,	4,	262},		// 264 bytes for #sprites\bfront2.spr
	{2,	4,	526},		// 252 bytes for #sprites\bnod1.spr
	{2,	5,	0},		// 252 bytes for #sprites\bnod2.spr
	{2,	5,	252},		// 254 bytes for #sprites\bmock1.spr
	{2,	5,	506},		// 254 bytes for #sprites\bmock2.spr
	{2,	6,	0},		// 304 bytes for #sprites\bdrink1.spr
	{2,	6,	304},		// 316 bytes for #sprites\bdrink2.spr
	{2,	6,	620},		// 336 bytes for #sprites\bjump1.spr
	{2,	7,	0},		// 272 bytes for #sprites\bburnin1.spr
	{2,	7,	272},		// 288 bytes for #sprites\bburnin2.spr
	{2,	7,	560},		// 286 bytes for #sprites\bburnin3.spr
	{2,	8,	0},		// 262 bytes for #sprites\bburnin4.spr
	{2,	8,	262},		// 254 bytes for #sprites\bburnin5.spr
	{2,	8,	516},		// 234 bytes for #sprites\bburnin6.spr
	{2,	8,	750},		// 236 bytes for #sprites\bburnin7.spr
	{2,	9,	0},		// 238 bytes for #sprites\bburnin8.spr
	{2,	9,	238},		// 228 bytes for #sprites\bburnin9.spr
	{2,	9,	466},		// 274 bytes for #sprites\bhit1.spr
	{2,	10,	0},		// 294 bytes for #sprites\bhit2.spr
	{2,	10,	294},		// 284 bytes for #sprites\bhit3.spr
	{2,	10,	578},		// 240 bytes for #sprites\bcaught1.spr
	{2,	11,	0},		// 244 bytes for #sprites\crun1.spr
	{2,	11,	244},		// 232 bytes for #sprites\crun2.spr
	{2,	11,	476},		// 238 bytes for #sprites\crun3.spr
	{2,	11,	714},		// 224 bytes for #sprites\crun4.spr
	{2,	12,	0},		// 232 bytes for #sprites\crun5.spr
	{2,	12,	232},		// 232 bytes for #sprites\crun6.spr
	{2,	12,	464},		// 224 bytes for #sprites\crun7.spr
	{2,	12,	688},		// 234 bytes for #sprites\cbreak1.spr
	{2,	13,	0},		// 234 bytes for #sprites\cbreak2.spr
	{2,	13,	234},		// 242 bytes for #sprites\cdrink1.spr
	{2,	13,	476},		// 242 bytes for #sprites\cdrink2.spr
//--8<------------------------------
	{2,	35,	0},		// 556 bytes for #sprites\van12.spr
	{2,	36,	0},		// 514 bytes for #sprites\van21.spr
	{2,	37,	0},		// 534 bytes for #sprites\van22.spr
	{2,	38,	0},		// 518 bytes for #sprites\van31.spr
	{2,	39,	0}		// 532 bytes for #sprites\van32.spr
	};

extern char SCB_test[];
#asm
_SCB_test			   	  dc.b $c4,$10,$20
          					dc.w 0
          					dc.w 0
          					dc.w 64,64
          					dc.w $100,$100
          					dc.b $01,$23,$45,$67,$89,$ab,$cd,$ef
#endasm

#include "ingame.pal"

extern uchar VBLflag;

#asm
_VBLflag = $a0
#endasm

#define VSYNC { ++VBLflag; while(VBLflag) {} }

VBL() interrupt { VBLflag = 0; }

register uchar joy;

void WaitTicks(waitticks) uchar waitticks {
	uchar tick;

	tick = 0;
	while (tick < waitticks) {
  	VSYNC;
    ++tick;
    }
	}

uchar WaitButton() {
	uchar key;
  while (!(key = joystick)) {}
  while (joystick) {}
  return key;
	}


void getFile(fp, fc) struct fileLocation *fp; struct fileCache *fc; {

	if (fc->entry != fp->fileEntry) {

		fc->entry = fp->fileEntry;
		fc->block = fp->blockOffset;
		fc->offset = fp->byteOffset;
		fc->address = fc->buffer + fc->offset;

		LoadCartDir(fc->entry);
		LoadCartBlock(FileEntry[ 0] + fc->block, fc->buffer);
		}
	else if (fc->block != fp->blockOffset) {
		
		fc->block = fp->blockOffset;
		fc->offset = fp->byteOffset;
		fc->address = fc->buffer + fc->offset;
		
		LoadCartBlock(FileEntry[ 0] + fc->block, fc->buffer);
		}
	else if (fc->offset != fp->byteOffset) {
		
		fc->offset = fp->byteOffset;
		fc->address = fc->buffer + fc->offset;
		}

	}

uchar sprite_id;
char *sprite_adr;

void main() {
  joy = 0;
  
 	InitIRQ();
 	InstallIRQ(2, VBL);
 	EnableIRQ(2);
  CLI;

  _SetRGB(pal);

  SetBuffers(0xa000, 0xc000, 0);

  cache.entry = 0;
  cache.block = 0;
  cache.offset = 0;

	sprite_id = 0;
  
  while(1) {

    getFile(&fpos[sprite_id], &cache);
		SCBDATA(SCB_test) = cache.address;

		DrawFBox(0, 0, 160, 102, 5);
		DrawSprite(SCB_test);
		WaitTicks(4); 
		SwapBuffers(); 
		//WaitButton();
    
    ++sprite_id;
    if (sprite_id == 125) { sprite_id = 0; }
    }
  }

J'ai mis un temps d'attente de 4 VBLs pour cette démo sinon on ne verrait rien. C'est trop rapide. Pour expliquer ce source : on considère que les sprites ne dépassent jamais 1024 octets, et qu'on les charge dans un buffer/cache de cette taille. Si le sprite est contenu dans ce cache, on l'affiche, sinon on va le chercher dans la ROM/cartouche. On pourrait faire un cache de N*1024, il suffirait de multiplier les LoadCartBlock et pour stocker plus de fichiers, les accoler avec un @ dans le .MAK et en calculant bien.

Le résultat se trouve là -> http://rajah.atari.org/files/ -> tst_spr2.lnx (attention, c'est un fichier de travail, donc je l'effacerai au bout de 2 semaines).

14

Excellent boulot, bravo !
avatar
Webmaster du site Ti-FRv3 (et aussi de DevLynx)
Si moins de monde enculait le système, alors celui ci aurait plus de mal à nous sortir de si grosses merdes !
"L'erreur humaine est humaine"©Nil (2006) // topics/6238-moved-jamais-jaurais-pense-faire-ca

15

Rajah (./1) :
J'ai 125 sprites à stocker (et ya pas encore les décors), la plupart font 250 octets, bonjour le gaspi avec le callage à 1024... à moins que je puisse accéder à un OLB ou lieu d'une multitude de SPR dans la ROM ?


Pour répondre à ta question (rapide la réponse tongue), il est possible d'accéder aux objets contenus dans un OLB sans trop de difficulté.
Petit exemple, je m'amuse avec les graphismes d'un jeu que tu dois connaitre par coeur actuellement, et j'ai plusieurs sprites de ce qu'on pourrait appeler des monstres que je ne veux charger en mémoire que lorsque l'un d'entre eux est visible.
J'ai donc généré des sprites ou format ASM (fichiers .SPR) puis créé une librairie juste pour eux avec libr65.
libr65 a une option l qui permet de lister son contenu et donne la taille des objets contenus. Par contre, il y a une entête (qui contient probablement ses infos, donc on pourrait se servir de l'entête si on savait son format) de taille variable suivant le nombre d'éléments inclus dans la librairie. Pour connaitre la taille de cette entête, il suffit de calculer le delta entre la taille du fichier en octet et la somme des objets contenus. Après, il "suffit" de linker la librairie à la ROM et d'y accéder normalement, puis de lire par blocs jusqu'à être au début de l'objet désiré et lire ensuite le nombre d'octets désiré (éventuellement en repassant par une lecture de bloc).
Je n'ai pas de routine propre et générique pour ça (je pars du principe que mes objets faisant moins de 2048, ils ne peuvent être à cheval que sur 2 blocs), mais ça marche bien (et du premier coup, j'étais étonné grin)

Bref, ça ouvre de nouvelles perspectives.

Une petite démo pour illustrer ce que ça donne (les fameux monstres sont donc chargés depuis la ROM à l'affichage, il y a des bugs car un seul type de monstres est censé être affiché à un instant et bon, des fois, un monstre caché fait changer la forme d'un visible...)


tromb Fichier joint : DM.lnx
(fichier de démo conservé 7 jours sur mirari)

Pour se déplacer, touches du pad, pour pivoter, c'est bouton A + droite ou gauche et il faut tout relâcher entre 2 mouvements...

PS : c'est juste une tech-démo, faut pas trop fantasmer dessus wink
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

16

Sympa ta petite démo !

Quelques très légers bugs graphiques, cependant smile
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

17

Oui je sais, il y a plusieurs raisons :
- la méthode de construction de l'écran (1 seule liste chainée avec tout) va bien pour le déplacement (utilise 15 sprites chainés max) mais commence à montrer ses limites si on ajoute des éléments en plus (9 monstres max à l'écran, plus déventuels objets ou éléments de décoration). C'est pour ça que c'est juste une tech démo, pour être utilisable, il faut tout repenser.
- les graphs originaux sont plus propres et plus grand -> réduction à 75% via Paint, d'où des effets bizarres, surtout que le découpage et le positionnement à l'écran n'est pas optimal
- pour simuler l'effet d'avancer, j'alterne les graphs droit et gauche en effet miroir, mais il y a une ligne d'un pixel à gauche 1 fois sur 2, faut que je trouve pourquoi.
- le positionnement des monstres à l'écran n'est pas idéal (c'est mieux après quelques tests)
- en plus, il y avait un gros bug quand on allait vers un des bords du donjon (impression de freeze pendant quelques secondes).
Mais l'intérêt, c'est qu'utiliser un fichier OLB depuis la ROM, ça se fait pas si mal, et que ça m'ouvre assez facilement des possibilités pour gérer plein de sprites/éléments. Je n'en avais pas eu besoin jusqu'à maintenant, mais là, ça commençait à devenir très important (pas forcément pour un truc relié à cette démo d'ailleurs).
Là, il me reste entre 10 et 15ko de libre, c'est énorme, surtout que je vais peut-être faire un test pour mettre aussi les graphs de sols et murs en ROM...
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

18

Salut à tous !

Je rebondis ici car le sujet original expliquant la méthode employée ("tuto Utiliser des fichiers externes dans vos programmes Lynx") est fermé.

Un peu de contexte : j'essaie de finir un petit jeu que j'avais commencé il y a 5 ou 6 ans de cela et dont j'ai retrouvé le code un peu par hasard. Je vais être tôt ou tard confronté à des problèmes d'espace, et utiliser le système de fichier pourrait s'avérer utile en fait. Comme j'utilise "new CC65" et que je ne suis pas spécialement motivé pour passer au "nouveau" CC65 (qui me permettrait d'exécuter plusieurs programmes les uns à la suite des autres si j'ai bien compris), cela semble être la seule solution possible pour gratter un peu de RAM.

1) Dans le tuto, il est écrit que "On définit donc 2 espaces mémoire titre (un sprite 160x102 prend 2048 octets) et musak (taille en fonction du fichier .lsf)." Mes compétences bas niveau sont un peu rouillées certes, mais je n'arrive pas à comprendre comment une image de 160*102 en 16 couleurs (donc 4 bits) ne prend que 2048 octets. Est-ce une coquille dans le texte... ou dans ma tête ? grin

2) Ensuite, je pensais utiliser un seul et unique buffer pour y charger des musiques ou des samples par exemple. Mais si les données sont de taille différentes, est-ce que mettre un '\0' à la fin des données dans le buffer suffit ?

3) Question subsidiaire : y a t'il encore des devs utilisant new CC65 ou bien tout le monde est-il passé au nouveau compilo ?

19

2 -> il faut déjà que tes données ne contiennent pas d'octet nul.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

20

1/ J'avais écrit ça il y a 12 ans, mais probablement que mes 3 fonds d'écran étaient basiques et ne dépassaient pas 2 ko une fois transformés en sprites (format compressé)
Sinon, effectivement, un écran Lynx peut monter jusqu'à 8 ko, si très détaillé/tramé

2/ Vu que dans les jeux ou je chargeaient des images de puis la ROM, je n'avais qu'un buffer et des tailles d'images différentes, ça devrait fonctionner. Mais ça doit faire depuis 2009 et la démo dungeon master que je n'ai plus eu besoin d'utiliser ce genre de techniques (je me contente de trucs plus basiques quand je recode un peu, je me limites à 40ko)

3/ Toujours pas changé, mais faut dire que je codes très rarement, donc ça ne compte pas
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

21

2 → il est plus simple/sur de mettre au debut, 1 ou 2 octets qui indiquent la taile. Tu peux utiliser un seul octet qui est multiplié par une valeur (par exemple 2 ou 4) pour indiquer la taille, donc *2 = taille entre 0 et 512 (par pas de 2 octets) et *4 = 0 et 1024 (par pas de 4 octets bien sur)

L'avantage tu veux la 3eme musique, tu lis la taille de la premiere, tu ajoute sa a ton pointeur, tu fait de meme avec la musique 2 et paf tu es sur la musique 3!
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

22

Merci pour les réponses et les précisions !

Je vais essayer de mettre ça en place... lentement mais surement. smile

Quelqu'un utilise abcmusic sinon ?

23

OK... Je viens de relire ta réponse Fadest et je realiser donc qu'on peut utiliser le mode RLE pour compresser les sprites avec sprpck... Je vais tester ca ce soir mais effectivement avec certaines images on doit pouvoir gagner pas mal de place.

24

Bon courage.
Pour ABCMusic, je continue de temps en temps à l'inclure quand je développe, mais à lire ta question sur Atari Age, ta problématique est plus l'écriture de musiques que l'utilisation de la librairie, c'est bien ça?
Je ne suis pas trop expert sur ce point là (et c'est un euphémisme - d'ailleurs, je reprends une musique existante à chaque fois), mais globalement, ça se décompose en 2 parties :
- la définition des instruments via les paramètres ABC (il doit y avoir un topic ou 2 avec des codes pour les instruments classiques, je crois que c'étaient Vince/Damdam et Cooper qui s'y étaient collé)
- la piste musicale en elle même en notation anglaise

Normalement, il doit y avoir quelques topics qui en parlent en creusant les archives

Rygar avait fait pas mal d'essais et composés plusieurs musiques (dont celles de Lynxopoly) il y a quelques années, il devrait pouvoir t'en dire plus. sinon, TurboLaserLynx sur AA en avait fait pas mal aussi (celles que j'ai utilisé dans Space Dance / Lock en particulier)

RYGAR a été invité sur ce sujet.
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

25

Oui utiliser abcmusic ne pose pas de gros soucis, mais il est en effet difficile de reproduire les musiques au format abc qu'on peut trouver sur le net il me semble que abcmusic ne supporte pas toutes les subtilités de la notation abc en plus).

Je vais essayer de retrouver le ou les sujets ou il y a effectivement des définitions d'instrument, ça peut être un bon début.

26

Les 1/2 tons (dieses, bémols) n'étaient pas pris en compte à un moment, je ne sais pas si ça a changé .

Pour les instruments :
topics/9-52993-des-instruments-issus-dabcmusic-creator
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

27

Pour les instruments, tu peux aussi faire des tests avec ABCMusic Creator
http://www.ataritimes.com/index.php?ArticleIDX=418

J'ai retrouvé le tuto que Karri avait écrit il y a bien longtemps et publié dans Revival, si cela peut t'aider. Je présumes que c'est dans sa doc, mais, au cas ou...

Utiliser ABCMusic par Karri Kaksonnen (traduit par Fadest)

J’ai créé un programme minimal.c qui utilise ma librairie abcmusic.m65. Il montre comment inclure des musiques sur 4 voies dans vos programmes en C en utilisant le module abcmusic.m65.


Voici la référence des commandes pour ABCMusic :
Contrôle des instruments :
On - octave n=0..6
Xn - XOR taps n=0..511
In - intergate n=0..1
Vn - volume n=0..127
Tn - durée n=0..255
Rn - Ramp (attack) n=0..127
Hn - Hold n=0..255
Kn - Kill (decay) n=0..127

Structure d’une piste
|: - début de section
: - repeat

Notes
CDEFGABcdefgabz - notes (z = silent)
Cn – joue la note C pour la durée n=2..4

Les espaces sont ignorés, Les codes d’instruments peut apparaître n’importe ou dans la chaîne de la musique. Donc, il est possible de changer d’instrument en cours de restitution.

Une musique est définie comme une chaîne ASCII :

char tune[]="O1 X7 I0 V66 T33 R60 H2 K3 |:CDEEDEFFEFGEFDGG:"

La musique est jouée par la commande abcmusic() qui reçoit en paramètre la voie ( de 0 à 3) et la musique.
Par exemple, la musique définit par tune[] sera jouée sur la voie 0 :
abcmusic(0, tune);
avatar
Futur ex éditeur de jeux Atari Lynx et Nintendo Game Boy
https://yastuna-games.com

28

ABCmusic tongue Le nombres d'heures que j'ai passé à m'arracher les cheveux à réécrire des partition trouvé sur le net gol
Le problème avec ABC c'est que le rendu n'est passable qu'a partir du moment ou tu utilises les 4 piste sonores. Avec moins tu as un rendu trop clavier Bontempis.

Le système demis croche croche noir blanche silence n'est pas trop dur à comprendre. Le seul point important est de bien repérer la plus longue des notes ou des silences de ta partition afin de l'utiliser comme référence pour les subdivision (un peu comme tu le fais pour la hauteur des notes) des notes et silences plus court. Si tu galère je dois avoir qqupart les correspondances de tempo noté sur un bout de papier chez moi, j’essaierais de le retrouver.

Après l’idéal évidement quand on parle de musique sur lynx c'est le programme de générateur de diaporama de Sage.
Tu as dedans un programme dans lequel tu balances directement un fichier midi et qui va de lui même le convertir en un fichier compréhensible par la lynx. Ce programme est d'une incroyable profondeur et te permet de retravailler chaque note si jamais le résultat de la conversion ne te plais pas complétement.
Il doit y avoir des roms qui trainent sur le net (le solitaire de Karri je crois entre autre) ou tu peux entendre le résultat et c'est bluffant, j'ai moi même converti une 100aine de musiques qui donnent super bien sur Lynx. J'ai une compil de M Jackson qui est excellente tongue
Problème de tout cela tu me diras ? Ses fichiers sonores je n'ai jamais réussi à les inclure dans mes programmes car je pense qu'il faut justement utiliser le nouveau CC65.
Mon site sur la LYNX :ZoneLynx

29

pour la zik lynx j'ai repris le code d'un ancien outil que j'avais fait qui convertissait du .mod en format abcmusic, par contre la version d'abc que j'utilise buggue (les ziks bouclent au bout d'une certaine durée).

C'est ce que j'ai utilisé pour mon 2048 avec la zik de mario, et on voit bien dans la rom le problème avec le bouclage...
---------------------------------
Cooper / Paradize
STf/Mega ST/STe/F030/Lynx
---------------------------------
Compilations de groupes ataristes français : https://www.youtube.com/channel/UCEBFi9nRczTRjRSvmy-QF8g

30

Merci pour les infos, qui sont finalement assez dures à trouver, même sur Atari age.

Rygar > je pense que tu parles de Chipper. J'ai rapidement jeté un oeil dessus, c'est beacuoup plus complexe que abcmusic et ça demande un investissement que je préfère pour le moment réserver au jeu. Je veux bien tes notes sur abcmusic du coup wink Tu es sûr sinon que abcmusic gère les dièse et bémol car j'ai eu des résultats surprenants, pour ne pas dire autre chose, avec Handy...

Cooper > La zik de 2048 rend bien, c'est 100% abcmusic ?