done with first draft of tutorial

This commit is contained in:
Kartik K. Agaram 2021-10-30 01:15:23 -07:00
parent bd356e5409
commit 29523c7eb6
6 changed files with 145 additions and 16 deletions

View File

@ -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: {

BIN
tutorial/counter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -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.

5
tutorial/task13.mu Normal file
View File

@ -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
}

19
tutorial/task15.mu Normal file
View File

@ -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
}
}

View File

@ -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_