https://github.com/akkartik/mu/blob/main/apps/colors.mu
1
2
3
4
5
6
7
8
9
10
11
12
13 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
14 var in-storage: (stream byte 0x10)
15 var in/esi: (addr stream byte) <- address in-storage
16 {
17
18 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
19
20 clear-stream in
21 {
22 draw-cursor screen, 0x20/space
23 var key/eax: byte <- read-key keyboard
24 compare key, 0xa/newline
25 break-if-=
26 compare key, 0
27 loop-if-=
28 var key2/eax: int <- copy key
29 append-byte in, key2
30 var g/eax: grapheme <- copy key2
31 draw-grapheme-at-cursor screen, g, 0xf/fg, 0/bg
32 move-cursor-right 0
33 loop
34 }
35 clear-screen screen
36
37 var a/ecx: int <- copy 0
38 var b/edx: int <- copy 0
39 var c/ebx: int <- copy 0
40
41 a, b, c <- parse in
42
43
44
45
46
47
48 a, b, c <- hsl a, b, c
49
50 print-nearby-colors screen, a, b, c
51
52 var color/eax: int <- nearest-color-euclidean-hsl a, b, c
53 set-cursor-position screen, 0x10/x, 0x26/y
54 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "nearest (euclidean, h/s/l): ", 0xf/fg, 0/bg
55 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, color, 7/fg, 0/bg
56 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 0xf/fg, 0/bg
57 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 0/fg, color
58
59 loop
60 }
61 }
62
63
64
65 fn parse in: (addr stream byte) -> _/ecx: int, _/edx: int, _/ebx: int {
66
67 var tmp/eax: byte <- read-byte in
68 {
69 var valid?/eax: boolean <- hex-digit? tmp
70 compare valid?, 0/false
71 break-if-!=
72 abort "invalid byte 0 of r"
73 }
74 tmp <- fast-hex-digit-value tmp
75 var r/ecx: int <- copy tmp
76
77
78
79 tmp <- read-byte in
80 {
81 {
82 var valid?/eax: boolean <- hex-digit? tmp
83 compare valid?, 0/false
84 }
85 break-if-=
86 r <- shift-left 4
87 tmp <- fast-hex-digit-value tmp
88
89
90
91
92
93 r <- add tmp
94
95
96
97
98 tmp <- read-byte in
99 }
100
101 var tmp/eax: byte <- read-byte in
102 {
103 var valid?/eax: boolean <- hex-digit? tmp
104 compare valid?, 0/false
105 break-if-!=
106 abort "invalid byte 0 of g"
107 }
108 tmp <- fast-hex-digit-value tmp
109 var g/edx: int <- copy tmp
110
111
112
113 tmp <- read-byte in
114 {
115 {
116 var valid?/eax: boolean <- hex-digit? tmp
117 compare valid?, 0/false
118 }
119 break-if-=
120 g <- shift-left 4
121 tmp <- fast-hex-digit-value tmp
122
123
124
125
126
127 g <- add tmp
128
129
130
131
132 tmp <- read-byte in
133 }
134
135 var tmp/eax: byte <- read-byte in
136 {
137 var valid?/eax: boolean <- hex-digit? tmp
138 compare valid?, 0/false
139 break-if-!=
140 abort "invalid byte 0 of b"
141 }
142 tmp <- fast-hex-digit-value tmp
143 var b/ebx: int <- copy tmp
144
145
146
147 {
148 {
149 var done?/eax: boolean <- stream-empty? in
150 compare done?, 0/false
151 }
152 break-if-!=
153 tmp <- read-byte in
154 {
155 var valid?/eax: boolean <- hex-digit? tmp
156 compare valid?, 0/false
157 }
158 break-if-=
159 b <- shift-left 4
160 tmp <- fast-hex-digit-value tmp
161
162
163
164
165
166 b <- add tmp
167
168
169
170
171 }
172 return r, g, b
173 }
174
175
176 fn fast-hex-digit-value in: byte -> _/eax: byte {
177 var result/eax: byte <- copy in
178 compare result, 0x39
179 {
180 break-if->
181 result <- subtract 0x30/0
182 return result
183 }
184 result <- subtract 0x61/a
185 result <- add 0xa/10
186 return result
187 }
188
189 fn print-nearby-colors screen: (addr screen), h: int, s: int, l: int {
190
191
192
193
194
195
196
197 shift-right h, 6
198 shift-right s, 6
199 shift-right l, 6
200
201
202
203
204
205
206 var a/ecx: int <- copy 0
207 var b/edx: int <- copy 0
208 var c/ebx: int <- copy 0
209 var color/eax: int <- copy 0
210 var y/esi: int <- copy 2
211 {
212 compare color, 0x100
213 break-if->=
214 a, b, c <- color-rgb color
215 a, b, c <- hsl a, b, c
216 a <- shift-right 6
217 b <- shift-right 6
218 c <- shift-right 6
219 {
220 compare a, h
221 break-if-!=
222 compare b, s
223 break-if-!=
224 compare c, l
225 break-if-!=
226 set-cursor-position screen, 0x10/x, y
227 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, color, 7/fg, 0/bg
228 set-cursor-position screen, 0x14/x, y
229 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg
230 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 0/fg, color
231
232
233
234
235
236
237 y <- increment
238 }
239 color <- increment
240 loop
241 }
242 }