corrected day 2 for new screen device and varvara name

This commit is contained in:
sejo 2021-07-31 16:02:21 -05:00
parent 201a3be641
commit ddfca16d0f
2 changed files with 114 additions and 107 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -2,12 +2,14 @@
this is the second section of the {uxn tutorial}!
in this section we start exploring the visual aspects of the uxn computer: we talk about the fundamentals of the screen device so that we can start drawing on it!
in this section we start exploring the visual aspects of the varvara computer: we talk about the fundamentals of its screen device so that we can start drawing on it!
we also discuss working with shorts (2-bytes) besides single bytes.
we also discuss working with shorts (2-bytes) besides single bytes in uxntal.
if you haven't done it already, i recommend you read the previous section at {uxn tutorial day 1}
12021-07-31: updated to correspond to the latest version of the varvara screen device.
# where are your shorts?
before jumping right into drawing to the screen, we need to talk about bytes and shorts :)
@ -154,7 +156,7 @@ the 'write' output of the console device has a size of 1 byte, so we can't reall
# system device and colors
the system device is the uxn device with an address of 00. its output addresses (starting at address 08) correspond to three different shorts: one called red, the other one green, and the last one blue.
the system device is the varvara device with an address of 00. its output addresses (starting at address 08) correspond to three different shorts: one called red, the other one green, and the last one blue.
in uxntal examples we can see its labels defined as follows:
@ -166,7 +168,7 @@ we will ignore the first elements for the moment, and focus on the color compone
## system colors
the uxn screen device can only show a maximum of four colors at a time.
the varvara screen device can only show a maximum of four colors at a time.
these four colors are called color 0, color 1, color 2 and color 3.
@ -277,15 +279,15 @@ otherwise, it means that our operations with the stack were left unbalanced: the
we mentioned already that the screen device can only show four different colors at a given time, and that these colors are numbered from 0 to 3. we set these colors already with the system device.
let's discuss and start using the uxn screen device!
let's discuss further and start using the screen device!
## inputs and outputs
in uxntal programs you will be able to find the labels corresponding to this device as follows:
in uxntal programs for the varvara computer you will be able to find the labels corresponding to this device as follows:
```
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
```
the inputs that we can read from this device are:
@ -299,7 +301,8 @@ the output fields of this device are:
* x coordinate (2 bytes)
* y coordinate (2 bytes)
* memory address (2 bytes)
* color (1 byte)
* pixel (1 byte)
* sprite (1 byte)
## foreground and background
@ -313,7 +316,7 @@ in the beginning the foreground layer is completey transparent: a process of alp
the first and simpler way to draw into the screen, is drawing a single pixel.
in order to do this, we need to set a pair of x,y coordinates where we want the pixel to be drawn, and we need to set the color byte to actually perform the drawing.
in order to do this, we need to set a pair of x,y coordinates where we want the pixel to be drawn, and we need to set the pixel byte to a value to actually perform the drawing.
## setting the coordinates
@ -339,7 +342,7 @@ a question for you: if we wanted to set the coordinates as ( x: 4, y: 8 ), which
## setting the color
sending a byte to .Screen/color will perform the drawing in the screen.
sending a byte to .Screen/pixel will perform the drawing in the screen.
the high nibble of that byte will determine the layer in which we'll draw:
@ -348,10 +351,10 @@ the high nibble of that byte will determine the layer in which we'll draw:
and the low nibble of the byte will determine its color.
the 8 possible combinations of the color byte that we have for drawing a pixel are:
the 8 possible combinations of the pixel byte that we have for drawing a pixel are:
+ <table>
+ <tr><th>color byte</th><th>layer</th><th>color</th></tr>
+ <tr><th>pixel byte</th><th>layer</th><th>color</th></tr>
+ <tr><td>00</td><td>background</td><td>0</td></tr>
+ <tr><td>01</td><td>background</td><td>1</td></tr>
+ <tr><td>02</td><td>background</td><td>2</td></tr>
@ -377,7 +380,7 @@ let's try it all together! the following code will draw a pixel with color 1 in
```
#0008 .Screen/x DEO2
#0008 .Screen/y DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
```
the complete program would look as follows:
@ -387,7 +390,7 @@ the complete program would look as follows:
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
( main program )
|0100
@ -399,7 +402,7 @@ the complete program would look as follows:
( draw a pixel in the screen )
#0008 .Screen/x DEO2
#0008 .Screen/y DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
```
woohoo!
@ -418,22 +421,22 @@ for example, we can draw multiple pixels in an horizontal line, setting the y co
( draw 6 pixels in an horizontal line )
#0008 .Screen/x DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
#0009 .Screen/x DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
#000a .Screen/x DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
#000b .Screen/x DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
#000c .Screen/x DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
#000d .Screen/x DEO2
#11 .Screen/color DEO
#11 .Screen/pixel DEO
```
note that we have to set the color for each pixel we draw; that operation signals the drawing.
@ -441,7 +444,7 @@ note that we have to set the color for each pixel we draw; that operation signal
we can define a macro to make it easier to repeat that:
```
%DRAW-PIXEL { #11 .Screen/color DEO } ( -- )
%DRAW-PIXEL { #11 .Screen/pixel DEO } ( -- )
```
## reading and manipulating coordinates
@ -490,11 +493,11 @@ using these macros we defined above, our code could end up looking as following:
( hello-pixels.tal )
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
( macros )
%DRAW-PIXEL { #11 .Screen/color DEO } ( -- )
%DRAW-PIXEL { #11 .Screen/pixel DEO } ( -- )
%INC-X { .Screen/x DEI2 #0001 ADD2 .Screen/x DEO2 } ( -- )
( main program )
@ -522,7 +525,7 @@ we'll see now how to leverage the built-in support for "sprites" in the uxn scre
# drawing 1bpp sprites
the uxn screen device allows us to use and draw tiles of 8x8 pixels (sprites), stored in the main memory.
the varvara screen device allows us to use and draw tiles of 8x8 pixels (sprites), stored in the main memory.
these tiles can be either in a 1bpp (1 bit per pixel) format, 8 bytes in size, or in a 2bpp (2 bits per pixel) format, with a size of 16 bytes.
@ -572,11 +575,11 @@ in uxntal, we need to write and label the data corresponding to the sprite into
note that we are not using the literal hex (#) rune here: we want to use the raw bytes in memory, and we don't need to push them down onto the stack.
to make sure that these bytes are not read as instructions by the cpu, it's a good practice to precede them with the BRK instruction: this will interrupt the execution of the program before arriving here, leaving the cpu "waiting" for inputs.
to make sure that these bytes are not read as instructions by the uxn cpu, it's a good practice to precede them with the BRK instruction: this will interrupt the execution of the program before arriving here, leaving uxn "waiting" for inputs.
## setting the address
in order to draw the sprite, we need to set its address in memory to the screen device, and we need to assign an appropriate color byte.
in order to draw the sprite, we need to set its address in memory to the screen device, and we need to assign an appropriate sprite byte.
to achieve the former, we write the following:
@ -592,9 +595,9 @@ because the address is 2-bytes long, we output it using DEO2.
## setting the color
as we saw already, sending a byte to .Screen/color will perform the drawing in the screen.
similar to what we saw already with the pixel, sending a byte to .Screen/sprite will perform the drawing in the screen.
### color high nibble for 1bpp
### sprite high nibble for 1bpp
as in the case of drawing pixels, the high nibble of that byte will determine the layer in which we'll draw.
@ -603,29 +606,29 @@ however, in this case we'll have other possibilities: we can flip the sprite in
the possible values of this high nibble, used for drawing a 1bpp sprite, are:
+ <table>
+ <tr><th>high nibble</th><th>layer</th><th>flip-x</th><th>flip-y</th></tr>
+ <tr><td>2</td><td>background</td><td>no</td><td>no</td></tr>
+ <tr><td>3</td><td>foreground</td><td>no</td><td>no</td></tr>
+ <tr><td>6</td><td>background</td><td>yes</td><td>no</td></tr>
+ <tr><td>7</td><td>foreground</td><td>yes</td><td>no</td></tr>
+ <tr><td>a</td><td>background</td><td>no</td><td>yes</td></tr>
+ <tr><td>b</td><td>foreground</td><td>no</td><td>yes</td></tr>
+ <tr><td>e</td><td>background</td><td>yes</td><td>yes</td></tr>
+ <tr><td>f</td><td>foreground</td><td>yes</td><td>yes</td></tr>
+ <tr><th>high nibble</th><th>layer</th><th>flip-y</th><th>flip-x</th></tr>
+ <tr><td>0</td><td>background</td><td>no</td><td>no</td></tr>
+ <tr><td>1</td><td>background</td><td>no</td><td>yes</td></tr>
+ <tr><td>2</td><td>background</td><td>yes</td><td>no</td></tr>
+ <tr><td>3</td><td>background</td><td>yes</td><td>yes</td></tr>
+ <tr><td>4</td><td>foreground</td><td>no</td><td>no</td></tr>
+ <tr><td>5</td><td>foreground</td><td>no</td><td>yes</td></tr>
+ <tr><td>5</td><td>foreground</td><td>yes</td><td>no</td></tr>
+ <tr><td>7</td><td>foreground</td><td>yes</td><td>yes</td></tr>
+ </table>
& * 2: draw a 1bpp sprite in the background, original orientation
& * 3: draw a 1bpp sprite in the foreground, original orientation
& * 6: draw a 1bpp sprite in the background, flipped horizontally
& * 7: draw a 1bpp sprite in the foreground, flipped horizontally
& * a: draw a 1bpp sprite in the background, flipped vertically
& * b: draw a 1bpp sprite in the foreground, flipped vertically
& * e: draw a 1bpp sprite in the background, flipped horizontally and vertically
& * f: draw a 1bpp sprite in the foreground, flipped horizontally and vertically
& * 0: draw a 1bpp sprite in the background, original orientation
& * 1: draw a 1bpp sprite in the background, flipped horizontally
& * 2: draw a 1bpp sprite in the background, flipped vertically
& * 3: draw a 1bpp sprite in the background, flipped horizontally and vertically
& * 4: draw a 1bpp sprite in the foreground, original orientation
& * 5: draw a 1bpp sprite in the foreground, flipped horizontally
& * 6: draw a 1bpp sprite in the foreground, flipped vertically
& * 7: draw a 1bpp sprite in the foreground, flipped horizontally and vertically
### color low nibble for 1bpp
### sprite low nibble for 1bpp
the low nibble of the byte color will determine the colors that are used to draw the "on" and "off" pixels of the tiles.
the low nibble of the sprite byte will determine the colors that are used to draw the "on" and "off" pixels of the tiles.
+ <table>
+ <tr><th>low nibble</th><th>"on" color</th><th>"off" color</th></tr>
@ -677,7 +680,7 @@ let's do this! the following program will draw our sprite once:
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
( main program )
|0100
@ -695,7 +698,7 @@ let's do this! the following program will draw our sprite once:
( draw sprite in the background )
( using color 1 for the outline )
#21 .Screen/color DEO
#01 .Screen/sprite DEO
BRK
@ -713,7 +716,7 @@ the following code will draw our square sprite with all 16 combinations of color
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
( macros )
%INIT-X { #0008 .Screen/x DEO2 } ( -- )
@ -734,28 +737,28 @@ the following code will draw our square sprite with all 16 combinations of color
( set sprite address )
;square .Screen/addr DEO2
#20 .Screen/color DEO INC-X
#21 .Screen/color DEO INC-X
#22 .Screen/color DEO INC-X
#23 .Screen/color DEO INC-Y
#00 .Screen/sprite DEO INC-X
#01 .Screen/sprite DEO INC-X
#02 .Screen/sprite DEO INC-X
#03 .Screen/sprite DEO INC-Y
INIT-X
#24 .Screen/color DEO INC-X
#25 .Screen/color DEO INC-X
#26 .Screen/color DEO INC-X
#27 .Screen/color DEO INC-Y
#04 .Screen/sprite DEO INC-X
#05 .Screen/sprite DEO INC-X
#06 .Screen/sprite DEO INC-X
#07 .Screen/sprite DEO INC-Y
INIT-X
#28 .Screen/color DEO INC-X
#29 .Screen/color DEO INC-X
#2a .Screen/color DEO INC-X
#2b .Screen/color DEO INC-Y
#08 .Screen/sprite DEO INC-X
#09 .Screen/sprite DEO INC-X
#0a .Screen/sprite DEO INC-X
#0b .Screen/sprite DEO INC-Y
INIT-X
#2c .Screen/color DEO INC-X
#2d .Screen/color DEO INC-X
#2e .Screen/color DEO INC-X
#2f .Screen/color DEO
#0c .Screen/sprite DEO INC-X
#0d .Screen/sprite DEO INC-X
#0e .Screen/sprite DEO INC-X
#0f .Screen/sprite DEO
BRK
@ -861,30 +864,34 @@ the screen device will use treat this address as a 2bpp sprite when we use the a
## setting the color
let's see how to use the color byte in order to draw 2bpp tiles!
let's see how to use the sprite byte in order to draw 2bpp tiles!
### color high nibble for 2bpp
### sprite high nibble for 2bpp
the high nibble for 2bpp sprites will allow us to choose the layer we want it to be drawn, and the flip direction, if any:
+ <table>
+ <tr><th>high nibble</th><th>layer</th><th>flip-x</th><th>flip-y</th></tr>
+ <tr><td>4</td><td>background</td><td>no</td><td>no</td></tr>
+ <tr><td>5</td><td>foreground</td><td>no</td><td>no</td></tr>
+ <tr><td>8</td><td>background</td><td>yes</td><td>no</td></tr>
+ <tr><td>9</td><td>foreground</td><td>yes</td><td>no</td></tr>
+ <tr><td>c</td><td>background</td><td>yes</td><td>yes</td></tr>
+ <tr><td>d</td><td>foreground</td><td>yes</td><td>yes</td></tr>
+ <tr><th>high nibble</th><th>layer</th><th>flip-y</th><th>flip-x</th></tr>
+ <tr><td>8</td><td>background</td><td>no</td><td>no</td></tr>
+ <tr><td>9</td><td>background</td><td>no</td><td>yes</td></tr>
+ <tr><td>a</td><td>background</td><td>yes</td><td>no</td></tr>
+ <tr><td>b</td><td>background</td><td>yes</td><td>yes</td></tr>
+ <tr><td>c</td><td>foreground</td><td>no</td><td>no</td></tr>
+ <tr><td>d</td><td>foreground</td><td>no</td><td>yes</td></tr>
+ <tr><td>e</td><td>foreground</td><td>yes</td><td>no</td></tr>
+ <tr><td>f</td><td>foreground</td><td>yes</td><td>yes</td></tr>
+ </table>
& * 4: draw a 2bpp sprite in the background, original orientation
& * 5: draw a 2bpp sprite in the foreground, original orientation
& * 8: draw a 2bpp sprite in the background, flipped horizontally
& * 9: draw a 2bpp sprite in the foreground, flipped horizontally
& * c: draw a 2bpp sprite in the background, flipped horizontally and vertically
& * d: draw a 2bpp sprite in the foreground, flipped horizontally and vertically
& * 8: draw a 2bpp sprite in the background, original orientation
& * 9: draw a 2bpp sprite in the background, flipped horizontally
& * a: draw a 2bpp sprite in the background, flipped vertically
& * b: draw a 2bpp sprite in the background, flipped horizontally and vertically
& * c: draw a 2bpp sprite in the foreground, original orientation
& * d: draw a 2bpp sprite in the foreground, flipped horizontally
& * e: draw a 2bpp sprite in the foreground, flipped vertically
& * f: draw a 2bpp sprite in the foreground, flipped horizontally and vertically
### color low nibble for 2bpp
### sprite low nibble for 2bpp
the low nibble will allow us to choose between many combinations of colors assigned to each different states of the pixels.
@ -936,7 +943,7 @@ the following code will show our sprite in the 16 different combinations of colo
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
( macros )
%INIT-X { #0008 .Screen/x DEO2 } ( -- )
@ -956,28 +963,28 @@ the following code will show our sprite in the 16 different combinations of colo
( set sprite address )
;new-square .Screen/addr DEO2
#40 .Screen/color DEO INC-X
#41 .Screen/color DEO INC-X
#42 .Screen/color DEO INC-X
#43 .Screen/color DEO INC-Y
#80 .Screen/sprite DEO INC-X
#81 .Screen/sprite DEO INC-X
#82 .Screen/sprite DEO INC-X
#83 .Screen/sprite DEO INC-Y
INIT-X
#44 .Screen/color DEO INC-X
#45 .Screen/color DEO INC-X
#46 .Screen/color DEO INC-X
#47 .Screen/color DEO INC-Y
#84 .Screen/sprite DEO INC-X
#85 .Screen/sprite DEO INC-X
#86 .Screen/sprite DEO INC-X
#87 .Screen/sprite DEO INC-Y
INIT-X
#48 .Screen/color DEO INC-X
#49 .Screen/color DEO INC-X
#4a .Screen/color DEO INC-X
#4b .Screen/color DEO INC-Y
#88 .Screen/sprite DEO INC-X
#89 .Screen/sprite DEO INC-X
#8a .Screen/sprite DEO INC-X
#8b .Screen/sprite DEO INC-Y
INIT-X
#4c .Screen/color DEO INC-X
#4d .Screen/color DEO INC-X
#4e .Screen/color DEO INC-X
#4f .Screen/color DEO
#8c .Screen/sprite DEO INC-X
#8d .Screen/sprite DEO INC-X
#8e .Screen/sprite DEO INC-X
#8f .Screen/sprite DEO
BRK
@ -986,15 +993,15 @@ BRK
try flipping the tiles!
## screen.tal and the combinations of the color byte
## screen.tal and the combinations of the sprite byte
the screen.tal example in the uxn repo consists of a table showing all possible (256!) combinations of high and low nibbles in the color byte.
the screen.tal example in the uxn repo consists of a table showing all possible (256!) combinations of high and low nibbles in the sprite byte.
=> ./img/screenshot_uxn-screen.png screenshot of the screen.tal example, that shows a sprite colored and flipped in different ways.
=> https://git.sr.ht/~rabbits/uxn/tree/master/item/projects/examples/devices/screen.tal screen.tal code
compare them with everything we have said before about the color byte!
compare them with everything we have said before about the sprite byte!
## designing sprites
@ -1010,13 +1017,13 @@ i recommend you give it a try!
# screen size and responsiveness
the last thing we'll cover today has to do with the assumptions uxn makes about the screen size, and some code strategies we can use to deal with them.
the last thing we'll cover today has to do with the assumptions varvara makes about its screen size, and some code strategies we can use to deal with them.
in short, there's not a standard screen size!
by default, the screen of the uxnemu emulator is 512x320 pixels (or 64x40 tiles).
by default, the screen of the varvara emulator is 512x320 pixels (or 64x40 tiles).
however, and for example, uxn also runs in the nintendo ds, with a resolution of 256x192 pixels (32x24 tiles), and in the teletype with a resolution of 128x64 pixels (16x8 tiles)
however, and for example, the virtual computer also runs in the nintendo ds, with a resolution of 256x192 pixels (32x24 tiles), and in the teletype with a resolution of 128x64 pixels (16x8 tiles)
as programmers, we are expected to decide what to do with these: our programs can adapt to the different screen sizes, they might have different modes depending on the screen size, and so on.