Pintando sprites de 16x16 en ensamblador

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

antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Pintando sprites de 16x16 en ensamblador

Mensajepor antoniovillena » Vie, 06 Dic 2013, 18:50

Pues sí, he dicho lo mismo que propuso na_th_an, no me había dado cuenta. Yo también tengo por ahí una rutinilla rápida, es para tiles pero te valdría también. Pero vamos, que la mejor rutina es la que se te ocurra a tí.
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Pintando sprites de 16x16 en ensamblador

Mensajepor radastan » Vie, 06 Dic 2013, 19:18

Hombre, evidentemente preferiría hacer la rutina yo para entenderla mejor. Si ya veo que me apuro de tiempo te pido ayuda directamente, pero creo que no hay prisa en sacar el tutorial. Lo estoy haciendo en tiempos muertos, cuando me canso de los otros proyectos.

Otra cosa son las rutinas pixel a pixel, que ahí ya directamente veremos lo que hago porque el tutorial va a ser con sprites caracter a caracter por narices (por sencillez). Lo mismo le dedico un anexo o algo, no se.
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Pintando sprites de 16x16 en ensamblador

Mensajepor antoniovillena » Vie, 06 Dic 2013, 22:15

Me acabo de encontrar esta perla por internet. Aquí te lo explican todo sobre los sprites, incluso cómo calcular la dirección mediante una tabla.

http://www.bobs-stuff.co.uk/sprites.rtf
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Pintando sprites de 16x16 en ensamblador

Mensajepor radastan » Vie, 06 Dic 2013, 23:15

Vale, ya está más optimizado:

$this->bbcode_second_pass_code('', '
void put_sprite_x16 (unsigned char *posicion, unsigned int x, unsigned int y)
{
// -------------------------------------------
// RUTINA DE IMPRESION DE UN SPRITE 16x16 PIXELS
// CON ATRIBUTOS EN CUALQUIER POSICION DE CARACTER
// ENTRADAS:
// D será la posición del cursor vertical en caracteres
// E será la posición del cursor horizontal en caracteres
// 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)
inc hl
inc hl
ld e, (hl)
inc hl
inc hl
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
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
push de ; guardamos DE (la posición de pantalla)
push de
ld b, 8
call draw
pop de ; recuperamos DE
ld a,e ; incrementamos una línea de caracteres (+32 bytes)
add 32
ld e,a
ld a,d
adc 0 ; aquí finaliza la suma de 32 a DE
ld d,a
ld b, 8
call draw
; Ahora imprimimos los atributos
pop de ; recuperamos el valor horizontal
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
push de ; guardamos la posición en pantalla
call colr ; imprimimos los colores de arriba
pop de ; recuperamos la posición de pantalla
ld a,e ; incrementamos una línea de caracteres (+32 bytes)
add 32
ld e,a
ld a,d
adc 0 ; aquí finaliza la suma de 32 a DE
call colr ; ponemos los colores de abajo
ret

.draw
ld a, (hl) ; HL indica la posición del sprite en memoria
ld (de),a ; de indica la posición de pantalla
inc hl
inc e
ld a,(hl) ; esta parte imprime el segundo byte
ld (de),a
inc hl
dec e
inc d
djnz draw ; decrementa B y si es cero deja de saltar a draw
ret

.colr
ld a,(hl)
ld (de),a
inc e
inc hl
ld a,(hl)
ld (de),a
dec e
inc hl
ret

#endasm
}
')

He echo que sólo se calcule una vez la posición en pantalla en los dos submapas de pantalla, cambiando el recálculo por sumar 32 (que es lo lógico) para calcular la siguiente línea. De paso he recolocado las dos subrutinas de cálculo directamente a su sitio (para evitar saltos).

¿Algún consejo más que no suponga uso de tablas?

Ya se que con una tabla iría aún más rápido, pero quiero evitar complicaciones innecesarias de momento en el código.
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Pintando sprites de 16x16 en ensamblador

Mensajepor radastan » Vie, 06 Dic 2013, 23:19

$this->bbcode_second_pass_quote('antoniovillena', 'M')e acabo de encontrar esta perla por internet. Aquí te lo explican todo sobre los sprites, incluso cómo calcular la dirección mediante una tabla.

http://www.bobs-stuff.co.uk/sprites.rtf


:lol:

Lo he visto, pero me parece lioso. Como lo estamos haciendo en este hilo es lo correcto, poco a poco y comprendiendo el porqué de cada optimización.

Se que usando una tabla de 48 bytes optimizo algo más, pero prefiero dejarlo para el final y sólo si veo que realmente marca una gran diferencia.

Por cierto, he modificado el fichero que subí, para que puedas volver a medirlo.