[Modo Radastaniano] - Sprites transparentes sin máscara
Publicado: 19 Nov 2015, 15:31
Vamos a ver, partimos de esta sencilla rutina:
La idea es que cuando detecte un pixel cero (0000xxxx ó xxxx0000 en binario) respete el pixel que hubiera anteriormente en pantalla. Es evidente que al tener que hacer alguna operación vamos a perder rapidez, pero tampoco es algo crítico porque no vamos a querer 32 sprites simultáneos en pantalla ni nada por el estilo (para animar fondos ya tenemos la rutina de arriba).
Lo que he pensado es en recuperar el byte de pantalla antes de "machacarlo" y hacer un par de operaciones con él:
- AND con valor 240, otro con 15 (para separar el tratamiento del primer y el segundo pixel) con cada byte del sprite
- Si el valor obtenido después de cada AND no es cero se dibuja el pixel, en caso contrario se salta el dibujado.
La parte que hay que modificar es esta:
Le daré vueltas y os contaré el progreso. Se aceptan sugerencias (sin usar máscara, evidentemente).
Código: Seleccionar todo
// ___________________________________________
// Posiciona un Sprite de 8x8 a color
// ___________________________________________
void put_sprite_x8 (unsigned char *posicion, unsigned int x, unsigned int y)
{
// -------------------------------------------
// RUTINA DE IMPRESION DE UN SPRITE 8x8 PIXELS
// EN CUALQUIER POSICION DE BYTES (cada byte dos pixels horizontales)
// ENTRADAS:
// D será la posición del cursor vertical en pixels
// E será la posición del cursor horizontal en parejas de pixels
// HL es la posición de memoria donde tenemos el sprite
// SALIDAS: se escribe en el mapa de pantalla
// ADVERTENCIAS: no comprueba límites de pantalla
// -------------------------------------------
#asm
ld hl,2 ; Pasamos la variable de entrada al acumulador
add hl,sp
ld d, (hl) ; D es el valor Y
inc hl
inc hl
ld e, (hl) ; E es el valor X
inc hl
inc hl
ld a, (hl)
inc hl
ld h, (hl)
ld l, a ; HL es el puntero al sprite
ld a, d ; recuperamos el valor vertical
rrca
rrca ; rotamos para dejar su valor en múltiplos de 64 (linea, de dos en dos pixels)
and 192 ; borramos el resto de bits por si las moscas
or e ; sumamos el valor horizontal
ld e, a ; e preparado
ld a, d ; cargamos el valor vertical
rrca
rrca ; rotamos para quedarnos con los bits altos
and 63 ; borramos el resto de bits
or 64 ; nos posicionamos a partir de 16384 (16384=64+0 en dos bytes)
ld d, a ; d preparado, ya tenemos la posición en pantalla
ld b,8 ; Indicamos que vamos a pintar 8 líneas
.draw ; dibujamos 8 pixels (4 bytes)
ld c,4 ; Indicamos que vamos a pintar 4 pares de pixels
ldi
ldi
ldi
ldi
ld a,e
add a,60 ; incrementamos una línea y retornamos los pixels dibujados
ld e,a
jr nc, sigue
inc d ; incrementamos D si sale acarrero al incrementar E en 64 bytes
.sigue
djnz, draw
ret
#endasm
}
Lo que he pensado es en recuperar el byte de pantalla antes de "machacarlo" y hacer un par de operaciones con él:
- AND con valor 240, otro con 15 (para separar el tratamiento del primer y el segundo pixel) con cada byte del sprite
- Si el valor obtenido después de cada AND no es cero se dibuja el pixel, en caso contrario se salta el dibujado.
La parte que hay que modificar es esta:
Código: Seleccionar todo
ld b,8 ; Indicamos que vamos a pintar 8 líneas
.draw ; dibujamos 8 pixels (4 bytes)
ld c,4 ; Indicamos que vamos a pintar 4 pares de pixels
ldi
ldi
ldi
ldi
ld a,e
add a,60 ; incrementamos una línea y retornamos los pixels dibujados
ld e,a
jr nc, sigue
inc d ; incrementamos D si sale acarrero al incrementar E en 64 bytes
.sigue
djnz, draw