https://github.com/akkartik/mu/blob/main/apps/ex11.mu
1
2
3
4
5
6
7
8
9
10
11
12 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
13 var env-storage: environment
14 var env/esi: (addr environment) <- address env-storage
15 initialize-environment env, 0x200 0x20, 0x180 0x90, 0x180 0x160
16 {
17 render screen, env
18 edit keyboard, env
19 loop
20 }
21 }
22
23 type environment {
24 p0: (handle point)
25 p1: (handle point)
26 p2: (handle point)
27 cursor: (handle point)
28 }
29
30 type point {
31 x: int
32 y: int
33 }
34
35 fn render screen: (addr screen), _self: (addr environment) {
36 clear-screen screen
37 var self/esi: (addr environment) <- copy _self
38 var tmp-ah/ecx: (addr handle point) <- get self, p0
39 var tmp/eax: (addr point) <- lookup *tmp-ah
40 var p0/ebx: (addr point) <- copy tmp
41 tmp-ah <- get self, p1
42 tmp <- lookup *tmp-ah
43 var p1/edx: (addr point) <- copy tmp
44 tmp-ah <- get self, p2
45 tmp <- lookup *tmp-ah
46 var p2/ecx: (addr point) <- copy tmp
47
48 line screen, p0, p1, 7/color
49 line screen, p1, p2, 7/color
50
51 bezier screen, p0, p1, p2, 0xc/color
52
53 disc screen, p0, 3/radius, 7/color 0xf/border
54 disc screen, p1, 3/radius, 7/color 0xf/border
55 disc screen, p2, 3/radius, 7/color 0xf/border
56
57 var cursor-ah/eax: (addr handle point) <- get self, cursor
58 var cursor/eax: (addr point) <- lookup *cursor-ah
59 cursor screen, cursor, 0xa/side, 3/color
60 }
61
62 fn bezier screen: (addr screen), _p0: (addr point), _p1: (addr point), _p2: (addr point), color: int {
63 var p0/esi: (addr point) <- copy _p0
64 var x0/ecx: (addr int) <- get p0, x
65 var y0/edx: (addr int) <- get p0, y
66 var p1/esi: (addr point) <- copy _p1
67 var x1/ebx: (addr int) <- get p1, x
68 var y1/eax: (addr int) <- get p1, y
69 var p2/esi: (addr point) <- copy _p2
70 var x2/edi: (addr int) <- get p2, x
71 var y2/esi: (addr int) <- get p2, y
72 draw-monotonic-bezier screen, *x0 *y0, *x1 *y1, *x2 *y2, color
73 }
74
75 fn cursor screen: (addr screen), _p: (addr point), side: int, color: int {
76 var half-side/eax: int <- copy side
77 half-side <- shift-right 1
78 var p/esi: (addr point) <- copy _p
79 var x-a/ecx: (addr int) <- get p, x
80 var left-x/ecx: int <- copy *x-a
81 left-x <- subtract half-side
82 var y-a/edx: (addr int) <- get p, y
83 var top-y/edx: int <- copy *y-a
84 top-y <- subtract half-side
85 var max/eax: int <- copy left-x
86 max <- add side
87 draw-horizontal-line screen, top-y, left-x, max, color
88 max <- copy top-y
89 max <- add side
90 draw-vertical-line screen, left-x, top-y, max, color
91 var right-x/ebx: int <- copy left-x
92 right-x <- add side
93 draw-vertical-line screen, right-x, top-y, max, color
94 var bottom-y/edx: int <- copy top-y
95 bottom-y <- add side
96 draw-horizontal-line screen, bottom-y, left-x, right-x, color
97 }
98
99 fn edit keyboard: (addr keyboard), _self: (addr environment) {
100 var self/esi: (addr environment) <- copy _self
101 var key/eax: byte <- read-key keyboard
102 compare key, 0
103 loop-if-=
104 {
105 compare key, 9/tab
106 break-if-!=
107 toggle-cursor self
108 return
109 }
110 {
111 compare key, 0x80/left-arrow
112 break-if-!=
113 cursor-left self
114 return
115 }
116 {
117 compare key, 0x83/right-arrow
118 break-if-!=
119 cursor-right self
120 return
121 }
122 {
123 compare key, 0x81/down-arrow
124 break-if-!=
125 cursor-down self
126 return
127 }
128 {
129 compare key, 0x82/up-arrow
130 break-if-!=
131 cursor-up self
132 return
133 }
134 }
135
136 fn toggle-cursor _self: (addr environment) {
137 var self/esi: (addr environment) <- copy _self
138 var cursor-ah/edi: (addr handle point) <- get self, cursor
139 var p0-ah/ecx: (addr handle point) <- get self, p0
140 var p1-ah/edx: (addr handle point) <- get self, p1
141 var p2-ah/ebx: (addr handle point) <- get self, p2
142 {
143 var p0?/eax: boolean <- handle-equal? *p0-ah, *cursor-ah
144 compare p0?, 0/false
145 break-if-=
146 copy-object p1-ah, cursor-ah
147 return
148 }
149 {
150 var p1?/eax: boolean <- handle-equal? *p1-ah, *cursor-ah
151 compare p1?, 0/false
152 break-if-=
153 copy-object p2-ah, cursor-ah
154 return
155 }
156 {
157 var p2?/eax: boolean <- handle-equal? *p2-ah, *cursor-ah
158 compare p2?, 0/false
159 break-if-=
160 copy-object p0-ah, cursor-ah
161 return
162 }
163 abort "lost cursor"
164 }
165
166 fn cursor-left _self: (addr environment) {
167 var self/esi: (addr environment) <- copy _self
168 var cursor-ah/esi: (addr handle point) <- get self, cursor
169 var cursor/eax: (addr point) <- lookup *cursor-ah
170 var cursor-x/eax: (addr int) <- get cursor, x
171 compare *cursor-x, 0x20
172 {
173 break-if-<
174 subtract-from *cursor-x, 0x20
175 }
176 }
177
178 fn cursor-right _self: (addr environment) {
179 var self/esi: (addr environment) <- copy _self
180 var cursor-ah/esi: (addr handle point) <- get self, cursor
181 var cursor/eax: (addr point) <- lookup *cursor-ah
182 var cursor-x/eax: (addr int) <- get cursor, x
183 compare *cursor-x, 0x3f0
184 {
185 break-if->
186 add-to *cursor-x, 0x20
187 }
188 }
189
190 fn cursor-up _self: (addr environment) {
191 var self/esi: (addr environment) <- copy _self
192 var cursor-ah/esi: (addr handle point) <- get self, cursor
193 var cursor/eax: (addr point) <- lookup *cursor-ah
194 var cursor-y/eax: (addr int) <- get cursor, y
195 compare *cursor-y, 0x20
196 {
197 break-if-<
198 subtract-from *cursor-y, 0x20
199 }
200 }
201
202 fn cursor-down _self: (addr environment) {
203 var self/esi: (addr environment) <- copy _self
204 var cursor-ah/esi: (addr handle point) <- get self, cursor
205 var cursor/eax: (addr point) <- lookup *cursor-ah
206 var cursor-y/eax: (addr int) <- get cursor, y
207 compare *cursor-y, 0x2f0
208 {
209 break-if->
210 add-to *cursor-y, 0x20
211 }
212 }
213
214 fn line screen: (addr screen), _p0: (addr point), _p1: (addr point), color: int {
215 var p0/esi: (addr point) <- copy _p0
216 var x0/ecx: (addr int) <- get p0, x
217 var y0/edx: (addr int) <- get p0, y
218 var p1/esi: (addr point) <- copy _p1
219 var x1/ebx: (addr int) <- get p1, x
220 var y1/eax: (addr int) <- get p1, y
221 draw-line screen, *x0 *y0, *x1 *y1, color
222 }
223
224 fn disc screen: (addr screen), _p: (addr point), radius: int, color: int, border-color: int {
225 var p/esi: (addr point) <- copy _p
226 var x/ecx: (addr int) <- get p, x
227 var y/edx: (addr int) <- get p, y
228 draw-disc screen, *x *y, radius, color, border-color
229 }
230
231 fn initialize-environment _self: (addr environment), x0: int, y0: int, x1: int, y1: int, x2: int, y2: int {
232 var self/esi: (addr environment) <- copy _self
233 var p0-ah/eax: (addr handle point) <- get self, p0
234 allocate p0-ah
235 var p0/eax: (addr point) <- lookup *p0-ah
236 initialize-point p0, x0 y0
237 var p1-ah/eax: (addr handle point) <- get self, p1
238 allocate p1-ah
239 var p1/eax: (addr point) <- lookup *p1-ah
240 initialize-point p1, x1 y1
241 var p2-ah/eax: (addr handle point) <- get self, p2
242 allocate p2-ah
243 var p2/eax: (addr point) <- lookup *p2-ah
244 initialize-point p2, x2 y2
245
246 var cursor-ah/edi: (addr handle point) <- get self, cursor
247 var src-ah/esi: (addr handle point) <- get self, p0
248 copy-object src-ah, cursor-ah
249 }
250
251 fn initialize-point _p: (addr point), x: int, y: int {
252 var p/esi: (addr point) <- copy _p
253 var dest/eax: (addr int) <- get p, x
254 var src/ecx: int <- copy x
255 copy-to *dest, src
256 dest <- get p, y
257 src <- copy y
258 copy-to *dest, src
259 }