From f3fe2ac1953118b1a93828c718eaa9bdb3397939 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 1 May 2021 23:41:24 -0700 Subject: tool: compute nearby colors in default palette --- colors.mu | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rpn.mu | 1 - 2 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 colors.mu diff --git a/colors.mu b/colors.mu new file mode 100644 index 00000000..57a74bdc --- /dev/null +++ b/colors.mu @@ -0,0 +1,235 @@ +# Return colors 'near' a given r/g/b value (expressed in hex) +# If we did this rigorously we'd need to implement cosines. So we won't. +# +# To build: +# $ ./translate colors.mu +# +# Example session: +# $ qemu-system-i386 code.img +# Enter 3 hex bytes for r, g, b (lowercase; no 0x prefix) separated by a single space> aa 0 aa +# 5 +# This means only color 5 in the default palette is similar to #aa00aa. + +fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { + var in-storage: (stream byte 0x10) + var in/esi: (addr stream byte) <- address in-storage + { + # print prompt + var x/eax: int <- draw-text-rightward screen, "Enter 3 hex bytes for r, g, b (lowercase; no 0x prefix) separated by a single space> ", 0x10/x, 0x80/xmax, 0x28/y, 3/fg/cyan, 0/bg + # read line from keyboard + clear-stream in + { + draw-cursor screen, 0x20/space + var key/eax: byte <- read-key keyboard + compare key, 0xa/newline + break-if-= + compare key, 0 + loop-if-= + var key2/eax: int <- copy key + append-byte in, key2 + var g/eax: grapheme <- copy key2 + draw-grapheme-at-cursor screen, g, 0xf/fg, 0/bg + move-cursor-right 0 + loop + } + clear-screen screen + # parse + var a/ecx: int <- copy 0 + var b/edx: int <- copy 0 + var c/ebx: int <- copy 0 + # a, b, c = r, g, b + a, b, c <- parse in +#? set-cursor-position screen, 0x10/x, 0x1a/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, a, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, b, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, c, 7/fg, 0/bg + a, b, c <- hsl a, b, c + # return all colors in the same quadrant in h, s and l + print-nearby-colors screen, a, b, c + # + loop + } +} + +# read exactly 3 words in a single line +# Each word consists of exactly 1 or 2 hex bytes. No hex prefix. +fn parse in: (addr stream byte) -> _/ecx: int, _/edx: int, _/ebx: int { + # read first byte of r + var tmp/eax: byte <- read-byte in + { + var valid?/eax: boolean <- hex-digit? tmp + compare valid?, 0/false + break-if-!= + abort "invalid byte 0 of r" + } + tmp <- fast-hex-digit-value tmp + var r/ecx: int <- copy tmp +#? set-cursor-position 0/screen, 0x10/x, 0x10/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, r, 7/fg, 0/bg + # read second byte of r + tmp <- read-byte in + { + { + var valid?/eax: boolean <- hex-digit? tmp + compare valid?, 0/false + } + break-if-= + r <- shift-left 4 + tmp <- fast-hex-digit-value tmp +#? { +#? var foo/eax: int <- copy tmp +#? set-cursor-position 0/screen, 0x10/x, 0x11/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, foo, 7/fg, 0/bg +#? } + r <- add tmp +#? { +#? set-cursor-position 0/screen, 0x10/x, 0x12/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, r, 7/fg, 0/bg +#? } + tmp <- read-byte in # skip space + } + # read first byte of g + var tmp/eax: byte <- read-byte in + { + var valid?/eax: boolean <- hex-digit? tmp + compare valid?, 0/false + break-if-!= + abort "invalid byte 0 of g" + } + tmp <- fast-hex-digit-value tmp + var g/edx: int <- copy tmp +#? set-cursor-position 0/screen, 0x10/x, 0x13/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, g, 7/fg, 0/bg + # read second byte of g + tmp <- read-byte in + { + { + var valid?/eax: boolean <- hex-digit? tmp + compare valid?, 0/false + } + break-if-= + g <- shift-left 4 + tmp <- fast-hex-digit-value tmp +#? { +#? var foo/eax: int <- copy tmp +#? set-cursor-position 0/screen, 0x10/x, 0x14/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, foo, 7/fg, 0/bg +#? } + g <- add tmp +#? { +#? set-cursor-position 0/screen, 0x10/x, 0x15/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, g, 7/fg, 0/bg +#? } + tmp <- read-byte in # skip space + } + # read first byte of b + var tmp/eax: byte <- read-byte in + { + var valid?/eax: boolean <- hex-digit? tmp + compare valid?, 0/false + break-if-!= + abort "invalid byte 0 of b" + } + tmp <- fast-hex-digit-value tmp + var b/ebx: int <- copy tmp +#? set-cursor-position 0/screen, 0x10/x, 0x16/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, b, 7/fg, 0/bg + # read second byte of b + { + { + var done?/eax: boolean <- stream-empty? in + compare done?, 0/false + } + break-if-!= + tmp <- read-byte in + { + var valid?/eax: boolean <- hex-digit? tmp + compare valid?, 0/false + } + break-if-= + b <- shift-left 4 + tmp <- fast-hex-digit-value tmp +#? { +#? var foo/eax: int <- copy tmp +#? set-cursor-position 0/screen, 0x10/x, 0x17/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, foo, 7/fg, 0/bg +#? } + b <- add tmp +#? { +#? set-cursor-position 0/screen, 0x10/x, 0x18/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, b, 7/fg, 0/bg +#? } + } + return r, g, b +} + +# no error checking +fn fast-hex-digit-value in: byte -> _/eax: byte { + var result/eax: byte <- copy in + compare result, 0x39 + { + break-if-> + result <- subtract 0x30/0 + return result + } + result <- subtract 0x61/a + result <- add 0xa/10 + return result +} + +fn print-nearby-colors screen: (addr screen), h: int, s: int, l: int { +#? set-cursor-position screen, 0x10/x, 0x1c/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, h, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, s, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, l, 7/fg, 0/bg + # save just top 2 bits of each, so that we narrow down to 1/64th of the volume + shift-right h, 6 + shift-right s, 6 + shift-right l, 6 +#? set-cursor-position screen, 0x10/x, 0x1/y +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, h, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, s, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, l, 7/fg, 0/bg + var a/ecx: int <- copy 0 + var b/edx: int <- copy 0 + var c/ebx: int <- copy 0 + var color/eax: int <- copy 0 + var y/esi: int <- copy 2 + { + compare color, 0x100 + break-if->= + a, b, c <- color-rgb color + a, b, c <- hsl a, b, c + a <- shift-right 6 + b <- shift-right 6 + c <- shift-right 6 + { + compare a, h + break-if-!= + compare b, s + break-if-!= + compare c, l + break-if-!= + set-cursor-position screen, 0x10/x, y + draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, color, 7/fg, 0/bg + set-cursor-position screen, 0x14/x, y + draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg + draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 0/fg, color +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, a, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, b, 7/fg, 0/bg +#? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg +#? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, c, 7/fg, 0/bg + y <- increment + } + color <- increment + loop + } +} diff --git a/rpn.mu b/rpn.mu index 88053e7c..a634c791 100644 --- a/rpn.mu +++ b/rpn.mu @@ -24,7 +24,6 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { # print prompt var x/eax: int <- draw-text-rightward screen, "> ", 0/x, 0x80/xmax, y, 3/fg/cyan, 0/bg - set-cursor-position screen, x, y # read line from keyboard clear-stream in { -- cgit 1.4.1-2-gfad0