Fire

Looking at the benchmarks on the web of the Julia programming language, I was surprised to see the speed at which JavaScript runs on V8. I decided I wanted to play with it.

I took an old code of mine from the demoscene era. At that time (1997), the way to be fast enough was to code in assembly. I translated the code to JavaScript to see how fast it run on the browser. This is the result:

This should be a colorful canvas :-(
Either your browser or my web suck.

The conclusion is clear, you can do now in JavaScript what was only possible in assembly in 1997. I wonder what would be possible today if someone was coding in assembly ;-)

For the curious, below are the two codes.

1997 - Assembly

.model tiny
.code
.386
                org     100h

start:

main    PROC
                mov     ax, 13h
                int     10h
                
                call    setpal

                mov     ax, 0A000h
                mov     es, ax
                mov     ax, ds
                add     ax, 512/16
                mov     ds, ax
                xor     si, si
                mov     di, si


segueix:        mov     si, 320*198
                mov     cx, 320*2
repet:          mov     ax, bx
                xor     ax, cx
                ror     ax, cl
                xor     ax, bx
                add     bx, ax

                and     al, 111b
                add     [si], al
                inc     si
                inc     di
                loop    repet

                mov     si, 320*0
                mov     cx, 320*200-320*2
                xor     dx, dx
repetimos:      movzx   ax, 320+320[si]
                mov     dl, 320+321[si]
                add     ax, dx
                mov     dl, 320+319[si]
                add     ax, dx
                shl     ax, 1
                mov     dl, 320[si]
                add     ax, dx
                mov     bx, ax
                shl     ax, 3
                add     ax, bx
                shl     ax, 2
res:            mov     [si], ah
                inc     si
                loop    repetimos


                xor     si, si
                mov     di, si
                mov     cx, 320*200/2
                rep     movsw



                mov     ah, 1
                int     16h
                jz      segueix
                
                mov     ax, 3h
                int     10h

                ret
main    ENDP


setpal  PROC
                mov     dx, 3C8h
                xor     ax, ax
                out     dx, al
                inc     dx
ColorLoop:      ror     al, 2
                out     dx, al
                rol     al, 1
                out     dx, al
                rol     al, 1
                out     dx, al
                inc     al
                jnz     ColorLoop
                ret
setpal  ENDP 

                end     start

2012 - JavaScript

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var id = ctx.getImageData(0, 0, c.width, c.height);
var w = id.width;
var h = id.height;

// Build palette.
var palette = Array();
for (var i = 0; i < 256; ++i) {
  palette[4 * i + 0] = (4 * i) % 256;
  palette[4 * i + 1] = (2 * i) % 256;
  palette[4 * i + 2] = (1 * i) % 256;
  palette[4 * i + 3] = 255;
}

// Init image.
var f = Array();
f.length = w * h;
for (var i = 0; i < f.length; ++i) {
  f[i] = Math.random() * 255;
}

function draw() {
  var bottom = 3;

  // Draw random values at the bottom.
  for (var p = w * (h - bottom); p < w * h; ++p) {
    f[p] = (f[p] + 15 * Math.random()) % 256;
  }

  // Shift pixels by combining lower rows.
  for (var p = 0; p < w * (h - bottom); ++p) {
    f[p] = (f[p+w] +
            2 * f[p+2*w-1] +
            2 * f[p+2*w] +
            2 * f[p+2*w+1]) * 36 / 256;
  }

  // Render with palette.
  for (var p = 0; p < w * h; ++p) {
    for (var c = 0; c < 4; ++c) {
      id.data[4 * p + c] = palette[4 * Math.floor(f[p]) + c];
    }
  }

  ctx.putImageData(id, 0, 0);
}

setInterval("draw()", 50);
posted on 14 Jul 2012 by Pau Gargallo