about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--tutorial/converter2.mu17
-rw-r--r--tutorial/counter.pngbin0 -> 10757 bytes
-rw-r--r--tutorial/index.md114
-rw-r--r--tutorial/task13.mu5
-rw-r--r--tutorial/task15.mu19
-rw-r--r--vocabulary.md6
6 files changed, 145 insertions, 16 deletions
diff --git a/tutorial/converter2.mu b/tutorial/converter2.mu
index c5dde9f5..ae445239 100644
--- a/tutorial/converter2.mu
+++ b/tutorial/converter2.mu
@@ -10,21 +10,6 @@
 #   error checking for input without hard-aborting
 
 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
-  # imgui approach
-  forever {
-    number-input fahrenheit, cursor-in-fahrenheit?
-    number-input celsius, cursor-in-celsius?
-    if (menu-key 9/tab "Tab" "switch sides") {  # requires non-blocking input
-      cursor-in-celsius? <- not
-      cursor-in-fahrenheit? <- not
-    }
-    if (menu-key 0xa/newline "Enter" "convert") {
-      if cursor-in-fahrenheit
-        celsius = fahrenheit-to-celsius fahrenheit
-      else
-        fahrenheit = celsius-to-fahrenheit celsius
-    }
-  }
   # celsius numeric representation
   var zero: float
   var celsius/xmm1: float <- fahrenheit-to-celsius zero
