Rutina para dibujar un Sprite en pantalla.

Programando el Amstrad en Ensamblador.
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
Avatar de Usuario
Mode 2
I am The Forum
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.

Mensajepor Mode 2 » Jue 31 Ene , 2013 2:32 pm

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.

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor Artaburu » Vie 01 Feb , 2013 8:28 pm

Ya me han despejado las dudas. Gracias.
Vaya, también llego tarde pero te puedo dar mi opinión.
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

pacomix
Forum Addict
Forum Addict
Mensajes: 460
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor pacomix » Lun 25 Mar , 2013 11:43 pm

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?

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;
}

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8419
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor Artaburu » Mar 26 Mar , 2013 2:50 pm

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.
Salu2,
Arta

pacomix
Forum Addict
Forum Addict
Mensajes: 460
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor pacomix » Mar 26 Mar , 2013 3:49 pm

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!

pacomix
Forum Addict
Forum Addict
Mensajes: 460
Registrado: Dom 11 Nov , 2012 8:05 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor pacomix » Mié 27 Mar , 2013 11:14 pm

¡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:

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;
}
Si alguien sabe si habría alguna forma más rápida de hacer esto ya sabe :p

ctap77
Lechoncillo
Lechoncillo
Mensajes: 17
Registrado: Lun 16 Ene , 2006 8:05 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor ctap77 » Vie 10 May , 2013 6:08 pm

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.

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

ctap77
Lechoncillo
Lechoncillo
Mensajes: 17
Registrado: Lun 16 Ene , 2006 8:05 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor ctap77 » Vie 10 May , 2013 11:36 pm

Vaya, me he dado cuenta que la rutina que colgué no tiene desplazamiento en el eje X.
A ver como la termino...

Avatar de Usuario
jgnavarro
Megaforero
Megaforero
Mensajes: 296
Registrado: Mar 24 Mar , 2009 12:27 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor jgnavarro » Vie 10 May , 2013 11:43 pm

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

ctap77
Lechoncillo
Lechoncillo
Mensajes: 17
Registrado: Lun 16 Ene , 2006 8:05 pm

Re: Rutina para dibujar un Sprite en pantalla.

Mensajepor ctap77 » Sab 11 May , 2013 1:12 am

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
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic