<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sl0pboy.git/tools/kitty_decode.py, branch master</title>
<subtitle>sl0pboy - a Game Boy Color emulator (companion to the gbos OS)</subtitle>
<id>https://git.sl0p.foo/sl0pboy.git/atom/tools/kitty_decode.py?h=master</id>
<link rel='self' href='https://git.sl0p.foo/sl0pboy.git/atom/tools/kitty_decode.py?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/sl0pboy.git/'/>
<updated>2026-09-22T12:55:45Z</updated>
<entry>
<title>kitty: truecolor graphics output with a layered HUD</title>
<updated>2026-09-22T12:55:45Z</updated>
<author>
<name>gbc dev</name>
<email>gbc@localhost</email>
</author>
<published>2026-09-22T12:55:45Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/sl0pboy.git/commit/?id=44c21908b4ff6a1e41a6b9ba17e3ed78de8ec3db'/>
<id>urn:sha1:44c21908b4ff6a1e41a6b9ba17e3ed78de8ec3db</id>
<content type='text'>
Sixel is a 1987 printer format wearing a terminal costume: 256 colors per
image, no alpha, no compositing, one flat picture. --kitty [scale] takes
the other road on kitty/ghostty/WezTerm/Konsole:

  - the framebuffer ships as raw RGB888, so no per-frame palette build and
    no coarser quantization when a CGB game blows past 256 colors
  - the HUD (title, render rate, frameskip, turbo, live button readout) is
    a *separate* alpha-blended image on z-index 1, composited over the game
    by the terminal instead of being burned into the picture; 'h' toggles
    it, --no-hud starts without it
  - consecutive identical images are dropped, so a pause menu or text box
    stops the traffic dead
  - pixels go over at 1x and the terminal scales them into a cell box, so
    --kitty 6 costs the same bytes as --kitty 1 (padded to whole cells
    first, so the zoom stays exact)

Two transfers: shm hands over the name of a POSIX shared-memory object
(~60 bytes/frame) when we can tell the terminal is local, b64 inlines the
bytes for ssh and tmux (which might be attached from another machine).
--kitty-shm / --kitty-b64 force either. tmux gets DCS passthrough wrapping.
--chrome and --palette work here just like in sixel mode.

Nothing about a graphics stream is human-readable, so tools/kitty_decode.py
reassembles a capture back into images - chunked payloads, tmux wrapping
and all - and can assert a frame is pixel-identical to a --shot:

  tools/kitty_decode.py cap.bin -o frames --check shot.ppm
  -&gt; OK: image 1 matches shot.ppm exactly (160x144)
</content>
</entry>
</feed>