@@ -47,7 +32,7 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk)
   # event loop
   {
     # render
-    render-state celsius-input, fahrenheit-input, cursor-in-celsius?
+    render-state screen, celsius-input, fahrenheit-input, cursor-in-celsius?
     render-menu-bar screen
     # process a single keystroke
     $main:input: {
diff --git a/tutorial/counter.png b/tutorial/counter.png
new file mode 100644
index 00000000..fa06caa7
--- /dev/null
+++ b/tutorial/counter.png
Binary files differdiff --git a/tutorial/index.md b/tutorial/index.md
index 1a595ed3..f8f3bed3 100644
--- a/tutorial/index.md
+++ b/tutorial/index.md
@@ -500,3 +500,117 @@ arguments together.
 
 This is a good time to skim [Mu's vocabulary of functions for pixel graphics](https://github.com/akkartik/mu/blob/main/vocabulary.md#pixel-graphics).
 They're fun to play with.
+
+## Task 13: reading input from keyboard
+
+Read the section on [events](https://github.com/akkartik/mu/blob/main/vocabulary.md#events)
+from Mu's vocabulary. Write a program to read a key from the keyboard. Mu
+receives a keyboard object as the second argument of `main`:
+
+```
+fn main screen: (addr screen), keyboard: (addr keyboard) {
+  # TODO: read a key from keyboard
+}
+```
+
+The _signature_ of `read-key` -- along with many other functions -- is in
+[400.mu](https://github.com/akkartik/mu/blob/main/400.mu).
+
+One wrinkle in this problem is that `read-key` may not actually return a key.
+You have to keep retrying until it does. You may have already encountered the
+list of `loop` operations in the section on [branches](https://github.com/akkartik/mu/blob/main/mu.md#branches).
+It might be a good time to refresh your knowledge there.
+
+## Task 14: streams and scanning input from the keyboard
+
+Check out the idiomatic way for processing text from the keyboard:
+
+```
+fn main screen: (addr screen), keyboard: (addr keyboard) {
+  var in-storage: (stream byte 0x80)
+  var in/esi: (addr stream byte) <- address in-storage
+  read-line-from-keyboard keyboard, in, screen, 0xf/fg 0/bg
+  {
+    var done?/eax: boolean <- stream-empty? in
+    compare done?, 0/false
+    break-if-!=
+    var g/eax: grapheme <- read-grapheme in
+    loop
+  }
+}
+```
+
+Can you modify this program to print out the text read from keyboard a second
+time? How about printing a space after every character (grapheme)?
+
+Now skim the section in the Mu reference on [streams](https://github.com/akkartik/mu/blob/main/mu.md#streams).
+Does the above program make sense?
+
+## Task 15: generating cool patterns
+
+Back to drawing to screen. Here's a program that draws every pixel on `screen`
+with a `color` equal to the value of its `x` coordinate.
+
+```
+fn main screen: (addr screen) {
+  var y/eax: int <- copy 0
+  {
+    compare y, 0x300/screen-height=768
+    break-if->=
+    var x/edx: int <- copy 0
+    {
+      compare x, 0x400/screen-width=1024
+      break-if->=
+      var color/ecx: int <- copy x
+      color <- and 0xff
+      pixel screen x, y, color
+      x <- increment
+      loop
+    }
+    y <- increment
+    loop
+  }
+}
+```
+
+Before you run it, form a hypothesis about what the picture will look like.
+The screen is 1024 pixels wide, but there are only 256 colors. What are the
+implications of these facts?
+
+After you run this program, try to modify it so every pixel gets a `color`
+equal to the sum of its `x` and `y` coordinates. Can you guess what pattern
+will result? Play around with more complex formulae. I particularly like the
+sum of squares of `x` and `y` coordinates. Check out the [Mandelbrot set](https://github.com/akkartik/mu/blob/main/apps/mandelbrot-silhouette.mu)
+for a really complex example of this sort of _procedural graphics_.
+
+## Task 16: a simple app
+
+We now know how to read keys from keyboard and draw on the screen. Look at
+[tutorial/counter.mu](https://github.com/akkartik/mu/blob/main/tutorial/counter.mu)
+which implements a simple counter app.
+
+<img alt='screenshot of the counter app' src='counter.png'>
+
+Do all the parts make sense? Read the extensive vocabulary of functions for
+[drawing text to screen](https://github.com/akkartik/mu/blob/main/vocabulary.md#events).
+
+---
+
+Here's a more challenging problem. Build an app to convert celsius to
+fahrenheit and vice versa. Two text fields, the `<Tab>` key to move the cursor
+between them, type in either field and hit `<Enter>` to populate the other
+field.
+
+After you build it, compare your solution with [tutorial/converter.mu](https://github.com/akkartik/mu/blob/main/tutorial/converter.mu).
+A second version breaks the program down into multiple functions, in
+[tutorial/converter2.mu](https://github.com/akkartik/mu/blob/main/tutorial/converter.mu).
+Can you see how the two do the same thing? Which one do you like better?
+
+---
+
+There's lots more programs in this repository. Look in the `apps/` directory.
+Check out the Mu `shell/`, which persists data between runs to a separate data
+disk. Hopefully this gives you some sense for how little software it takes to
+build useful programs for yourself. Do you have any new ideas for programs to
+write in Mu? [Tell me about them!](http://akkartik.name/about) I'd love to jam
+with you.
diff --git a/tutorial/task13.mu b/tutorial/task13.mu
new file mode 100644
index 00000000..9a4bc7f2
--- /dev/null
+++ b/tutorial/task13.mu
@@ -0,0 +1,5 @@
+fn main screen: (addr screen), keyboard: (addr keyboard) {
+  var in-storage: (stream byte 0x80)
+  var in/esi: (addr stream byte) <- address in-storage
+  read-line-from-keyboard keyboard, in, screen, 0xf/fg 0/bg
+}
diff --git a/tutorial/task15.mu b/tutorial/task15.mu
new file mode 100644
index 00000000..a53c2454
--- /dev/null
+++ b/tutorial/task15.mu
@@ -0,0 +1,19 @@
+fn main screen: (addr screen) {
+  var y/eax: int <- copy 0
+  {
+    compare y, 0x300/screen-height=768
+    break-if->=
+    var x/edx: int <- copy 0
+    {
+      compare x, 0x400/screen-width=1024
+      break-if->=
+      var color/ecx: int <- copy x
+      color <- and 0xff
+      pixel screen x, y, color
+      x <- increment
+      loop
+    }
+    y <- increment
+    loop
+  }
+}
diff --git a/vocabulary.md b/vocabulary.md
index f2be5f1e..c7d0bd46 100644
--- a/vocabulary.md
+++ b/vocabulary.md
@@ -243,6 +243,10 @@ Assertions for tests:
 `read-key` reads a single key from the keyboard and returns it if it exists.
 Returns 0 if no key has been pressed.
 
+`read-line-from-keyboard` reads keys from keyboard, echoes them to screen
+(with given fg/bg colors) and accumulates them in a stream until it encounters
+a newline.
+
 `read-mouse-event` returns a recent change in x and y coordinate.
 
 `timer-counter` returns a monotonically increasing counter with some
@@ -251,6 +255,8 @@ but can't make assumptions about how much time has passed.
 
 Mu doesn't currently support interrupt-based events.
 
+We also don't yet have a fake keyboard.
+
 #### persistent storage
 
 `read-ata-disk` synchronously reads a whole number of _sectors_ from a _disk_