# Conway's Game of Life in a Hestified way # https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life # https://ivanish.ca/hest-podcast # # To build: # $ ./translate hest-life.mu # I run it on my 2.5GHz Linux laptop like this: # $ qemu-system-i386 -enable-kvm code.img # # If things seem too fast or too slow on your computer, adjust the loop bounds # in the function `linger` at the bottom. Its value will depend on how you # accelerate Qemu. Mu will eventually get a clock to obviate the need for this # tuning. # # Keyboard shortcuts: # space: pause/resume # 0: restart time # l: start looping from 0 to curren time # L: stop looping # +: zoom in # -: zoom out fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { var env-storage: environment var env/esi: (addr environment) <- address env-storage initialize-environment env var second-buffer: screen var second-screen/edi: (addr screen) <- address second-buffer initialize-screen second-screen, 0x80, 0x30, 1/include-pixels render second-screen, env convert-graphemes-to-pixels second-screen copy-pixels second-screen, screen { edit keyboard, env var play?/eax: (addr boolean) <- get env, play? compare *play?, 0/false { break-if-= step env clear-screen second-screen render second-screen, env convert-graphemes-to-pixels second-screen copy-pixels second-screen, screen } linger env loop } } type environment { data: (handle array handle array cell) zoom: int # 0 = 1024 px per cell; 5 = 4px per cell; each step adjusts by a factor of 4 tick: int play?: boolean loop: int # if non-zero, return tick to 0 after this point } type cell { curr: boolean next: boolean } fn render screen: (addr screen), _self: (addr environment) { var self/esi: (addr environment) <- copy _self var zoom/eax: (addr int) <- get self, zoom compare *zoom, 0 { break-if-!= clear-screen screen render0 screen, self } compare *zoom, 1 { break-if-!= clear-screen screen render1 screen, self } compare *zoom, 4 { break-if-!= render4 screen, self } # clock var tick-a/eax: (addr int) <- get self, tick set-cursor-position screen, 0x78/x, 0/y draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, *tick-a, 7/fg 0/bg } # Lots of hardcoded constants for now. # TODO: split this up into a primitive to render a single cell and its # incoming edges (but not the neighboring nodes they emanate from) fn render0 screen: (addr screen), _self: (addr environment) { var self/esi: (addr environment) <- copy _self # cell border draw-vertical-line screen, 0xc0/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey draw-vertical-line screen, 0x340/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey draw-horizontal-line screen, 0x40/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey draw-horizontal-line screen, 0x2c0/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey # neighboring inputs, corners var color/eax: int <- state-color self, 0x7f/cur-topleftx, 0x5f/cur-toplefty draw-rect screen, 0x90/xmin 0x10/ymin, 0xb0/xmax 0x30/ymax, color color <- state-color self, 0x81/cur-toprightx, 0x5f/cur-toprighty draw-rect screen, 0x350/xmin 0x10/ymin, 0x370/xmax 0x30/ymax, color color <- state-color self, 0x7f/cur-botleftx, 0x61/cur-botlefty draw-rect screen, 0x90/xmin 0x2d0/ymin, 0xb0/xmax 0x2f0/ymax, color color <- state-color self, 0x81/cur-botrightx, 0x61/cur-botrighty draw-rect screen, 0x350/xmin 0x2d0/ymin, 0x370/xmax 0x2f0/ymax, color # neighboring inputs, edges color <- state-color self, 0x80/cur-topx, 0x5f/cur-topy draw-rect screen, 0x1f0/xmin 0x10/ymin, 0x210/xmax 0x30/ymax, color color <- state-color self, 0x7f/cur-leftx, 0x60/cur-lefty draw-rect screen, 0x90/xmin 0x170/ymin, 0xb0/xmax 0x190/ymax, color color <- state-color self, 0x80/cur-botx, 0x61/cur-boty draw-rect screen, 0x1f0/xmin 0x2d0/ymin, 0x210/xmax 0x2f0/ymax, color color <- state-color self, 0x81/cur-rightx, 0x60/cur-righty draw-rect screen, 0x350/xmin 0x170/ymin, 0x370/xmax 0x190/ymax, color # sum node draw-rect screen, 0x170/xsmin 0x140/ysmin, 0x190/xsmax 0x160/ysmax, 0x40/color set-cursor-position screen, 0x2d/scol, 0x13/srow draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "+", 0xf/color, 0/bg # conveyors from neighboring inputs to sum node draw-monotonic-bezier screen, 0xa0/x0 0x20/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0xa0/x0 0x180/y0, 0xc0/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0xa0/x0 0x2e0/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0x200/x0 0x20/y0, 0x180/x1 0x90/y1, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0x200/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0x360/x0 0x20/y0, 0x180/x1 0xc0/y1, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0x360/x0 0x180/y0, 0x35c/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color draw-monotonic-bezier screen, 0x360/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 4/color # filter node draw-rect screen, 0x200/xfmin 0x1c0/yfmin, 0x220/xfmax 0x1e0/yfmax, 0x31/color set-cursor-position screen, 0x40/fcol, 0x1b/frow draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "?", 0xf/color, 0/bg # conveyor from sum node to filter node draw-line screen 0x180/xs, 0x150/ys, 0x210/xf, 0x1d0/yf, 0xa2/color # cell outputs at corners var color/eax: int <- state-color self, 0x80/curx, 0x60/cury draw-rect screen, 0xd0/xmin 0x50/ymin, 0xf0/xmax 0x70/ymax, color draw-rect screen, 0x310/xmin 0x50/ymin, 0x330/xmax 0x70/ymax, color draw-rect screen, 0xd0/xmin 0x290/ymin, 0xf0/xmax 0x2b0/ymax, color draw-rect screen, 0x310/xmin 0x290/ymin, 0x330/xmax 0x2b0/ymax, color # cell outputs at edges draw-rect screen, 0x1f0/xmin 0x50/ymin, 0x210/xmax 0x70/ymax, color draw-rect screen, 0xd0/xmin 0x170/ymin, 0xf0/xmax 0x190/ymax, color draw-rect screen, 0x1f0/xmin 0x290/ymin, 0x210/xmax 0x2b0/ymax, color draw-rect screen, 0x310/xmin 0x170/ymin, 0x330/xmax 0x190/ymax, color # conveyors from filter to outputs draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x60/y1, 0xe0/x2 0x60/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0xe0/x1 0x1c0/y1, 0xe0/x2 0x180/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x2a0/y1, 0xe0/x2 0x2a0/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x210/x1 0x60/y1, 0x200/x2 0x60/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x210/x1 0x230/y1, 0x200/x2 0x2a0/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x120/y1, 0x320/x2 0x60/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x1c0/y1 0x320/x2 0x180/y2, 0x2a/color draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x230/y1, 0x320/x2 0x2a0/y2, 0x2a/color # time-variant portion: 16 repeating steps var tick-a/eax: (addr int) <- get self, tick var progress/eax: int <- copy *tick-a progress <- and 0xf # 7 time steps for getting inputs to sum { compare progress, 7 break-if->= var u/xmm7: float <- convert progress var six/eax: int <- copy 6 var six-f/xmm0: float <- convert six u <- divide six-f # points on conveyors from neighboring cells draw-bezier-point screen, u, 0xa0/x0 0x20/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0xa0/x0 0x180/y0, 0xc0/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0xa0/x0 0x2e0/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x200/x0 0x20/y0, 0x180/x1 0x90/y1, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x200/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x360/x0 0x20/y0, 0x180/x1 0xc0/y1, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x360/x0 0x180/y0, 0x35c/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x360/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 7/color, 4/radius return } # two time steps for getting count to filter progress <- subtract 7 { compare progress, 2 break-if->= progress <- increment # (0, 1) => (1, 2) var u/xmm7: float <- convert progress var three/eax: int <- copy 3 var three-f/xmm0: float <- convert three u <- divide three-f draw-linear-point screen, u, 0x180/xs, 0x150/ys, 0x210/xf, 0x1d0/yf, 7/color, 4/radius set-cursor-position screen, 0x3a/scol, 0x18/srow var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x60/cury draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg return } # final 7 time steps for updating output progress <- subtract 2 # points on conveyors to outputs var u/xmm7: float <- convert progress var six/eax: int <- copy 6 var six-f/xmm0: float <- convert six u <- divide six-f draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x60/y1, 0xe0/x2 0x60/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0xe0/x1 0x1c0/y1, 0xe0/x2 0x180/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x2a0/y1, 0xe0/x2 0x2a0/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x210/xf 0x60/y1, 0x200/x2 0x60/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x210/xf 0x230/y1, 0x200/x2 0x2a0/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x120/y1, 0x320/x2 0x60/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x1c0/y1, 0x320/x2 0x180/y2, 7/color, 4/radius draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x230/y1, 0x320/x2 0x2a0/y2, 7/color, 4/radius } fn render1 screen: (addr screen), _self: (addr environment) { var self/esi: (addr environment) <- copy _self # cell borders draw-vertical-line screen, 0xe0/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey draw-vertical-line screen, 0x200/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey draw-vertical-line screen, 0x320/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey draw-horizontal-line screen, 0x60/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey draw-horizontal-line screen, 0x180/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey draw-horizontal-line screen, 0x2a0/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey # cell 0: outputs var color/eax: int <- state-color self, 0x80/curx, 0x60/cury draw-rect screen, 0xe8/xmin 0x68/ymin, 0x118/xmax 0x98/ymax, color draw-rect screen, 0xe8/xmin 0xd0/ymin, 0x118/xmax 0x100/ymax, color draw-rect screen, 0xe8/xmin 0x148/ymin, 0x118/xmax 0x178/ymax, color draw-rect screen, 0x158/xmin 0x68/ymin, 0x188/xmax 0x98/ymax, color draw-rect screen, 0x158/xmin 0x148/ymin, 0x188/xmax 0x178/ymax, color draw-rect screen, 0x1c8/xmin 0x68/ymin, 0x1f8/xmax 0x98/ymax, color draw-rect screen, 0x1c8/xmin 0xd0/ymin, 0x1f8/xmax 0x100/ymax, color draw-rect screen, 0x1c8/xmin 0x148/ymin, 0x1f8/xmax 0x178/ymax, color # cell 1: outputs var color/eax: int <- state-color self, 0x81/curx, 0x60/cury draw-rect screen, 0x208/xmin 0x68/ymin, 0x238/xmax 0x98/ymax, color draw-rect screen, 0x208/xmin 0xd0/ymin, 0x238/xmax 0x100/ymax, color draw-rect screen, 0x208/xmin 0x148/ymin, 0x238/xmax 0x178/ymax, color draw-rect screen, 0x278/xmin 0x68/ymin, 0x2a8/xmax 0x98/ymax, color draw-rect screen, 0x278/xmin 0x148/ymin, 0x2a8/xmax 0x178/ymax, color draw-rect screen, 0x2e8/xmin 0x68/ymin, 0x318/xmax 0x98/ymax, color draw-rect screen, 0x2e8/xmin 0xd0/ymin, 0x318/xmax 0x100/ymax, color draw-rect screen, 0x2e8/xmin 0x148/ymin, 0x318/xmax 0x178/ymax, color # cell 2: outputs var color/eax: int <- state-color self, 0x80/curx, 0x61/cury draw-rect screen, 0xe8/xmin 0x188/ymin, 0x118/xmax 0x1b8/ymax, color draw-rect screen, 0xe8/xmin 0x1f0/ymin, 0x118/xmax 0x220/ymax, color draw-rect screen, 0xe8/xmin 0x268/ymin, 0x118/xmax 0x298/ymax, color draw-rect screen, 0x158/xmin 0x188/ymin, 0x188/xmax 0x1b8/ymax, color draw-rect screen, 0x158/xmin 0x268/ymin, 0x188/xmax 0x298/ymax, color draw-rect screen, 0x1c8/xmin 0x188/ymin, 0x1f8/xmax 0x1b8/ymax, color draw-rect screen, 0x1c8/xmin 0x1f0/ymin, 0x1f8/xmax 0x220/ymax, color draw-rect screen, 0x1c8/xmin 0x268/ymin, 0x1f8/xmax 0x298/ymax, color # cell 3: outputs var color/eax: int <- state-color self, 0x81/curx, 0x61/cury draw-rect screen, 0x208/xmin 0x188/ymin, 0x238/xmax 0x1b8/ymax, color draw-rect screen, 0x208/xmin 0x1f0/ymin, 0x238/xmax 0x220/ymax, color draw-rect screen, 0x208/xmin 0x268/ymin, 0x238/xmax 0x298/ymax, color draw-rect screen, 0x278/xmin 0x188/ymin, 0x2a8/xmax 0x1b8/ymax, color draw-rect screen, 0x278/xmin 0x268/ymin, 0x2a8/xmax 0x298/ymax, color draw-rect screen, 0x2e8/xmin 0x188/ymin, 0x318/xmax 0x1b8/ymax, color draw-rect screen, 0x2e8/xmin 0x1f0/ymin, 0x318/xmax 0x220/ymax, color draw-rect screen, 0x2e8/xmin 0x268/ymin, 0x318/xmax 0x298/ymax, color # neighboring nodes var color/eax: int <- state-color self, 0x7f/curx, 0x5f/cury draw-rect screen, 0xa8/xmin 0x28/ymin, 0xd8/xmax 0x58/ymax, color var color/eax: int <- state-color self, 0x80/curx, 0x5f/cury draw-rect screen, 0x158/xmin 0x28/ymin, 0x188/xmax 0x58/ymax, color draw-rect screen, 0x1c8/xmin 0x28/ymin, 0x1f8/xmax 0x58/ymax, color var color/eax: int <- state-color self, 0x81/curx, 0x5f/cury draw-rect screen, 0x208/xmin 0x28/ymin, 0x238/xmax 0x58/ymax, color draw-rect screen, 0x278/xmin 0x28/ymin, 0x2a8/xmax 0x58/ymax, color var color/eax: int <- state-color self, 0x82/curx, 0x5f/cury draw-rect screen, 0x328/xmin 0x28/ymin, 0x358/xmax 0x58/ymax, color var color/eax: int <- state-color self, 0x7f/curx, 0x60/cury draw-rect screen, 0xa8/xmin 0xd0/ymin, 0xd8/xmax 0x100/ymax, color draw-rect screen, 0xa8/xmin 0x148/ymin, 0xd8/xmax 0x178/ymax, color var color/eax: int <- state-color self, 0x82/curx, 0x60/cury draw-rect screen, 0x328/xmin 0xd0/ymin, 0x358/xmax 0x100/ymax, color draw-rect screen, 0x328/xmin 0x148/ymin, 0x358/xmax 0x178/ymax, color var color/eax: int <- state-color self, 0x7f/curx, 0x61/cury draw-rect screen, 0xa8/xmin 0x188/ymin, 0xd8/xmax 0x1b8/ymax, color draw-rect screen, 0xa8/xmin 0x1f0/ymin, 0xd8/xmax 0x220/ymax, color var color/eax: int <- state-color self, 0x82/curx, 0x61/cury draw-rect screen, 0x328/xmin 0x188/ymin, 0x358/xmax 0x1b8/ymax, color draw-rect screen, 0x328/xmin 0x1f0/ymin, 0x358/xmax 0x220/ymax, color var color/eax: int <- state-color self, 0x7f/curx, 0x62/cury draw-rect screen, 0xa8/xmin 0x2a8/ymin, 0xd8/xmax 0x2d8/ymax, color var color/eax: int <- state-color self, 0x80/curx, 0x62/cury draw-rect screen, 0x158/xmin 0x2a8/ymin, 0x188/xmax 0x2d8/ymax, color draw-rect screen, 0x1c8/xmin 0x2a8/ymin, 0x1f8/xmax 0x2d8/ymax, color var color/eax: int <- state-color self, 0x81/curx, 0x62/cury draw-rect screen, 0x208/xmin 0x2a8/ymin, 0x238/xmax 0x2d8/ymax, color draw-rect screen, 0x278/xmin 0x2a8/ymin, 0x2a8/xmax 0x2d8/ymax, color var color/eax: int <- state-color self, 0x82/curx, 0x62/cury draw-rect screen, 0x328/xmin 0x2a8/ymin, 0x358/xmax 0x2d8/ymax, color # cell 0: sum and filter nodes draw-rect screen, 0x148/xsmin 0xc8/ysmin, 0x158/xsmax 0xd8/ysmax, 0x40/color draw-rect screen, 0x180/xfmin 0xf8/yfmin, 0x190/xfmax 0x108/yfmax, 0x31/color # cell 1: sum and filter nodes draw-rect screen, 0x268/xsmin 0xc8/ysmin, 0x278/xsmax 0xd8/ysmax, 0x40/color draw-rect screen, 0x2a0/xfmin 0xf8/yfmin, 0x2b0/xfmax 0x108/yfmax, 0x31/color # cell 2: sum and filter nodes draw-rect screen, 0x148/xsmin 0x1e8/ysmin, 0x158/xsmax 0x1f8/ysmax, 0x40/color draw-rect screen, 0x180/xfmin 0x218/yfmin, 0x190/xfmax 0x228/yfmax, 0x31/color # cell 3: sum and filter nodes draw-rect screen, 0x268/xsmin 0x1e8/ysmin, 0x278/xsmax 0x1f8/ysmax, 0x40/color draw-rect screen, 0x2a0/xfmin 0x218/yfmin, 0x2b0/xfmax 0x228/yfmax, 0x31/color # neighbor counts var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x60/cury set-cursor-position screen, 0x2d, 0xe draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg var n/eax: int <- num-live-neighbors self, 0x81/curx, 0x60/cury set-cursor-position screen, 0x52, 0xe draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x61/cury set-cursor-position screen, 0x2d, 0x20 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg var n/eax: int <- num-live-neighbors self, 0x81/curx, 0x61/cury set-cursor-position screen, 0x52, 0x20 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg # cell 0: conveyors from neighboring inputs to sum node draw-monotonic-bezier screen, 0xc0/x0 0x40/y0, 0x100/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0xc0/x0 0xe8/y0, 0xc0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0xc0/x0 0x1a0/y0, 0xe0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0x170/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0x170/x0 0x1a0/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0x220/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0x220/x0 0xe8/y0, 0x220/x1 0xd0/y1, 0x150/xs 0xd0/ys, 4/color draw-monotonic-bezier screen, 0x220/x0 0x1a0/y0, 0x180/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 4/color # cell 0: conveyors from filter to outputs draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x160/x1 0x8c/y1, 0x100/x2 0x80/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0xe8/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0x160/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x188/x1 0x80/y1, 0x170/x2 0x80/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x188/x1 0x160/y1, 0x170/x2 0x160/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x80/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1 0x1e0/x2 0xe8/y2, 0x2a/color draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x160/y2, 0x2a/color # cell 0: time-variant portion: 16 repeating steps $render1:cell0: { var tick-a/eax: (addr int) <- get self, tick var progress/eax: int <- copy *tick-a progress <- and 0xf # cell 0: 7 time steps for getting inputs to sum { compare progress, 7 break-if->= var u/xmm7: float <- convert progress var six/eax: int <- copy 6 var six-f/xmm0: float <- convert six u <- divide six-f # points on conveyors from neighboring cells draw-bezier-point screen, u, 0xc0/x0 0x40/y0, 0x100/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0xc0/x0 0xe8/y0, 0xc0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0xc0/x0 0x1a0/y0, 0xe0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x170/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x170/x0 0x1a0/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x220/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x220/x0 0xe8/y0, 0x220/x1 0xd0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius draw-bezier-point screen, u, 0x220/x0 0x1a0/y0, 0x180/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius break $render1:cell0 } # cell 0: two time steps for getting count to filter progress <- subtract 7 { compare progress, 2 break-if->= break $render1:cell0 } # cell 0: final 7 time steps for updat