Showing posts with label asm. Show all posts
Showing posts with label asm. Show all posts

Friday, May 23, 2025

Microblaze

Bon, je vais pas faire comme si je m'étais mis au développement FPGA, mais je m'en approche de plus en plus. Assez en tous cas pour avoir commencer à programmer/débugger du code pour des soft cores, c'est à dire des processeurs réalisés à coups de LUTs et de flip/flops à l'intérieur d'un FPGA, qui a pour mission de piloter les différentes unités de traitement écrites en VHDL.

Et c'est l'occasion de découvrir quelques exotismes et autres vieilles connaissances en découvrant un peu l'architecture microblaze, chère à Xilinx. 

  • une instruction imm %%% qui permet de précharger la partie haute/basse d'un mot 32 bits qui devra servir de constante dans une des instructions *i, et ça malgré le fait que toutes les instructions font elles-même 32 bits. (ARM doit aussi jouer à ça, mais d'une façon moins sexy :)
  • un registre r0 qui vaut toujours 0
  • une variante addk en plus de l'instruction add, qui évite que le carry flag soit modifié par effet de bord de l'addition (le compilateur adore, même si ça a l'air un peu gadget la plupart du temps)
  • une variante brid en plus de l'instruction de saut bri, qui permet d'éxécuter malgré tout une instruction qui se trouve après le saut pour éviter de perdre le travail présent dans le pipeline (on avait ça sous le nom "deferred" sur le processeur IXP2400 de ma thèse ... ici, ça peut s'appliquer aussi aux sauts conditionnels (heureusement) et même aux appels de fonction !

the NIOS quest

I had learnt of Microblaze by my FPGA colleagues, of course. It felt a bit weird at first that you would use fully programmable silicium to remake a CPU because I was working on a design where there was a CPU onboard already. And yes, if I want my gates in the FPGA do what they have to (e.g. convert the proper video signal based on width and height), they need to be filled with proper values, and in many cases, a compact CPU fetching instructions from memory is more practical for the job than turning that into state machines that turn into FIFOs and LUTs. I still had to learn that not all of them are microblaze. There are actually so many soft cores!

In intel/altera technosystem, it seems that NIOS is the reference softcore. And readers, it is sure tricky to install. I finally got nios2eds/bin/gnu/*/bin/nios2-elf-addr2line and friends installed on my linux VM after I manually started QuartusSetup-23.1std.0.991-linux.run and manually checked the md5sum because the Intel Quartus Prime Installer was stuck in the "checking file integrity step" forever. Now that it is done, I should be able to close the installer, but it insists that it has a background task to complete. I don't see anything but the qinst processes ... I guess I'll have to kill them manually as well.

So much about not sending humans do machines' job.


Thu Apr 18 16:10:08 2024 INFO: Do download ...
Thu Apr 18 16:10:08 2024 INFO: Path: /tmp/intelFPGA_standard_23.1std
Thu Apr 18 16:10:08 2024 INFO: Total disk space: 21,83 GB
Thu Apr 18 16:10:08 2024 INFO: Free disk space: 4,44 GB
Thu Apr 18 16:10:08 2024 INFO: File: QuartusSetup-23.1std.0.991-linux.run resume position: 0

Thu Apr 18 16:10:08 2024 INFO: GET QuartusSetup-23.1std.0.991-linux.run
Thu Apr 18 16:11:30 2024 INFO: Downloaded /tmp/intelFPGA_standard_23.1std/QuartusSetup-23.1std.0.991-linux.run, 2671252465 bytes (status: 200)
Thu Apr 18 16:11:31 2024 INFO: File: max10-23.1std.0.991.qdz resume position: 0

Thu Apr 18 16:11:31 2024 INFO: GET max10-23.1std.0.991.qdz
Thu Apr 18 16:11:41 2024 INFO: Downloaded /tmp/intelFPGA_standard_23.1std/max10-23.1std.0.991.qdz, 300376601 bytes (status: 200)
Thu Apr 18 16:11:42 2024 INFO: Checking file integrity ...
Thu Apr 18 16:57:02 2024 INFO: Download stopped
Thu Apr 18 16:57:02 2024 INFO: Total download time: 46 mins 54 secs
A few tips about the machine code
  • uses the RISC-typical approach of OP dst, op1 [,op2] except for store instructions that follow STx data, target(offset)
  • movhi reg, 0xcafe ; addi reg, 0xbabe is the natural way to put 0xcafebabe in some register
  • arguments in function calls are put in r4, r5, r6, r7, ...
  • function calls can fit 1 32-bit word.
  • it is not unusual to see a bunch of ldbu reg, ...; stb reg, ... in place of a memcpy call (for small amount of data)

Wednesday, December 11, 2024

Des nouvelles de Crazy Brix

February 9th, Case Portman, author of the platformer game "Flynn, son of Crimson" was asking

The first ever game you developed, "finished" and publicly released. Show the world (don't be shy!).

In my case, that was Crazy Brix. More a technical demo than a real game. A breakout clone with raytraced graphics and 6-tracks. His was "Blappy Fird", a clone where a pipe must avoid columns of birds. But Brix eventually turned into a 100K compo entry that got 1st place at Inscene, so I count it as "publicly released". I got a few tokens of appreciation, but also a fun feedback and congratulations from Joke

C'est parti d'une question/chaîne comme il en apparaît régulièrement sur twitter: l'auteur de "Flynn, son of Crimson" avait lancé "montrez votre premier jeu grand-public" avec quelques captures d'écran de son blappy Fird. J'ai suivi en postant à mon tour les quelques images de Crazy Brix qui illustrent les pages que mon frangin lui a consacré dans son blog musical.

Parmi les réaction, les félicitations de Joke:

c'est impressionnant tout ça dans le contexte 1997/langage machine/pas d'Internet... vous êtes des génies ! -- Joke, Biloumaster

Mais il relève aussi au passage le côté un peu discutable du décor de fond, image zoomée à l'appui. Alors je pars à la fouille aux archives et je retrouve un répertoire BRiX avec des fichiers "NEXT.PCX", "EGYPT.PCX", etc. voilà donc à quoi le jeu aurait pu ressembler sans l'intervention du raytracing ... et je dois dire avec le recul que le décor présenté à la inscene est peut-être discutable, mais au moins on arrive à voir sa balle et sa raquette. On ne pouvait pas en dire autant de l'original.

And digging for archives of Brix, I found old pictures from pre-raytracing era ... initial "all flat" bricks, mock up showing tentacle bobs attacking and sized-up bat suggesting an arkanoïd clone for the second title.

There was also a second tileset intended for "egypt theme" that never got used. 

Je n'ai pas souvenir que le thème égyptien ait jamais été utilisé, pas même pour des tests. Il faut dire que ça n'a jamais vraiment emballé mon frère au niveau musical ... 

Je reposte un coup tout ça sur bluesky, et je tombe de ma chaise en découvrant que pix3l connait mon jeu ... il y a joué, aux alentours de 2010. Que le jeu est maintenant repris dans la machine à voyager internet dans le temps: archive.org !

That happened a few days after I created my BSKY account, so I posted pictures there too and to my surprise, I got someone saying

I played this one back then 😁 My first developed game was a collection of arcade games, like pong, breakout and tetris, but nothing special tho... :] Still need maintenance nowdays... -- pix3l on bluesky
It was some years ago, 2010 if I remember correctly... I think it was this one, or just another arkanoid clone, but I'm quite sure it was this one, since it looks pretty familiar :/ Its also on Internet archive, and published in 1999. Whats make strange to you? ó.ó
I've played a lot of games myself, also the more obscure ones, and sometimes I've reviewed them on my blog. Maybe this one has been came out in some search, I don't remember now :]

So there it is. Not only Crazy Brix was a publicly released game, it is now archived, playable online (although sound will be crappy until you figure out how to increase cpu rate). Oh, and it is used by dosbox folks to improve their code, apparently. And while I was in the mood for posting old BRiX pictures, I finally found the name of the game that inspired me to make a breakout clone in first place: the MS-Dos title "powball" (which I thought to be "powerball", and thus couldn't find anymore). It's a game released in 1997 I most likely discovered through the PC-Team sharewares CD. It featured the original idea of mixing a breakout and a shoot-em-up. Oh, I know: you were already seeing some shoot-em-up elements in Arkanoïd, but did you see your paddle morph into a spaceship ? could you purchase upgrades with collectibles you got from breaking bricks ? I don't think so.

Et en creusant après ces images, je finis par tomber sur un nom de casse-brique que je cherche depuis la création de wikipédia ... mais que je cherchais sous le mauvais titre. C'était le mélange parfait entre shoot-em-up et casse-brique, avec des graphismes raytracing lui aussi, mais de bien meilleure facture, des trucs à ramasser dans tous les sens pour pouvoir s'acheter des améliorations à son vaisseau et donc augmenter ses chances dans les champs d'astéroïdes ... que notre balle ne peut malheureusement pas casser. J'ai nommé Powball que j'ai cherché sous le nom "powerball", ce qui ne donnait évidemment rien ^^" . Oh, et bien entendu, powball est aussi dans le "dosbox archive", mais on ne va pas se mentir: c'est totalement injouable.

un tout premier écran-titre pour Brix, qui n'a manifestement pas plus, mais où le logo de PPP Team est bien reconnaissable
Un autre candidat d'écran-titre produit à partir d'une "heightmap" qui m'aura finalement surtout servi d'écran de boot pour Windows 98 :-P

Sunday, September 19, 2021

Eclipse Operating System

Un de mes objectifs en 1997, c'était de parvenir à maîtriser le mode 32-bits des PC. Windows était encore un hybride 16/32 à l'époque, et pas franchement convainquant pour la programmation de jeux. Tous les jeux dos parus sur les dernières années annonçaient "Dos4GW" ou quelque-chose de ce genre, et la taille toujours croissante des modules de mon frère me faisaient bien comprendre que "640Ko pour tout le monde", ça ne serait plus suffisant bien longtemps.

Seulement voilà: basculer du mode 16-bit au mode 32-bit (connu à l'époque sous le nom de 'mode protégé'), ça demande une rigueur à tout épreuve et ma documentation était malheureusement plutôt imprécise. En plus, les fonctions du BIOS et du MS-DOS deviennent du coup inaccessibles (plus de chargement de fichier ni de changement de mode graphique, par exemple). Et au milieu de tout ça, je tombe sur une pépite venant de la démoscène: Eclipse Operating System et son jeu-démo Greedy. Il me lancera à la recherche du Watcom C++ sans lequel on ne sait pas recompiler les exemples. Une chasse qui durera jusqu'à la Inscene, si ma mémoire est bonne.

edit: on présentait Greedy dans le PC-Team #15, p. 78. C'était en Juillet '96, il était proposé en shareware et était toujours baptisé "eclipse pacman"
Du coup, il faudra que je vous parle de Slurp'n'Burp

oh!? on dirait que c'était Rez à la bande son !?

Thursday, April 08, 2021

Retro Game Dev

My brother got me a copy of Derek Morris' book on C64 game development. It is more or less a printed tutorial to his studio-like application that features code editor, resource packer, Commodore emulator and C64 graphic editors. I haven't managed to run that in WINE so far, unfortunately, but reading the book was already quite interesting.

One nice thing is that the games discussed in the book are programmed in assembly language. So we can skip the usual PEEK and POKE things and start straight with the main meal. I'd love to be able to say that the libraries that come with the studio let you focus on your game logic without having to figure out how to pull joystick state and push tiles into graphics memory, but the reality is that it adds a layer of confusion instead of abstraction.

Things like Screen_SetColors or Sprite_SetFrame are understandable and generic enough, but the "particles system" using special background characters to emulate more sprites would have been nice to see discussed in the book. Same goes for a few more key algorithms like map update after something got picked up, played monster collision, and the like.


A défaut de la démoparty espérée pour mes 42 ans, mon frangin m'a dégotté un bouquin sur la programmation de jeux pour C64. Il faut dire qu'entre Wolfling, PowerGlove et Relentless, mon frangin avait eu le temps aussi de cogiter à une adaptation de Spector sur C64 (mais bon, lazycow a finalement remis le couvert avec le chapitre II de Wolfling). J'imagine que ça pourrait être un appel du pied.
Le côté intéressant, c'est que le bouquin ne s'embarasse pas des PEEK/POKE bien connus de ceux qui ont essayé d'aller plus loin que le PETSCII en BASIC: ici, on code en assembleur. Enfin ... d'une certaine façon.
A côté du bouquin, Derek Morris nous propose en effet un "studio" pour windows, avec éditeur de salles, de sprites, de tiles et compagnie et une série de bibliothèques de macros pour pouvoir commencer son petit titre sans devoir se farcir les détails techniques de la programmation hardware de la bête.
C'est sympathique (et plus gamejam-friendly), mais ça transforme aussi une grande partie de la lecture en une sorte de visite-guidée-faites-moi-confiance où ira rarement plus loin avec l'assembleur qu'une petite augmentation du score ou une bidouille de la vitesse, parce que le reste se situe généralement à l'intérieur d'une macro qui n'est pas reprise à l'écran. Pour celui qui est curieux de savoir comment les tirs, les collisions ou les mises à jour de maps sont gérées, bin il faudra ouvrir le .zip parce que ce ne sera pas dans les pages.

Ah, par contre, sorry frangin: la gestion des musiques de fond, c'est aussi réservé au tome 2.

It is also a bit disappointing that the "engine" is only capable of scrolling 1/3rd of the screen, and thus the "platformer" example looks more like a simplified Wonder Boy title than the Great Giane Sisters.
60-fps full-screen scrolling requires page-flipping and interrupts, says the last page. It's a starter kit, in a sense, not a PhD thesis on Wolfling-like guru techniques that would push the limits of the machine. Well, I guess starter kits are good to have too, aren't they?
Now ... maybe for game jams ...Yes, I think that could be a good setup for an 8-bit game jam. 
 
edit: j'étais étonné de voir des macros un peu dans tous les sens dans le bouquin, et en particulier des macros qui font des appels de fonction ... un tweet vient de me faire comprendre pourquoi: sur 6502, on va devoir se souvenir du "protocole" d'appel de chaque fonction, qui n'a rien à envier à celui des appels systèmes MS-DOS. Si on a pas envie de se souvenir "mets la destination dans X, la source dans Y et la longueur du bloc à copier dans l'accumulateur", on peut se faire une macro qui prendra 3 arguments "simples" (disons une constante ou un nom de variable) et qui prépare l'appel à la fonction block_copy. Ce sera plus flagrant encore si on doit accéder à un chip externe avec un protocole du style "écrit le numéro du registre vidéo à l'adresse $8000 puis la valeur en $8001. Recommence ensuite avec la coordonnée Y que tu mettras dans le registre vidéo suivant".
Par contre, suivant le conseil de Mario Nesrock, on garde ses macros dans les sources principales (on ne les planque pas dans un .zip) et on les garde courtes (sinon gare à la taille de sa ROM).

Friday, February 05, 2021

Programming Pitfall Harry

L'aventure racontée par 8-bit show and tell est presque surréaliste: un dévelopeur de jeu qui vous envoie un morceau de son code source comme ça, juste sur demande. Et pas n'importe quel développeur: le créateur de Pitfall!

Pitfall, pour ceux qui n'ont pas vécu ça, c'est ce qui se rapproche le plus du phénomène Super Mario Bros pour les possesseurs de micro-ordinateurs jusqu'à ce que Great Giana Sisters ne devienne facile à trouver.

Je m'attendais à un bouquin/carnet déjà costaud, du coup, en fait, la chose tient sur l'espace de menu de mariage. juste une page US letter pliée en deux, l'extérieur contenant un petit mot du créateur et des illustrations.

C'est un programme a priori typique de la "programmation système" en BASIC C64, avec plein de POKEs pour modifier des registres du contrôleur vidéo et des DATA avec les trucs à y mettre. Le machin bien opaque pour qui n'a pas un bon manuel pour décrypter ce qui se passe. En plus des DATA avec des sprites convertis en décimal, il y a un autre jeu avec du code machine pré-assemblé qu'on va aller POKEr dans un coin de mémoire pour pouvoir l'exécuter. (Là aussi, il y a un bouquin, mais c'est plus chaud).

if you speak English, you're lucky. Because that means you can enjoy the full 8-bit show'n'tell where the story of that 'Programming Pitfall! Harry' leaflet that invited kids of the eighties to type from scratch something that would make the most iconic video game adventurer of the time do a footing on their screen. I mean it. That dude was the early eighties' Lara Croft.

If you've done some C64 programming, the content of the leaflet will be obscure but somewhat familiar. It's a loop POKEing things in memory so that the video chip (VIC-II) can render sprites and some obscure DATA that contain what it takes to get pixels the expected shape. There's something alike in the C64 manual to make your first sprite and I had tweaked a lunar lander BASIC game to feature Calimero instead of the LM back in my 10s.

Au final, on aura 'juste' le personnage Harry qui se promène à l'écran. Ouaip, je vois déjà les blasés du Scratch qui rigolent au fond, mais eh. 1) il est multi-colore. 2) il court (animation) et bouge tout à la fois. 3) il est grand. Rien à voir avec la démo-ballon du manuel C64, hein!

Et surtout, tu fais RUN STOP pour revenir à l'interpréteur BASIC, et le mec, il continue son footing. C'est le Mario-de-l'éditeur-de-Bisquit avec 25 ans d'avance!

En fait, on a pas ici une boucle BASIC qui anime et déplace: c'est un morceau de code machine installé juste avant le code qui fait clignoter le curseur texte qui s'occupe de faire bouger le personnage. Tout ça tenant dans le tampon mémoire prévu pour la lecture des cassette.

Pour se situer, le tape buffer utilisé dans le programme présenté dispose d'à peu près 200 bytes. A côté de ça, l'autre zone mémoire qui est disponible sans toucher au setup habituel pour faire du BASIC fait 4K et se trouve en 0xc000, juste avant les ROMS CHR et KERNEL.

But there's actually more here. You don't have to interrupt the program to return to BASIC interpreter: it does it by itself. And yet, Harry keeps footing on your screen while you can tweak the program or scratch it and run another one. That's because you haven't only POKEd some sprites data: you've also POKEd a small assembler routine that will be invoked ahead of the cursor blinking logic that will move and animate Harry's sprite.

I can only dream of what I'd have done with this if I had been exposed to such a sample when I was a C64 teenager. Think of it: tweak a few locations in memory and you could switch the character's behaviour between jump, idle, run, fall ... Chain a few other routines in a BASIC room-loader with POKEs and you could have a monster patrolling on line 42 while your character is running on another location. And you're free to run your loop checking their positions, computing whether collisions occured and adjust their behaviour if it did.

With some extra LDA and CMP opcodes, maybe the characters under the sprite could be checked and a flag could be set so that the BASIC code would know we've entered a 'FAIL' condition ...

Je ne peux m'empêcher de penser ... et si ... Et si au moment de commencer à travailler sur Logic Labyrinth j'avais eu accès à un petit programme de ce genre qui puisse déplacer un objet de manière quasi-autonome.

On aurait gardé un programme BASIC qui dessinerait la bonne salle et ajouterait quelques POKE pour chainer les uns derrière les autres character_interrupt, puis hshot_interrupt et walking_monster1_interrupt pour que les différents "personnages" de l'écran soient présents.

Ensuite, on aurait eu une boucle qui faisait de son mieux pour tester la position du personnage par rapport aux triggers du niveau et qui aurait fait apparaître ou disparaître certains éléments...

VRAM tricks used by Lazycow
Mais bon, mon seul contact avec le code machine du C64, c'était en 1997, 10 ans trop tard, et tout ce que mon bouquin proposait, c'était de charger un bout de code pour remplacer les caractères ROM par des caractères RAM histoire de pouvoir remplacer le T par un smiley.
Par contre, il faudra que je tire au clair cette histoire de 'VIC bank'. Quand j'ai commencé à écrire des programmes plus grands (pour Space Mission) mélangeant des tableaux de grande DIM(ension) et plus de sprites, je finissais par avoir mon programme qui provoquait des "erreurs systèmes", au point que le listing lui-même n'était plus garanti. Et si c'était simplement parce que j'écrasais des morceaux de listing avec mes POKEs ?


Friday, March 30, 2018

Aladdin Sources Analysis

They made a wonderful job at gamehistory.org, based on an in-depth analysis of the sources of the Mega-drive game "Aladdin". The game was made by David Perry's team who also brought us Cool Spot. At the core of their work is a technique and a toolset to allow more flexibility in animating graphics on 16-bits system that had read/write video memory on-board (as opposed to NES with read-only video memory alone, on the cartridge) and fixed-size sprites (e.g. 16x16, 16x32, 32x32).

https://gamehistory.org/aladdin-source-code/#sect_36Everything else will seem silly to you if you do not accept that, by then, getting more KB of memory for your game was very - very - hard. The size of your game was decided by non-technical people based on how much the console vendor would charge for a 2Mbit chip, when the game should came out and how much kids would be allowed to spend given which license you'd be using. So they have early planning deciding how much to dedicate to sprites, levels, code, maps, etc. Based on that, they'll decide how much levels there will be in the game, etc.

Of course, game characters animation all started by having characters whose size fit the hardware requirements (mario nicely stands within a 16x16 box and a 16x16 mushroom makes him 16x32), flipping from one sprite to another within an all-in-VRAM bank. Then some special characters (the hero) would get a special status and only get one or two VRAM slots dynamically updated. To crunch more animation frames, one could use run-length-encoding compression that does wonders on row of pixels of identical color. Others have used 2/3-bit-to-4-bit decompression once realizing that Link sprite (and all others) only need 8 colors per palette, not 16. But all this requires CPU, and the CPU resources too, were limited (Not even 8MHz. Less than my good old 80386).


If we could instead keep the same binary format between the ROM and the RAM, having the right picture in video memory at the right time is all a matter of "blasting" them through the Direct Memory Access chip. See that big line on my notes ? that's the DMA doing its job, while the CPU can focus on crunching numbers to make the game physics stunning and fun...

To make that possible with fun stretch-and-squash, cartoon-like animation, they ultimately relied on their chopper tool that cuts pictures into hardware-sized sprites. Just like the one I imagined for Titus's Prehistorik II sprites.

Ok, granted, it doesn't look completely automated. But the idea is clearly there. And ultimately, it would run on a system that has 1/4 of the power of my Nintendo DS.

So, am I allowed to dream of porting some libgeds game on 16-bit engines ? Well, with the engine refactoring that splits script parsing, it is pretty tempting to see what we could do about it.


Let's start with the animations, thus. What is weird with the animations is that their code has to interrupt every here and there when there is some delay. In high-level language, we'd likely use a switch construct branching you to frame T or frame T+1 code depending on some argument we'd pass to the function. But if we're generating machine code instead, we can do much better. We can then have the actual next animation instruction remembered, rather than an index into an array of virtual instructions. No more conditionals and branch delays on that non-speculating old CPU. Just one jump.

Implementing "keep that state for N screen refreshes" is then looking a lot like software multi-threading: you have a call to some yield_animation micro-routine (and saving your current position into the generated animation code on the stack), which will pop that resume position into some CPU register (an internal scratch variable, in case you didn't know yet), and then return to the code that called animate_aladdin, letting it save the next animation position where it sees fit. Looping animation ? super-easy ! Have you seen how much boilerplate the current virtual-RISC-processor-for-animations of libgeds and AnimEDS must deal with instead ?


What else ? State machine of course. State machines are built with simple expressions used either to guard transition (only let them used when some condition is met) or to define what to do when the transition occur (besides changing states, that is, like playing a sound, changing speed, etc).

The collision system currently will follow a list of GobExpressions calling eval(guard_predicate) until one returns true, then proceeding with eval(action) and changing state. Instead, with generated machine code, that would all be packed into a sequence of predicate code that branch to the appropriate action code or keep testing until we hit the "okay, then nothing happens" terminator that returns to the collision system itself.

One day ... maybe. That would be much more interesting on 16-bit than it would be on DS or native x86_64 code, anyway.

edit: for more background information about how things actually came into existence, seeing tools and teams in action, don't miss the excellent "Splash Wave" episode on the game.
 

Monday, October 23, 2017

out'm'up

The inscene'99 visit had been quite as success, especially regading the 100K game competition. My brother and I then tried to figure out what we would do on the next instance - obviously, our chance of making a good game were higher than making a big demo like the one envisioned for "samedi, tous in my home".

A comment by my peer "Gedeon" about how it was a shame that crazy brix was only using boxes for collisions pushed me towards the implementation of some pixel-perfect collision routines. I remember I wanted to do some pinball game, but after all, it was decided to go for a shoot-em-up. Our secret "games to do" folder had a long list aborted shmups, from the "Polycosmos" conversion of "space Mission", the failed "cosmowars" on RSD Game-Maker, and the aborted "Bilou sky quest" ... Nothing getting any close to our childhood golden award "Warhawk". So I picked the "Tyrian" palette and started to pixel some ships.

Retournons au passage à l'an 2000. La Inscene '99 avait plutôt été un succès en particulier pour mon jeu 100K, Crazy Brix. Deux choses étaient claires: 1) on y retourne l'an prochain et 2) on a plus de chances de parvenir à refaire un p'tit jeu en 1 an que d'aligner une mégadémo sur le thème "Samedi tous in my home"... Gédéon m'avait motivé à dépasser le simple test de boîtes de collisions pour le prochain titre. ça pourrait convenir pour un pinball ou un shoot-em-up. 

Des shoot'em'up abandonés, j'en ai déjà une belle liste derrière moi, à l'époque: le Space Mission pour C64, la BD impliquant le polycosmos, le "Bilou Sky Quest" annulé par un verre de Franta et le Cosmowars foireux sous Game-Maker. Pourtant j'aime ça quand c'est bien fait. Que ce soit Warhawk ou Tyrian si il y a des étoiles et des barres de vies, je suis partant. Et comme j'avais la palette de couleurs de Tyrian sous la main, justement, je me suis lancé.

The assembly code for crazy Brix was quite horrible, and I remember taking care of increasing the quality of the organisation for out'm'up. Especially, frames-to-aminations, level layout, and to some extent the sprites behaviour were described in a "data-oriented" macros system that looked a bit like game script, but converted straight into binary pointers and values -- something that was apparently common in MegaDrive games development.

The second key development was to support a dynamic list of sprites, allowing fancy explosions, lots of shots and even powerups where crazybrix couldn't even accomodate for anything but a ball and a paddle. Two lists, in fact. This engine was the first time I decided to split objects in two separate casts to reduce the amount of collision checks required.

While the level design wasn't very inspired, the game received a brilliant soundtrack, a classic but good-looking starfield effect and Out'm'Up won the first place - although mostly due to the lack of significant competition.

Même s'il a disposé de 3 fois moins de temps que Crazy Brix, Out'm'Up a eu droit au niveau programmation à tout ce qui faisait défaut à son prédécesseur: des effets d'explosions, des power-ups, des sprites ennemis, des niveaux programmables.

J'avais même une structure 'scriptable' pour permettre à mon frangin de passer au level design une fois le travail sur le son terminé, mais il n'y a jamais montré beaucoup d'intérêt. L'aventure s'arrêtera donc une fois la première place de la Inscene y2k empochée. Ce sera mon dernier projet en VGA + S3M. mon dernier projet MS-DOS.

Sunday, January 10, 2016

100 bytes for a level

Il m'aura fallu me promener dans le code désassemblé de Super Mario Bros 1 pour finir par y croire. Oui, sur cette cartouche de 40KB, les niveaux sont extrêmement compacts. Oui, la technique pour en faire le rendu est à la base de ce que j'avais observé avec l'éditeur pour NSMB: bien que le hardware travaille avec des "tiles", le niveau est décrit par une série de commandes (un byte de coordonnées, un byte indiquant le type de commande et éventuellement une taille). On aura ainsi des "un tuyau de 3 blocs de haut" puis "une rangée de 5 briques" et "un escalier de hauteur 3". Voire même "un trou dans le sol de largeur 4". Pas de "patterns extensibles" derrière ces codes, mais directement du code assembleur!
Les buissons, nuages, le sol sont eux décrits sur une autre couche qui est utilisée en premier lieu pour remplir la zone mémoire sur laquelle le niveau sera ensuite dessiné.

Thanks fly to Daniel Turner who teased my interest for how SMB1 encoded its levels. The cartridge was incredibly small (40KB) and indeed encoded levels as a list of "painters" operation, each giving a coordinate on the current screen, a type and possibly a size. Painters are simply dedicated assembly routine, and thus they could have something as complex as "add a staircase of 9 steps".

What I beleived to be an original technique in NSMB was thus a good old recipe. Would it be useful to shrunk those 64K levels of Bilou : School Rush ? Well, hardly, because compared to SMB1 I have much more variety in the graphics of the level, and I used those "alternate tiles" to make books, folders and pencils looks as unique as I could and avoid giving the feeling of a world built by copy-pasting. That's a bit sad, because SMB approach definitely makes editing the level much easier.

L'équipe RD4 aura profité au maximum du fait que le jeu ne fait pas marche arrière: le niveau est encodé écran par écran, et les coordonnées des objets sont données à l'intérieur de l'écran en cours. Un marqueur est ajouté aux objets qui se trouvent sur un nouvel écran par rapport à leur prédécesseur. (I AM ERROR) Il faudra attendre que SMB3 embarque une RAM additionnelle dans sa cartouche pour que le jeu puisse se souvenir des blocs déjà cassés et des pièces collectées, rendant ainsi possible une navigation plus libre dans le niveau (/I AM ERROR).

Un monde de différence, donc, avec le stockage brutal d'un tableau de MxN éléments que j'utilise dans LEDS (avec des niveaux de 32 ou 64KB. Plus gros que l'entièreté du jeu SMB1, donc), mais qui me permet en contre-partie une souplesse totale pour que les livres ne soient pas tous exactement les même. Allez, apparemment, une simple compression .zip pourrait réduire les niveaux à une taille d'environ 8KB.

Tuesday, May 19, 2015

Life-changing books [3/3]

1998. Bilou devient la cerise sur le gateau du projet "Ultimate Game Maker". Pour le réaliser, j'ai attaqué très sérieusement la lecture des documents (et les sources) de TRAN sur le mode protégé du 80386, les moyens de passer en mode "unreal" (code 16 bits avec données 32 bits) et ce genre de choses en ligne droite de la démoscène PC.

Many game development studios faced a hard time switching to 2D to 3D at the end of the 90's. Things were quite troublesome for my little self too. I had at last access to massive knowledge about VESA, sound cards and newer tools such as DJGPP compiler and early mikmod player source code ... but it was clear 320x200 MS-DOS games were gone for good. My quest for an improved Game-Maker software turned into a quest for a better operating system to run both game engines and game development tools. Filesystems that would make sharing of samples across a large bank of tracked songs trivial, etc. The cornerstone book for that shift is Andrew Tanenbaum's book on operating system, found somewhere in the university's library, and it will stay at my home, studied dailynightly as the Clicker 32 operating system project shaped up.

Je tombe ensuite sur un bouquin à la bibliothèque universitaire qui présente les structures de système d'exploitations avec environ 2 ans d'avance sur la matière dans mon cursus. Pendant à peu près 8 mois, le bouquin sera emprunté presqu'en permanence, et je remplis des carnets entiers de notes de lectures, d'idées pour aller au-delà des techniques habituelles avec l'idée de construire un système idéal où les politiques de gestion de mémoire et de temps CPU peuvent être échangées en temps réel (comprenez, lors du démarrage ou de l'arrêt de Bilou pour revenir au game maker).

Je vais ensuite tomber sur une description assez détaillées de Linux pour me permettre de définir les objectifs avec assez de précision, et identifier les aspects originaux de mon propre design. Un grand nombre des idées de base visent à donner une sensation de programmation Amiga sur une plate-forme multi-threads x86, avec les pilotes de périphériques vus comme des sortes de co-processeurs. Cette quête va m'occuper l'esprit jusqu'à mon travail de fin d'études et au-delà.

A second book, detailing the internals of the Linux system further refined what I did not wanted to have. Like a monolithic system, purely based on function calls. I wanted to give the programmer in the Clicker operating system the feeling to work on a virtual Amiga-like platform, with programmable co-processors for virtual memory, sound mixing and window compositing tasks, where you could hot-swap the process scheduler.

All this started 100% assembly, but that project taught me to use the C language for what it is and to avoid assembly whenever possible. The reason was you are too much bound to what you write. Do you realize there's a mistake in your algorithm ? you'll be to go through registers allocation planning and pipeline optimization once again.


Le projet Clicker sera aussi celui qui me fera lâcher l'assembleur pour chercher à comprendre le véritable fonctionnement du langage C grâce au bouquin de Kernighan & Ritchie. Les algorithmes utilisés pour la gestion de la mémoire deviennent tout simplement trop sophistiqués pour rester écrits en assembleur. Corriger une erreur de conception dans un code de recherche "best fit avec back-tracking" revient à reprendre le design d'une page blanche, re-réfléchir à l'affectation des registres et revoir tous les efforts destinés à assurer un comportement optimal sur le double pipeline du Pentium. C'est tout simplement intenable.

Thursday, March 10, 2011

Life-changing books (2/3)

When I turned 17, it became clear that I couldn't realise all my projects with BASIC alone. I opted for physics/chemics labs rather than computer labs, unfortunately, and the teacher wouldn't let me get a copy of the Turbo Pascal she was using for her courses. "It wouldn't make any sense to me without her teaching" or something alike.

A friend of mine (later known as Parmy in PPP Team) had a copy of A86 -- a 16-bit assembler for dos -- left over a floppy, and a book "Easy Assembly" he never really made sense of. Being from the 8-bit era, "Assembly" meant to me "the language of gods" and "blazing fast execution speed", so I immediately accepted the offer and started studying Intel's instruction set.


Vers 16 ans, je commençais a avoir fait le tour de ce qui peut se faire en BASIC. J'avais (mal?)heureusement préféré les cours de labo physique/chimie l'année précédente, et la prof d'informatique ne voulait pas me faire une copie du Turbo Pascal sous prétexte que je serais incapable de m'en servir sans suivre ses cours. Grmbl. En allant expliquer à un de nos nouveaux amis (que l'on connaîtra plus tard dans PPP Team sous le nom de Parmy) mes techniques graphiques en BASIC, je tombe dans sa bibliothèque sur un bouquin "L'assembleur facile" et une diskette 5'1/4 estampillée "A86". "Je ne m'y suis jamais vraiment mis", me confie-t'il. Pour un enfant de la génération 8-bit comme moi, l'assembleur, c'est comme le langage des dieux. J'emprunte sans hésiter le bouquin et je me mets à potasser le jeu d'instruction des processeurs Intel.


After I showed my uncle my first assembly program (iirc, a password-prompting tool to prevent my sister to mess up with "our" computer), he brought me a box full of low-level C64 stuff, including a copy of "programming the 6502" book, a disassembled and commented dump of the C64 kernal rom, an EEPROM programmer (with no EEPROM provided) and other similar books. SYS 49152 was no longer a mystery to me -- although POKEing machine instructions from a BASIC program wasn't a very sexy way to proceed. It took me time to wrap my brain around the LIFO stack concept ...
I never really "programmed" the 6502 at assembly level, as it was already a decade-old machine, but I must admit the beauty of 6502's instruction set simplicity has been inspiring to many regards... more about that in part 3.

At last, mastering assembly and the Ms-DOS service interrupts allow direct manipulation of any file format, opening up countless possibilities.


Voyant mon premier programme assembleur, mon oncle me propose de reprendre une caisse de documentation technique sur le commodore, dont une copie d'un livre d'introduction à la programmation du 6502 en assembleur -- le processeur du commodore 64. La caisse contient un programmateur d'EEPROM pour faire "de véritables cartouches" façon Rick Dangerous. Je bave. Je prends. Il n'en sortira pas grand-chose, cependant, hormis une meilleure compréhension de cette machine de rêve définitivement désuète et une admiration sans borne pour la simplicité de ces LAY et LAX. Mais n'anticipons pas.

Knowing the assembly language, however, wouldn't be of much use without knowing the hardware that sits around the CPU. A "PC" was still fairly simple by that time: everyone had a VGA-clone video card (super-VGA was only slowly starting to be adopted, and not by game vendors) and a Sound Blaster clone. Both and more were discussed in the "Bible of PC System Programming", a fairly huge book that I borrowed to another friend -- later known as Nowan -- before I got myself a copy of my own. He also let me grab another Sound-blaster related book (ISBN 978-2742901951) from the same editor, which was describing "how to build a 4-track modplayer from scratch -- in Pascal".

Bien sûr, l'assembleur tout seul ne servirait pas à grand-chose sans une meilleure compréhension du hardware du PC. Fort opportunément, c'est approximativement à ce moment qu'un autre ami (connu plus tard sous le pseudo de Nowan) va me préter coup sur coup la bible du PC et le supergrand livre de la SoundBlaster. Me voilà plongé de plus belle dans les documentations techniques, et armé jusqu'aux dents pour attaquer la conception 100% assembleur d'un modplayer -- pardon un S3Mplayer -- qui devra être le coeur de l'Ultimate Game Maker. J'aurai bien un petit jeu réalisé (Crazy Brix) fin '97, qui sera amélioré plus tard pour la Inscene '99, mais UGM restera un tas de papier attendant la réalisation de mon propre OS -- Clicker, une idée de Nowan, à l'origine -- le Windows 95 ne pouvant définitivement pas convenir pour nos projets.

I still had no Pascal compiler by that time, and I was sufficiently confident that, with that knowledge and the S3MINFO.TXT file shipped with my brother's Scream Tracker III, I would be able to run a 8-track Stereo S3M player instead, with 2 tracks dedicated to sound effects and 6 tracks dedicated to background music. I started copying every meaningful bit of information into a smaller draftbook, easier to carry around and not to be returned to a friend by the end of the month ^_^

According to my brother's archive, it took me another 6 month to convert that idea into something capable of replaying some simple modules. I never made it "the corner stone of the ultimate game maker" as I initially intended, but it was the core of Crazy Brix and Out'm'Up, the two awards-winning 100K game at Inscene'99 and Inscene'Y2K, respectively.

Wednesday, June 02, 2010

BRIX.TXT

Amusant, ce qu'on retrouve dans les fonds de tiroir ... voilà le fichier "readme" de mon premier jeu en Assembleur pour MS-DOS: Crazy Brix, qui (2 ans plus tard), remporta la compétion "100K games" à la Inscene'99 ... A défaut d'Internet, à cette époque, je tentais de voir mes jeux paraître sur le CD du magazine PC-Fun ... sans grand succès, malheureusement.

Well, I dug a README.TXT file for my first A86 game : Crazy Brix, as submitted to the French magazine Pc-Fun. It wouldn't make much sense to translate that to you, right ? it mostly has some nostalgic value. What I find amusing is how it built up : from a proof-of-concept QuickBas game (hardly playable, but conceptually correct), i retro-fitted the "algorithms" into my growing assembly-written .S3M player for the Sound Blaster Pro. Somehow, "importing" the S3M player into a fresh game project didn't work. Debugging such a program was a nightmare ...
I had no idea of the existence of GPL or free-software by that time (neither did I have any free software at hand, which more or less explain the use of assembly), so I was trying to trade my code against something else I could have a use for. Funny.


- - - 8< - - - 8< - - -

Salut à tous !
Bien le bonjour à vous, futurs joueurs de CrAzY BRIX.
Je me permets de me présenter: je suis Sylvain
( alias PYPEIN ), programmeur de BRIX. Vous allez sans tarder découvrir la version 1.9 du nouveau XAM-WARE de PPP TEAM SOFTWARE.

(XAM-WARE comme produit pendant les examens.)

Les Versions.
1.0: Développement de l'algorithme de jeu en BASIC ("appelle moi pour jouer",dit Vivien)
1.1: Première implémentation en Assembleur: MODPLAY+ chargement des images (ricanement de Piet)
1.2: Réalisation des routines graphiques
1.3: On peut commencer à jouer, mais c'est plein de bugs.
1.4: premiers essais de transparence ("C'est quoi, cette horreur?" dit Piet " C'était encore mieux en BASIC!")
1.5: décors de fond retravaillés
1.6: ajout des patterns "GAME OVER" et "NEXT LEVEL"
1.7: on peut changer la vitesse de la balle.
1.8: Ajout des samples pour les bruitages ("Je te laisse débugger, Pype, je reviens à 12h00")
1.9: image d'intro en POVRAY
1.A: "ajout d'animations"

Note aux programmeurs
Mon module player n'est pas encore au point, néanmoins, si l'un d'entre vous veut en faire un en assembleur, je lui conseille d'abord de lire 'Le SuperLivre de la SoundBlaster' paru chez Micro Application. Je peux aussi vous passer une partie des sources (les fonctions de la S.B.) mais ne me demandez pas les sources complètes du player: le code est pas encore optimisé (PENTIUM minimum). Je vous le passerai seulement contre d'autres trucs (un player pour un autre format, des truc de balaises sur le mode protégé, un jeu que vous avez fait et qui est mieux que le mien...)

- - - >8 - - - >8 - - -

(tout ça, c'était avant que je ne découvre la GPL, NDLR)
D'une certaine manière, Crazy Brix reflète assez bien ce qu'était PPP Team : en apparence un projet solo, ce jeu n'aurait jamais vu le jour sans le bouquin de Nowan sur la soundblaster ni sans l'assembleur A86 de Parmy. Il n'aurait pas été fun sans les Bilou/Badman de Pierrick, ni sans le personnage "tentacle bob" de Tbob, ni sans les mods de mon frère. Il n'aurait pas gagné la 100k sans les routines de compression de Kris, ni sans la voiture de Gino. Il n'aurait pas eu de sens si Pierrick n'avait pas lâché à Romu "tu te rends compte qu'il a fait ça en 100% assembleur !?"

download and play in DosBOX

Saturday, December 31, 2005

coding [t.a.g.]

How brave you are! Truly !

I mean ... You made it! You've been reading through the *whole* set of "coding"-related topics. They weren't just todo lists, but true stories about behind-the-scene hacks, fixes, eurekas and such that turn dreams into reality.

You definitely deserve


     *
      }( 1 ){
        \ /*
       o[ ]o
     ___  ___
    /   \/   \
    /  ^   ^ \
    /__ooOOoo_
The Ultimate Ascii aRt Trophy of Awesomeness!

Franchement, je suis impressionné! Lire tous les posts de la catégorie "coding", c'est du costaud. Si ça n'avait été que des toudou-listes, mais non. Les hésitations, les bidouilles en coulisses, les correctifs, les eurekas, les victoires. Bref, tous ces petits moments numérisés qui ont conduit à réaliser un rêve ...


NB: I guess you have noted that I use tag cxx for things about c++, since blogger doesn't seem reliable in whether it supports '+' in tag names or not.