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