https://github.com/akkartik/mu/blob/main/apps/tile.mu
  1 # Randomly tile from a given set of tiles
  2 #
  3 # To build:
  4 #   $ git clone https://github.com/akkartik/mu
  5 #   $ cd mu
  6 #   $ ./translate apps/tile.mu
  7 # To run:
  8 #   $ qemu-system-i386 code.img
  9 
 10 type tile {
 11   data: (handle array handle array int)
 12 }
 13 
 14 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
 15   # basic maze
 16   # 10 PRINT CHR$(205.5 + RND(1))
 17   # GOTO 10
 18 #?   var tiles-storage: (array tile 2)
 19 #?   var tiles/esi: (addr array tile) <- address tiles-storage
 20 #?   set-tile tiles, 0/idx, 1 0 0, 0 1 0, 0 0 1
 21 #?   set-tile tiles, 1/idx, 0 0 1, 0 1 0, 1 0 0
 22 
 23   # https://pbat.ch/wiki/trikuf
 24   var tiles-storage: (array tile 0x62)
 25   var tiles/esi: (addr array tile) <- address tiles-storage
 26   set-tile tiles, 0x00/idx, 1 1 1, 0 1 0, 0 0 0
 27   set-tile tiles, 0x01/idx, 0 1 1, 1 1 0, 0 0 0
 28   set-tile tiles, 0x02/idx, 1 1 1, 1 0 1, 0 0 0
 29   set-tile tiles, 0x03/idx, 1 1 0, 0 1 1, 0 0 0
 30   set-tile tiles, 0x04/idx, 0 0 0, 1 1 1, 0 0 0
 31   set-tile tiles, 0x05/idx, 1 0 0, 1 1 1, 0 0 0
 32   set-tile tiles, 0x06/idx, 0 1 0, 1 1 1, 0 0 0
 33   set-tile tiles, 0x07/idx, 0 0 1, 1 1 1, 0 0 0
 34   set-tile tiles, 0x08/idx, 1 0 1, 1 1 1, 0 0 0
 35   set-tile tiles, 0x09/idx, 0 1 1, 1 1 0, 1 0 0
 36   set-tile tiles, 0x0a/idx, 0 1 1, 0 0 1, 1 0 0
 37   set-tile tiles, 0x0b/idx, 1 1 1, 0 0 1, 1 0 0
 38   set-tile tiles, 0x0c/idx, 1 1 1, 1 0 1, 1 0 0
 39   set-tile tiles, 0x0d/idx, 0 0 0, 1 1 1, 1 0 0
 40   set-tile tiles, 0x0e/idx, 1 0 0, 1 1 1, 1 0 0
 41   set-tile tiles, 0x0f/idx, 0 1 0, 1 1 1, 1 0 0
 42   set-tile tiles, 0x10/idx, 0 0 1, 1 1 1, 1 0 0
 43   set-tile tiles, 0x11/idx, 1 0 1, 1 1 1, 1 0 0
 44   set-tile tiles, 0x12/idx, 1 0 1, 0 0 0, 0 1 0
 45   set-tile tiles, 0x13/idx, 1 1 1, 0 0 0, 0 1 0
 46   set-tile tiles, 0x14/idx, 1 1 1, 0 1 0, 0 1 0
 47   set-tile tiles, 0x15/idx, 0 1 1, 1 1 0, 0 1 0
 48   set-tile tiles, 0x16/idx, 1 1 0, 0 1 1, 0 1 0
 49   set-tile tiles, 0x17/idx, 0 0 0, 1 1 1, 0 1 0
 50   set-tile tiles, 0x18/idx, 1 0 0, 1 1 1, 0 1 0
 51   set-tile tiles, 0x19/idx, 0 1 0, 1 1 1, 0 1 0
 52   set-tile tiles, 0x1a/idx, 0 0 1, 1 1 1, 0 1 0
 53   set-tile tiles, 0x1b/idx, 1 0 1, 1 1 1, 0 1 0
 54   set-tile tiles, 0x1c/idx, 1 0 1, 0 0 0, 1 1 0
 55   set-tile tiles, 0x1d/idx, 0 1 1, 0 0 0, 1 1 0
 56   set-tile tiles, 0x1e/idx, 1 1 1, 0 0 0, 1 1 0
 57   set-tile tiles, 0x1f/idx, 0 0 1, 1 0 0, 1 1 0
 58   set-tile tiles, 0x20/idx, 1 0 1, 1 0 0, 1 1 0
 59   set-tile tiles, 0x21/idx, 1 1 1, 1 0 0, 1 1 0
 60   set-tile tiles, 0x22/idx, 0 1 1, 0 1 0, 1 1 0
 61   set-tile tiles, 0x23/idx, 1 1 1, 0 1 0, 1 1 0
 62   set-tile tiles, 0x24/idx, 0 0 0, 0 1 1, 1 1 0
 63   set-tile tiles, 0x25/idx, 0 1 0, 0 1 1, 1 1 0
 64   set-tile tiles, 0x26/idx, 1 1 0, 0 1 1, 1 1 0
 65   set-tile tiles, 0x27/idx, 0 0 1, 0 1 1, 1 1 0
 66   set-tile tiles, 0x28/idx, 1 1 0, 1 0 0, 0 0 1
 67   set-tile tiles, 0x29/idx, 1 1 1, 1 0 0, 0 0 1
 68   set-tile tiles, 0x2a/idx, 1 1 1, 1 0 1, 0 0 1
 69   set-tile tiles, 0x2b/idx, 1 1 0, 0 1 1, 0 0 1
 70   set-tile tiles, 0x2c/idx, 0 0 0, 1 1 1, 0 0 1
 71   set-tile tiles, 0x2d/idx, 1 0 0, 1 1 1, 0 0 1
 72   set-tile tiles, 0x2e/idx, 0 1 0, 1 1 1, 0 0 1
 73   set-tile tiles, 0x2f/idx, 0 0 1, 1 1 1, 0 0 1
 74   set-tile tiles, 0x30/idx, 1 0 1, 1 1 1, 0 0 1
 75   set-tile tiles, 0x31/idx, 0 1 0, 0 0 0, 1 0 1
 76   set-tile tiles, 0x32/idx, 1 1 0, 0 0 0, 1 0 1
 77   set-tile tiles, 0x33/idx, 0 1 1, 0 0 0, 1 0 1
 78   set-tile tiles, 0x34/idx, 1 1 1, 0 0 0, 1 0 1
 79   set-tile tiles, 0x35/idx, 1 1 0, 1 0 0, 1 0 1
 80   set-tile tiles, 0x36/idx, 1 1 1, 1 0 0, 1 0 1
 81   set-tile tiles, 0x37/idx, 0 1 1, 0 0 1, 1 0 1
 82   set-tile tiles, 0x38/idx, 1 1 1, 0 0 1, 1 0 1
 83   set-tile tiles, 0x39/idx, 1 1 1, 1 0 1, 1 0 1
 84   set-tile tiles, 0x3a/idx, 0 0 0, 1 1 1, 1 0 1
 85   set-tile tiles, 0x3b/idx, 1 0 0, 1 1 1, 1 0 1
 86   set-tile tiles, 0x3c/idx, 0 1 0, 1 1 1, 1 0 1
 87   set-tile tiles, 0x3d/idx, 0 0 1, 1 1 1, 1 0 1
 88   set-tile tiles, 0x3e/idx, 1 0 1, 1 1 1, 1 0 1
 89   set-tile tiles, 0x3f/idx, 1 1 0, 0 0 0, 0 1 1
 90   set-tile tiles, 0x40/idx, 1 0 1, 0 0 0, 0 1 1
 91   set-tile tiles, 0x41/idx, 1 1 1, 0 0 0, 0 1 1
 92   set-tile tiles, 0x42/idx, 1 1 0, 0 1 0, 0 1 1
 93   set-tile tiles, 0x43/idx, 1 1 1, 0 1 0, 0 1 1
 94   set-tile tiles, 0x44/idx, 0 0 0, 1 1 0, 0 1 1
 95   set-tile tiles, 0x45/idx, 1 0 0, 1 1 0, 0 1 1
 96   set-tile tiles, 0x46/idx, 0 1 0, 1 1 0, 0 1 1
 97   set-tile tiles, 0x47/idx, 0 1 1, 1 1 0, 0 1 1
 98   set-tile tiles, 0x48/idx, 1 0 0, 0 0 1, 0 1 1
 99   set-tile tiles, 0x49/idx, 1 0 1, 0 0 1, 0 1 1
