Saturday, July 27, 2019

Refactoring "QuickGo" widget

I'm trying to make that "mini-map" widget better following good practice software engineering, so that I could maintain the rest of the tool more easily. I've done that refactoring one small touch at a time, in usually one-hour session while it was damn hot outside and while kids were sleeping in the living room.

It looks like I've introduced a few bugs with the refactoring, though. It's been a while since I didn't get something that messy !

edit: oh, btw, that got fixed through early August.

And yeah, I know, it's a bit odd to keep blogging such things. Likely something that is both a public version control and a social website would do the job, and 'github' would immediately come to mind. Unfortunately, A) I hardly trust Microsoft to keep running github nicely and B) github doesn't work with my boox device >_<

Thursday, July 18, 2019


My colleagues brought me from the habit of explaining lots of things through comments into the habit of writing almost no comments in my code. Explaining a lot came from my 386 assembly years, where I'd have to write code that does the desired processing on the one side, and carefully detailed what I was trying to achieve in the comments section.

The new fashion is to go from
sprtrsp(spr1, spr2); // make the sprite more transparent
makeSpriteTransparent(newSprite, oldSprite);

As I'm applying this over the QuickGo class to better see whether I can structure that code better, I still stumble upon code chunks that remain pretty obscure. Why the hell am I doing those computation on the map size ? and why the test with those * 4 multiplications ?

Hopefully, seeing the widget in action with up to 4 slices of the 'School Rush' level made me understand myself again.

When I want to fit a large stripe of level or a tileset into something that's closer to a square, I tend to cut it in two and put the halves above one another. If that isn't enough yet, I repeat the process. In each step, I exactly halve the largest dimension but double the other. It only makes sense to do so if I'm going closer to a square by doing so, that is if width/2 >= height * 2 when the image was currently wider than high. That exactly converts to width >= height * 4.

When that condition is false, I could still keep processing it further, but by doing so, I'd make the picture less readable. It doesn't make sense to consider it once we have reached the perfect square of course (the sprite rendering the mini-map is always square), but if we end up with a 3x2 rectangle and consider going into 2x3 instead, then sticking to 3x2 remains more readable.

Saturday, July 13, 2019

Monster selector

Okay, it's not much and it wouldn't even be posted alone despite I haven't been posting about tools development for weeks. I have now the 'selected monster' arrow showing you where on the map is the selected monster if you happen to get it off-screen.

But it is not alone. Changing that required more refactoring that I kept track of, and I'll have to break that giant "stash: okay, it works" commit into proper commits. It's not just that the code was old or buggy: my coding standards have quite evolved by working in a team where most of the code you have to deal with has been written long ago (and likely not by yourself).

It's not that much about the lack of comments. Having something like

// use sprite tile 0 for the cursor
sprites[CURSOR].attribute[2] = 0;

only works if this is the only place in your code where it can happen, and without coding habits that guide you towards

const oamno_t CURSOR_TILE=0;
sprite[CURSOR].attribute[2] = CURSOR_TILE;

you're very unlikely to get it done at a single place.

I had to fix things like that, as over time, I ended up with two widgets deciding to use sprite tile 0 for their own special purpose. I had to migrate the 'sprites granularity' into the recently-introduced "UsingSprites" class as I realised that more and more parts of the code now depended on that granularity (like whenever you're allocating sprite tiles) and top-screen and bottom-screen might not be using the same granularity...

Among the ugly things in LEDS code, I shall name a global "UI-like" object -- QuickGo -- that renders the level into a small bitmap, so that we can quickly navigate the level. That object is created in the 'MapEditWindow', but it is never inserted as a widget. It seems to be a global pointer, which is accessed through LayersWindow -- the part of the application where it actually shows up -- and even there, it doesn't directly reacts to user inputs. Instead, there is a 'QuickWidget' object that doesn't show anything on screen, but that does produce events on stylus touches that MapEditWindow will further catch and process.

Such a "code-that-works" approach that breaks almost every coding convention in the "GEDS" library is tricky to reason upon. You see QuickGo in a window, so you should be allowed to assume it is part of the UI, and used in that window. 

Tuesday, July 09, 2019


Salut. Je m'appelle Bilou et je suis explorateur de l'espace. j'ai eu le malheur de m'approcher un peu trop d'une planète non-répertoriée dans le quadrant 79.03.24 et j'ai été mystérieusement happé sur la planète. Mon astronef est hors d'usage, la planète pour le moins curieuse et mon sort serait lié à 7 pierres mystiques auquelles les autochtones prêtent des pouvoir magiques.

Je n'irais pas jusqu'à dire que je peux compter sur mon coéquipier et ami Bouli pour nous tirer de là : cette planète a l'air de faire ressurgir en lui tout ce qu'il semblait avoir réglé comme problèmes d'adolescent... quand il ne se fait pas tout simplement kidnapper *soupir*

centres d'intérêts: astroconduite, planetologie, haute-technologie, biologie des blobs, physique des plate-formes scrollantes, téléportation par ondes Wi-Fi, spirographe hyper-spatial, tir de précision à l'astro-flasheur à perforation en vrille

(c'était la présentation du personnage fictif "Bilou" sur Facebook, mais l'Ordinateur a décidé de remplacer ça par une "description de page" qui est malheureusement limitée à 255 caractères >_<

Toolset and MonsterPropWindow

I've got less free-reading time during my vacation this time, and likely, I should be not blogging right now, but cleaning up all the mess that going to vulcan(eifel) and back brought to the house. When I did get some time, I spent it clarifying some obscure parts of my Level Editor which puzzled me when I initially tried to add some additional monster edition features, like being able to decide within LEDs whether a given game object belongs to the 'hero' cast, the 'evil' cast or none of them.

I refactored a few things to make that possible already and I hope I'll get some time to continue working on it within the upcoming days.

I also took some time documenting one of the more elaborate (but arcane) widget that I might have to use to do that: the 'ToolSet' meta-widget, which is truly a bunch of buttons hacked to behave like the typical radiobuttons of point-and-click GUIs.