La fenetre virtuelle, qu'est ce ?
Imaginons que tu ais un espace d'affichage plus grand que l'écran de la Lynx.
Si tu veux te déplacer dans cet espace, tu as le choix entre 2 possibilités :
- déplacer ton fond, c'est à dire recalculer les positions x & y des sprites constituant ce décor à chaque appui sur une direction.
- déplacer ton écran, c'est à dire toujours afficher ces sprites au même endroits, mais changer le pixel haut/gauche ou commence l'affichage.
Pour prendre un exemple, imagines un grand poster et une petite feuille.
Si tu veux que ta feuille soit à un autre endroit du poster, soit tu déplaces tout le poster dessous, soit tu déplaces la feuille.
Là, c'est pareil, tu as 2 variables hoff et voff qui correspondent aux coordonnées du pixel 0,0 de ton écran dans ton monde virtuel.
Ce sont ces variables qui vont être modifiées en cas d'appui sur une direction.
L'idéal, c'est de combiner avec un affichage chainé de tes 2 images de fond pour ne faire qu'un ordre DrawSprite().
Le chainage de sprite permet de dire au moteur de sprite qu'après l'affichage d'un sprite, il faut qu'il affiche le suivant et ainsi de suite, c'est donc plus rapide à gérer pour la Lynx.
Normalement, ce sera un peu plus fluide que ta version actuelle. Même si bien sur, chainage + fenetre virtuelle, c'est surtout super efficace quand le fond est constitué de plein de petits blocs (ça évite de recalculer les coordonnées de chaques, et le chainage est obligatoire dans ce cas là).
Ton exemple deviendrait donc :
#include <stdlib.h>
#include <lynx.h>
#include <lynxlib.h>
#include "inc\lake.pal"
#define JOY_RIGHT 0x10
#define JOY_LEFT 0x20
#define JOY_DOWN 0x40
#define JOY_UP 0x80
#define BUTTON_OPTION1 0x08
#define BUTTON_OPTION2 0x04
#define BUTTON_INNER 0x02
#define BUTTON_OUTER 0x01
#define BUTTON_PAUSE 0x01
char SCREEN[8160] at (MEMTOP-16320);
char RENDER[8160] at (MEMTOP-8160);
extern char lake[];
extern char SCB1[];
#asm
_SCB1 dc.b $c0,$10,$20
dc.w 0,0
dc.w 0,0,$100,$100
dc.b $01,$23,$45,$67,$89,$ab,$cd,$ef
#endasm
extern char SCB2[];
#asm
_SCB2 dc.b $c0,$10,$20
dc.w 0,0
dc.w 0,0,$100,$100
dc.b $01,$23,$45,$67,$89,$ab,$cd,$ef
#endasm
void Vsync()
{
#asm
vretrace:
lda $fd0a
bne vretrace
#endasm
}
char main()
{
InitIRQ();
CLI;
SetBuffers(SCREEN, RENDER ,0);
SetRGB(pal);
DrawFBox(0,0,160,102,0);
SCBX(SCB1) = 0;
SCBY(SCB1) = 0;
SCBDATA(SCB1) = lake;
SCBNEXT(SCB1) = SCB2;
SCBX(SCB2) = 450;
SCBY(SCB2) = 0;
SCBDATA(SCB2) = lake;
hoff=0;
voff=0;
for( ; ; )
{
if (joystick & JOY_RIGHT)hoff++;
if (hoff>450) {hoff=0;}
if (joystick & JOY_LEFT)hoff--;
if (hoff<0) {hoff=450;}
DrawSprite(SCB1);
Vsync();
SwapBuffers();
}
}
Pas testé, mais ça devrait marcher (enfin je pense).
