en la primera parte del {tutorial de uxn día 6} hablamos de cómo cubrir el fondo de la pantalla con un tile dado.
aquí generalizaremos un procedimiento similar en una subrutina dibuja-tiles que dibuje un rectángulo relleno con un tile dado. recibirá las coordenadas x,y de la esquina superior izquierda del rectángulo, su anchura y altura en píxeles, y la dirección del tile:
```
@dibuja-tiles ( x^ y^ ancho^ alto^ direc* -- )
```
un recordatorio de que estamos utilizando la convención de añadir un signo de intercalación (^) después del nombre de un valor para indicar que es un corto, y un asterisco (*) para indicar que es un corto que funciona como un puntero (es decir, una dirección en la memoria del programa)
vamos a detallar cómo llegar a dos versiones de esta subrutina, una que se basa en una fuerte manipulación de la pila, y otra que utiliza variables. esto con el fin de comparar ambos enfoques y darnos una visión más amplia de las posibilidades dentro de uxntal.
## configuración
comencemos con el siguiente programa como plantilla. incluye los datos para un sprite de 1bpp compuesto por líneas diagonales.
recuerda que estamos mostrando la parte superior de las pilas a su derecha.
después de estos pasos, la x inicial está en la parte superior de la pila, por lo que podemos enviarla directamente a la pantalla.
el último cambio que necesitaríamos es reemplazar nuestro límite codificado por una instrucción STH2kr (copiar el límite de la pila de retorno a la pila de trabajo), y terminar nuestra rutina con una POP2r (eliminar el límite de la pila de retorno).
nuestra subrutina se vería entonces de la siguiente manera:
similar a lo que acabamos de hacer: ¿cuál es el procedimiento que podríamos seguir para repetir verticalmente una fila empezando por `y`, y terminando en un límite correspondiente a y+altura?
siguiendo la misma estrategia, podríamos hacer:
* dibujar la fila en y
* añadir 8 (el tamaño del tile) a y
* ¿es `y` menor que el límite? si lo es, repetir el procedimiento, en caso contrario terminar
### versión concreta
utilicemos los mismos números que antes, suponiendo que nuestra `y` inicial es 0008, nuestra altura es 0100, y por tanto nuestro límite siendo 0108.
en el caso de x, comencemos en 0000 y tengamos un ancho correspondiente al ancho de la pantalla.
como la dirección no cambiaría en el proceso, podemos establecerla al principio y olvidarnos de ella.
el siguiente código se basa en el bucle anterior de x, pero ahora dibuja una fila en una coordenada `y` dada, le suma 8 y luego comprueba si es menor que el límite:
```
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
#0008 .Pantalla/y ( establecer y inicial )
&bucle-y
( preparar y dibujar fila )
#0000 ( x inicial )
.Pantalla/ancho DEI2 ( obtener el ancho de la pantalla )
;dibuja-tiles-en-fila JSR2
.Pantalla/y DEI2 #0008 ADD2 DUP2 ( añade 8 a y )
.Pantalla/y DEO2 ( guardar la nueva y )
#0108 ( poner límite en la parte superior de la pila )
LTH2 ,&bucle-y JCN ( saltar si x es menor que el límite )
```
### versión abstracta
ahora, antes de saltar directamente a la emulación de la solución para dibujar la fila, vamos a notar que en este caso no es tan fácil.
¿por qué? porque la idea de nuestra subrutina dibuja-tiles es que debe ser capaz de recibir la x inicial y el ancho del rectángulo, y ahora mismo estos valores están codificados dentro del bucle.
esta debería ser la firma de nuestra subrutina:
```
@dibuja-tiles ( x^ y^ ancho^ alto^ direc* -- )
```
podemos abordar este problema bien con alguna "manipulación de la pila ", o bien con "variables ".
también hay que tener en cuenta que lo haremos porque estamos tratando de llegar a una subrutina generalizada.
si sólo quisiéramos cubrir toda la pantalla con un sprite, ya tenemos todo el código necesario: sólo tendríamos que adaptar el límite vertical del bucle para que se corresponda con la altura de la pantalla, ¡y ya está!
entonces podríamos pasar a la sección relativa de las paletas. sin embargo, lo que sigue puede ser interesante como una forma de ver un posible enfoque para escribir un código uxntal más complejo :)
### usando la manipulación de la pila
en principio podríamos simplemente manipular los elementos dados en la pila, almacenándolos cuando sea apropiado, para adaptar nuestra subrutina a su firma.
en primer lugar, la dirección del tile es el valor de la parte superior de la pila. podemos consumirlo y olvidarnos de él:
el problema es que dentro del bucle, ambas instrucciones STH2r recuperan y consumen los valores de `x` y ancho de la pila de retorno. por tanto, en la siguiente iteración no podríamos volver a utilizarlos, ya que se perderían.
podemos pensar que podríamos reemplazar estas instrucciones con STH2kr:
pero ah, antes de hacer la comparación y el salto, debemos reordenar la pila de retorno para que se corresponda con la ordenación que teníamos al principio del bucle:
como he dicho antes, podemos encontrar aquí algunas oportunidades de optimización.
tal vez el límite vertical puede ser escondido en la pila de retorno como en el bucle dibuja-tiles-en-fila, o tal vez la variable para la altura y para la `y` inicial no son necesarios.
en nuestro caso eso no es un gran problema, pero es una buena manera de evaluar nuestras prioridades: código súper legible pero probablemente ineficiente (como esta última subrutina), código súper optimizado pero probablemente ilegible (código de sólo escritura, dicen), o algo en el medio.
## dibuja-fondo
ahora que tenemos estas bonitas subrutinas, podemos simplemente envolverlas en otra que cubrirá todo el fondo con nuestro tile elegido.
por ejemplo:
```
@dibuja-fondo ( -- )
#0000 #0010 ( x e `y` iniciales )
.Pantalla/ancho DEI2
.Pantalla/alto DEI2 #0010 SUB2
;tile-fondo
;dibuja-tiles JSR2
RTN
```
que podemos llamar simplemente desde nuestra subrutina de iniciación: