Afficher du texte en gros pixels dans une page Web

Pas facile de la jouer rétro avec les technologies du jour ! Afficher un texte en gros pixels comme sur les vieilles bécanes, c'est toute une affaire quand on sait que le moindre texte subit désormais de multiples traitements pour le rendre bien lisible à l'écran. En particulier, ses courbes sont lissées en recourant à l'anti-aliasing.
L'anti-aliasing: voilà l'ennemi. On connaît quelques contournements mis en place pour tenir compte du revival des jeux à gros pixels. Sur ce blog, cet article montre comment désactiver l'anti-aliasing dans le contexte 2D du canvas.
Toutefois, ce contournement ne fonctionne que dans le cas de la copie d'une image et le dessin de formes simples - le rectangle. L'API Canvas ne propose rien pour afficher un texte en gros pixels dans une police donnée, une police de 8x8 pixels à l'ancienne qui plus est.
Dès lors, comment parvenir à produire un pareil résultat ?
La page d'accueil de Pixel Saga: du texte pixelisé généré automatiquement
La solution est très simple. C'est tout simplement celle qui était en vigueur sur les vieux coucous... Explications.
Continuer la lecture de "Afficher du texte en gros pixels dans une page Web"
Afficher du texte en gros pixels dans une page Web

Web Components : un élément <TR> personnalisé (2/2)

Cet article est le second, et donc le dernier, d'un série de deux consacrés à la réalisation d'un élément <tr> personnalisé exploitant des technologies de la famille Web Components.
Dans le premier article, il s'agissait de passer en revue l'intégralité du code requis pour créer un élément <tr> personnalisé <param-number> permettant d'ajouter un spinner précédé d'un libellé dans un tableau, comme ici :
Un élément personnalisé
Ce spinner est lié à une propriété quelconque que le développeur pointe à l'élément personnalisé en fournissant un chemin d'accès, comme par exemple shader.particle.start.delay. Ainsi, une fois qu'il a rajouté un élément <param-number> dans la page Web, le développeur n'a plus qu'à réagir aux modifications de la propriété via son getter. Le chemin est réévalué à chaque accès, si bien que le développeur peut toujours changer l'objet sur lequel il débouche.
Dans ce second article, il s'agit de revenir sur certains choix techniques qui ont présidé à l'écriture du code de l'élément personnalisé. En particulier, on s'interroge sur les avantages et les inconvénients d'une personnalisation d'un élément HTML existant tel que <tr>. Il s'agit aussi de pointer quelques enjeux des technologies de la famille Web Components pour l'avenir, notamment le recours aux classes en JavaScript et la prise de distance avec les éléments HTML standards.
Continuer la lecture de "Web Components : un élément <TR> personnalisé (2/2)"
Web Components : un élément <TR> personnalisé (2/2)

Web Components : un élément <TR> personnalisé (1/2)

Web Components est un ensemble de technologies apparues dans le cadre de HTML5 : custom elements, templates et shadow DOM - les imports HTML aussi, mais ils ne sont toujours pas standardisés. D'après Can I use... (ici, ici et ), ces technologies sont désormais assez largement adoptées dans leurs dernières versions - la v1. En particulier, Firefox gère parfaitement cela depuis l'automone dernier - la version 63.
Pour faire court, cet ensemble permet de créer un élément ou une variante d'élément HTML dans une page Web, et de faire exécuter du code JavaScript au moment où le navigateur cherche à l'interpréter, ce qui permet d'injecter dans la page Web ce que vous voulez. Par exemple, on peut écrire... :
<param-number name="Delay" property="g.shaderUI.delay" step="1" iseditable="true" buttonclassname="uiButton" numberclassname="uiNumber" layout="middle"></param-number>
...et récupérer une référence sur cet élément au moment où le navigateur cherche quoi en faire. Ici, il serait possible d'afficher un champ de saisie entouré de deux boutons, l'un pour décrémenter et l'autre pour incrémenter la valeur figurant dans le champ :
Un élément personnalisé
On comprend qu'il serait alors facile d'utiliser un tel composant à volonté, comme par exemple ici :
Une page Web utilisant généreusement des éléments personnalisés
Mais il pourrait tout autant s'agir d'effectuer une requête asynchrone à une base de données - une bonne occasion d'utiliser une promise -, afin de récupérer des informations sur un client et de les afficher quand elles sont disponibles, sans bloquer l'affichage du reste de la page - soyons progressifs.
Le sujet des Web Components est bien documenté sur MDN, et la spécification HTML qui doit servir de référence est pour sa part assez claire. Pourquoi en parler alors ?
Il faut en parler, car le sujet reste assez nouveau, et car la pratique montre que le développeur peut être confronté à des choix assez cornéliens. L'exemple pris ici est celui de la création d'un élément custom pour rajouter des lignes à un tableau. Ce sujet s'impose de lui-même dès que l'on commence à manipuler les Web Components, car la première idée qu'on y voit est de factoriser des éléments redondants, à ce titre souvent affichés dans un tableau.
Cet article est le premier d'un série de deux. Il s'agit de présenter l'intégralité du code requis pour faire fonctionner l'élément <param-number> évoqué. Dans le second article, plusieurs choix techniques et perspectives des technologies utilisées feront l'objet d'une discussion.
Continuer la lecture de "Web Components : un élément <TR> personnalisé (1/2)"
Web Components : un élément <TR> personnalisé (1/2)

