From 03825d42880e09bbbd13fd1dba48d4d4bc3149d3 Mon Sep 17 00:00:00 2001 From: sejo Date: Wed, 9 Feb 2022 16:59:01 -0600 Subject: [PATCH] new tables in pixel and 1bpp sprites --- src/tutorial_de_uxn_día_2.gmo | 130 ++++++++++++++++++--------------- src/uxn_tutorial_day_2.gmo | 117 +++++++++++++++-------------- 2 files changed, 135 insertions(+), 112 deletions(-) diff --git a/src/tutorial_de_uxn_día_2.gmo b/src/tutorial_de_uxn_día_2.gmo index ee70636..b75df0b 100644 --- a/src/tutorial_de_uxn_día_2.gmo +++ b/src/tutorial_de_uxn_día_2.gmo @@ -273,8 +273,8 @@ el envío de un único byte a .Pantalla/píxel realizará el dibujo en la pantal el nibble alto de ese byte, es decir, el dígito hexadecimal de la izquierda, determinará la capa en la que dibujaremos: -* 0: dibujar un solo píxel en el fondo -* 4: dibujar un solo píxel en el primer plano +* 0: dibujar un solo píxel en el fondo (fn) +* 4: dibujar un solo píxel en el primer plano (pp) el nibble inferior del byte, es decir, el dígito hexadecimal de la derecha, determinará su color. @@ -282,21 +282,21 @@ las 8 posibles combinaciones del byte 'píxel' que tenemos para dibujar un píxe + + -+ -+ -+ -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ++ ++ ++ +
píxelcolorcapa
000fondo
011
022
033
400primer plano
411
422
433
000fn
011
022
033
400pp
411
422
433
& capa del fondo: & * 00: dibujar el píxel con el color 0 & * 01: dibujar un píxel con el color 1 & * 02: dibujar el píxel con el color 2 & * 03: dibujar el píxel con el color 3 -& +& & capa del primer plano: & * 40: dibujar un píxel con el color 0 & * 41: dibujar el píxel con el color 1 @@ -541,6 +541,8 @@ tengamos en cuenta que aquí no estamos utilizando la runa hexadecimal literal ( para asegurarse de que estos bytes no son leídos como instrucciones por la cpu uxn, es una buena práctica precederlos con la instrucción BRK: esto interrumpirá la ejecución del programa antes de llegar aquí, dejando a uxn en un estado en el que está esperando entradas. +un poco más adelante revisaremos dónde colocar este código. + ## configurando la dirección para dibujar el sprite, necesitamos enviar su dirección en memoria al dispositivo de pantalla y necesitamos asignar un byte de sprite apropiado. @@ -561,73 +563,79 @@ como la dirección es de 2 bytes, la imprimimos con DEO2. de forma similar a lo que ya vimos con el píxel, el envío de un byte a .Pantalla/sprite realizará el dibujo en la pantalla. -### sprite de nibble alto para 1bpp +### nibble alto de sprite para 1bpp el nibble alto del byte 'sprite' determinará la capa en la que dibujaremos, igual que cuando dibujábamos usando el byte 'píxel'. -sin embargo, en este caso tendremos otras posibilidades: podemos rotar el sprite en el eje horizontal (x) o en el vertical (y). +sin embargo, en este caso tendremos otras posibilidades: podemos invertir el sprite en el eje horizontal (x) o en el vertical (y). -los ocho valores posibles de este nibble alto, utilizados para dibujar un sprite de 1bpp, son: +los ocho valores posibles de este nibble alto de 'sprite', utilizados para dibujar un sprite de 1bpp, son: + -+ -+ -+ -+ -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
nibble altocaparotar-yrotar-x
0plano de fondonono
1plano de fondono
2plano de fondono
3plano de fondo
4primer planonono
5primero planono
6primero planono
7primero plano
sprite altocapainv-yinv-x
0fnnono
1
2no
3
4ppnono
5
6no
7
-& * 0: dibujar un sprite de 1bpp en el fondo, con la orientación original -& * 1: dibujar un sprite de 1bpp en el fondo, rotado horizontalmente -& * 2: dibujar un sprite de 1bpp en el fondo, rotado verticalmente -& * 3: dibujar un sprite de 1bpp en el fondo, rotado horizontalmente y verticalmente -& * 4: dibujar un sprite de 1bpp en primer plano, con la orientación original -& * 5: dibujar un sprite de 1bpp en primer plano, rotado horizontalmente -& * 6: dibujar un sprite de 1bpp en primer plano, rotado verticalmente -& * 7: dibujar un sprite de 1bpp en primer plano, rotado horizontalmente y verticalmente +& fondo: +& * 0: dibujar un sprite de 1bpp, con la orientación original +& * 1: dibujar un sprite de 1bpp, rotado horizontalmente +& * 2: dibujar un sprite de 1bpp, rotado verticalmente +& * 3: dibujar un sprite de 1bpp, rotado horizontalmente y verticalmente +& +& primer plano: +& * 4: dibujar un sprite de 1bpp, con la orientación original +& * 5: dibujar un sprite de 1bpp, rotado horizontalmente +& * 6: dibujar un sprite de 1bpp, rotado verticalmente +& * 7: dibujar un sprite de 1bpp, rotado horizontalmente y verticalmente si se observa con atención, se puede ver algún patrón: cada bit del nibble alto del byte del sprite corresponde a un aspecto diferente de este comportamiento. lo siguiente muestra el significado de cada uno de estos bits en el nibble alto, suponiendo que estamos contando los bits del byte de derecha a izquierda y de 0 a 7: + -+ -+ ++ ++ ++ ++ ++ +
bit 7bit 6bit 5bit 4
modo (0 es 1bpp, 1 es 2bpp)capa (0 es plano de fondo, 1 es primer plano)rotar verticalmente (0 es no, 1 es sí)rotar horizontalmente (0 es no, 1 es sí)
bitbandera01
7modo1bpp2bpp
6capafnpp
5inv-yno
4inv-xno
-& * bit 4: rotación-x -& * bit 5: rotación-y -& * bit 6: capa (0 es plano de fondo, 1 es primer plano) & * bit 7: modo (0 es 1bpp, 1 es 2bpp) +& * bit 6: capa (0 es plano de fondo, 1 es primer plano) +& * bit 5: inversión-y +& * bit 4: inversión-x -como por ejemplo, cuando el nibble alto del 'sprite' es 0, que en binario es 0000, significa que todas las banderas están apagadas: por eso dibuja un sprite de 1bpp (0) en el fondo (0), que no esta rotado ni verticalmente (0) ni horizontalmente (0). +como por ejemplo, cuando el nibble alto del 'sprite' es 0, que en binario es 0000, significa que todas las banderas están apagadas: por eso dibuja un sprite de 1bpp (0) en el fondo (0), que no esta invertido ni verticalmente (0) ni horizontalmente (0). -un nibble alto de 1, es decir, 0001 en binario, tiene la última bandera encendida, por eso se rota horizontalmente, y así sucesivamente. +un nibble alto de 1, es decir, 0001 en binario, tiene la última bandera encendida, por eso se invierte horizontalmente, y así sucesivamente. -### sprite de nibble bajo para 1bpp +### nibble bajo de sprite para 1bpp -el nibble bajo del byte 'sprite' determinará los colores que se utilizan para dibujar los píxeles "encendido" y "apagado" de los tiles. +el nibble bajo del byte 'sprite' determinará los colores que se utilizan para dibujar los píxeles "encendido" (1) y "apagado" (0) de los tiles. + -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
nibble bajocolor "encendido"color "apagado"
0borrarborrar
110
220
330
401
51nada
621
731
802
912
a2nada
b32
c03
d13
e23
f3nada
sprite bajocolor 1color 0
0borrarborrar
110
220
330
401
51nada
621
731
802
912
a2nada
b32
c03
d13
e23
f3nada
& * 0: borrar tile & * 1: "encendido" con el color 1, "apagado" con el color 0 @@ -646,13 +654,17 @@ el nibble bajo del byte 'sprite' determinará los colores que se utilizan para d & * e: "encendido" con el color 2, "apagado" con el color 3 & * f: "encendido" con el color 3, "apagado" sin color -notemos que un 0 en el nibble inferior borrará el tile. +por ejemplo, esto significa que si establecemos el nibble bajo de 'sprite' con el valor de 6, varvara dibujará el sprite utilizando el color 2 para los pixeles "encendidos" y el color 1 para los pixeles "apagados". + +notemos que un 0 en el este nibble borrará el tile. además, 5, 'a' y 'f' en el nibble bajo dibujarán los píxeles que están "encendidos" pero dejarán los que están "apagados" como están: esto le permitirá dibujar sobre algo que ha sido dibujado antes, sin borrarlo completamente. +no te preocupes si esto no está teniendo mucho sentido, ¡veamos un ejemplo! + ## hola sprite -¡hagámoslo! el siguiente programa dibujará nuestro sprite una vez: +el siguiente programa dibujará nuestro sprite una vez: ``` ( hola-sprite.tal ) diff --git a/src/uxn_tutorial_day_2.gmo b/src/uxn_tutorial_day_2.gmo index a823828..d1ceaca 100644 --- a/src/uxn_tutorial_day_2.gmo +++ b/src/uxn_tutorial_day_2.gmo @@ -273,8 +273,8 @@ sending a single byte to .Screen/pixel will perform the drawing in the screen. the high nibble of that byte, i.e. the hexadecimal digit at the left, will determine the layer in which we'll draw: -* 0: draw a single pixel in the background -* 4: draw a single pixel in the foreground +* 0: draw a single pixel in the background (bg) +* 4: draw a single pixel in the foreground (fg) the low nibble of the byte, i.e. the hexadecimal digit at the right, will determine its color. @@ -282,14 +282,14 @@ the 8 possible combinations of the 'pixel' byte that we have for drawing a pixel + + -+ -+ -+ -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ++ ++ ++ +
pixelcolorlayer
000background
011
022
033
400foreground
411
422
433
000bg
011
022
033
400fg
411
422
433
& background layer: & * 00: draw pixel with color 0 @@ -541,6 +541,8 @@ note that we are not using the literal hex (#) rune here: we want to use the raw 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 in a state where it's waiting for inputs. +we'll see in a moment where to write this code. + ## setting the address in order to draw the sprite, we need to send its address in memory to the screen device, and we need to assign an appropriate sprite byte. @@ -567,41 +569,46 @@ the high nibble of the 'sprite' byte will determine the layer in which we'll dra however, in this case we'll have other possibilities: we can flip the sprite in the horizontal (x) and/or the vertical (y) axis. -the eight possible values of this high nibble, used for drawing a 1bpp sprite, are: +the eight possible values of the sprite high nibble, used for drawing a 1bpp sprite, are: + -+ -+ -+ -+ -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
high nibblelayerflip-yflip-x
0backgroundnono
1backgroundnoyes
2backgroundyesno
3backgroundyesyes
4foregroundnono
5foregroundnoyes
6foregroundyesno
7foregroundyesyes
sprite highlayerflip-yflip-x
0bgnono
1yes
2yesno
3yes
4fgnono
5yes
6yesno
7yes
-& * 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 +& background: +& * 0: draw a 1bpp sprite, original orientation +& * 1: draw a 1bpp sprite, flipped horizontally +& * 2: draw a 1bpp sprite, flipped vertically +& * 3: draw a 1bpp sprite, flipped horizontally and vertically +& +& foreground: +& * 4: draw a 1bpp sprite, original orientation +& * 5: draw a 1bpp sprite, flipped horizontally +& * 6: draw a 1bpp sprite, flipped vertically +& * 7: draw a 1bpp sprite, flipped horizontally and vertically if you observe carefully, you might see some pattern: each bit in the high nibble of the sprite byte corresponds to a different aspect of this behavior. the following shows the meaning of each of these bits in the high nibble, assuming that we are counting the byte bits from right to left, and from 0 to 7: + -+ -+ ++ ++ ++ ++ ++ +
bit 7bit 6bit 5bit 4
mode (0 is 1bpp, 1 is 2bpp)layer (0 is background, 1 is foreground)flip vertically (0 is no, 1 is yes)flip horizontally (0 is no, 1 is yes)
bitflag01
7mode1bpp2bpp
6layerbgfg
5flip-ynoyes
4flip-xnoyes
- -& * bit 4: flip-x -& * bit 5: flip-y -& * bit 6: layer (0 is background, 1 is foreground) & * bit 7: mode (0 is 1bpp, 1 is 2bpp) +& * bit 6: layer (0 is background, 1 is foreground) +& * bit 5: flip-y +& * bit 4: flip-x as an example, when the 'sprite' high nibble is 0, that in binary is 0000, it means that all the flags are off: that's why it draws a 1bpp (0) sprite in the background (0), not flipped neither vertically (0) nor horizontally (0). @@ -609,26 +616,26 @@ a high nible of 1, i.e. 0001 in binary, has the last flag on, so that's why it's ### sprite low nibble for 1bpp -the low nibble of the 'sprite' byte 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" (1) and "off"(0) pixels of the tiles. + -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
low nibble"on" color"off" color
0clearclear
110
220
330
401
51none
621
731
802
912
a2none
b32
c03
d13
e23
f3none
sprite lowcolor 1color 0
0clearclear
110
220
330
401
51none
621
731
802
912
a2none
b32
c03
d13
e23
f3none
& * 0: clear tile & * 1: "on" with color 1, "off" with color 0 @@ -647,13 +654,17 @@ the low nibble of the 'sprite' byte will determine the colors that are used to d & * e: "on" with color 2, "off" with color 3 & * f: "on" with color 3, "off" with no color +as an example, this means that setting the sprite low nibble to 6 will draw the sprite with color 2 in the "on" pixels, and color 1 in the "off" pixels. + note that 0 in the low nibble will clear the tile. additionally, 5, 'a' and 'f' in the low nibble will draw the pixels that are "on" but will leave the ones that are "off" as is: this will allow you to draw over something that has been drawn before, without erasing it completely. +don't worry if this is not making a lot of sense: let's see an example! + ## hello sprite -let's do this! the following program will draw our sprite once: +the following program will draw our sprite once: ``` ( hello-sprite.tal )