Monday, November 19, 2007

Ideas for smooth scrolling on the DS...

Bien sûr, la DS est capable de faire un scrolling fluide à travers un grand niveau, mais ce n'est pas nécessairement une mince affaire. Je cogitais sur les méthodes possibles l'autre jour et j'ai pris mes notes dans mon blog.

Je rafinerai et traduirai plus tard ...

maps & tiles sharing VRAMThe hardware (from Liranura's 2D tutorial)

Map bases always have 32×32 entries. To create bigger BGs (Like 64×64) you need to use several map bases. As for tile bases - If you want to make use of the full tileset (1024 tiles), you will have to use several tile bases - 4 Tile bases for 256col full tileset, and 2 Tile bases for full tileset of 16col mode. Since the Map bases and the Tile bases are located on the same region in VRAM, they can overlap. Since a map base is 2Kbytes and a Tile base is 16Kbytes, each Tile base contains 8 Map bases.
Une surface affichable sur la DS est constituée de 32x32 tiles (l'écran en fait 32x24) et occupe 2KB dans la mémoire vidéo. Pour construire des plans de décor plus larges (p.ex 64x64 tiles), il nous faudra plusieurs 'morceaux' de 32x32 mis côte à côte pour former une surface plus grande. On retrouve le même phénomène avec les tiles (pour utiliser l'entièreté d'un jeu de tiles (1024 tiles), il nous faut 4 sections de 16K en mode 256 couleurs). Notez que c'est au programmeur de choisir s'il va stocker 16K de tiles ou 8 maps dans une région donnée de la mémoire vidéo.

La console nous permet de positionner l'écran librement dans la surface définie (pour chaque plan séparément, hein, ) et -- contrairement aux carte VGA -- par défaut la surface 'boucle' sur elle-même (si la zone affichée déborde par la droite, c'est la gauche de la surface qui sera réutilisée).

We can have hybrid technique ...
At some point we have to alter parts of the map to keep scrolling smoothly. Nothing forces us, however, to have a unified technique that accomodates both horizontal and vertical moves. The fact that the screen isn't a square, that memory stores lines continuously and columns discontinuously and similar consideration -- not omitting the fact that our game may have a side-scrolling or vertical-scrolling action (shmups ;) -- may suggest that we have two distinct mechanisms for updating the map after a vertical and a horizontal movement of the "camera".

Le système de scrolling va forcément mélanger software et hardware. Le côté hardware, c'est le choix de la portion visible de la surface en VRAM (on l'appelle "onscreen surface" -- litéralement 'à l'écran' en anglais). Le côté software consistera à modifier des portions de cette surface (de préférence qui sont actuellement invisible pour le joueur) afin de donner l'illusion d'un décalage continu alors qu'en réalité, nous somme piégés dans un carré de 512x512 pixels.
Avant de ce lancer dans le code, il serait bon de se rappeler que rien ne nous oblige à avoir une technique unique pour les scrolling horizontaux et verticaux. Les uns pourrait parfaitement s'opérer à grands coups de DMA sur des tranches entières alors que les autres se feraient "bloc par bloc" gérés entièrement depuis le CPU.
  1. we can't have smooth scrolling in a 64x64 area if we reprogram 32x32 entries (dma copy) at once (<-- cyril contests this, see next post).
  2. we could do the "John Carmack" trick, using hardware scroll in the 64x64 area and then "jump" to a second 64x64 area when we're about to move out, but that would kind of be silly on hardware that allows to "wrap around" the area with our viewport (which the PC hardware couldn't do properly).
  3. doing "double-buffer" of the map will involve a burst of up to 8K memory transfer (through DMA), potentially leading to gameplay lags
  4. we have better things to do with the other maps (e.g. additional planes)
  5. DMA copy for the map might be interesting to save CPU (well, it is actually frozen during the move), but it requires that the offscreen map is a verbatim copy of what's used on screen. manual copy of the map parts instead allow us to use more bits for tiles meta-data and wipe them as the tiles are moved on screen. That would give us 64 types of block, more than we need to encode "slipperiness", identify bonus, etc.
thinking again ...
Nothing forces us to use 64x64 ... since the height of the screen is smaller than 32 tiles, we can very well work with e.g. 64x32 instead. This is not only nice because it halves the amount of work without loss of functionnality (maybe a bit less effective "caching" of vertical scrolling), but also because it means we now can do the "carmack jump" thing effectively: Suppose we are working with maps 0 and 1 initially (side-by-side 32x32 areas of the level map) and that the viewport is getting close to the edge of the currently displayed area ... rush! we dump another 32x32 chunk of the level map (and now we can just ask for a DmaCopy of the whole data if it is properly stored offscreen) into map #2. When it then appears that we are about to scroll out of the current 32x32 area, we then cheat the video hardware, reprogramming the map base to be map#1 (instead of map #0) and the X scrolling register to show us in the new area (most likely x=x-256 or x=x+256 depending on the movement).

Autre petite constatation: rien ne nous oblige à utiliser du 512x512 pixels! en fait, ce serait même l'inverse (en cas de scrolling horizontal, ce mode nous oblige à faire plus de mises à jour et ne nous offre pas grand-chose en contrepartie). Au passage, ça nous permettrait de faire un "scrolling à la John Carmack" plus efficacement (enfin, au moins une fois de temps en temps...).

Mais entretemps, je suis nettement plus sceptique sur l'interêt de la technique Carmack (rendue célèbre par la série des Commander Keen) sur le hardware de la DS.

I'm not sure we could keep it smooth forever with that technique, unfortunately: there would be no way for us to tell the hardware that map #N-1 and map #0 should be shown as a continuous 64x32 area...

see also captain Apathy's tutorial
voir aussi le tutoriel de Edorul (GBA)
Sonic the Hedgehog 2 (Emerald Hill) from soniccenter.org

2 comments:

Anonymous said...

Aaaah, ca me rapelle de bon vieux souvenirs tout ca.

Anonymous said...

je vois que Sonic t'inspire dans te réflection ;p
bon, je me noie un petit peu dans la partie théorique, mais je vois ou tu veux en venir... j'ai testé hier, le fameux Crash Bandicoot dont je te parlais... super nul !! et j'ai par contre passé la matinée sur le Konami Classics.. Pooyan, Twinbee 1, Yie are Kung Fu et surtout Time Pilot !! (tu te souviens pas.. enfait c'est le Space Pilot du C64 ;p)