Scroll en baja resolución

Chit chat general. Habla con los MojonTwins y con los amigos de los MojonTwins. Reza a Vah-ka. Delinque. Aviso: está PROHIBIDO tirarse peos fuerte. Si les cortas el pescuezo, vale.

Moderador: na_th_an

Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Scroll en baja resolución

Mensajepor radastan » Jue, 12 Dic 2013, 00:17

Bien, voy a ir comentando por aquí cómo hacer una rutina de scroll en baja resolución y los pasos que voy a seguir. Así de paso los que quieran aprender ensamblador se van coscando de algo.

La instrucción principal que maneja todo es LDIR, que se encarga de mover bloques de bytes:

- Introducimos en los registros HL la dirección de origen
- Introducimos en los registros DE la dirección de destino
- Introducimos en los registros BC el número de bytes a mover

Esta instrucción también es la adecuada si vamos a poner imágenes grandes en pantalla, ya que es más rápida que poner múltiples LDI. Pero esa es otra rutina, centrémonos en un scroll.

¿Cómo se usa para un scroll en baja resolución? muy simple: metemos en HL la dirección siguiente a la que meteremos en DE y como BC el valor de la anchura del área a mover menos un caracter. Con eso scrollearemos una línea completa de pixels, iteramos hasta 8, saltamos a la siguiente fila de caracteres, y así hasta terminar con todos los pixels para luego hacer lo mismo con los atributos de color.

Para la entrada de datos vamos a poner la dirección X, Y de la esquina superior izquierda del área que vamos a scrollear y con otras dos entradas la altura y anchura de dicha área en caracteres. Esa es la idea inicial, y ejecutando la función desplazaremos todo un carácter a la izquierda, dejando la columna de caracteres de la derecha del todo repetida (es decir, copiaremos su contenido a la izquierda pero no la borraremos). Esto lo vamos a hacer así para poder usar posteriormente un buffer con el que ir copiando a dicha columna nuevo contenido, que es la segunda parte del asunto.

Pero vayamos al grano:

