; Sprite 16x16 con mascara ORG 35000 call ClearScreen_Pattern ; Establecemos los parametros de entrada a la rutina ; Los 2 primeros se pueden establecer una unica vez ld hl, bicho_gfx ld (DS_SPRITES), hl ld hl, bicho_attrib ld (DS_ATTRIBS), hl ld a, 15 ld (DS_COORD_X), a ld a, 8 ld (DS_COORD_Y), a ld a, 0 ld (DS_NUMSPR), a call DrawSprite_16x16_MASK loop: jr loop ret ; Variables que usaremos como parĂ¡metros DS_SPRITES DEFW 0 DS_ATTRIBS DEFW 0 DS_COORD_X DEFB 0 DS_COORD_Y DEFB 0 DS_NUMSPR DEFB 0 ;----------------------------------------------------------------------- ;ASM source file created by SevenuP v1.20 ;SevenuP (C) Copyright 2002-2006 by Jaime Tejedor Gomez, aka Metalbrain ;GRAPHIC DATA: ;Pixel Size: ( 16, 64) ;Char Size: ( 2, 8) ;Sort Priorities: Mask, X char, Char line, Y char ;Data Outputted: Gfx+Attr ;Mask: Yes, before graphic ;----------------------------------------------------------------------- bicho_gfx: DEFB 247, 8,127,128,251, 4,191, 64, 255, 0,255, 0,248, 7, 31,224 DEFB 240, 15, 15, 80,240, 15, 15, 80, 240, 15, 15,240,248, 7, 31,224 DEFB 255, 0,255, 0,254, 1,191, 64, 255, 0,223, 32,253, 2,255, 0 DEFB 151,104,233, 22,143,112,241, 14, 199, 56,227, 28,255, 0,255, 0 DEFB 251, 4,191, 64,255, 0,255, 0, 248, 7, 31,224,240, 15, 15, 80 DEFB 240, 15, 15, 80,240, 15, 15,240, 248, 7, 31,224,255, 0,255, 0 DEFB 255, 0,255, 0,254, 1,191, 64, 255, 0,255, 0,253, 2,223, 32 DEFB 247, 8,255, 0,241, 14,143,112, 248, 7,135,120,255, 0,255, 0 DEFB 253, 2,223, 32,255, 0,255, 0, 252, 3, 15,240,248, 7, 7,168 DEFB 248, 7, 7,168,248, 7, 7,248, 252, 3, 15,240,255, 0,255, 0 DEFB 255, 0,255, 0,254, 1,191, 64, 255, 0,255, 0,254, 1,191, 64 DEFB 255, 0,255, 0,253, 2, 31,224, 250, 5, 15,240,255, 0,255, 0 DEFB 254, 1,239, 16,253, 2,223, 32, 255, 0,255, 0,252, 3, 15,240 DEFB 248, 7, 7,168,248, 7, 7,168, 248, 7, 7,248,252, 3, 15,240 DEFB 255, 0,255, 0,254, 1,191, 64, 255, 0,223, 32,253, 2,255, 0 DEFB 151,104,233, 22,143,112,241, 14, 199, 56,227, 28,255, 0,255, 0 bicho_attrib: DEFB 70, 71, 67, 3, 70, 71, 67, 3, 70, 71, 3, 67, 70, 71, 3, 67 ;;; Version en monocolor de los atributos: ;;;DEFB 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 ;-------------------------------------------------------------------- ; ClearScreen_Pattern ; Limpia la pantalla con patrones de pixeles alternados ;-------------------------------------------------------------------- ClearScreen_Pattern: ld b, 191 ; Numero de lineas a rellenar cs_line_loop: ld c, 0 ld a, b ld b, a call $22b1 ; ROM (Pixel-Address) ld a, b and 1 jr z, cs_es_par ld a, 170 jr cs_pintar cs_es_par: ld a, 85 cs_pintar: ld d, b ; Salvar el contador del bucle ld b, 32 ; Imprimir 32 bytes cs_x_loop: ld (hl), a inc hl djnz cs_x_loop ld b, d ; Recuperamos el contador externo djnz cs_line_loop ; Repetimos 192 veces ret ;------------------------------------------------------------- ; DrawSprite_16x16_MASK: ; Imprime un sprite de 16x16 pixeles + mascara con o sin atributos. ; ; Entrada (paso por parametros en memoria): ; Direccion Parametro ; (DS_SPRITES) Direccion de la tabla de Sprites ; (DS_ATTRIBS) Direccion de la tabla de Atribs (0=no atributos) ; (DS_COORD_X) Coordenada X en baja resolucion ; (DS_COORD_Y) Coordenada Y en baja resolucion ; (DS_NUMSPR) Numero de sprite a dibujar (0-N) ;------------------------------------------------------------- DrawSprite_16x16_MASK: ; Guardamos en BC la pareja (x,y) -> B=COORD_Y y C=COORD_X ld bc, (DS_COORD_X) ;;; Calculamos las coordenadas destino de pantalla en DE: ld a, b and $18 add a, $40 ld d, a ld a, b and 7 rrca rrca rrca add a, c ld e, a push de ; Lo guardamos para luego, lo usaremos para ; calcular la direccion del atributo ;;; Calcular posicion origen (array sprites) en HL como: ;;; direccion = base_sprites + (NUM_SPRITE*64) ld bc, (DS_SPRITES) ld a, (DS_NUMSPR) ld l, 0 ; AL = DS_NUMSPR*256 srl a ; Desplazamos a la derecha para dividir por dos rr l ; AL = DS_NUMSPR*128 rra ; Rotamos, ya que el bit que salio de L al CF fue 0 rr l ; AL = DS_NUMSPR*64 ld h, a ; HL = DS_NUMSPR*64 add hl, bc ; HL = BC + HL = DS_SPRITES + (DS_NUMSPR * 64) ; HL contiene la direccion de inicio en el sprite ex de, hl ; Intercambiamos DE y HL para el OR ;;; Dibujar 8 scanlines (DE) -> (HL) + bajar scanline y avanzar en SPR ld b, 8 drawspr16m_loop1: ld a, (de) ; Obtenemos un byte del sprite (el byte de mascara) and (hl) ; A = A and (hl) ld c, a ; Nos guardamos el valor del AND inc de ; Avanzamos al siguiente byte (el dato grafico) ld a, (de) ; Obtenemos el byte grafico or c ; A = A or c = A OR (MASK and fONDO) ld (hl), a ; Imprimimos el dato tras aplicar operaciones logicas inc de ; Avanzamos al siguiente dato del sprite inc l ; Avanzamos al segundo bloque en pantalla ld a, (de) ; Obtenemos un byte del sprite (el byte de mascara) and (hl) ; A = A and (hl) ld c, a ; Nos guardamos el valor del AND inc de ; Avanzamos al siguiente byte (el dato grafico) ld a, (de) ; Obtenemos el byte grafico or c ; A = A or c = A OR (MASK and fONDO) ld (hl), a ; Imprimimos el dato tras aplicar operaciones logicas inc de ; Avanzamos al siguiente dato del sprite dec l ; Volvemos atras del valor que incrementamos inc h ; Incrementamos puntero en pantalla (siguiente scanline) djnz drawspr16m_loop1 ; Avanzamos HL 1 scanline (codigo de incremento de HL en 1 scanline) ; desde el septimo scanline de la fila Y+1 al primero de la Y+2 ;;;inc h ; No hay que hacer inc d, lo hizo en el bucle ;;;ld a, h ;;;and 7 ;;;jr nz, drawsp16m_nofix_abajop ld a, l add a, 32 ld l, a jr c, drawsp16m_nofix_abajop ld a, h sub 8 ld h, a drawsp16m_nofix_abajop: ;;; Repetir 8 veces (segundos 2 bloques horizontales): ld b, 8 drawspr16m_loop2: ld a, (de) ; Obtenemos un byte del sprite (el byte de mascara) and (hl) ; A = A and (hl) ld c, a ; Nos guardamos el valor del AND inc de ; Avanzamos al siguiente byte (el dato grafico) ld a, (de) ; Obtenemos el byte grafico or c ; A = A or c = A OR (MASK and fONDO) ld (hl), a ; Imprimimos el dato tras aplicar operaciones logicas inc de ; Avanzamos al siguiente dato del sprite inc l ; Avanzamos al segundo bloque en pantalla ld a, (de) ; Obtenemos un byte del sprite (el byte de mascara) and (hl) ; A = A and (hl) ld c, a ; Nos guardamos el valor del AND inc de ; Avanzamos al siguiente byte (el dato grafico) ld a, (de) ; Obtenemos el byte grafico or c ; A = A or c = A OR (MASK and fONDO) ld (hl), a ; Imprimimos el dato tras aplicar operaciones logicas inc de ; Avanzamos al siguiente dato del sprite dec l ; Volvemos atras del valor que incrementamos inc h ; Incrementamos puntero en pantalla (siguiente scanline) djnz drawspr16m_loop2 ;;; En este punto, los 16 scanlines del sprite estan dibujados. pop bc ; Recuperamos el offset del primer scanline ;;; Considerar el dibujado de los atributos (Si DS_ATTRIBS=0 -> ret) ld hl, (DS_ATTRIBS) xor a ; A = 0 add a, h ; A = 0 + H = H ret z ; Si H = 0, volver (no dibujar atributos) ;;; Calcular posicion destino en area de atributos en DE. ld a, b ; Codigo de Get_Attr_Offset_From_Image rrca ; Obtenemos dir de atributo a partir de rrca ; dir de zona de imagen. rrca ; Nos evita volver a obtener X e Y and 3 ; y hacer el calculo completo de la or $58 ; direccion en zona de atributos ld d, a ld e, c ; DE tiene el offset del attr de HL ld a, (DS_NUMSPR) ; Cogemos el numero de sprite a dibujar ld c, a ld b, 0 add hl, bc ; HL = HL+DS_NUMSPR add hl, bc ; HL = HL+DS_NUMSPR*2 add hl, bc ; HL = HL+DS_NUMSPR*3 add hl, bc ; HL = HL+HL=(DS_NUMSPR*4) = Origen de atributo ldi ldi ; Imprimimos las 2 primeras filas de atributo ;;; Avance diferencial a la siguiente linea de atributos ld a, e ; A = L add a, 30 ; Sumamos A = A + 30 mas los 2 INCs de ldi. ld e, a ; Guardamos en L (L = L+30 + 2 por ldi=L+32) jr nc, drawsp16m_attrab_noinc inc d drawsp16m_attrab_noinc: ldi ldi ret ; porque no necesitamos incrementar HL y DE END 35000