100   set-tile tiles, 0x4a/idx, 1 1 1, 0 0 1, 0 1 1
101   set-tile tiles, 0x4b/idx, 0 1 0, 0 0 0, 1 1 1
102   set-tile tiles, 0x4c/idx, 1 1 0, 0 0 0, 1 1 1
103   set-tile tiles, 0x4d/idx, 1 0 1, 0 0 0, 1 1 1
104   set-tile tiles, 0x4e/idx, 0 1 1, 0 0 0, 1 1 1
105   set-tile tiles, 0x4f/idx, 1 1 1, 0 0 0, 1 1 1
106   set-tile tiles, 0x50/idx, 1 1 0, 1 0 0, 1 1 1
107   set-tile tiles, 0x51/idx, 0 0 1, 1 0 0, 1 1 1
108   set-tile tiles, 0x52/idx, 1 0 1, 1 0 0, 1 1 1
109   set-tile tiles, 0x53/idx, 1 1 1, 1 0 0, 1 1 1
110   set-tile tiles, 0x54/idx, 0 0 0, 0 1 0, 1 1 1
111   set-tile tiles, 0x55/idx, 0 1 0, 0 1 0, 1 1 1
112   set-tile tiles, 0x56/idx, 1 1 0, 0 1 0, 1 1 1
113   set-tile tiles, 0x57/idx, 0 1 1, 0 1 0, 1 1 1
114   set-tile tiles, 0x58/idx, 1 1 1, 0 1 0, 1 1 1
115   set-tile tiles, 0x59/idx, 1 0 0, 0 0 1, 1 1 1
116   set-tile tiles, 0x5a/idx, 1 0 1, 0 0 1, 1 1 1
117   set-tile tiles, 0x5b/idx, 0 1 1, 0 0 1, 1 1 1
118   set-tile tiles, 0x5c/idx, 1 1 1, 0 0 1, 1 1 1
119   set-tile tiles, 0x5d/idx, 0 0 0, 1 0 1, 1 1 1
120   set-tile tiles, 0x5e/idx, 1 0 0, 1 0 1, 1 1 1
121   set-tile tiles, 0x5f/idx, 0 0 1, 1 0 1, 1 1 1
122   set-tile tiles, 0x60/idx, 1 0 1, 1 0 1, 1 1 1
123   set-tile tiles, 0x61/idx, 1 1 1, 1 0 1, 1 1 1
124 
125   render-tiles screen, tiles
126   {
127     var key/eax: byte <- read-key keyboard
128     compare key, 0
129     loop-if-=
130   }
131   var step/eax: int <- copy 0
132   {
133     render-random screen, tiles, 4/pixels-per-cell, step
134     {
135       var key/eax: byte <- read-key keyboard
136       compare key, 0
137       loop-if-=
138     }
139     step <- increment
140     loop
141   }
142 }
143 
144 fn set-tile _tiles: (addr array tile), _idx: int, n0: int, n1: int, n2: int, n3: int, n4: int, n5: int, n6: int, n7: int, n8: int {
145   var tiles/eax: (addr array tile) <- copy _tiles
146   var idx/ecx: int <- copy _idx
147   var tile/edi: (addr tile) <- index tiles, idx
148   var rows-ah/eax: (addr handle array handle array int) <- get tile, data
149   populate rows-ah, 3
150   var _rows/eax: (addr array handle array int) <- lookup *rows-ah
151   var rows/edi: (addr array handle array int) <- copy _rows
152   var row0-ah/eax: (addr handle array int) <- index rows, 0
153   populate row0-ah, 3
154   var row0/eax: (addr array int) <- lookup *row0-ah
155   var x0/ecx: (addr int) <- index row0, 0
156   var src/esi: int <- copy n0
157   copy-to *x0, src
158   var x1/ecx: (addr int) <- index row0, 1
159   var src/esi: int <- copy n1
160   copy-to *x1, src
161   var x2/ecx: (addr int) <- index row0, 2
162   var src/esi: int <- copy n2
163   copy-to *x2, src
164   var row1-ah/eax: (addr handle array int) <- index rows, 1
165   populate row1-ah, 3
166   var row1/eax: (addr array int) <- lookup *row1-ah
167   var x3/ecx: (addr int) <- index row1, 0
168   var src/esi: int <- copy n3
169   copy-to *x3, src
170   var x4/ecx: (addr int) <- index row1, 1
171   var src/esi: int <- copy n4
172   copy-to *x4, src
173   var x5/ecx: (addr int) <- index row1, 2
174   var src/esi: int <- copy n5
175   copy-to *x5, src
176   var row2-ah/eax: (addr handle array int) <- index rows, 2
177   populate row2-ah, 3
178   var row2/eax: (addr array int) <- lookup *row2-ah
179   var x6/ecx: (addr int) <- index row2, 0
180   var src/esi: int <- copy n6
181   copy-to *x6, src
182   var x7/ecx: (addr int) <- index row2, 1
183   var src/esi: int <- copy n7
184   copy-to *x7, src
185   var x8/ecx: (addr int) <- index row2, 2
186   var src/esi: int <- copy n8
187   copy-to *x8, src
188 }
189 
190 fn render-tiles screen: (addr screen), _tiles: (addr array tile) {
191   draw-rect screen, 0 0, 0x400 0x300, 8
192   var tiles/esi: (addr array tile) <- copy _tiles
193   var num-tiles: int
194   var tmp/eax: int <- length tiles
195   copy-to num-tiles, tmp
196 #?   draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, num-tiles, 0x31, 0
197   var i/ecx: int <- copy 0
198   {
199     compare i, num-tiles
200     break-if->=
201 #?     draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, i, 0x31, 0
202     var tile/eax: (addr tile) <- index tiles, i
203     var start-x/edx: int <- copy i
204     start-x <- and 0xf/tiles-per-row-minus-one
205     start-x <- shift-left 5  # ceil(log(3 * pixels-per-cell))
206     start-x <- add 0x20/left-margin
207 #?     draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, start-x, 0x31 0
208     var start-y/ebx: int <- copy i
209     start-y <- shift-right 4/log2-tiles-per-row
210     start-y <- shift-left 5  # ceil(log(3 * pixels-per-cell))
211     start-y <- add 0x20/top-margin
212 #?     draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, start-x, 0x31, 0
213     render-tile screen, tile, start-x, start-y, 8/pixels-per-cell
214     i <- increment
215     loop
216   }
217 }
218 
219 fn render-tile screen: (addr screen), _tile: (addr tile), start-x: int, start-y: int, n: int {
220   var tile/esi: (addr tile) <- copy _tile
221   var y/ecx: int <- copy start-y
222   y <- add 4/margin-top
223   var rows-ah/eax: (addr handle array handle array int) <- get tile, data
224   var rows/eax: (addr array handle array int) <- lookup *rows-ah
225   var i/ebx: int <- copy 0
226   {
227     compare i, 3
228     break-if->=
229     var x/edx: int <- copy start-x
230     x <- add 4/margin-left
231     var curr-row-ah/eax: (addr handle array int) <- index rows, i
232     var curr-row/eax: (addr array int) <- lookup *curr-row-ah
233     var j/edi: int <- copy 0
234     {
235       compare j, 3
236       break-if->=
237       var curr/eax: (addr int) <- index curr-row, j
238       var color/eax: int <- copy *curr
239       color <- shift-left 1
240 #?       draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 9 0
241 #?       draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 0xc 0
242       draw-rect2 screen, x y, n n, color
243       j <- increment
244       x <- add n
245       loop
246     }
247     i <- increment
248     y <- add n
249     loop
250   }
251 }
252 
253 fn render-random screen: (addr screen), _tiles: (addr array tile), pixels-per-cell: int, seed: int {
254   draw-rect screen, 0 0, 0x400 0x300, 8
255   var tiles/esi: (addr array tile) <- copy _tiles
256   var rand/edi: int <- next-random seed
257   var num-tiles/ebx: int <- length tiles
258   var y/ecx: int <- copy 0
259   {
260     compare y, 0x300
261     break-if->=
262     var x/edx: int <- copy 0
263     {
264       compare x, 0x400
265       break-if->=
266       var i/eax: int <- remainder rand, num-tiles
267       var tile/eax: (addr tile) <- index tiles, i
268       render-tile-without-margin screen, tile, x, y, pixels-per-cell
269       x <- add pixels-per-cell
270       x <- add pixels-per-cell
271       x <- add pixels-per-cell
272       rand <- next-random rand
273       loop
274     }
275     y <- add pixels-per-cell
276     y <- add pixels-per-cell
277     y <- add pixels-per-cell
278     loop
279   }
280 }
281 
282 fn render-tile-without-margin screen: (addr screen), _tile: (addr tile), start-x: int, start-y: int, pixels-per-cell: int {
283   var tile/esi: (addr tile) <- copy _tile
284   var y/ecx: int <- copy start-y
285   var rows-ah/eax: (addr handle array handle array int) <- get tile, data
286   var rows/eax: (addr array handle array int) <- lookup *rows-ah
287   var i/ebx: int <- copy 0
288   {
289     compare i, 3
290     break-if->=
291     var x/edx: int <- copy start-x
292     var curr-row-ah/eax: (addr handle array int) <- index rows, i
293     var curr-row/eax: (addr array int) <- lookup *curr-row-ah
294     var j/edi: int <- copy 0
295     {
296       compare j, 3
297       break-if->=
298       var curr/eax: (addr int) <- index curr-row, j
299       var color/eax: int <- copy *curr
300       color <- shift-left 1
301       draw-rect2 screen, x y, pixels-per-cell pixels-per-cell, color
302       j <- increment
303       x <- add pixels-per-cell
304       loop
305     }
306     i <- increment
307     y <- add pixels-per-cell
308     loop
309   }
310 }
311 
312 fn remainder a: int, b: int -> _/eax: int {
313   var q/eax: int <- copy 0
314   var r/edx: int <- copy 0
315   q, r <- integer-divide a, b
316   return r
317 }