Merge pull request 'Revisión del día 3 del tutorial de Uxn' (#10) from Roboe/compudanzas:revisión/día-3 into main
Reviewed-on: https://codeberg.org/sejo/compudanzas/pulls/10
This commit is contained in:
commit
9bc605766b
|
@ -1,4 +1,4 @@
|
|||
# tutorial de uxn: día 3, saltos condicionales y el teclado/controlador
|
||||
# tutorial de uxn: día 3, saltos condicionales y el teclado o controlador
|
||||
|
||||
¡esta es la tercera sección del {tutorial de uxn}!
|
||||
|
||||
|
@ -18,7 +18,7 @@ la definición de sus puertos tendría el siguiente aspecto en un programa típi
|
|||
|
||||
## el byte de botón
|
||||
|
||||
el byte de botón codifica en cada uno de sus ocho bits el estado de ocho "botones" diferentes, basados en la disposición del controlador de NES.
|
||||
el byte de botón codifica en cada uno de sus ocho bits el estado de ocho "botones" diferentes, basados en la disposición del controlador de NES, la videoconsola clásica de 8 bits de Nintendo.
|
||||
|
||||
=> https://wiki.nesdev.com/w/index.php/Standard_controller controlador NES estándar
|
||||
|
||||
|
@ -46,21 +46,21 @@ numerando los bits de derecha a izquierda y de 0 a 7, las teclas correspondiente
|
|||
|
||||
codificar los estados de los botones de esta manera nos permite presionar y leer muchas de estas teclas al mismo tiempo.
|
||||
|
||||
## el byte de la tecla
|
||||
## el byte de tecla
|
||||
|
||||
el byte de la tecla almacena el código ascii de la tecla del teclado que se está pulsando en ese momento.
|
||||
el byte de tecla almacena el código ascii de la tecla del teclado que se está pulsando en ese momento.
|
||||
|
||||
la diferencia entre el byte 'de la tecla' y el byte 'de botón' puede ser confusa, especialmente cuando se ejecuta varvara desde uxnemu donde los botones están en el mismo lugar que las teclas.
|
||||
la diferencia entre el byte 'de tecla' y el byte 'de botón' puede ser confusa, especialmente cuando se ejecuta varvara desde uxnemu, donde varias teclas actúan además de botones.
|
||||
|
||||
una posible manera de recordar podría ser pensar en el byte 'botón' como refiriéndose a un controlador de gamepad.
|
||||
una posible manera de recordar podría ser pensar en el byte 'de botón' como refiriéndose a un controlador de gamepad.
|
||||
|
||||
## el vector del controlador
|
||||
|
||||
en el contexto de la programación de uxn, un vector se refiere a una dirección en la memoria principal donde se asigna a uxn para que salte cuando ocurra un evento específico.
|
||||
|
||||
en el caso del vector controlador, este evento específico consiste en cada vez que se pulsa o suelta una tecla.
|
||||
en el caso del vector del controlador, este evento específico consiste en cada vez que se pulsa o suelta una tecla.
|
||||
|
||||
en otras palabras: uxn saltará a la dirección asignada como vector controlador, cada vez que se pulse o suelte una tecla.
|
||||
en otras palabras: uxn saltará a la dirección asignada como vector del controlador, cada vez que se pulse o suelte una tecla.
|
||||
|
||||
la siguiente línea de código asignaría ese vector, utilizando la dirección absoluta de la etiqueta en-controlador:
|
||||
|
||||
|
@ -82,7 +82,7 @@ vamos a empezar a organizar nuestros programas uxntal en términos de subrutinas
|
|||
|
||||
cada una de estas subrutinas terminará con la instrucción BRK, para que puedan hacer que uxn vuelva al estado de espera.
|
||||
|
||||
## subrutina del vector controlador
|
||||
## subrutina del vector del controlador
|
||||
|
||||
para ilustrar ese comportamiento, leamos el siguiente programa.
|
||||
|
||||
|
@ -231,7 +231,7 @@ un "exclusive-OR", o también "o-exclusivo", es una operación lógica que tiene
|
|||
|
||||
basándose en este comportamiento, esta instrucción puede utilizarse para invertir el valor de una bandera utilizando un valor especial en el que el o los bits que queremos invertir se pongan a 1. este tipo de valores se llaman máscaras.
|
||||
|
||||
por ejemplo, el siguiente código empujará una bandera correspondiente a que la te sea mayor o igual a 20, calculando primero si es menor que 20 y luego invirtiendo el resultado:
|
||||
por ejemplo, el siguiente código empujará una bandera correspondiente a que la tecla sea mayor o igual a 20, calculando primero si es menor que 20 y luego invirtiendo el resultado:
|
||||
|
||||
```
|
||||
.Controlador/tecla DEI ( lee la tecla y la empuja a la pila )
|
||||
|
@ -259,7 +259,7 @@ EOR 0000 0001 ( máscara )
|
|||
0000 0001 ( verdadero )
|
||||
```
|
||||
|
||||
observe que la máscara es la misma y el resultado es el valor opuesto de la bandera.
|
||||
observa que la máscara es la misma y el resultado es el valor opuesto de la bandera.
|
||||
|
||||
# flujo de control: saltos condicionales
|
||||
|
||||
|
@ -294,7 +294,7 @@ en los días anteriores ya hablamos de algunas de ellas; esta es una recapitulac
|
|||
para definir las etiquetas, utilizamos:
|
||||
|
||||
* definición de etiquetas: @etiqueta
|
||||
* definición de la sub-etiqueta: &subetiqueta, donde esta sub-etiqueta será "hije" de la etiqueta previamente definida
|
||||
* definición de la subetiqueta: &subetiqueta, donde esta subetiqueta será "hije" de la etiqueta previamente definida
|
||||
|
||||
y finalmente, para referirse a las etiquetas dentro de nuestro código uxntal, tenemos los siguientes casos:
|
||||
|
||||
|
@ -334,9 +334,9 @@ la siguiente subrutina en-controlador ilustra el uso de los saltos, dibujando nu
|
|||
BRK
|
||||
```
|
||||
|
||||
nótese el uso de sub-etiquetas "dentro" (después) de en-controlador.
|
||||
nota el uso de subetiquetas "dentro" (después) de en-controlador.
|
||||
|
||||
también note como la expresión ,&subetiqueta corresponde a la dirección relativa (,) que se necesita para saltar a esa ubicación en el código nombrado con una sub-etiqueta local (&).
|
||||
también nota como la expresión ,&subetiqueta corresponde a la dirección relativa (,) que se necesita para saltar a esa ubicación en el código nombrado con una subetiqueta local (&).
|
||||
|
||||
estas direcciones relativas, de un byte, son utilizadas por JCN o JMP.
|
||||
|
||||
|
@ -353,13 +353,13 @@ el siguiente código ilustra el uso de muchas condiciones: el color del sprite c
|
|||
( establecer direccion del sprite )
|
||||
;cuadrado .Pantalla/direc DEO2
|
||||
|
||||
.Controlador/teclaDEI LIT '1 EQU ( ¿es la tecla '1'? )
|
||||
.Controlador/tecla DEI LIT '1 EQU ( ¿es la tecla '1'? )
|
||||
,&color-1 JCN ( salta al color-1 si es el caso )
|
||||
|
||||
.Controlador/tecla DEI LIT '2 EQU ( ¿es la tecla '2'? )
|
||||
,&color-2 JCN ( salta al color-2 si es el caso )
|
||||
|
||||
Controlador/tecla DEI LIT '3 EQU ( ¿es la tecla '3'? )
|
||||
.Controlador/tecla DEI LIT '3 EQU ( ¿es la tecla '3'? )
|
||||
,&color-3 JCN ( salta al color-3 si es el caso )
|
||||
|
||||
( en cualquier otro caso, terminar )
|
||||
|
@ -385,19 +385,19 @@ el siguiente código ilustra el uso de muchas condiciones: el color del sprite c
|
|||
BRK
|
||||
```
|
||||
|
||||
observe cómo las condiciones se escriben una tras otra: siempre que una bandera es falsa, JCN permite a uxn continuar con la siguiente instrucción en memoria.
|
||||
observa cómo las condiciones se escriben una tras otra: siempre que una bandera es falsa, JCN permite a uxn continuar con la siguiente instrucción en memoria.
|
||||
|
||||
también note que este código no está optimizado para el tamaño o la velocidad, sino para la legibilidad.
|
||||
también nota que este código no está optimizado para el tamaño o la velocidad, sino para la legibilidad.
|
||||
|
||||
estaría en ti, por ejemplo, realizar una aritmética con el valor de la tecla que se pulsó para calcular el color a asignar al sprite - ¡podrías inspirarte en tu macro IMPRIMIR-DÍGITO del día 1!
|
||||
|
||||
# manipulación de la pila
|
||||
|
||||
hasta ahora hemos estado usando la pila como un lugar para almacenar operandos de instrucciones y sus resultados, ¡pero aún no hemos usado todo el potencial de este entorno basado en la pila!
|
||||
hasta ahora hemos estado usando la pila como un lugar para almacenar operandos de instrucciones y sus resultados, ¡pero aún no hemos usado todo el potencial de este entorno basado en pila!
|
||||
|
||||
## instrucciones de pila
|
||||
|
||||
uxntal tiene seis instrucciones que actúan sobre los elementos de la pila más cercanos a la parte superior:g
|
||||
uxntal tiene seis instrucciones que actúan sobre los elementos de la pila más cercanos a la parte superior:
|
||||
|
||||
* POP: eliminar el elemento superior de la pila ( a -- )
|
||||
* DUP: duplicar; empujar una copia del elemento superior ( a -- a a )
|
||||
|
@ -423,7 +423,7 @@ discutimos anteriormente este segmento de código, que empuja una bandera que re
|
|||
```
|
||||
.Controlador/tecla DEI ( lee la tecla y la empuja a la pila)
|
||||
#2f GTH ( ¿es mayor que 2f? empuja la bandera a la pila )
|
||||
Controlador/tecla DEI ( lee la tecla y la introduce en la pila )
|
||||
.Controlador/tecla DEI ( lee la tecla y la introduce en la pila )
|
||||
#3a LTH ( ¿es menor que 3a? empuja la bandera a la pila )
|
||||
AND ( aplica un AND a las banderas en la pila y empuja el resultado en la pila )
|
||||
```
|
||||
|
@ -491,7 +491,7 @@ AND ( aplica un AND a las banderas en la pila y empuja el resultado en la pila )
|
|||
|
||||
el primer código se ensambla en 13 bytes y este se ensambla en 12 bytes. quizá no haya demasiada diferencia en ese aspecto.
|
||||
|
||||
sin embargo, una ventaja más significativa es que esta nueva rutina ahora necesita su entrada empujada hacia abajo en la pila solo al principio.
|
||||
sin embargo, la ventaja más significativa es que esta nueva rutina ahora necesita su entrada empujada hacia abajo en la pila solo al principio.
|
||||
|
||||
en el caso que acabamos de discutir la entrada es la tecla que se presiona, pero podríamos fácilmente tener como entrada cualquier otro valor de la pila.
|
||||
|
||||
|
@ -569,7 +569,7 @@ pista: compara el estado final de la pila con y sin las instrucciones POP.
|
|||
|
||||
# botón del controlador
|
||||
|
||||
la última cosa que discutiremos hoy es el uso del byte del botón del controlador en la computadora varvara.
|
||||
la última cosa que discutiremos hoy es el uso del byte de botón del controlador en la computadora varvara.
|
||||
|
||||
como ya hemos mencionado, la principal diferencia aquí es que este byte mantiene el estado de 8 botones en cada uno de sus bits.
|
||||
|
||||
|
@ -581,16 +581,16 @@ conoce las máscaras AND a nivel de bits.
|
|||
|
||||
## máscara AND
|
||||
|
||||
una máscara AND es un valor especial que utilizaremos para mantener o perder bits específicos de otro valor dado, como el byte del botón del controlador.
|
||||
una máscara AND es un valor especial que utilizaremos para mantener o perder bits específicos de otro valor dado, como el byte de botón del controlador.
|
||||
|
||||
en nuestra máscara AND, estableceremos como 1 los bits en las posiciones en las que queramos mantener el valor de los bits de entrada. las posiciones en las que los bits de la máscara sean 0 se convertirán en 0 en la entrada.
|
||||
en nuestra máscara AND, estableceremos como 1 los bits en las posiciones en las que queramos mantener el valor de los bits de entrada. las posiciones en las que los bits de la máscara sean 0 se convertirán a 0 en la salida.
|
||||
|
||||
por ejemplo, digamos que queremos ver si el bit número 4, que corresponde al botón Arriba, está encendido o apagado, independientemente del estado de los otros botones.
|
||||
|
||||
nuestra máscara AND tendrá un 1 en el bit número 4 (de derecha a izquierda y empezando por el 0) y 0 en el resto:
|
||||
|
||||
```
|
||||
0001 000: 10
|
||||
0001 0000: 10
|
||||
```
|
||||
|
||||
¿qué pasaría si se pulsa el botón A (tecla Ctrl), con su estado codificado en el bit 0 y nada más?
|
||||
|
@ -625,7 +625,7 @@ así vemos cómo la máscara nos permite aislar efectivamente el bit que nos imp
|
|||
aplicar esta máscara sería tan sencillo como escribir:
|
||||
|
||||
```
|
||||
#10 AND ( aplicar máscara 0001 000 )
|
||||
#10 AND ( aplicar máscara 0001 0000 )
|
||||
```
|
||||
|
||||
## ejemplo: dibujar con flechas y Ctrl
|
||||
|
@ -665,7 +665,7 @@ BRK
|
|||
@en-controlador ( -> )
|
||||
.Controlador/botón DEI DUP ( leer y duplicar el byte del botón )
|
||||
#01 AND ( aislar el bit 0, correspondiente a Ctrl )
|
||||
,&relleno JCN ( si el bit no es 0, saltar al relleno, si no, continuar )
|
||||
,&relleno JCN ( si el bit no es 0, saltar al relleno; si es 0, continuar )
|
||||
|
||||
&contorno
|
||||
#01 .Pantalla/sprite DEO ( dibujar contorno )
|
||||
|
@ -718,7 +718,7 @@ algunas posibilidades para que practiques:
|
|||
.Pantalla/y INCREMENTO
|
||||
```
|
||||
|
||||
recuerde que .Pantalla/x es una dirección literal en la página cero, es decir, empuja un byte correspondiente a la dirección de la sub-etiqueta Pantalla/x :)
|
||||
recuerde que .Pantalla/x es una dirección literal en la página cero, es decir, empuja un byte correspondiente a la dirección de la subetiqueta Pantalla/x :)
|
||||
|
||||
# practica posibilidades
|
||||
|
||||
|
@ -770,9 +770,9 @@ en el {tutorial de uxn día 4} cubrimos el uso del vector de pantalla para crear
|
|||
|
||||
¡también exploramos las posibilidades de usar "variables" en uxntal que pueden ayudarnos a crear programas más elaborados!
|
||||
|
||||
¡antes de entrar en materia, les invito a seguir explorando y también a tomarse un descanso!
|
||||
¡antes de entrar en materia, te invito a seguir explorando y también a tomar un descanso!
|
||||
|
||||
¡manténgase en sintonía!
|
||||
¡mantente en sintonía!
|
||||
|
||||
# apoyo
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ o si no quisiéramos iniciarlas aquí, podríamos definirlas de la siguiente man
|
|||
|
||||
recuerda que $2 crea un pad relativo de dos bytes: esto hace que píxel-y sea una etiqueta para una dirección en memoria dos bytes después de píxel-x. y cualquier código posterior ocurrirá dos bytes después de píxel-y.
|
||||
|
||||
también podríamos usar etiquetas y sub-etiquetas, de manera muy similar a como definimos los dispositivos y sus puertos:
|
||||
también podríamos usar etiquetas y subetiquetas, de manera muy similar a como definimos los dispositivos y sus puertos:
|
||||
|
||||
```
|
||||
@píxel [ &x $2 &y $2 ]
|
||||
|
@ -329,7 +329,7 @@ nótese el uso de la runa coma (,) para indicar que es una dirección relativa;
|
|||
|
||||
en este caso realmente no podemos duplicar ese desfase como hicimos anteriormente con la dirección de página cero, porque es específica de la posición en el código en que fue escrita.
|
||||
|
||||
si declaráramos estas variables como sub-etiquetas de en-cuadro, el código quedaría como sigue:
|
||||
si declaráramos estas variables como subetiquetas de en-cuadro, el código quedaría como sigue:
|
||||
|
||||
```
|
||||
@en-cuadro ( -> )
|
||||
|
@ -347,7 +347,7 @@ BRK
|
|||
&píxel-x $2 &píxel-y $2
|
||||
```
|
||||
|
||||
observe que en este caso, la runa de la coma (,) va acompañada de la runa de la sub-etiqueta (&).
|
||||
observe que en este caso, la runa de la coma (,) va acompañada de la runa de la subetiqueta (&).
|
||||
|
||||
el uso de este tipo de variables tendrá más sentido en el día 5 del tutorial :)
|
||||
|
||||
|
|
|
@ -569,7 +569,7 @@ para llamar a la subrutina, podrías hacer algo como lo siguiente:
|
|||
|
||||
### notas
|
||||
|
||||
nota que en esta subrutina específica, el uso de STH2 y STH2r después de la sub-etiqueta &bucle no es realmente necesario: las operaciones entre estas instrucciones sí tocan la pila de trabajo pero después la dejan como estaba.
|
||||
nota que en esta subrutina específica, el uso de STH2 y STH2r después de la subetiqueta &bucle no es realmente necesario: las operaciones entre estas instrucciones sí tocan la pila de trabajo pero después la dejan como estaba.
|
||||
|
||||
sin embargo, muestra cómo podemos usar estas instrucciones para tener una pila de trabajo limpia sin que otros valores interfieran.
|
||||
|
||||
|
|
|
@ -583,14 +583,14 @@ meet the bitwise AND masks!
|
|||
|
||||
an AND mask is a special value that we will use to keep or lose specific bits from another given value, like the controller button byte.
|
||||
|
||||
in our AND mask, we will set as 1 the bits in the positions where we want to keep the value of the input bits. the positions where the bits of the mask are 0 will be converted to 0 in the input.
|
||||
in our AND mask, we will set as 1 the bits in the positions where we want to keep the value of the input bits. the positions where the bits of the mask are 0 will be converted to 0 in the output.
|
||||
|
||||
for example, let's say we want to see if bit number 4, corresponding to the Up button, is on or off, regardless of the state of the other buttons.
|
||||
|
||||
our AND mask will have a 1 in bit number 4 (from right to left, and starting at 0), and 0 elsewhere:
|
||||
|
||||
```
|
||||
0001 000: 10
|
||||
0001 0000: 10
|
||||
```
|
||||
|
||||
what would happen if button A (Ctrl key), with its state encoded in bit 0, is pressed, and nothing else?
|
||||
|
@ -625,7 +625,7 @@ see how the mask allows us to effectively isolate the bit that matters to us, re
|
|||
applying this mask would be as simple as writing:
|
||||
|
||||
```
|
||||
#10 AND ( apply 0001 000 mask )
|
||||
#10 AND ( apply 0001 0000 mask )
|
||||
```
|
||||
|
||||
## example: draw with arrows and Ctrl
|
||||
|
|
Loading…
Reference in New Issue