From 91ae7ff9badc803e7de93fefa7aaf233df13247b Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 11 Aug 2021 19:44:22 -0700 Subject: . --- html/browse-slack/environment.mu.html | 541 +++++++++++++++++----------------- 1 file changed, 269 insertions(+), 272 deletions(-) (limited to 'html/browse-slack/environment.mu.html') diff --git a/html/browse-slack/environment.mu.html b/html/browse-slack/environment.mu.html index 50872a6c..2ec18205 100644 --- a/html/browse-slack/environment.mu.html +++ b/html/browse-slack/environment.mu.html @@ -61,278 +61,275 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/main/browse-slack/environment.mu
-  1 # The environment is a thin layer in this app, just a history of 'tabs' that
-  2 # are fully specified by the operations used to generate them.
-  3 
-  4 type environment {
-  5   item-index: int
-  6 }
-  7 
-  8 # static buffer sizes in this file:
-  9 #   main-panel-hor            # in characters
- 10 #   item-padding-hor          # in pixels
- 11 #   item-padding-ver          # in characters
- 12 #   avatar-side               # in pixels
- 13 #   avatar-space-hor          # in characters
- 14 #   avatar-space-ver          # in characters
- 15 #   search-position-x         # in characters
- 16 #   search-space-ver          # in characters
- 17 #   author-name-padding-ver   # in characters
- 18 #   post-right-coord          # in characters
- 19 #   channel-offset-x          # in characters
- 20 #   menu-space-ver            # in characters
- 21 
- 22 fn initialize-environment _self: (addr environment), _items: (addr item-list) {
- 23   var self/esi: (addr environment) <- copy _self
- 24   var items/eax: (addr item-list) <- copy _items
- 25   var newest-item-a/eax: (addr int) <- get items, newest
- 26   var newest-item/eax: int <- copy *newest-item-a
- 27   var dest/edi: (addr int) <- get self, item-index
- 28   copy-to *dest, newest-item
- 29 }
- 30 
- 31 fn render-environment screen: (addr screen), env: (addr environment), users: (addr array user), channels: (addr array channel), items: (addr item-list) {
- 32   clear-screen screen
- 33   render-search-input screen, env
- 34   render-channels screen, env, channels
- 35   render-item-list screen, env, items, users
- 36   render-menu screen
- 37 }
- 38 
- 39 fn render-channels screen: (addr screen), env: (addr environment), _channels: (addr array channel) {
- 40   var channels/esi: (addr array channel) <- copy _channels
- 41   var y/ebx: int <- copy 2/search-space-ver
- 42   y <- add 1/item-padding-ver
- 43   var i/ecx: int <- copy 0
- 44   var max/edx: int <- length channels
- 45   {
- 46     compare i, max
- 47     break-if->=
- 48     var offset/eax: (offset channel) <- compute-offset channels, i
- 49     var curr/eax: (addr channel) <- index channels, offset
- 50     var name-ah/eax: (addr handle array byte) <- get curr, name
- 51     var name/eax: (addr array byte) <- lookup *name-ah
- 52     compare name, 0
- 53     break-if-=
- 54     set-cursor-position screen, 2/x y
- 55     draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "#", 0xf/grey 0/black
- 56     draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, name, 0xf/grey 0/black
- 57     y <- add 2/channel-padding
- 58     i <- increment
- 59     loop
- 60   }
- 61 }
- 62 
- 63 fn render-item-list screen: (addr screen), _env: (addr environment), _items: (addr item-list), users: (addr array user) {
- 64   var env/esi: (addr environment) <- copy _env
- 65   var tmp-width/eax: int <- copy 0
- 66   var tmp-height/ecx: int <- copy 0
- 67   tmp-width, tmp-height <- screen-size screen
- 68   var screen-width: int
- 69   copy-to screen-width, tmp-width
- 70   var screen-height: int
- 71   copy-to screen-height, tmp-height
- 72   #
- 73   var y/ecx: int <- copy 2/search-space-ver
- 74   y <- add 1/item-padding-ver
- 75   var newest-item/eax: (addr int) <- get env, item-index
- 76   var i/ebx: int <- copy *newest-item
- 77   var items/esi: (addr item-list) <- copy _items
- 78   var items-data-ah/eax: (addr handle array item) <- get items, data
- 79   var _items-data/eax: (addr array item) <- lookup *items-data-ah
- 80   var items-data/edi: (addr array item) <- copy _items-data
- 81   {
- 82     compare i, 0
- 83     break-if-<
- 84     compare y, screen-height
- 85     break-if->=
- 86     var offset/eax: (offset item) <- compute-offset items-data, i
- 87     var curr-item/eax: (addr item) <- index items-data, offset
- 88     y <- render-item screen, curr-item, users, y, screen-height
- 89     i <- decrement
- 90     loop
- 91   }
- 92   var top/eax: int <- copy screen-height
- 93   top <- subtract 2/menu-space-ver
- 94   clear-rect screen, 0 top, screen-width screen-height, 0/bg
- 95 }
- 96 
- 97 fn render-search-input screen: (addr screen), env: (addr environment) {
- 98   set-cursor-position 0/screen, 0x22/x=search-position-x 1/y
- 99   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "search ", 7/fg 0/bg
-100   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "________________________________", 0xf/fg 0/bg
-101 }
-102 
-103 fn render-menu screen: (addr screen) {
-104   var width/eax: int <- copy 0
-105   var y/ecx: int <- copy 0
-106   width, y <- screen-size screen
-107   y <- decrement
-108   set-cursor-position screen, 2/x, y
-109   draw-text-rightward-from-cursor screen, " / ", width, 0/fg 0xf/bg
-110   draw-text-rightward-from-cursor screen, " search  ", width, 0xf/fg, 0/bg
-111   draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg 0xf/bg
-112   draw-text-rightward-from-cursor screen, " next page  ", width, 0xf/fg, 0/bg
-113   draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg 0xf/bg
-114   draw-text-rightward-from-cursor screen, " previous page  ", width, 0xf/fg, 0/bg
-115 }
-116 
-117 fn render-item screen: (addr screen), _item: (addr item), _users: (addr array user), y: int, screen-height: int -> _/ecx: int {
-118   var item/esi: (addr item) <- copy _item
-119   var users/edi: (addr array user) <- copy _users
-120   var author-index-addr/ecx: (addr int) <- get item, by
-121   var author-index/ecx: int <- copy *author-index-addr
-122   var author-offset/ecx: (offset user) <- compute-offset users, author-index
-123   var author/ecx: (addr user) <- index users, author-offset
-124   # author avatar
-125   var author-avatar-ah/eax: (addr handle image) <- get author, avatar
-126   var _author-avatar/eax: (addr image) <- lookup *author-avatar-ah
-127   var author-avatar/ebx: (addr image) <- copy _author-avatar
-128   {
-129     compare author-avatar, 0
-130     break-if-=
-131     var y/edx: int <- copy y
-132     y <- shift-left 4/log2font-height
-133     var x/eax: int <- copy 0x20/main-panel-hor
-134     x <- shift-left 3/log2font-width
-135     x <- add 0x18/item-padding-hor
-136     render-image screen, author-avatar, x, y, 0x50/avatar-side, 0x50/avatar-side
-137   }
-138   # channel
-139   var channel-name-ah/eax: (addr handle array byte) <- get item, channel
-140   var channel-name/eax: (addr array byte) <- lookup *channel-name-ah
-141   {
-142     var x/eax: int <- copy 0x20/main-panel-hor
-143     x <- add 0x40/channel-offset-x
-144     set-cursor-position screen, x y
-145   }
-146   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "#", 7/grey 0/black
-147   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, channel-name, 7/grey 0/black
-148   # author name
-149   var author-real-name-ah/eax: (addr handle array byte) <- get author, real-name
-150   var author-real-name/eax: (addr array byte) <- lookup *author-real-name-ah
-151   {
-152     var x/ecx: int <- copy 0x20/main-panel-hor
-153     x <- add 0x10/avatar-space-hor
-154     set-cursor-position screen, x y
-155     draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, author-real-name, 0xf/white 0/black
-156   }
-157   increment y
-158   # text
-159   var text-ah/eax: (addr handle array byte) <- get item, text
-160   var _text/eax: (addr array byte) <- lookup *text-ah
-161   var text/edx: (addr array byte) <- copy _text
-162   var x/eax: int <- copy 0x20/main-panel-hor
-163   x <- add 0x10/avatar-space-hor
-164   var text-y/ecx: int <- copy y
-165   text-y <- add 1/author-name-padding-ver
-166   x, text-y <- draw-text-wrapping-right-then-down screen, text, x text-y, 0x70/xmax=post-right-coord screen-height, x text-y, 7/fg 0/bg
-167   text-y <- add 2/item-padding-ver
-168   # flush
-169   add-to y, 6/avatar-space-ver
-170   compare y, text-y
-171   {
-172     break-if-<
-173     return y
-174   }
-175   return text-y
-176 }
-177 
-178 fn update-environment env: (addr environment), key: byte, items: (addr item-list) {
-179   {
-180     compare key, 6/ctrl-f
-181     break-if-!=
-182     page-down env, items
-183     return
-184   }
-185   {
-186     compare key, 2/ctrl-b
-187     break-if-!=
-188     page-up env, items
-189     return
-190   }
-191 }
-192 
-193 fn page-down _env: (addr environment), _items: (addr item-list) {
-194   var env/edi: (addr environment) <- copy _env
-195   var items/esi: (addr item-list) <- copy _items
-196   var items-data-ah/eax: (addr handle array item) <- get items, data
-197   var _items-data/eax: (addr array item) <- lookup *items-data-ah
-198   var items-data/ebx: (addr array item) <- copy _items-data
-199   var src/eax: (addr int) <- get env, item-index
-200   var new-item-index/ecx: int <- copy *src
-201   var y/edx: int <- copy 2
-202   {
-203     compare new-item-index, 0
-204     break-if-<
-205     compare y, 0x28/screen-height-minus-menu
-206     break-if->=
-207     var offset/eax: (offset item) <- compute-offset items-data, new-item-index
-208     var item/eax: (addr item) <- index items-data, offset
-209     var item-text-ah/eax: (addr handle array byte) <- get item, text
-210     var item-text/eax: (addr array byte) <- lookup *item-text-ah
-211     var h/eax: int <- estimate-height item-text
-212     set-cursor-position 0/screen, 0 0
-213     draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, h, 4/fg 0/bg
-214     y <- add h
-215     new-item-index <- decrement
-216     loop
-217   }
-218   new-item-index <- increment
-219   var dest/eax: (addr int) <- get env, item-index
-220   copy-to *dest, new-item-index
-221 }
-222 
-223 fn page-up _env: (addr environment), _items: (addr item-list) {
-224   var env/edi: (addr environment) <- copy _env
-225   var items/esi: (addr item-list) <- copy _items
-226   var items-data-ah/eax: (addr handle array item) <- get items, data
-227   var _items-data/eax: (addr array item) <- lookup *items-data-ah
-228   var items-data/ebx: (addr array item) <- copy _items-data
-229   var newest-item-index-a/esi: (addr int) <- get items, newest
-230   var src/eax: (addr int) <- get env, item-index
-231   var new-item-index/ecx: int <- copy *src
-232   var y/edx: int <- copy 2
-233   {
-234     compare new-item-index, *newest-item-index-a
-235     break-if->
-236     compare y, 0x28/screen-height-minus-menu
-237     break-if->=
-238     var offset/eax: (offset item) <- compute-offset items-data, new-item-index
-239     var item/eax: (addr item) <- index items-data, offset
-240     var item-text-ah/eax: (addr handle array byte) <- get item, text
-241     var item-text/eax: (addr array byte) <- lookup *item-text-ah
-242     var h/eax: int <- estimate-height item-text
-243     set-cursor-position 0/screen, 0 0
-244     draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, h, 4/fg 0/bg
-245     y <- add h
-246     new-item-index <- increment
-247     loop
-248   }
-249   new-item-index <- decrement
-250   var dest/eax: (addr int) <- get env, item-index
-251   copy-to *dest, new-item-index
-252 }
-253 
-254 # keep sync'd with render-item
-255 fn estimate-height _message-text: (addr array byte) -> _/eax: int {
-256   var message-text/esi: (addr array byte) <- copy _message-text
-257   var result/eax: int <- length message-text
-258   var remainder/edx: int <- copy 0
-259   result, remainder <- integer-divide result, 0x40/post-width
-260   compare remainder, 0
-261   {
-262     break-if-=
-263     result <- increment
-264   }
-265   result <- add 2/item-padding-ver
-266   compare result, 6/avatar-space-ver
-267   {
-268     break-if->
-269     return 6/avatar-space-ver
-270   }
-271   return result
-272 }
+  1 type environment {
+  2   item-index: int
+  3 }
+  4 
+  5 # static buffer sizes in this file:
+  6 #   main-panel-hor            # in characters
+  7 #   item-padding-hor          # in pixels
+  8 #   item-padding-ver          # in characters
+  9 #   avatar-side               # in pixels
+ 10 #   avatar-space-hor          # in characters
+ 11 #   avatar-space-ver          # in characters
+ 12 #   search-position-x         # in characters
+ 13 #   search-space-ver          # in characters
+ 14 #   author-name-padding-ver   # in characters
+ 15 #   post-right-coord          # in characters
+ 16 #   channel-offset-x          # in characters
+ 17 #   menu-space-ver            # in characters
+ 18 
+ 19 fn initialize-environment _self: (addr environment), _items: (addr item-list) {
+ 20   var self/esi: (addr environment) <- copy _self
+ 21   var items/eax: (addr item-list) <- copy _items
+ 22   var newest-item-a/eax: (addr int) <- get items, newest
+ 23   var newest-item/eax: int <- copy *newest-item-a
+ 24   var dest/edi: (addr int) <- get self, item-index
+ 25   copy-to *dest, newest-item
+ 26 }
+ 27 
+ 28 fn render-environment screen: (addr screen), env: (addr environment), users: (addr array user), channels: (addr array channel), items: (addr item-list) {
+ 29   clear-screen screen
+ 30   render-search-input screen, env
+ 31   render-channels screen, env, channels
+ 32   render-item-list screen, env, items, users
+ 33   render-menu screen
+ 34 }
+ 35 
+ 36 fn render-channels screen: (addr screen), env: (addr environment), _channels: (addr array channel) {
+ 37   var channels/esi: (addr array channel) <- copy _channels
+ 38   var y/ebx: int <- copy 2/search-space-ver
+ 39   y <- add 1/item-padding-ver
+ 40   var i/ecx: int <- copy 0
+ 41   var max/edx: int <- length channels
+ 42   {
+ 43     compare i, max
+ 44     break-if->=
+ 45     var offset/eax: (offset channel) <- compute-offset channels, i
+ 46     var curr/eax: (addr channel) <- index channels, offset
+ 47     var name-ah/eax: (addr handle array byte) <- get curr, name
+ 48     var name/eax: (addr array byte) <- lookup *name-ah
+ 49     compare name, 0
+ 50     break-if-=
+ 51     set-cursor-position screen, 2/x y
+ 52     draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "#", 0xf/grey 0/black
+ 53     draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, name, 0xf/grey 0/black
+ 54     y <- add 2/channel-padding
+ 55     i <- increment
+ 56     loop
+ 57   }
+ 58 }
+ 59 
+ 60 fn render-item-list screen: (addr screen), _env: (addr environment), _items: (addr item-list), users: (addr array user) {
+ 61   var env/esi: (addr environment) <- copy _env
+ 62   var tmp-width/eax: int <- copy 0
+ 63   var tmp-height/ecx: int <- copy 0
+ 64   tmp-width, tmp-height <- screen-size screen
+ 65   var screen-width: int
+ 66   copy-to screen-width, tmp-width
+ 67   var screen-height: int
+ 68   copy-to screen-height, tmp-height
+ 69   #
+ 70   var y/ecx: int <- copy 2/search-space-ver
+ 71   y <- add 1/item-padding-ver
+ 72   var newest-item/eax: (addr int) <- get env, item-index
+ 73   var i/ebx: int <- copy *newest-item
+ 74   var items/esi: (addr item-list) <- copy _items
+ 75   var items-data-ah/eax: (addr handle array item) <- get items, data
+ 76   var _items-data/eax: (addr array item) <- lookup *items-data-ah
+ 77   var items-data/edi: (addr array item) <- copy _items-data
+ 78   {
+ 79     compare i, 0
+ 80     break-if-<
+ 81     compare y, screen-height
+ 82     break-if->=
+ 83     var offset/eax: (offset item) <- compute-offset items-data, i
+ 84     var curr-item/eax: (addr item) <- index items-data, offset
+ 85     y <- render-item screen, curr-item, users, y, screen-height
+ 86     i <- decrement
+ 87     loop
+ 88   }
+ 89   var top/eax: int <- copy screen-height
+ 90   top <- subtract 2/menu-space-ver
+ 91   clear-rect screen, 0 top, screen-width screen-height, 0/bg
+ 92 }
+ 93 
+ 94 fn render-search-input screen: (addr screen), env: (addr environment) {
+ 95   set-cursor-position 0/screen, 0x22/x=search-position-x 1/y
+ 96   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "search ", 7/fg 0/bg
+ 97   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "________________________________", 0xf/fg 0/bg
+ 98 }
+ 99 
+100 fn render-menu screen: (addr screen) {
+101   var width/eax: int <- copy 0
+102   var y/ecx: int <- copy 0
+103   width, y <- screen-size screen
+104   y <- decrement
+105   set-cursor-position screen, 2/x, y
+106   draw-text-rightward-from-cursor screen, " / ", width, 0/fg 0xf/bg
+107   draw-text-rightward-from-cursor screen, " search  ", width, 0xf/fg, 0/bg
+108   draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg 0xf/bg
+109   draw-text-rightward-from-cursor screen, " next page  ", width, 0xf/fg, 0/bg
+110   draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg 0xf/bg
+111   draw-text-rightward-from-cursor screen, " previous page  ", width, 0xf/fg, 0/bg
+112 }
+113 
+114 fn render-item screen: (addr screen), _item: (addr item), _users: (addr array user), y: int, screen-height: int -> _/ecx: int {
+115   var item/esi: (addr item) <- copy _item
+116   var users/edi: (addr array user) <- copy _users
+117   var author-index-addr/ecx: (addr int) <- get item, by
+118   var author-index/ecx: int <- copy *author-index-addr
+119   var author-offset/ecx: (offset user) <- compute-offset users, author-index
+120   var author/ecx: (addr user) <- index users, author-offset
+121   # author avatar
+122   var author-avatar-ah/eax: (addr handle image) <- get author, avatar
+123   var _author-avatar/eax: (addr image) <- lookup *author-avatar-ah
+124   var author-avatar/ebx: (addr image) <- copy _author-avatar
+125   {
+126     compare author-avatar, 0
+127     break-if-=
+128     var y/edx: int <- copy y
+129     y <- shift-left 4/log2font-height
+130     var x/eax: int <- copy 0x20/main-panel-hor
+131     x <- shift-left 3/log2font-width
+132     x <- add 0x18/item-padding-hor
+133     render-image screen, author-avatar, x, y, 0x50/avatar-side, 0x50/avatar-side
+134   }
+135   # channel
+136   var channel-name-ah/eax: (addr handle array byte) <- get item, channel
+137   var channel-name/eax: (addr array byte) <- lookup *channel-name-ah
+138   {
+139     var x/eax: int <- copy 0x20/main-panel-hor
+140     x <- add 0x40/channel-offset-x
+141     set-cursor-position screen, x y
+142   }
+143   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "#", 7/grey 0/black
+144   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, channel-name, 7/grey 0/black
+145   # author name
+146   var author-real-name-ah/eax: (addr handle array byte) <- get author, real-name
+147   var author-real-name/eax: (addr array byte) <- lookup *author-real-name-ah
+148   {
+149     var x/ecx: int <- copy 0x20/main-panel-hor
+150     x <- add 0x10/avatar-space-hor
+151     set-cursor-position screen, x y
+152     draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, author-real-name, 0xf/white 0/black
+153   }
+154   increment y
+155   # text
+156   var text-ah/eax: (addr handle array byte) <- get item, text
+157   var _text/eax: (addr array byte) <- lookup *text-ah
+158   var text/edx: (addr array byte) <- copy _text
+159   var x/eax: int <- copy 0x20/main-panel-hor
+160   x <- add 0x10/avatar-space-hor
+161   var text-y/ecx: int <- copy y
+162   text-y <- add 1/author-name-padding-ver
+163   x, text-y <- draw-text-wrapping-right-then-down screen, text, x text-y, 0x70/xmax=post-right-coord screen-height, x text-y, 7/fg 0/bg
+164   text-y <- add 2/item-padding-ver
+165   # flush
+166   add-to y, 6/avatar-space-ver
+167   compare y, text-y
+168   {
+169     break-if-<
+170     return y
+171   }
+172   return text-y
+173 }
+174 
+175 fn update-environment env: (addr environment), key: byte, items: (addr item-list) {
+176   {
+177     compare key, 6/ctrl-f
+178     break-if-!=
+179     page-down env, items
+180     return
+181   }
+182   {
+183     compare key, 2/ctrl-b
+184     break-if-!=
+185     page-up env, items
+186     return
+187   }
+188 }
+189 
+190 fn page-down _env: (addr environment), _items: (addr item-list) {
+191   var env/edi: (addr environment) <- copy _env
+192   var items/esi: (addr item-list) <- copy _items
+193   var items-data-ah/eax: (addr handle array item) <- get items, data
+194   var _items-data/eax: (addr array item) <- lookup *items-data-ah
+195   var items-data/ebx: (addr array item) <- copy _items-data
+196   var src/eax: (addr int) <- get env, item-index
+197   var new-item-index/ecx: int <- copy *src
+198   var y/edx: int <- copy 2
+199   {
+200     compare new-item-index, 0
+201     break-if-<
+202     compare y, 0x28/screen-height-minus-menu
+203     break-if->=
+204     var offset/eax: (offset item) <- compute-offset items-data, new-item-index
+205     var item/eax: (addr item) <- index items-data, offset
+206     var item-text-ah/eax: (addr handle array byte) <- get item, text
+207     var item-text/eax: (addr array byte) <- lookup *item-text-ah
+208     var h/eax: int <- estimate-height item-text
+209     set-cursor-position 0/screen, 0 0
+210     draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, h, 4/fg 0/bg
+211     y <- add h
+212     new-item-index <- decrement
+213     loop
+214   }
+215   new-item-index <- increment
+216   var dest/eax: (addr int) <- get env, item-index
+217   copy-to *dest, new-item-index
+218 }
+219 
+220 fn page-up _env: (addr environment), _items: (addr item-list) {
+221   var env/edi: (addr environment) <- copy _env
+222   var items/esi: (addr item-list) <- copy _items
+223   var items-data-ah/eax: (addr handle array item) <- get items, data
+224   var _items-data/eax: (addr array item) <- lookup *items-data-ah
+225   var items-data/ebx: (addr array item) <- copy _items-data
+226   var newest-item-index-a/esi: (addr int) <- get items, newest
+227   var src/eax: (addr int) <- get env, item-index
+228   var new-item-index/ecx: int <- copy *src
+229   var y/edx: int <- copy 2
+230   {
+231     compare new-item-index, *newest-item-index-a
+232     break-if->
+233     compare y, 0x28/screen-height-minus-menu
+234     break-if->=
+235     var offset/eax: (offset item) <- compute-offset items-data, new-item-index
+236     var item/eax: (addr item) <- index items-data, offset
+237     var item-text-ah/eax: (addr handle array byte) <- get item, text
+238     var item-text/eax: (addr array byte) <- lookup *item-text-ah
+239     var h/eax: int <- estimate-height item-text
+240     set-cursor-position 0/screen, 0 0
+241     draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, h, 4/fg 0/bg
+242     y <- add h
+243     new-item-index <- increment
+244     loop
+245   }
+246   new-item-index <- decrement
+247   var dest/eax: (addr int) <- get env, item-index
+248   copy-to *dest, new-item-index
+249 }
+250 
+251 # keep sync'd with render-item
+252 fn estimate-height _message-text: (addr array byte) -> _/eax: int {
+253   var message-text/esi: (addr array byte) <- copy _message-text
+254   var result/eax: int <- length message-text
+255   var remainder/edx: int <- copy 0
+256   result, remainder <- integer-divide result, 0x40/post-width
+257   compare remainder, 0
+258   {
+259     break-if-=
+260     result <- increment
+261   }
+262   result <- add 2/item-padding-ver
+263   compare result, 6/avatar-space-ver
+264   {
+265     break-if->
+266     return 6/avatar-space-ver
+267   }
+268   return result
+269 }
 
-- cgit 1.4.1-2-gfad0