Faciliter la modification du format de point WebGL en JavaScript

Ceux qui programment directement WebGL, version 1 ou 2, avec JavaScript connaissent l'enfer que représente l'élaboration d'un shader. Qu'un format de point soit modifié, et plus généralement qu'un attribut de point, une composante variable ou une variable uniforme soit supprimé, rajouté ou modifié dans le code GLSL d'un shader, et il faut :
  • mettre à jour leur liste avant la fonction main () du shader ;
  • dans le cas d'uniformes, mettre à jour la liste des appels à getUniformLocation () ;
  • dans le cas d'attributs, ce qui résulte inévitable de la modification du format de point :
    • mettre à jour la liste des appels à getAttribLocation () ;
    • mettre à jour la liste des appels à enableVertexAttribArray (), enableVertexAttribArray (), vertexAttribPointer () et disableVertexAttribArray ().
Exemple d'animation modifiée à la volée avec les shaders
Pour soulager la vie du développeur, WebGL 2 met désormais à disposition un nouvel objet : le Vertex Array Object, ou VBO pour les intimes. Il permet d'éviter de répéter dans le code des séquences d'appels pour configurer les attributs avant chaque rendu.
Toutefois, cela ne répond que très partiellement au problème évoqué à l'instant, car les mises à jour évoquées restent toujours aussi nécessaires et fastidieuses, quand bien même les occurences des appels à modifier sont réduites. N'y a-t-il pas moyen de se simplifier la vie ? Modeste proposition.
NB : Cet article renoue avec le format abrégé de premiers articles de ce blog. C'est qu'au terme d'une série de prises en main de technologies Web (WebG 2, promises, fonction fléchées, Web Components, etc.), un certain de nombre de difficultés rencontrées dans le cadre du développement d'une application à base de JavaScript et de WebGL en donnent l'opportunité.
Continuer la lecture de "Faciliter la modification du format de point WebGL en JavaScript"
Faciliter la modification du format de point WebGL en JavaScript

La promesse des promises en JavaScript

L'implémentation de la spécification ECMAScript 2015 sur laquelle JavaScript est fondé a conduit à introduire un nouvel objet standard en JavaScript : Promise. Il s'agit bien d'un objet standard, c'est-à-dire propre au langage comme String et non au navigateur, comme XMLHttpRequest.
Cet objet permet de faciliter et de sécuriser l'écriture d'un appel à une fonction asynchrone, c'est-à-dire à une fonction qui rend la main sans avoir encore retourné son résultat, s'engageant à signaler au programme qui l'a appelée quand ce résultat sera disponible, par exemple en appelant une fonction que le programme lui a fournie - une callback.
Le Serment des Horaces par David
Tout développeur JavaScript a très probablement déjà utilisé ce type de fonction, notamment pour charger des fichiers via l'objet XMLHttpRequest, ou pour déclencher une action après expiration d'un timer programmé via window.setTimeout ().
Avec l'objet Promise, l'asynchronisme a en quelque sorte été dégagé des objets qui viennent d'être cités pour accéder au rang d'aspect fonctionnel fondamental de JavaScript, au même titre que l'héritage basé sur les prototypes ou les closures. Partant tout développeur JavaScript doit maîtriser l'asynchronisme.
Pour autant, qui met le nez dans la spécification ne peut être que rapidement rebuté par l'opacité de cette dernière. Fort heureusement, il existe de nombreuses autres sources auxquelles se référer. Apportons ici une modeste contribution avec une présentation détaillée du système des promises destinée à qui découvre le sujet.
Continuer la lecture de "La promesse des promises en JavaScript"
La promesse des promises en JavaScript

