Showing posts with label z-order. Show all posts
Showing posts with label z-order. Show all posts

Sunday, May 21, 2017

shell to cybook

I got the z-list issue fixed. The error was what I suspected, but what is more interesting is that I have been able to write a test case that reproduced the bug systematically, and thus that demonstrate that the problem is gone with the fix.

I had to change my approach for investigating that because I've been doing so much on-line activities these last days that my eyes started to "panic". So rather than staring at my laptop top understand the outcome of a test, I pushed it into a .html file that I could browse with my e-ink cybook.


python -m SimpleHTTPServer 8000 & # http.server if you're on python3

(echo "<html><body><pre>" ; 
  ./testme ; 
  echo "</pre></body></html>") > /tmp/html/out.html

(echo "<html><body><pre>" ; 
  grep -h -C14 prepare libgeds/source/* 
    | sed -e 's:&:&amp;:g;' 
    | sed -e "s:<:\&lt;:g;" 
    | sed -e 's:>:\&gt;:g;' ; 
  echo "</pre></body></html>") > /tmp/html/code.html

Bon, ça n'a pas été une semaine simple, mais j'ai réussi à pouvoir prouver que le bug d'affichage de Bilou est corrigé tout en reposant suffisamment mes yeux qui criaient "au secours" la semaine d'avant. J'ai notamment utilisé assez abondamment ma liseuse pour passer en revue les résultats des tests (puisque oui, j'ai choisi l'approche "test automatique plutôt que l'approche "debugging interactif raffiné", la faute aux yeux précédemment cités). Celà dit, je vais rester prudent et laisser les détails techniques uniquement en Anglais pour cette fois-ci. Dès que j'aurai compris pourquoi l'encre refuse de s'arrêter à la hauteur demandée, je pourrai faire une release améliorée de School Rush.

The test itself is actually fairly simple conceptually: I just drag Bilou around in the level, back and forth, emulating the camera and the game logic after each displacement. As the camera moves through the level, some game objects freeze and unfreeze, recycling the hardware sprites, and inkjets use the top-layer sprites so that ink drops look to come from within it.

On the first round, the bug did not happen, but I had programmed a "trap" to report what I thought to be the precondition to reproduce the bug (having the inkjet frozen while it had one hardware sprite at top priority). The test then showed me that this happened, but less often that I thought. Actually, it only happened with one inkjet near the end of the level.

Then, I extended the test so that I would make an increased number of scrolls through the level. There I got the bug appearing systematically on one of the levels. I had to filter out some of the events reported during the scroll (I reported every change in the zlist's size as well as any arrival/departure of hardware sprites): inkjets throwing ink corresponding for instance to 4 correlated events. Making sure that the camera coordinates are reported (instead of Bilou's coordinate) helped as well.

Monday, May 08, 2017

Another Inspector Widget ?

I have another instance of sprites disappearing and re-appearing in School Rush. It is likely something with the "pull part on top of every other sprite (aka. zlist[0]). I believe the issue happens when a modular sprite gets frozen while it had one of its component pulled to zlist[0], and then comes back to activity.

It would be great to investigate those situations to have an alternate widget for the Inspector Window Something that would show the on-screen area, the "GPU-active area" around it (where hardware sprites are are still programmed to be shown), and the area where the objects are still active although their OAMs are all disabled to avoid display glitches.


Bon, je tape un peu en vrac mes cogitations du week-end. Si je n'ai pas encore refait une release avec les améliorations de School Rush du mois dernier, c'est que je suis confronté à un retour des sprites-fantômes. Au départ, c'était juste dans la tour encrièrnale, mais ça se généralise à tout le jeu School Rush... J'ai ma petite idée sur la cause, mais j'aurais bien aimé en avoir la preuve avant de tenter une correction du code. Histoire d'être en mesure de montrer que c'est bien corrigé.

L'ennui c'est que j'estime le rapport entre corriger et démontrer que c'est corrigé de 1 à 10 au minimum. Voire de 1 à 100. L'autre ennui, c'est que ni l'amélioration d'Inspector Widget (qui aurait de la gueule) ni l'écriture de cas de tests (qui serait en aveugle) ne me paraît préférable

Ideally, it should be able to show "regular" and "pulled" sprites differently so that we can spot what state they are in and when. It should of course allow pausing and step-by-step processing to maximize our chances to reproduce the believed cause of the crash. Would that be enough ? should I rather try to have that investigated through "unit" testing ? I don't know yet.


Wednesday, May 01, 2013

Inside the Inkjet

Pas si simple de mettre Bilou dans un encrier, même une fois le résultat à obtenir défini. Il serait sans doute bon de reprendre les évolutions de la semaine qui se sont agglutinées dans une "todo list" qui n'était pas initialement prévue pour ça.
En premier, il me fallait un moyen de forcer les sprites à clignoter de manière sélective, et dont la définition se ferait au niveau des scripts. C'est pour un test, je ne fais pas dans la dentelle et j'introduis simplement un nouvel opérateur dans les expressions de changement d'état qui modifiera cette propriété de clignotement. En quelques essais, je peux rendre Bilou semi-transparent lorsqu'il s'est fait touché. Encourageant.

It wasn't supposed to be that long. With the desired rendering defined, I'd have thought I could implement the flickering-translucent-inkjet in one sunday afternoon at most. I started with a couple of simple checks, like blinking Bilou when hit, and then selectively blink only some limbs. That was all neat and sleek. I had forgotten, however, that 'pulling' some limbs worked only "locally" by rearranging limbs within a sprite (although 3 distinct, globally ordered OAMs lists were introduced).

Mais je ne veux pas que l'entièreté de Inkjet clignote: seulement le "patch" destiné à masquer Bilou lorsqu'il est à l'intérieur. Je change donc la sémantique de cet "opérateur-clignotant" pour qu'il reçoive plutôt des bits de contrôle et laisse le rôle de "compteur" à une variable accessible depuis les expressions du script. Je peux du coup faire clignoter seulement le corps de Bilou ou une de ses mains ... tout va pour le mieux.

Par contre, le code permettant de modifier l'ordre d'affichage des composants d'un sprite (les OAMs du hardware, donc) n'offrait jusqu'ici qu'une modification interne au sprite, faisant passer une main devant le corps, etc. mais sans permettre de placer un composant devant Bilou et un autre derrière. Or, c'est essentiel pour "entrer" dans l'encrier.
C'est le comportement "global pull" qui utilise les mêmes commandes "pullmask" qu'auparavant, mais qui force maintenant un changement de zlist pour les composants tirés vers l'avant-plan. Le code du moteur de jeu n'était pas tout à fait prêt pour ça.

Once invariants for pulling limbs into list 0 on demand were ready, I realised the path to victory was cluttered with unrevealed bugs dating from z-ordering and even per-controller-events introduction. It's all fixed now, but it leaves a kind of annoying "not-quite-professional-coding"... I guess I should have known this from the start, this being a hobby project, I can't always afford being professional :P

That being said, I definitely want to take the time to clean up the interface and provide some coherent way to define the (pullzero?, flickermask, pullmask, flickertime) variables in a cleaner way.


Il m'aura encore fallu un ou deux temps de midi pour comprendre pourquoi ce damné encrier refusait de tenir compte de mes commandes pour continuer à clignoter. En fait, il restait un bug datant de l'introduction des évènements-par-contrôleur. Qu'un seul contrôleur voie sa liste d'évènements prise en compte lorsque deux (ou plus) disent simultanément "évènement", je pouvais m'y attendre. Qu'un "évènement" et un "impossible" se traduise en "réinitialisation", franchement, je ne l'avais pas vu venir. Il aurait été plus "pro" de concevoir des cas de tests suffisament riches au moment où cette nouvelle fonctionalité a été ajoutée. Seulement voilà, un pro code aussi en-dehors des temps de midi :)

Sunday, April 21, 2013

translucent ?

I managed to have some translucent effect through fast (60Hz) sprite flickering. That's mandatory if I want sprite-versus-sprite transparency. So if I want Bilou to look "inside" the inkjet, I need an extra patch of glass that will flicker over Bilou to partially obscure him.

J'étais tombé par hasard sur l'épisode "Spécial Disney" du joueur du grenier, dernièrement.  Après une bonne tranche de rire avec ma fée sur la partie "La Belle et La Bête", l'analyse (nettement plus grossière) de Fantasia par Infogrames me rappelle à quel point il est important de soigner la communication des règles du gameplay à travers l'aspect visuel. Le livre géant et menaçant qui est en réalité un bonus (et non un ennemi comme son aspect le suggère) et l'espèce de rond dans l'eau qui est en réalité une plate-forme.

Mais maintenant que j'ai le moyen technique de rendre les sprites transparents les uns par rapport aux autres, est-il intéressant de rendre l'encrier transparent ? C'est plus réaliste, sans aucun doute mais ça n'est pas forcément mieux pour autant. L'aspect d'Inkjet doit transmettre au joueur "solide, dangereux, mais pas blessant", et pas "fantôme immatériel mélangé à l'arrière plan". J'ai donc fort probablement commencé l'ajout des sprites rectangulaires (pourtant attendu depuis longtemps) sans que ça n'ait aucune utilité immédiate.

That being done, shouldn't the inkjet itself be translucent (against the background), and if so, how do I achieve that, given that the ink itself must remain opaque ? Basically, the only way is to separate the "glass" of the inkjet and the ink itself. That puts enormous stress on the vram as inkjet animation takes almost 1/4th of the spriteset so far. doubling it ? aouch. Hopefully, the ink only takes 16 pixels high, so that would be worth an update of SEDS to support wide (and tall?) in addition to square sprites.

Although its in progress, is it really wise to go that way ? Does the translucent inkjet on the right look better than the non-translucent (except for the patch) on the left ? Or does it rather look ghost-like rear object which you wouldn't expect to be solid and ride-able ? After all, form-fits-function is crucial in video games, and the only way to allow the player to have "eureka" feeling rather than progressing through frustrating trial-and-error.


Bref, c'est l'occasion de rajouter le terme "Form Fits Function" au tagtionaire... ce lien entre l'aspect et l'effet si cher à Miyamoto et qu'Infogrames a systématiquement ignoré.

PS: the DS also has 16-color sprites, and obviously, the inkjet shouldn't need more. Converting the whole sprite page into 16 colors could do the trick ... but that's not supported neither by the Game Engine nor by the Sprite Editor at the time of writing. At best, it's a wish.

PPS: pour ceux qui voudraient essayer le jeu, c'est par ici.

Monday, September 17, 2012

Let's get cracking

Okay, hardware is restored, it's now time to merge summer experiments and converge towards a platform for more pixels, more animations, more levels and more monster design experiments ...

  • [done] merge the 'z-order' branch back: it has proved it's a GoodThing
  • [done] 4-palettes LEDS must be backward-compatible with one-palette spritesets
  • [done] make sure we still see the background and monsters in 4-palettes LEDS
  • [done] restore disappeared iprintf (known bug)
  • [done] barebones to update colours on BG layer in LEDS
  • [done] ensure that LEDS runs on real hardware (fix blue screens when loading a .cmd file and when switching to colors mode)
  • [badbuild?] ensure it's still possible to L-pick tiles in draw mode
  • [bug?] need to press select twice in SEDS to enable PaletteWindow ? 
  • [done] something odd happens on SEDS when loading a spriteset while a non-zero palette is currently selected in PaletteWindow (palette #0 overwrites current slot)
  • [workaround] entering sleep mode breaks iPlayer's access to the media card.
  • [done] palette selection in AnimEDS as well
  • [fork] find something better than Window::swap() to structure widgets.
  • [bugfix] ensure that SEDS works in the noswap branch too (currently, it's all black!?)
  • [badbuild?] some widget only display randomly on real hardware
  • decide what to do with left-handed mode
  • [done] ensure I've got all the material to edit/test levels on the DSi (currently, something displays "T.M.A.P" and random tiles on the console, and the level doesn't load). LEDS apparently saved a map file as autoexec.cmd. Needs investigation.
  • [done] allow map2png.pl to work again
  • [wish] make map2png.pl work with swapped (and coloured) tiles too.
  • [done] complete the books tileset so that I can change books size (cf. CyanGmou's mockup).
  • [postponed] fix the landing bug for Bilou
  • [postponed] fix blador.cmd so that bladors can be stunned
  • [now] revamp the School's owl
  • [postponed] draw/animate some pendats
En clair, ça en fait du travail pour se remettre à avancer sur la School zone ... l'objectif, c'est bien sûr plus de souplesse pour construire les niveaux, plus de variétés dans les décors et de nouveaux monstres à développer.

    Saturday, September 01, 2012

    Back to School!

    Here's at last the demonstration of game engine improvement and new graphics for the School Zone, on a temporary soundtrack by Cyborg Jeff.
    There's no "gameplay" or "mission" yet: you can navigate through a single map, bop sponges and dumbladors and track bugs (there sure are some). The ink doesn't hurt yet, but the baddies do. How many roll-jump can you chain ?

    New features:

    • better animations with AnimEDS
    • transition animation (in jumps, mostly)
    • improved parallax scrolling
    Known bugs:
    • Bilou may pause at the end of a downward slope. Just release the DPAD and move forward again.
    • Bilou may get stuck in corners. I need to figure how and why.
    • Dumbladors can be trapped mid air.
    • If the bottom screen turns pink, you've entered debug mode -- known as InspectorWidget. Press 'L' trigger for frame-by-frame game or hold 'L' and press 'START' again to resume "normal" gaming.
    • if all you can see is "efs:/strtrk.xm not found" on black background, you're using an incompatible linker or emulator. If you're using desmume, you need to add "--gbaslot-rom=self" on the command line.
    Download SchoolTest.nds and have fun.

    Oh, this is the 700th post, by the way ^_^
    vu sur dev-fr.org, et - chose amusante - c'est aussi mon 700eme post sur dev-fr (et ça, je jure que c'est pas fait exprès :P)

    edit: just understood and fixed the slope issues.

    Friday, August 31, 2012

    pullmask working!

    That's quite an achievement for the z-order branch: I got the 'pull mask' technique working properly in the game engine. No more than 14 hours ago, I still had Bilou disappearing (with only one hand remaining) when I made him do a roll-jump. I also altered the engine so that a transition animation *always completes* before another animation is launched. Switching to mid-roll-jump transition to jump/fall transition just kills the whole purpose of transanims (offer some more smoothness). The "new Bilou" track is thus completed and ready for a new release.

    Après le décor, c'est Bilou qui - in extremis - est prêt pour la Grrande Riliize de Septembre. Il n'y a pas 14 heures, faire faire un saut-boule à Bilou le faisait disparaître presque complètement... c'est maintenant résolu. Les "transanims" sont donc prêtes à l'emploi et il me restera au plus à faire une copie-miroir du saut-boule (pour qu'on puisse aussi en faire vers la gauche ;) Mes nouveaux outils sprsplit, dumpanim et sprmerge ont été bien utiles dans la bagarre, si vous voulez savoir.

    Reste donc juste à peaufiner la map pour faire un premier schooldemo.nds... et là aussi j'ai une bonne nouvelle: je viens de retrouver sous un fauteuil le chargeur de la DS "phat" de ma fée (la DSlite étant en réparation depuis sa Grande Chute du mois de juin et la DSi pas encore homebrew-ready, mais j'y travaille :)

    Il me restera donc tous les aspects "collisions étendues" pour l'après-vacances.

    Friday, August 10, 2012

    next steps

    The July todo list is now completely check-marked. Many steps on animations are completed, and the Next Big Thing is to add support for the transanims that have been identified to be a mandatory addition to the game engine.

    • [done] Regarding the slopes, I'm still in the same situation as I was with Apple Assault. No better, but not worse either.
    • [done] dynamic sprite priorities are now supported by the engine, using them from the game logic needs some more thinking. However, I can easily try out transanims with just static priorities ...
    • [done] Enabling SEDS to store several palettes in one .spr file will open the way to tileset tinting. then will come AnimEDS, the game engine, LEDS and the game engine again.

    Saturday, July 28, 2012

    OAM priority issues

    I'm about to introduce significant complexity in the game engine for the purpose of displaying some compound animations properly. I've took the time to think about it (while drilling staircase for a kid-safety-barrier, if you ask :P) and figured out how to sort all the needed details. I just missed one point: this is absolutely not the only place where I need OAM depth-sorting.

    Remember of Apple Assault's frenzy, and how you could end up not seeing that appleman that runs towards you because it's actually sneaking behind a row of stunned applemen ? That's never been fixed to date because I had no way to instruct the game engine that "those stunned applemen should be moved to the background".

    Then I remembered of that "talk" by Rafael Baptista about resource management on the GBA. Before he entered the core meat of his talk, he suggested that copying OAM entries (you can think of them as sprite descriptors) could be the right time to follow a Z-order linked list and keep the "hardware" OAM entries and their "shadow" counterpart. Nice move, although I still wonder how he manages the scaling/rotation matrices along the way...

    I used to have a large, one-chunk DMA transfer of all the sprites & rotation information. I would have to split that in 3-u16 slices. That sounds like I'll have to pay sverx's report on memory copies performance benchmark a second - and more careful - read... and possibly opt for an intermediate - sorted, but in-cache - version out of the vblank period and then DMA that into VRAM when the vblank is hit.

    A final consideration: there is little chance that I need a fine-grained Z-sorting. low/normal/high priority should be enough in 99% of the cases, and the remaining case could likely be "sorted" out at GOB instanciation by internally sorting the OAMs the GOB received.

    edit: I asked myself the right question: 'is that move out of DMA sync'ing gonna cost me framerate or not ?'. From that point on, I hacked a modified version of my game engine, that uses CPU-driven copy with merging of OAM and rotations into one single table (as the DS hardware expects) and started Apple Assault with aggressivity setting turned at max (so many apples that you'll experience "ghost" berry bats and shots). Good news: it still works flawlessly (that is, I can't observe any slowdown). Next: the depth-re-ordering...


    edit++: just applied silly reverse-priority and order-enforcement-at-sync() in an AppleAssault check: it proves the concept: now Bilou can sneak behind stunned applemen. Useless, but you can't deny it's no longer the default z-order that is applied.

    edit+++: checked that a (Simple)Gob set on zlist[0] appears in front of (Compound)Gobs set on zlist[1]... now I've got to figure out how to use that best to implement the pullmask for my "roll jump" animation ...

    Sunday, July 22, 2012

    pullmask

    Je vous disais que l'animation de Bilou avait été fortement inspirée par Fury of the Furries ... Ça m'a donc semblé normal d'utiliser le "roulé-boulé-en-l'air" comme cas de test des "animations de transitions". Entre "je tombe" et "j'ai rebondi", par exemple.
    Après avoir dessiné quelques sprites de plus pour Bilou lui-même, je me suis retrouvé tout bête dans AnimEDS: pas moyen d'avoir les pieds de Bilou qui passent devant puis derrière son corps, vu que l'ordre d'affichage reste fixe.

    Bilou has Sonic and Fury-of-the-Furries influences, and one of them is rolling in the air. I wanted to use that as a test for transanims, and I started pixel'ing more rolling frame for Bilou's body. But when I opened AnimEDS to convert it into a full-blown animation, I just went ^^" : it's notwasn't built for animations where the relative order of limbs change over time. In short, the order you add limbs in the 'skeletton' also define which limbs obscures which other one. To do a roll, Bilou's feet need to be shown in front of his body in some frame, and behind his body on other frames. That just was impossible before AnimEDS revision 999 which features a "pull" button that let some limbs belong to a "second pass" rendering.

    Bon, maintenant, il faut que je trouve le moyen de faire ça *aussi* dans le moteur de jeu.

    The trick is easy to do in the animation editor: I can just use hardware OAM priorities and set ATTR2_PRIORITY(0) on those limbs that are on the "pulled layer". Unfortunately, that won't work in the game engine. I could end up with some limbs randomly appearing in secret passages or with other limbs randomly disapperaring when moving in front of complex background elements. The only viable option here is to re-order limbs in the Engine::sprites[] array. Let's see which is the best way to do it ...