https://github.com/akkartik/mu/blob/main/500text-screen.mu
1
2
3
4
5
6
7
8
9 type screen {
10 width: int
11 height: int
12 data: (handle array screen-cell)
13 cursor-x: int
14 cursor-y: int
15 }
16
17 type screen-cell {
18 data: grapheme
19 color: int
20 background-color: int
21 }
22
23 fn initialize-screen _screen: (addr screen), width: int, height: int {
24 var screen/esi: (addr screen) <- copy _screen
25 var tmp/eax: int <- copy 0
26 var dest/edi: (addr int) <- copy 0
27
28 dest <- get screen, width
29 tmp <- copy width
30 copy-to *dest, tmp
31
32 dest <- get screen, height
33 tmp <- copy height
34 copy-to *dest, tmp
35
36 {
37 var data-addr/edi: (addr handle array screen-cell) <- get screen, data
38 tmp <- multiply width
39 populate data-addr, tmp
40 }
41
42 dest <- get screen, cursor-x
43 copy-to *dest, 0
44
45 dest <- get screen, cursor-y
46 copy-to *dest, 0
47 }
48
49
50 fn screen-size _screen: (addr screen) -> _/eax: int, _/ecx: int {
51 var screen/esi: (addr screen) <- copy _screen
52 var width/eax: int <- copy 0
53 var height/ecx: int <- copy 0
54 compare screen, 0
55 {
56 break-if-!=
57 return 0x80/128, 0x30/48
58 }
59
60 var tmp/edx: (addr int) <- get screen, width
61 width <- copy *tmp
62 tmp <- get screen, height
63 height <- copy *tmp
64 return width, height
65 }
66
67
68 fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int {
69 var screen/esi: (addr screen) <- copy _screen
70 {
71 compare screen, 0
72 break-if-!=
73 draw-grapheme-on-real-screen g, x, y, color, background-color
74 return
75 }
76
77 var idx/ecx: int <- screen-cell-index screen, x, y
78 var data-ah/eax: (addr handle array screen-cell) <- get screen, data
79 var data/eax: (addr array screen-cell) <- lookup *data-ah
80 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
81 var dest-cell/ecx: (addr screen-cell) <- index data, offset
82 var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data
83 var g2/edx: grapheme <- copy g
84 copy-to *dest-grapheme, g2
85 var dest-color/eax: (addr int) <- get dest-cell, color
86 var src-color/edx: int <- copy color
87 copy-to *dest-color, src-color
88 dest-color <- get dest-cell, background-color
89 src-color <- copy background-color
90 copy-to *dest-color, src-color
91 }
92
93
94 fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int {
95 var g/eax: grapheme <- copy c
96 draw-grapheme screen, g, x, y, color, background-color
97 }
98
99
100 fn screen-cell-index _screen: (addr screen), x: int, y: int -> _/ecx: int {
101 var screen/esi: (addr screen) <- copy _screen
102
103 {
104 var xmax/eax: (addr int) <- get screen, width
105 var xcurr/ecx: int <- copy x
106 compare xcurr, *xmax
107 break-if-<
108 abort "tried to print out of screen bounds"
109 }
110 var width-addr/eax: (addr int) <- get screen, width
111 var result/ecx: int <- copy y
112 result <- multiply *width-addr
113 result <- add x
114 return result
115 }
116
117 fn cursor-position _screen: (addr screen) -> _/eax: int, _/ecx: int {
118 var screen/esi: (addr screen) <- copy _screen
119 {
120 compare screen, 0
121 break-if-!=
122 var x/eax: int <- copy 0
123 var y/ecx: int <- copy 0
124 x, y <- cursor-position-on-real-screen
125 return x, y
126 }
127
128 var cursor-x-addr/eax: (addr int) <- get screen, cursor-x
129 var cursor-y-addr/ecx: (addr int) <- get screen, cursor-y
130 return *cursor-x-addr, *cursor-y-addr
131 }
132
133 fn set-cursor-position _screen: (addr screen), x: int, y: int {
134 var screen/esi: (addr screen) <- copy _screen
135 {
136 compare screen, 0
137 break-if-!=
138 set-cursor-position-on-real-screen x, y
139 return
140 }
141
142
143 {
144 compare x, 0
145 break-if->=
146 return
147 }
148
149 {
150 var width-addr/eax: (addr int) <- get screen, width
151 var width/eax: int <- copy *width-addr
152 compare x, width
153 break-if-<=
154 return
155 }
156
157 {
158 compare y, 0
159 break-if->=
160 return
161 }
162
163 {
164 var height-addr/eax: (addr int) <- get screen, height
165 var height/eax: int <- copy *height-addr
166 compare y, height
167 break-if-<
168 return
169 }
170
171 var dest/edi: (addr int) <- get screen, cursor-x
172 var src/eax: int <- copy x
173 copy-to *dest, src
174
175 dest <- get screen, cursor-y
176 src <- copy y
177 copy-to *dest, src
178 }
179
180 fn draw-cursor screen: (addr screen), g: grapheme {
181 {
182 compare screen, 0
183 break-if-!=
184 draw-cursor-on-real-screen g
185 return
186 }
187
188 var cursor-x/eax: int <- copy 0
189 var cursor-y/ecx: int <- copy 0
190 cursor-x, cursor-y <- cursor-position screen
191 draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg
192 }
193
194 fn clear-screen _screen: (addr screen) {
195 var screen/esi: (addr screen) <- copy _screen
196 {
197 compare screen, 0
198 break-if-!=
199 clear-real-screen
200 return
201 }
202
203 set-cursor-position screen, 0, 0
204 var y/eax: int <- copy 0
205 var height/ecx: (addr int) <- get screen, height
206 {
207 compare y, *height
208 break-if->=
209 var x/edx: int <- copy 0
210 var width/ebx: (addr int) <- get screen, width
211 {
212 compare x, *width
213 break-if->=
214 draw-code-point screen, 0x20/space, x, y, 0/fg=black, 0/bg=black
215 x <- increment
216 loop
217 }
218 y <- increment
219 loop
220 }
221 set-cursor-position screen, 0, 0
222 }
223
224 fn fake-screen-empty? _screen: (addr screen) -> _/eax: boolean {
225 var screen/esi: (addr screen) <- copy _screen
226 var y/eax: int <- copy 0
227 var height/ecx: (addr int) <- get screen, height
228 {
229 compare y, *height
230 break-if->=
231 var x/edx: int <- copy 0
232 var width/ebx: (addr int) <- get screen, width
233 {
234 compare x, *width
235 break-if->=
236 var g/eax: grapheme <- screen-grapheme-at screen, x, y
237 {
238 compare g, 0
239 break-if-=
240 compare g, 0x20/space
241 break-if-=
242 return 0/false
243 }
244 x <- increment
245 loop
246 }
247 y <- increment
248 loop
249 }
250 return 1/true
251 }
252
253 fn clear-rect _screen: (addr screen), xmin: int, ymin: int, xmax: int, ymax: int, background-color: int {
254 var screen/esi: (addr screen) <- copy _screen
255 {
256 compare screen, 0
257 break-if-!=
258 clear-rect-on-real-screen xmin, ymin, xmax, ymax, background-color
259 return
260 }
261
262 set-cursor-position screen, 0, 0
263 var y/eax: int <- copy ymin
264 var ymax/ecx: int <- copy ymax
265 {
266 compare y, ymax
267 break-if->=
268 var x/edx: int <- copy xmin
269 var xmax/ebx: int <- copy xmax
270 {
271 compare x, xmax
272 break-if->=
273 draw-code-point screen, 0x20/space, x, y, 0/fg, background-color
274 x <- increment
275 loop
276 }
277 y <- increment
278 loop
279 }
280 set-cursor-position screen, 0, 0
281 }
282
283
284
285 fn clear-real-screen {
286 var y/eax: int <- copy 0
287 {
288 compare y, 0x300/screen-height=768
289 break-if->=
290 var x/edx: int <- copy 0
291 {
292 compare x, 0x400/screen-width=1024
293 break-if->=
294 pixel-on-real-screen x, y, 0/color=black
295 x <- increment
296 loop
297 }
298 y <- increment
299 loop
300 }
301 }
302
303 fn clear-rect-on-real-screen xmin: int, ymin: int, xmax: int, ymax: int, background-color: int {
304 var y/eax: int <- copy ymin
305 y <- shift-left 4/log-font-height
306 var ymax/ecx: int <- copy ymax
307 ymax <- shift-left 4/log-font-height
308 {
309 compare y, ymax
310 break-if->=
311 var x/edx: int <- copy xmin
312 x <- shift-left 3/log-font-width
313 var xmax/ebx: int <- copy xmax
314 xmax <- shift-left 3/log-font-width
315 {
316 compare x, xmax
317 break-if->=
318 pixel-on-real-screen x, y, background-color
319 x <- increment
320 loop
321 }
322 y <- increment
323 loop
324 }
325 }
326
327 fn screen-grapheme-at _screen: (addr screen), x: int, y: int -> _/eax: grapheme {
328 var screen/esi: (addr screen) <- copy _screen
329 var idx/ecx: int <- screen-cell-index screen, x, y
330 var result/eax: grapheme <- screen-grapheme-at-idx screen, idx
331 return result
332 }
333
334 fn screen-grapheme-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: grapheme {
335 var screen/esi: (addr screen) <- copy _screen
336 var data-ah/eax: (addr handle array screen-cell) <- get screen, data
337 var data/eax: (addr array screen-cell) <- lookup *data-ah
338 var idx/ecx: int <- copy idx-on-stack
339 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
340 var cell/eax: (addr screen-cell) <- index data, offset
341 var src/eax: (addr grapheme) <- get cell, data
342 return *src
343 }
344
345 fn screen-color-at _screen: (addr screen), x: int, y: int -> _/eax: int {
346 var screen/esi: (addr screen) <- copy _screen
347 var idx/ecx: int <- screen-cell-index screen, x, y
348 var result/eax: int <- screen-color-at-idx screen, idx
349 return result
350 }
351
352 fn screen-color-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: int {
353 var screen/esi: (addr screen) <- copy _screen
354 var data-ah/eax: (addr handle array screen-cell) <- get screen, data
355 var data/eax: (addr array screen-cell) <- lookup *data-ah
356 var idx/ecx: int <- copy idx-on-stack
357 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
358 var cell/eax: (addr screen-cell) <- index data, offset
359 var src/eax: (addr int) <- get cell, color
360 var result/eax: int <- copy *src
361 return result
362 }
363
364 fn screen-background-color-at _screen: (addr screen), x: int, y: int -> _/eax: int {
365 var screen/esi: (addr screen) <- copy _screen
366 var idx/ecx: int <- screen-cell-index screen, x, y
367 var result/eax: int <- screen-background-color-at-idx screen, idx
368 return result
369 }
370
371 fn screen-background-color-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: int {
372 var screen/esi: (addr screen) <- copy _screen
373 var data-ah/eax: (addr handle array screen-cell) <- get screen, data
374 var data/eax: (addr array screen-cell) <- lookup *data-ah
375 var idx/ecx: int <- copy idx-on-stack
376 var offset/ecx: (offset screen-cell) <- compute-offset data, idx
377 var cell/eax: (addr screen-cell) <- index data, offset
378 var src/eax: (addr int) <- get cell, background-color
379 var result/eax: int <- copy *src
380 return result
381 }