diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-10-30 01:15:23 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-10-30 01:15:23 -0700 |
commit | 29523c7eb665c942897833fd68d609b0d5651a6d (patch) | |
tree | 2980ef6ad8eb8f25dd400f6f638aed8763c2d299 /tutorial | |
parent | bd356e540926f27a1180b436fa0ec5e8031564ee (diff) | |
download | mu-29523c7eb665c942897833fd68d609b0d5651a6d.tar.gz |
done with first draft of tutorial
Diffstat (limited to 'tutorial')
-rw-r--r-- | tutorial/converter2.mu | 17 | ||||
-rw-r--r-- | tutorial/counter.png | bin | 0 -> 10757 bytes | |||
-rw-r--r-- | tutorial/index.md | 114 | ||||
-rw-r--r-- | tutorial/task13.mu | 5 | ||||
-rw-r--r-- | tutorial/task15.mu | 19 |
5 files changed, 139 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 + } +} |