$this->bbcode_second_pass_code('', '
void scroll_izquierda (unsigned int x, unsigned int y, unsigned int ancho, unsigned int alto)
{
}
')

Este va a ser nuestro esqueleto para la función, el siguiente paso (que veremos mañana) será recoger todos los datos para su uso.
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Scroll en baja resolución

Mensajepor na_th_an » Jue, 12 Dic 2013, 08:23

Tengo rutinas mierder que hacen casi eso que dices pero circularmente, volviendo a meter el caracter que sale por el otro lado.

Lo malo de escrollear directamente lo que hay en pantalla es que los sprites también se mueven, a menos que los borres antes, con el siguiente parpadeo.

Estas son. Las hice hace siglos, así que tienen que ser realmente muy mierders :lol:

$this->bbcode_second_pass_code('', ' .escrolleft

;; calculamos hl

ld a, (_asm_int) ; nos traemos el numero de linea
ld l,a ; lo guardamos para no tener que pillarlo otra vez
add a, $40 ;
and $58 ; nos quedamos con el tercio + $40
ld h, a

ld a, l ; recuperamos el numero de linea
and 7 ; linea dentro del tercio: linea MOD 8
rrca
rrca
rrca ; rotamos pa la derecha del byte
ld l, a

;;

ld a, 8 ; ocho lineas...
.buclebmp1
push af

ld d,h
ld e,l
push bc
push hl
ld a,(hl)
inc hl
ld bc, 31
ldir
dec hl
ld (hl),a
pop hl
pop bc

pop af
inc h
dec a
jr nz, buclebmp1

ret

.escrolright

;; calculamos hl

ld a, (_asm_int) ; nos traemos el numero de linea
ld l,a ; lo guardamos para no tener que pillarlo otra vez
add a, $40 ;
and $58 ; nos quedamos con el tercio + $40
ld h, a

ld a, l ; recuperamos el numero de linea
and 7 ; linea dentro del tercio: linea MOD 8
rrca
rrca
rrca ; rotamos pa la derecha del byte
or 31 ; columna 31
ld l, a

;;

ld a, 8 ; ocho lineas...
.buclebmp2
push af

ld a,l
ld l,a
ld d,h
ld e,l
push bc
push hl
ld a,(hl)
dec hl
ld bc,31
lddr
inc hl
ld (hl),a
pop hl
pop bc

pop af
inc h
dec a
jr nz, buclebmp2

ret
')

Cada rutina rota una linea de la pantalla (la que esté en asm_int) un carácter. Hay un montón de cálculos de direcciones al principio que lo suyo sería cargarse e integrar todo en una única rutina ASM que incrementase las coordenadas, pero en un principio estaba pensada para usarla desde BASIC.
Como diría Rorshach: "Urm..."
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Scroll en baja resolución

Mensajepor radastan » Jue, 12 Dic 2013, 23:53

A ver si he aprendido de una vez, para recoger los datos y tenerlos en ASM hago:

$this->bbcode_second_pass_code('', '
ld hl,2 ;pasamos la variable de entrada al acumulador
add hl,sp
ld b, 0
ld c, (hl)
push bc ; la altura la metemos en la pila
inc hl
inc hl
ld c, (hl) ; BC = ancho
dec c ; decrementamos en uno el ancho, ya que la columna de la derecha no se moverá
inc hl
inc hl
ld d, (hl)
inc hl
inc hl
ld e, (hl)
')

Si la función es:

$this->bbcode_second_pass_code('', '
void scroll_izquierda (unsigned int x, unsigned int y, unsigned int ancho, unsigned int alto)')

Debería quedarme:

alto -> en la pila
ancho -> en BC
Y -> en D
X -> en E

¿Es correcto?
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Scroll en baja resolución

Mensajepor radastan » Dom, 15 Dic 2013, 00:50

Bueno, tras unas pruebas esta es la rutina completamente funcional (no he optimizado, lo mismo cabe alguna mejora):

$this->bbcode_second_pass_code('', '
void scroll_izquierda (unsigned int x, unsigned int y, unsigned int ancho, unsigned int alto)
{
#asm
ld hl,2 ;pasamos la variable de entrada al acumulador
add hl,sp
ld b, 0
ld c, (hl)
push bc ; la altura la metemos en la pila
inc hl
inc hl
ld c, (hl) ; BC = ancho
dec c ; decrementamos en uno el ancho, ya que la columna de la derecha no se moverá
inc hl
inc hl
ld d, (hl)
inc hl
inc hl
ld e, (hl)
; FIN DE LA RECOGIDA DE LOS DATOS DE ENTRADA
ld a, d ; recuperamos el valor vertical
and 7 ; nos quedamos con la posición en el tercio
rrca
rrca
rrca ; rotamos para dejar su valor en múltiplos de 32 (linea)
and 224 ; borramos el resto de bits por si las moscas
or e ; sumamos el valor horizontal
ld e, a ; e preparado
ld a, d
and 24 ; modificamos según el tercio de pantalla
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
; FIN DEL CÁLCULO DE LA DIRECCIÓN DE PANTALLA
ld l, e ; introducimos en HL el valor de DE+1
inc l
ld h,d
.otra
push de ; guardamos la posición de la línea a mover
push de ; guardamos la posición de la línea a mover
ld a,8
.scroll
push bc ; guardamos los bytes a mover
ldir ; scroll de una línea de pixels
pop bc ; recuperamos los bytes a mover
pop de
inc d
push de
ld l, e ; introducimos en HL el valor de DE+1
inc l
ld h,d
dec a
jr nz, scroll ; iteramos las 8 líneas
; INICIO DEL SCROLL DE LOS ATRIBUTOS
pop de
pop de ; recuperamos el valor horizontal
push de
ld a,d ; calculamos el valor de posición en la pantalla
rra
rra
rra ; multiplicamos por 32
and 3 ; nos quedamos con los tres bits bajos
or 88 ; apuntamos al comienzo del mapa de atributos
ld d,a ; ya tenemos d listo, e no hay que cambiarlo
ld l, e ; introducimos en HL el valor de DE+1
inc l
ld h,d
push bc ; guardamos los bytes a mover
ldir ; scroll de una línea de pixels
pop bc ; recuperamos los bytes a mover
; FIN DEL SCROLL DE LOS ATRIBUTOS
pop de ; recuperamos la línea a mover
pop hl ; recuperamos la altura
dec l
jr nz, seguir ; iteramos hasta terminar el scroll de toda el área
ret ; FIN DE LA RUTINA
.seguir
push hl ; volvemos a guardar la altura
ld a,e ; incrementamos una línea de caracteres (+32 bytes)
add a,32
ld e,a ; aquí finaliza la suma de 32 a E
jr nc, saltox
ld a,d
add a,8
ld d,a
.saltox ; aquí finaliza la suma de 32 a D
ld l, e ; introducimos en HL el valor de DE+1
inc l
ld h,d
jr otra
#endasm
}
')
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Scroll en baja resolución

Mensajepor radastan » Dom, 15 Dic 2013, 01:07

Para los que queréis ver como queda aquí os dejo un ejemplo. Estoy usando las tres columnas de la derecha como buffer de impresión, así que ignorar los errores que aparecen en ellas, en un juego normal el buffer sería externo a la pantalla.

Está a tope de velocidad y a toda pantalla, lo más burro posible.

Como se puede apreciar apenas hay artefactos, gracias a que cada línea desplazada lo hace con atributos (no desplazo primero los pixels de toda el área y luego los atributos).

El resultado es cojonudísimo, si centro el scroll arriba y abajo sería perfectamente posible un matamarcianos a todo color a lo R-Type teniéndome sólo que preocupar de la nave protagonista antes de hacer el scroll (borrarla y luego pnerla nuevamente), ya que los enemigos van por medio. Incluso ni eso, si hago que la parte de arriba y abajo no sean navegables.

A partir de esta rutina voy a elaborar la que hace el scroll a la derecha, y luego vendrán las verticales.
Adjuntos
juego.tap
(1.95 KiB) Descargado 173 veces
Gocho
Mensajes: 123
Registrado: Mar, 19 Nov 2013, 10:32

Re: Scroll en baja resolución

Mensajepor Gocho » Dom, 15 Dic 2013, 10:24

Joer, demasiado rápido a mi me matan a esa velocidad XD

Buen trabajo
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Scroll en baja resolución

Mensajepor radastan » Dom, 15 Dic 2013, 10:43

Si lo mejor de todo es que la "biblioteca" (es más un conjunto de rutinas) va a permitir juegos de todo tipo, es decir habrá total libertad para hacer un juego del género que más te guste. Hasta voy a currarme rutinas de colisiones, par facilitar al máximo hacer un juego.

El objetivo es que programar en Z88DK sea más fácil que en BASIC, ya veréis.
Avatar de Usuario
D_Skywalk
Mensajes: 352
Registrado: Mar, 01 Oct 2013, 13:36

Re: Scroll en baja resolución

Mensajepor D_Skywalk » Dom, 15 Dic 2013, 13:50

ESE SCROLLL! TO MOLON!

:ymca:
:adore: :adore: :adore:
David Skywalker
Weblog: http://david.dantoine.org

Volver a “General”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 4 invitados