Rutina para dibujar un Sprite en pantalla.
Reglas del Foro
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.
De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.
De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
- Mode 2
- I am The Forum
- Mensajes: 2068
- Registrado: Lun 10 Oct , 2005 8:01 pm
- Ubicación: Sevilla, años 80.
- Contactar:
Re: Rutina para dibujar un Sprite en pantalla.
Ya me han despejado las dudas. Gracias.
BUSCO: VideoPac+, Jaguar Saturn, Micromanía 1, Amstrad Semanal, MicroHobby, juegos especialmente CPC y Vectrex, Aquarius, Sam Copé, 520 ST, manual +3, manual CPC664.
Re: Rutina para dibujar un Sprite en pantalla.
Vaya, también llego tarde pero te puedo dar mi opinión.Ya me han despejado las dudas. Gracias.
Yo creo que es la más rápida, de las que conozco. Si tuvieras dimensiones de sprite fijas la podrías acelerar un poco más, pero no mucho.
Lo de los parámetros creo que el basic los mete en pila y se van leyendo, luego el último queda en DE.
Salu2,
Arta
Arta
Re: Rutina para dibujar un Sprite en pantalla.
Reflotando... jejeje
Esto es válido cuando se escribe de C000 para arriba pero... ¿habría alguna forma equivalente para escribir de 8000 para arriba?
Llevo un buen rato dándole vueltas y no encuentro una solución. De momento lo que tenía era una adaptación de una rutina que pintaba en C000 que pillé (creo que de Artaburu) con push and pops que pintaba. Esto pinta en 8000. Pero es evidente que la rutina aquí expuesta es más rápida.
El problema es el calcular el salto de carácter correctamente.
Esto es lo que tengo para 8000. ¿Se podría hacer más rápido?
Esto es válido cuando se escribe de C000 para arriba pero... ¿habría alguna forma equivalente para escribir de 8000 para arriba?
Llevo un buen rato dándole vueltas y no encuentro una solución. De momento lo que tenía era una adaptación de una rutina que pintaba en C000 que pillé (creo que de Artaburu) con push and pops que pintaba. Esto pinta en 8000. Pero es evidente que la rutina aquí expuesta es más rápida.
El problema es el calcular el salto de carácter correctamente.
Esto es lo que tengo para 8000. ¿Se podría hacer más rápido?
Código: Seleccionar todo
void PutSprite4x16Mode0Mid(U8* pAddress, U8* pSprite)
{
__asm
LD L, 4(IX)
LD H, 5(IX)
LD E, 6(IX)
LD D, 7(IX)
LD B, #0x10 // Alto
_loop_alto_4x16_mid:
PUSH BC
PUSH HL
EX DE, HL
LDI
LDI
LDI
LDI
EX DE, HL
POP HL
LD A,H
ADD #0x08
LD H,A
SUB #0xC0
JP C, _sig_linea_4x16_mid
LD BC, #0xC040
ADD HL,BC
_sig_linea_4x16_mid:
POP BC
DJNZ _loop_alto_4x16_mid
__endasm;
}
Re: Rutina para dibujar un Sprite en pantalla.
Pues no debería ser nada complicado modificar la que usa un montón de LDIs para que trabaje en &8000.
Y esta otra que cuelgas es mejorable sobre todo viendo que el alto es fijo. Por el foro tiene que haber otras opciones, por ejemplo usando los registros de IXH, IXL.
Intento buscar algo esta noche desde casa.
Y esta otra que cuelgas es mejorable sobre todo viendo que el alto es fijo. Por el foro tiene que haber otras opciones, por ejemplo usando los registros de IXH, IXL.
Intento buscar algo esta noche desde casa.
Salu2,
Arta
Arta
Re: Rutina para dibujar un Sprite en pantalla.
Finalmente lo que he hecho para la de 0x8000 de momento es coger la que tiene un huevo de LDIs y hardcodearlos para un alto fijo (16 en este caso) y meterle el salto de carácter a mano entre medio a mano ya que los gráficos que pinto están alineados a carácter.
El problema lo tenía en el salto de carácter pues no encontraba un valor adecuado que se sumase y me dejase en hl la siguiente dirección. Con lo que hay puesto en la rutina se hace bien para 0x8000 pero no se produce el salto de carácter.
A ver si lo investigo un poco más hoy que anoche estaba muy cansado.
Saludos!
El problema lo tenía en el salto de carácter pues no encontraba un valor adecuado que se sumase y me dejase en hl la siguiente dirección. Con lo que hay puesto en la rutina se hace bien para 0x8000 pero no se produce el salto de carácter.
A ver si lo investigo un poco más hoy que anoche estaba muy cansado.
Saludos!
Re: Rutina para dibujar un Sprite en pantalla.
¡Bueñas!
Pues después de comerme un poco la cabeza y dar con la solución creo que más rápida, finalmente me he decantado por la opción de hacerla unrolled ya que la misma rutina serviría para pintar en 0x8000 y en 0xC000 sin absolutamente ninguna modificación. Eso sí, la versión unrolled requiere por huevos que tu sprite (en este caso la uso para los tiles) esté alineado a carácter. Así que también me viene ideal para usarla con un par de modificaciones para pintar texto.
La diferencia respecto a tener (y mantener) dos rutinas diferentes, una para que pinte en 0x8000 y la otra para 0xC000, y la rutina sin loops (joder perdonad pero es que no se el vocablo en ejpañolo y desenrollado suena un poco chungo) es de unos 30 bytes con la cosa de que encima pinta un pelín más rápida al no usar saltos condicionales.
De todas formas dejo por aquí la versión que hice para tamaño fijo que pinta en 0x8000. Para agregarle más ancho tan solo sería necesario ponerle más ldi's y el alto va en el registro A:
Si alguien sabe si habría alguna forma más rápida de hacer esto ya sabe :p
Pues después de comerme un poco la cabeza y dar con la solución creo que más rápida, finalmente me he decantado por la opción de hacerla unrolled ya que la misma rutina serviría para pintar en 0x8000 y en 0xC000 sin absolutamente ninguna modificación. Eso sí, la versión unrolled requiere por huevos que tu sprite (en este caso la uso para los tiles) esté alineado a carácter. Así que también me viene ideal para usarla con un par de modificaciones para pintar texto.
La diferencia respecto a tener (y mantener) dos rutinas diferentes, una para que pinte en 0x8000 y la otra para 0xC000, y la rutina sin loops (joder perdonad pero es que no se el vocablo en ejpañolo y desenrollado suena un poco chungo) es de unos 30 bytes con la cosa de que encima pinta un pelín más rápida al no usar saltos condicionales.
De todas formas dejo por aquí la versión que hice para tamaño fijo que pinta en 0x8000. Para agregarle más ancho tan solo sería necesario ponerle más ldi's y el alto va en el registro A:
Código: Seleccionar todo
#define TILE_HEIGHT_PIXELS 16
#define TILE_WIDTH_BYTES 4
void drawTile4x16Mid(U8* pAddress, U8* pSprite)
{
__asm
LD L, 4(IX) ; HL = pSprite
LD H, 5(IX)
LD E, 6(IX) ; DE = pAddress
LD D, 7(IX)
ld a, #TILE_HEIGHT_PIXELS ; Height
jp drawTile4x16MidWidth
drawTile4x16MidReloc: ; Adjust the correct destination after line jump detection
ld bc, #0xC000
add hl, bc
drawTile4x16MidWidth: ; Copy 4 bytes to the destiny. 8 pixels = Mode0
ex de,hl
ldi
ldi
ldi
ldi
; Finish if we have already finished drawing the height
dec a
jp z, drawTile4x16MidEnd
; Check if the next line is in the same screen character
ld bc, #0x0800-#TILE_WIDTH_BYTES+#0x4000 ; Screen line byte width - tile width in bytes + 1 ram page (16kb) to see if it is higher than 0xFFFF
ex de, hl
add hl, bc
jp nc, drawTile4x16MidReloc ; If the next line is in the same character there is no carry (result of hl+bc is < 0x0000)
; If it is not in the same character calculate the jump to the start of the next screen character
ld bc, #0xC040-#0x4000
add hl, bc
jp drawTile4x16MidWidth
drawTile4x16MidEnd:
__endasm;
}
Re: Rutina para dibujar un Sprite en pantalla.
Muchas rutinas se han visto ya, pero por falta que no sea, a ver si alguien me puede
decir cuan rápida o lenta es esta.
Un saludo.
decir cuan rápida o lenta es esta.
Un saludo.
Código: Seleccionar todo
org &8000
; HL = SPRITE
; DE = LINEA DE PANTALLA DONDE PINTA (0-199) CERO ES &C000
; BC = AlTO Y ANCHO DEL SPRITE
LD HL,&4000
LD DE,0
LD BC,&C850
ADD DE,DE
LD A,C
LD (TRE2-1),A
LD IX,LINES
ADD IX,DE
TRE1:LD D,(IX)
INC IX
LD E,(IX)
INC IX
PUSH BC
LD B,80
TRE2:
LDI
DJNZ TRE2
POP BC
DJNZ TRE1
RET
LINES:
DB &C0,&00
DB &C8,&00
DB &D0,&00
DB &D8,&00
DB &E0,&00
DB &E8,&00
DB &F0,&00
DB &F8,&00
DB &C0,&50
DB &C8,&50
DB &D0,&50
DB &D8,&50
DB &E0,&50
DB &E8,&50
DB &F0,&50
DB &F8,&50
DB &C0,&A0
DB &C8,&A0
DB &D0,&A0
DB &D8,&A0
DB &E0,&A0
DB &E8,&A0
DB &F0,&A0
DB &F8,&A0
DB &C0,&F0
DB &C8,&F0
DB &D0,&F0
DB &D8,&F0
DB &E0,&F0
DB &E8,&F0
DB &F0,&F0
DB &F8,&F0
DB &C1,&40
DB &C9,&40
DB &D1,&40
DB &D9,&40
DB &E1,&40
DB &E9,&40
DB &F1,&40
DB &F9,&40
DB &C1,&90
DB &C9,&90
DB &D1,&90
DB &D9,&90
DB &E1,&90
DB &E9,&90
DB &F1,&90
DB &F9,&90
DB &C1,&E0
DB &C9,&E0
DB &D1,&E0
DB &D9,&E0
DB &E1,&E0
DB &E9,&E0
DB &F1,&E0
DB &F9,&E0
DB &C2,&30
DB &CA,&30
DB &D2,&30
DB &DA,&30
DB &E2,&30
DB &EA,&30
DB &F2,&30
DB &FA,&30
DB &C2,&80
DB &CA,&80
DB &D2,&80
DB &DA,&80
DB &E2,&80
DB &EA,&80
DB &F2,&80
DB &FA,&80
DB &C2,&D0
DB &CA,&D0
DB &D2,&D0
DB &DA,&D0
DB &E2,&D0
DB &EA,&D0
DB &F2,&D0
DB &FA,&D0
DB &C3,&20
DB &CB,&20
DB &D3,&20
DB &DB,&20
DB &E3,&20
DB &EB,&20
DB &F3,&20
DB &FB,&20
DB &C3,&70
DB &CB,&70
DB &D3,&70
DB &DB,&70
DB &E3,&70
DB &EB,&70
DB &F3,&70
DB &FB,&70
DB &C3,&C0
DB &CB,&C0
DB &D3,&C0
DB &DB,&C0
DB &E3,&C0
DB &EB,&C0
DB &F3,&C0
DB &FB,&C0
DB &C4,&10
DB &CC,&10
DB &D4,&10
DB &DC,&10
DB &E4,&10
DB &EC,&10
DB &F4,&10
DB &FC,&10
DB &C4,&60
DB &CC,&60
DB &D4,&60
DB &DC,&60
DB &E4,&60
DB &EC,&60
DB &F4,&60
DB &FC,&60
DB &C4,&B0
DB &CC,&B0
DB &D4,&B0
DB &DC,&B0
DB &E4,&B0
DB &EC,&B0
DB &F4,&B0
DB &FC,&B0
DB &C5,&00
DB &CD,&00
DB &D5,&00
DB &DD,&00
DB &E5,&00
DB &ED,&00
DB &F5,&00
DB &FD,&00
DB &C5,&50
DB &CD,&50
DB &D5,&50
DB &DD,&50
DB &E5,&50
DB &ED,&50
DB &F5,&50
DB &FD,&50
DB &C5,&A0
DB &CD,&A0
DB &D5,&A0
DB &DD,&A0
DB &E5,&A0
DB &ED,&A0
DB &F5,&A0
DB &FD,&A0
DB &C5,&F0
DB &CD,&F0
DB &D5,&F0
DB &DD,&F0
DB &E5,&F0
DB &ED,&F0
DB &F5,&F0
DB &FD,&F0
DB &C6,&40
DB &CE,&40
DB &D6,&40
DB &DE,&40
DB &E6,&40
DB &EE,&40
DB &F6,&40
DB &FE,&40
DB &C6,&90
DB &CE,&90
DB &D6,&90
DB &DE,&90
DB &E6,&90
DB &EE,&90
DB &F6,&90
DB &FE,&90
DB &C6,&E0
DB &CE,&E0
DB &D6,&E0
DB &DE,&E0
DB &E6,&E0
DB &EE,&E0
DB &F6,&E0
DB &FE,&E0
DB &C7,&30
DB &CF,&30
DB &D7,&30
DB &DF,&30
DB &E7,&30
DB &EF,&30
DB &F7,&30
DB &FF,&30
DB &C7,&80
DB &CF,&80
DB &D7,&80
DB &DF,&80
DB &E7,&80
DB &EF,&80
DB &F7,&80
DB &FF,&80
DB &C7,&D0
DB &CF,&D0
DB &D7,&D0
DB &DF,&D0
DB &E7,&D0
DB &EF,&D0
DB &F7,&D0
DB &FF,&D0
Re: Rutina para dibujar un Sprite en pantalla.
Vaya, me he dado cuenta que la rutina que colgué no tiene desplazamiento en el eje X.
A ver como la termino...
A ver como la termino...
Re: Rutina para dibujar un Sprite en pantalla.
Muy fácil. Suma la x a lo que obtienes en la tabla, aunque dependerá del modo debes dividir primero.
--
Salu2 (-:) JAVIER
Who'd need windows in a world without gates?
¿Quien necesita ventanas en un mundo sin puertas?
Visita www.4mhz.es
Salu2 (-:) JAVIER
Who'd need windows in a world without gates?
¿Quien necesita ventanas en un mundo sin puertas?
Visita www.4mhz.es
Re: Rutina para dibujar un Sprite en pantalla.
Con el desplazamiento en X debe haber perdido velocidad...
Código: Seleccionar todo
org &8000
; HL = SPRITE
; BC = ALTO Y ANCHO DEL SPRITE
; DE = LINEA DE PANTALLA DONDE PINTA (0-199) CERO ES &C000
; A = DESPLAZAMIENTO X (0-79) BYTES DE PANTALLA
LD HL,SPRITE
LD BC,&1406
LD DE,100
LD A,40
LD (OFFX+1),A
EX DE,HL
ADD HL,HL
EX DE,HL
LD A,C
LD (ANCH+1),A
LD IX,LINES
ADD IX,DE
TRE1: LD D,(IX)
INC IX
LD E,(IX)
INC IX
PUSH BC
OFFX: LD BC,&0000
EX DE,HL
ADD HL,BC
EX DE,HL
ANCH: LD BC,&0000
LDIR
POP BC
DJNZ TRE1
RET
SPRITE
db &00,&00,&F0,&F0,&00,&00
db &00,&50,&DA,&CF,&F0,&00
db &00,&E5,&B0,&F0,&B0,&A0
db &50,&F0,&B0,&E5,&B0,&A0
db &50,&DA,&DA,&CF,&DA,&00
db &50,&CF,&CF,&F0,&DA,&00
db &00,&E5,&CF,&CF,&DA,&00
db &00,&E5,&DA,&F0,&DA,&00
db &00,&F0,&CF,&CF,&A0,&00
db &50,&CC,&F0,&F0,&A0,&00
db &E4,&E4,&F0,&CC,&F0,&00
db &E4,&F0,&CF,&E4,&D8,&8A
db &E4,&D8,&CF,&E4,&D8,&8A
db &F0,&CC,&F0,&D8,&D2,&A0
db &50,&B4,&3C,&3D,&2A,&00
db &00,&F0,&F0,&F0,&A0,&00
db &50,&30,&A0,&B0,&20,&00
db &41,&C3,&D2,&41,&C3,&82
db &50,&E1,&C3,&E1,&D2,&A0
db &00,&50,&F0,&F0,&A0,&00
LINES:
DB &C0,&00
DB &C8,&00
DB &D0,&00
DB &D8,&00
DB &E0,&00
DB &E8,&00
DB &F0,&00
DB &F8,&00
DB &C0,&50
DB &C8,&50
DB &D0,&50
DB &D8,&50
DB &E0,&50
DB &E8,&50
DB &F0,&50
DB &F8,&50
DB &C0,&A0
DB &C8,&A0
DB &D0,&A0
DB &D8,&A0
DB &E0,&A0
DB &E8,&A0
DB &F0,&A0
DB &F8,&A0
DB &C0,&F0
DB &C8,&F0
DB &D0,&F0
DB &D8,&F0
DB &E0,&F0
DB &E8,&F0
DB &F0,&F0
DB &F8,&F0
DB &C1,&40
DB &C9,&40
DB &D1,&40
DB &D9,&40
DB &E1,&40
DB &E9,&40
DB &F1,&40
DB &F9,&40
DB &C1,&90
DB &C9,&90
DB &D1,&90
DB &D9,&90
DB &E1,&90
DB &E9,&90
DB &F1,&90
DB &F9,&90
DB &C1,&E0
DB &C9,&E0
DB &D1,&E0
DB &D9,&E0
DB &E1,&E0
DB &E9,&E0
DB &F1,&E0
DB &F9,&E0
DB &C2,&30
DB &CA,&30
DB &D2,&30
DB &DA,&30
DB &E2,&30
DB &EA,&30
DB &F2,&30
DB &FA,&30
DB &C2,&80
DB &CA,&80
DB &D2,&80
DB &DA,&80
DB &E2,&80
DB &EA,&80
DB &F2,&80
DB &FA,&80
DB &C2,&D0
DB &CA,&D0
DB &D2,&D0
DB &DA,&D0
DB &E2,&D0
DB &EA,&D0
DB &F2,&D0
DB &FA,&D0
DB &C3,&20
DB &CB,&20
DB &D3,&20
DB &DB,&20
DB &E3,&20
DB &EB,&20
DB &F3,&20
DB &FB,&20
DB &C3,&70
DB &CB,&70
DB &D3,&70
DB &DB,&70
DB &E3,&70
DB &EB,&70
DB &F3,&70
DB &FB,&70
DB &C3,&C0
DB &CB,&C0
DB &D3,&C0
DB &DB,&C0
DB &E3,&C0
DB &EB,&C0
DB &F3,&C0
DB &FB,&C0
DB &C4,&10
DB &CC,&10
DB &D4,&10
DB &DC,&10
DB &E4,&10
DB &EC,&10
DB &F4,&10
DB &FC,&10
DB &C4,&60
DB &CC,&60
DB &D4,&60
DB &DC,&60
DB &E4,&60
DB &EC,&60
DB &F4,&60
DB &FC,&60
DB &C4,&B0
DB &CC,&B0
DB &D4,&B0
DB &DC,&B0
DB &E4,&B0
DB &EC,&B0
DB &F4,&B0
DB &FC,&B0
DB &C5,&00
DB &CD,&00
DB &D5,&00
DB &DD,&00
DB &E5,&00
DB &ED,&00
DB &F5,&00
DB &FD,&00
DB &C5,&50
DB &CD,&50
DB &D5,&50
DB &DD,&50
DB &E5,&50
DB &ED,&50
DB &F5,&50
DB &FD,&50
DB &C5,&A0
DB &CD,&A0
DB &D5,&A0
DB &DD,&A0
DB &E5,&A0
DB &ED,&A0
DB &F5,&A0
DB &FD,&A0
DB &C5,&F0
DB &CD,&F0
DB &D5,&F0
DB &DD,&F0
DB &E5,&F0
DB &ED,&F0
DB &F5,&F0
DB &FD,&F0
DB &C6,&40
DB &CE,&40
DB &D6,&40
DB &DE,&40
DB &E6,&40
DB &EE,&40
DB &F6,&40
DB &FE,&40
DB &C6,&90
DB &CE,&90
DB &D6,&90
DB &DE,&90
DB &E6,&90
DB &EE,&90
DB &F6,&90
DB &FE,&90
DB &C6,&E0
DB &CE,&E0
DB &D6,&E0
DB &DE,&E0
DB &E6,&E0
DB &EE,&E0
DB &F6,&E0
DB &FE,&E0
DB &C7,&30
DB &CF,&30
DB &D7,&30
DB &DF,&30
DB &E7,&30
DB &EF,&30
DB &F7,&30
DB &FF,&30
DB &C7,&80
DB &CF,&80
DB &D7,&80
DB &DF,&80
DB &E7,&80
DB &EF,&80
DB &F7,&80
DB &FF,&80
DB &C7,&D0
DB &CF,&D0
DB &D7,&D0
DB &DF,&D0
DB &E7,&D0
DB &EF,&D0
DB &F7,&D0
DB &FF,&D0
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro
La Comunidad Española |