Skip to content

Instantly share code, notes, and snippets.

@mrange
Created September 20, 2024 21:01
Show Gist options
  • Save mrange/1691226799a535010b2bb903fcc1c1be to your computer and use it in GitHub Desktop.
Save mrange/1691226799a535010b2bb903fcc1c1be to your computer and use it in GitHub Desktop.
Sixel
open System
open System.Diagnostics
open System.Text
open System.Threading
let inline fract x = x - floor x
let rec mandelbrot (x : float) (y : float) (cx : float) (cy : float) i =
if i > 0 then
let x2 = x*x
let y2 = y*y
if x2 + y2 >= 4. then
i
else
mandelbrot (x2-y2+cx) (2.*x*y+cy) cx cy (i - 1)
else
0
let effect time x y =
(*
let b = fract time - 0.5
let b = b*b
let y = y - b
let d = sqrt (x*x+y*y) - 0.5
int (round (d * 20.))
*)
let x = 1.5*x-0.5
let y = 1.5*y
mandelbrot x y x y 50
[<EntryPoint>]
let main args =
let sw = Stopwatch.StartNew ()
let width = 132*2
let height = 132
let palette =
// The tic-80 palette
[|
0x1C, 0x1C, 0x2C // 0x0
0x5D, 0x27, 0x5D // 0x1
0xB1, 0x3E, 0x53 // 0x2
0xEF, 0x7D, 0x57 // 0x3
0xFF, 0xCD, 0x75 // 0x4
0xA7, 0xF0, 0x70 // 0x5
0x38, 0xB7, 0x64 // 0x6
0x25, 0x71, 0x79 // 0x7
0x29, 0x36, 0x6F // 0x8
0x3B, 0x5F, 0xC9 // 0x9
0x41, 0xA6, 0xF6 // 0xA
0x73, 0xEF, 0xF7 // 0xB
0xF4, 0xF4, 0xF4 // 0xC
0x94, 0xB0, 0xC2 // 0xD
0x56, 0x6C, 0x86 // 0xE
0x33, 0x3C, 0x57 // 0xF
|]
let paletteStr =
let m i (r,g,b) =
let inline f (v : int) = int (round (float v*100./255.))
sprintf "#%d;2;%d;%d;%d" i (f r) (f g) (f b)
palette
|> Array.mapi m
let sb = StringBuilder ()
let inline str (s : string) = sb.Append s |> ignore
let inline ch (c : char) = sb.Append c |> ignore
let blank : int array = Array.zeroCreate (width*height)
let screen : int array = Array.zeroCreate (width*height)
let set : int array = Array.zeroCreate 16
for i = 0 to 1 do
// Clear screen
Array.Copy (blank, screen, width*height)
let time = float sw.ElapsedMilliseconds/1000.
sb.Clear () |> ignore
for y = 0 to height-1 do
let yy = -1.+(float y)*(2./float height)
let yoff = width*y
for x = 0 to width-1 do
let xx = -1.+(float x)*(2./float width)
screen.[x + yoff] <- effect time xx yy
// Clear the screen
// str "\x1B[2J"
// Move to top of screen
str "\x1B[H"
// Start the sixel bitmap
str "\x1BPq"
for p in paletteStr do
str p
for y6 = 0 to height/6-1 do
let y = y6*6
let yoff = y*width
for c = 0 to 15 do
str ("#" + string c)
for x = 0 to width-1 do
let mutable sixel = 0
for i = 0 to 5 do
let yoff = yoff + i*width
let pix = if (screen.[x + yoff] &&& 0xF) = c then 1 else 0
sixel <- sixel ||| (pix <<< i)
ch (char (63+(sixel&&&0x3F)))
ch '$'
ch '-'
// End the sixel bitmap
str "\x1B\\"
Console.Write (sb.ToString())
Thread.Sleep 100
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment