{"name":"doomfire.nu","source":"// doomfire.nu — Classic Doom Fire Effect\n\n& `libc` @ rand → i\n\n& `canvas` @ canvas_open i w i h → *i\n\n& `canvas` @ canvas_present → v\n\n& `canvas` @ canvas_sleep i ms → v\n\n& `canvas` @ canvas_should_close → i\n\n& `canvas` @ canvas_close → v\n\n: i W 320\n: i H 180\n: i FPS 60\n\n@ main → i {\n    : i total_px * W H\n    // Lämpöpuskuri (0 = musta, 36 = valkoinen/kuumin)\n    : *i fire # *i ( malloc * total_px 8 )\n\n    // Alustetaan taulukko nollilla\n    : ~ i i 0\n    ~ < i total_px {\n        = . fire i 0\n        = i + i 1\n    }\n\n    // Luodaan 37 värin paletti (mustasta punaiseen, keltaiseen ja valkoiseen)\n    : *i pal # *i ( malloc * 37 8 )\n    : ~ i p 0\n    ~ < p 37 {\n        : ~ i r 0 : ~ i g 0 : ~ i b 0\n\n        ? < p 13 {\n            = r * p 21\n        } {\n            ? < p 25 {\n                = r 255\n                = g * - p 12 21\n            } {\n                = r 255\n                = g 255\n                = b * - p 24 21\n            }\n        }\n\n        // Estetään ylivuodot varotoimena\n        ? > r 255 { = r 255 } {}\n        ? > g 255 { = g 255 } {}\n        ? > b 255 { = b 255 } {}\n\n        // Pakataan NURLin ARGB-muotoon: 0xFF000000 | R<<16 | G<<8 | B\n        : i color | 4278190080 | | * r 65536 * g 256 b\n        = . pal p color\n        = p + p 1\n    }\n\n    : *i fb ( canvas_open W H )\n    : i frame_ms / 1000 FPS\n\n    ~ == 0 ( canvas_should_close ) {\n        // 1. Asetetaan alimmalle riville aina maksimilämpö (36)\n        : i bottom_offset * - H 1 W\n        : ~ i bx 0\n        ~ < bx W {\n            = . fire + bottom_offset bx 36\n            = bx + bx 1\n        }\n\n        // 2. Liekkialgoritmi: levitetään lämpöä alhaalta ylöspäin\n        : ~ i x 0\n        ~ < x W {\n            : ~ i y 1\n            ~ < y H {\n                : i src + * y W x\n                : i pixel . fire src\n\n                ? == pixel 0 {\n                    // Jos pikseli on musta, yläpuolikin pysyy mustana\n                    = . fire - src W 0\n                } {\n                    // Arvotaan tuulen sivuttaissiirtymä (0-2) ja lämmön hiipuminen (0-1)\n                    : i r % ( rand ) 3\n                    : i heat - pixel & r 1\n\n                    // X-koordinaatti johon liekki siirtyy: x - r + 1\n                    : i dst_x + - x r 1\n\n                    // Kohdeindeksi muistissa\n                    : i dst + - - src W r 1\n\n                    // Varmistetaan ettei liekki kiedo ruudun reunojen yli\n                    ? & >= dst_x 0 < dst_x W {\n                        = . fire dst heat\n                    } {}\n                }\n                = y + y 1\n            }\n            = x + x 1\n        }\n\n        // 3. Piirretään liekkipuskuri ruudulle paletin läpi\n        : ~ i idx 0\n        ~ < idx total_px {\n            // luetaan lämpötila -> haetaan väri -> kirjoitetaan ruudulle\n            = . fb idx . pal . fire idx\n            = idx + idx 1\n        }\n\n        ( canvas_present )\n        ( canvas_sleep frame_ms )\n    }\n\n    ( canvas_close )\n    ^ 0\n}\n","bytes":3027}