ATTR0_ROTSCALE : partie I

Tout comme le GBA et la SNES, la DS est capable de zoom et “rotations” sur un sprite. Une fonction quelque peu obscure, sans doute parce que liée à une implémentation hardware alors qu’on serait tenté de penser “transformations géométriques” (comme dans le cas d’OpenGL) ou “programme de rendu”. Eh bin non. Puisque je projette de me servir de sprites aussi pour la visualisation des zones de collisions pour mon InspectorWidget, voilà un peu de bidouille pour identifier les quelques points importants à prendre en compte. Mon “sprite de base” est une sorte de grille/radiateur noir dans une zone de 16×16.

Engine::sprites[oam].attribute[0]=ATTR0_ROTSCALE|ATTR0_ROTSCALE_DOUBLE|
ATTR0_TYPE_BLENDED|ATTR0_SQUARE|y;
Engine::sprites[oam].attribute[1]=ATTR1_ROTDATA(oarot)|ATTR1_SIZE_16|x;
pSpriteRotation sr = Engine::spriteRotations + oarot;
sr->hdx=0x100; sr->hdy=0x0; // 8.8 fixed point : 0x100 is 1.00 here
sr->vdx=0x0; sr->vdy=0x100;

ROTSCALE_DOUBLE affecte la manière dont les coordonnées sont interprétées. C’est la zone de visualisation — de 32×32 ici, matérialisée par les # blancs — qui aura ses coordonnées en (x,y). Le sprite proprement dit, lui, verra son centre coïncider avec le centre de cette zone.
Si je donne les paramètres (hdx,hdy,vdx,vdy) = (1,0,0,1) — ce qui correspond à un affichage sans aucune transformation — mon sprite apparaîtra donc w/2 pixels plus à droite et h/2 pixels plus bas que les coordonnées (x,y) que je lui fixe.

A noter que [hv]d[xy] indique “de combien avancer (en X et Y) dans la “texture” du sprite lorsqu’on avance d’1 pixel Horizontalement ou Verticalement sur l’écran. Du coup, un zoom grossissant s’obtient avec des valeurs de hdx plus petites que 1.

Si je zoome (0.5,0,0,0.5) puis (0.25,0,0,0.25), le centre de mon sprite continue effectivement à coïncider avec le centre du “viseur”. En revanche, impossible de sortir de la “zone de visibilité” de 32×32, même avec un facteur de zoom (4x) qui devrait m’afficher un sprite de 64×64, je ne vois plus que le centre de l’image.

En clair, le hardware permettra sans problème de légère déformations, comme celles subies par Morton Koopa Jr., et n’importe qu’elle réduction de taille (jusqu’à 256 fois plus petit ;), mais pour un zoom prend-toi-ça-dans-les-dents tels qu’on en a vu dans le combat contre Bowser dans SMW ou dans Turtles in Time, il faut ruser…

  • soit en utilisant plus de sprites,
  • soit en prenant des sprites plus gros que ce qui est nécessaire (p.ex. 64×64), zoomés de manière logicielle et rapetissés artificiellement par le hardware — probablement la solution pour mes zones de collision,
  • soit (à mon avis plus plausible) en utilisant un fond plutôt qu’un sprite pour le boss. Ca s’est régulièrement vu sur NES où les sprites avait des tailles ridicule (8×8 ou 8×16 :P)

PS: tests réalisés sous Desmume 0.9.4 (linux) et confirmés par le hardware.

6 thoughts on “ATTR0_ROTSCALE : partie I

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.