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