Mandelbrot en WebAssembly

Ainsi donc, grâce à WebAssembly, il serait possible de faire tourner des programmes fulgurants dans une page Web.
Mazette ! Pourquoi ne pas tester la proposition en réalisant un petit programme qui requiert traditionnellement une certaine puissance de calcul, comme une représentation de l'ensemble de Mandelbrot ? Ce serait plus sympa que le jeu de la vie de Conway comme proposé ici, qui est certes fascinant, mais pas des plus sexy à regarder.
Une représentation de l'ensemble de Mandelbrot
Ce serait aussi l'opportunité de discuter un peu des performances des opérations graphiques nécessitant de travailler au pixel pour produire une image dans une page Web. Oh! nous ne sortirons pas l'artillerie lourde, à savoir WebGL, qui a été longuement présenté dans plusieurs articles sur ce blog. Nous nous concentrerons simplement sur le contexte 2D d'un objet <canvas>, en dessinant au pixel.
Tout cela, et plus encore, dans ce qui suit.
Continuer la lecture de "Mandelbrot en WebAssembly"
Mandelbrot en WebAssembly

WebAssembly : programmer en assembleur dans une page Web

Qui programme en assembleur de nos jours ? Plus qu'il n'y paraît en fait, si l'on veut bien considérer qu'avec WebAssembly - Wasm pour les intimes -, il est devenu possible d'écrire des programmes dans un langage qui s'en approche, et de les exécuter dans le contexte d'une page Web.
Wasm, un assembleur pour le Web
L'intérêt ? Des performances annoncées de très loin supérieures à celle de tout code JavaScript, aussi optimisé qu'il soit, sans perdre le bénéfice d'une intégration parfaite dans l'environnement d'exécution d'une page Web, c'est-à-dire en pouvant facilement accéder à des données et à des sous-programmes Wasm depuis du code JavaScript, mais aussi faire l'inverse.
Comment écrire en Wasm ? Comment exécuter du Wasm dans une page Web ? Et comment dialoguer entre Wasm et JavaScript ? Tout cela et plus encore dans ce qui suit...
Mise à jour du 21/12/2018 : Rajout d'un encadré pour remercier Dan Gohman, l'auteur du WebAssembly Reference Manual.
Mise à jour du 18/12/2018 : Mention à une représentation intelligible de la syntaxe d'un module, finalement trouvée (en creusant profond) ici.
Mise à jour du 17/12/2018 : Correction de petits bogues dans importExportMemory.zip.
Mise à jour du 16/12/2018 : Ajout d'une section liminaire "WebAssembly, c'est quoi ?", et d'une conclusion "WebAssembly en vaut-il la peine ?".
Continuer la lecture de "WebAssembly : programmer en assembleur dans une page Web"
WebAssembly : programmer en assembleur dans une page Web

Développer pour Android sous Windows sans IDE (notamment sans Android Studio !)

