top of page

Entenent un sprite animat en MSX2 amb MSXgl

  • Writer: MoltS Xalats
    MoltS Xalats
  • 13 hours ago
  • 5 min de lectura
Sam
Sam

Una introducció pas a pas per a neòfits

 

Programar gràfics en un MSX pot intimidar al principi: VDP, VRAM, sprites, hooks del BIOS…

Però amb MSXgl, moltes d’aquestes complexitats queden encapsulades en funcions clares i coherents.

 

En aquest article veurem com funciona un sprite animat de 16×16 píxels en MSX2, des del patró en memòria fins a l’animació a pantalla, explicant totes les crides importants sense necessitat de conèixer el maquinari a baix nivell.


El punt de partida: què és un sprite al MSX?

 

En MSX clàssic:


  • Un pattern és un dibuix de 8×8 píxels, codificat en 8 bytes

  • Un sprite de 16×16 està format per 4 patterns de 8×8

  • L’ordre no és intuïtiu: el VDP espera


Top-Left, Bottom-Left, Top-Right, Bottom-Right

 

En el nostre exemple, el personatge Sam té:


  • 2 frames d’animació (idle i walk)

  • 2 capes de sprite:

    • BODY (cos)

    • DETAIL (contorn o detalls)

 

En total: 16 patterns (16 × 8 bytes)


Dibuixant Sam: els patterns en memòria

 

Tots els patterns estan definits en un únic array:


const unsigned char g_DataSprt16_Sam[];


Aquest array no és encara VRAM, sinó RAM normal.


Cada grup de 8 bytes representa un tile 8×8.

 

Per facilitar la lectura, definim una funció auxiliar:


static const u8* TilePtr(u8 tileIndex)

{

    return g_DataSprt16_Sam + ((u16)tileIndex * 8);

}


Així podem dir: “Carrega el tile número 3” sense preocupar-nos d’offsets ni càlculs manuals.


Comprovant que som en MSX2


Abans de fer servir SCREEN 5, cal assegurar-nos que l’ordinador ho suporta:


if(g_MSXVER == 0)

{

    Bios_ClearScreen();

    Bios_TextPrintSting("MSX2 required");

    Bios_GetCharacter();

    return;

}


  • g_MSXVER és una variable global proporcionada per MSXgl

  • Si és 0, estem en MSX1

  • Mostrem un missatge en mode text i sortim elegantment

 

Inicialitzant el mode gràfic (SCREEN 5)

 

Ara sí, entrem en territori MSX2:


VDP_SetMode(VDP_MODE_SCREEN5);

VDP_SetColor(COLOR_BLACK);


Això configura el VDP en SCREEN 5 (256×212, bitmap).

 

Per netejar la pantalla fem servir un comandament del VDP, molt més ràpid que pintar píxel a píxel:


VDP_CommandHMMV(0, 0, 256, 1024, COLOR_MERGE(COLOR_BLACK, COLOR_BLACK));

VDP_CommandWait();


  • HMMV = High-speed Move, Fill

  • Omple una gran zona de VRAM amb negre

  • VDP_CommandWait() assegura que el VDP ha acabat abans de continuar

 

Activant i configurant els sprites

 

Els sprites tenen taules pròpies dins la VRAM:


VDP_EnableSprite(TRUE);

VDP_SetSpritePatternTable(0x17000);

VDP_SetSpriteAttributeTable(0x17A00);


Aquí indiquem:


  • On viuran els patterns de sprite

  • On viurà la taula d’atributs (posició, forma, color…)

 

I definim el format global:


VDP_SetSpriteFlag(VDP_SPRITE_SIZE_16 + VDP_SPRITE_SCALE_2);


És a dir:


  • Sprites de 16×16

  • Escalats ×2 → visualment 32×32

 

Carregant els patterns a la VRAM

 

Ara copiem els dibuixos des de RAM cap a VRAM:


VDP_LoadSpritePattern(TilePtr(...), pat, 1);


Aquesta funció:


  • copia 1 pattern de 8 bytes

  • a la posició pat de la Sprite Pattern Table

 

És important respectar l’ordre del VDP:


Top Left (1) → Bottom Left (2) → Top Right (3) → Bottom Right (4)


Sam idle pattern
Sam idle pattern

Per això el codi carrega els patterns amb molt de compte, frame a frame i capa a capa.


Sincronització: animar sense córrer massa

 

Per evitar animacions massa ràpides, fem servir un hook del BIOS:


Bios_SetHookCallback(H_TIMI, VBlankHook);


H_TIMI és una interrupció periòdica (50/60 Hz).


Cada cop que salta:


static void VBlankHook()

{

    g_VBlank = 1;

}


I al bucle principal:


static void WaitVBlank()

{

    while(g_VBlank == 0) {}

    g_VBlank = 0;

    g_Frame++;

}


Això ens permet:


  • avançar el temps de manera estable

  • controlar l’animació amb un simple comptador

 

Creant Sam amb dues capes de sprite

 

Creem dos sprites superposats:


VDP_SetSpriteExUniColor(SPR_SAM_BODY,   x, y, shape, 0x04);

VDP_SetSpriteExUniColor(SPR_SAM_DETAIL, x, y, shape, 0x0E);


  • Mateixa posició

  • Mateixa animació

  • Colors diferents

 

Resultat: un sol personatge amb contorn, molt habitual en jocs MSX.


Body
Body

Detail
Detail

Body + Detail
Body + Detail

Animació i moviment


Cada frame:


u8 frame = (g_Frame >> 2) % 2;


  • canviem d’animació cada 4 ticks

  • alternem entre frame 0 i 1

 

Actualitzem només el necessari:


VDP_SetSpriteData(spriteId, &sam);


Això escriu:


  • X

  • Y

  • Shape

 

Sense tocar el color ni recrear el sprite.

 

Sortida neta


Quan l’usuari prem la tecla ESC, sortim del bucle principal i tanquem el programa de manera ordenada:


Bios_ClearHook(H_TIMI);

Bios_Exit(0);


Aquí passen dues coses importants:


  1. Desenganxem el hook del BIOS


Amb Bios_ClearHook(H_TIMI) evitem deixar el sistema amb una interrupció activa que ja no s’utilitzarà.


Això és fonamental per no provocar comportaments estranys després de sortir del programa.


  1. Sortim del programa amb Bios_Exit(0)


Aquesta crida retorna el control al sistema… però el comportament final depèn del format amb què hàgim compilat el programa.

 

ROM vs DSK: un detall clau


  • Si el programa s’ha compilat com una ROM


En prémer ESC, el que observarem és que el programa es torna a carregar, com si féssim un warm reset.


Això és normal: en una ROM no existeix un “sistema operatiu” al qual tornar, així que el MSX reinicia l’execució del cartutx.


  • Si el programa s’ha compilat com un executable MSX-DOS (DSK)


En aquest cas, en sortir amb Bios_Exit(0) tornarem al prompt del MSX-DOS, exactament com esperaríem en un entorn de línia de comandes.

 

El mateix codi, per tant, pot tenir comportaments diferents segons si s’executa des de ROM o des de DOS, i això és una característica pròpia i històrica de la plataforma MSX.

 

Conclusions: i ara què?

 

En aquest article hem fet una cosa molt concreta… però molt potent: hem agafat un MSX2, un personatge de 16×16 píxels i MSXgl, i l’hem fet moure i animar amb criteri.

 

Pel camí hem vist que:


  • Un sprite al MSX no és màgia negra, sinó:


    • patterns de 8×8 ben ordenats,

    • una taula d’atributs,

    • i una mica de disciplina a l’hora de carregar-los.


  • MSXgl ens permet treballar a un nivell molt més còmode:


    • sense tocar registres a pèl,

    • sense assemblador,

    • i amb codi C llegible, modular i mantenible.


  • Conceptes clàssics com:


    • animació per frames,

    • sincronització amb el temps,

    • sprites multicapa (cos + detall),


Es poden implementar de manera clara i pedagògica, ideal tant per aprendre com per ensenyar.


Dit d’una altra manera: el MSX continua sent un terreny de joc fantàstic, i MSXgl és una eina excel·lent per explotar-lo avui.

 

El potencial de MSXgl (vist amb ulls MoltSXalats)

 

Aquest exemple és petit, però deixa entreveure molt clarament el potencial de MSXgl:


  • Permet crear codi modern sobre maquinari clàssic.

  • Facilita fer demos, jocs i experiments sense haver de reescriure mitja VDP spec cada cop.

  • És ideal per:


    • articles didàctics,

    • tallers,

    • experiments ràpids,

    • i projectes col·lectius com els que tant ens agraden a la comunitat.

 

Per a nosaltres, MSXgl és una mena de pont entre el MSX de sempre i la manera actual d’entendre el desenvolupament.

 

I això no s’acaba aquí…

 

Aquest article és només un primer pas. A partir d’aquí, el camí natural és seguir creixent:


  • Afegir scroll


Fer el següent pas lògic: un escenari que es mou mentre Sam camina.

Exactament el que ja vam treballar en altres articles… però ara amb MSXgl i SCREEN 5.


  • Mapes de tiles i col·lisions


Introduir un mapa, detectar parets, límits i objectes, i començar a parlar de “joc” de veritat.


  • Comparar enfocaments


Veure com canvia el codi si ho fem:


  • en SCREEN 2,

  • en MSX1,

  • o combinant sprites i fons amb diferents tècniques.


  • De demo a joc


Convertir aquest exemple en una base reutilitzable:


  • estructura de projecte,

  • gestió d’estats,

  • i bones pràctiques per a futurs desenvolupaments.

 

En resum

 

Si has arribat fins aquí, ja no estàs “mirant” MSXgl: l’estàs fent servir.


I això, en l’esperit MoltSXalats, és el més important: provar, entendre, tocar, trencar… i tornar a provar.


Ens veiem al proper article. Amb més codi, més scroll… i segurament més gats 🐾


Clica aquí per a veure l'exemple funcionant.

Pots descarregar el codi d’aquest projecte aquí.


Codi font



Sam Sprite Data




 
 
 

Comentaris


Envia'ns un missatge i digues què et sembla

Gràcies pel teu missatge!

© 2035 Creat per Tren d'idees con Wix.com

bottom of page