Le moins qu'on puisse en dire, c'est qu'Android Studio n'est pas du genre léger. Sans doute, cet IDE est très complet, et il faut être reconnaissant à Google de le mettre gratuitement à disposition des développeurs, mais il requiert beaucoup de ressources pour fonctionner, et peut en conséquence se révèler très lent à l'usage.
Un canon pour tuer les mouches ? Ce serait bien dans l'air du temps. Comme l'explique avec beaucoup d('im)pertinence Bryan Lundunke dans programmers_are_evil(), "Everyone writing code is writing code that is getting exponentially larger and slower".
Partant, on peut se demander si Android Studio, c'est le bon choix pour commencer à développer des apps pour Android.
La question se pose d'autant plus que l'IDE masque nombre d'opérations dont la connaissance paraît essentielle pour que le développeur puisse comprendre ce qu'il est en train de faire. De manière un peu réductrice, mais qui n'est donc pas si éloignée de la réalité, l'IDE n'est qu'une IHM qui appelle des outils en ligne de commande pour faire tout ce qui dépasse l'édition de code. Se donner la peine de regarder sous le capot, c'est non seulement se ménager l'opportunité de pouvoir se débrouiller en cas de panne, mais aussi celle de gagner beaucoup de temps pour réaliser certains opérations.
Reste à savoir comment procéder, car pour la jouer roots, force est de constater que Google ne simplifie pas la tâche... Explications pour qui souhaiterait se lancer aujourd'hui même dans le développement d'apps pour Android.
Continuer la lecture de "Développer pour Android sous Windows sans IDE (notamment sans Android Studio !)"
Développer pour Android sous Windows sans IDE (notamment sans Android Studio !)

Scoopex « TWO » : Le coding-of d’une cracktro sur Amiga 500

Et voilà ! On promet que c'est le dernier pour la route, et on s'en remet un malgré tout. Difficile de décrocher de la programmation en assembleur du hardware vidéo de l'Amiga 500, tant que la connaissance de ce dernier semble à parfaire, qu'il se trouve des FX à créer ou, plus modestement, à reproduire.
Un quart de siècle après la "dernière", trinquons donc encore ensemble avec Scoopex "TWO", cracktro codée en 2018 en guise d'appetizer pour le portage du jeu Starquake par Galahad du glorieux groupe Scoopex.
Scoopex "TWO" : Une cracktro pour A500 en 2018
Au menu : BOBs qui bougent, printer qui affiche, et rotozoom qui tourne. Et comme toujours, quelques leçons de portée plus générale que le sujet initial ne semblerait offrir l'opportunité d'en dispenser.
Mise à jour du 22/11/2018 : Optimisation du code JavaScript du rotozoom pour le mettre à disposition de l'auteur du portage de la cractro en HTML5 sur Flashtro.
Mise à jour du 19/11/2018 : Ajout d'un encadré (un peu long, mais me semble-t-il intéressant) sur l'enjeu pour l'authenticité que soulève l'émulation d'un jeu.
Mise à jour du 18/11/2018 : Cliquez ici pour télécharger copperScreen.s, un programme qui permet de générer un écran au Copper de n'importe quelle hauteur à n'importe quelle position verticale.
Mise à jour du 17/11/2018 : En complément, une vidéo de la cracktro est disponible sur YouTube. Par ailleurs Galahad raconte l'intéressant making-of du portage du jeu dans un fil de l'English Amiga Bord.
Continuer la lecture de "Scoopex « TWO » : Le coding-of d’une cracktro sur Amiga 500"
Scoopex « TWO » : Le coding-of d’une cracktro sur Amiga 500

Un traceroute roots en Python avec Scapy

Scapy est un package de Python bien connu dans le monde du hacking. Il permet d'interagir à bas niveau avec une interface réseau, c'est-à-dire de déterminer les octets qu'elle émet et de récupérer ceux qu'elle reçoit.
Scapy peut donc notamment être utilisé pour forger des trames et/ou paquets sur un réseau. Cela peut permettre de se livrer à des activités que la morale réprouve, comme l'ARP cache poisoning et autres joyeusetés. A l'inverse, comme nous le recommanderons, cela peut permettre de s'adonner à des activités tout à fait respectables, comme le diagnostic.
Scapy, pour sniffer, spoofer et autres
Dans tous les cas, se mettre à Scapy permet de se former au fonctionnement de réseaux en commençant par là où il faut commencer chaque fois qu'on prétend réellement apprendre quelque chose dans quel que domaine, c'est-à-dire à la base. C'est cette finalité pédagogique que poursuit cet article, à l'attention de tous ceux qui n'ont jamais mis le nez dans le réseau. Il présente comment réaliser une version simplifiée d'un outil qui figure inévitablement dans la boite à outils de tout hacker, à savoir traceroute.
Continuer la lecture de "Un traceroute roots en Python avec Scapy"
Un traceroute roots en Python avec Scapy