; Sprites 16x16 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, 13 ld (DS_COORD_X), a ld a, 8 ld (DS_COORD_Y), a xor a ld (DS_NUMSPR), a call DrawSprite_16x16_LD 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 ;------------------------------------------------------------- ; DrawSprite_16x16_LD: ; Imprime un sprite de 16x16 pixeles 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_LD: ; 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*32) 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 rra ; Rotamos, ya que el bit que salio de L al CF fue 0 rr l ; AL = DS_NUMSPR*32 ld h, a ; HL = DS_NUMSPR*32 add hl, bc ; HL = BC + HL = DS_SPRITES + (DS_NUMSPR * 32) ; HL contiene la direccion de inicio en el sprite ex de, hl ; Intercambiamos DE y HL (DE=origen, HL=destino) ;;; Repetir 8 veces (primeros 2 bloques horizontales): ld b, 8 drawsp16x16_loop1: ld a, (de) ; Bloque 1: Leemos dato del sprite ld (hl), a ; Copiamos dato a pantalla inc de ; Incrementar puntero en sprite inc l ; Incrementar puntero en pantalla ld a, (de) ; Bloque 2: Leemos dato del sprite ld (hl), a ; Copiamos dato a pantalla inc de ; Incrementar puntero en sprite inc h ; Hay que sumar 256 para ir al siguiente scanline dec l ; pero hay que restar el inc l que hicimos. djnz drawsp16x16_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 h, lo hizo en el bucle ;;;ld a, h ; No hay que hacer esta prueba, sabemos que ;;;and 7 ; no hay salto (es un cambio de bloque) ;;;jr nz, drawsp16_nofix_abajop ld a, l add a, 32 ld l, a jr c, drawsp16_nofix_abajop ld a, h sub 8 ld h, a drawsp16_nofix_abajop: ;;; Repetir 8 veces (segundos 2 bloques horizontales): ld b, 8 drawsp16x16_loop2: ld a, (de) ; Bloque 1: Leemos dato del sprite ld (hl), a ; Copiamos dato a pantalla inc de ; Incrementar puntero en sprite inc l ; Incrementar puntero en pantalla ld a, (de) ; Bloque 2: Leemos dato del sprite ld (hl), a ; Copiamos dato a pantalla inc de ; Incrementar puntero en sprite inc h ; Hay que sumar 256 para ir al siguiente scanline dec l ; pero hay que restar el inc l que hicimos. djnz drawsp16x16_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, drawsp16x16_attrab_noinc inc d drawsp16x16_attrab_noinc: ldi ldi ret ; porque no necesitamos incrementar HL y DE ;-------------------------------------------------------------------- ; 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 ;----------------------------------------------------------------------- ;ASM source file created by SevenuP v1.20 ;GRAPHIC DATA: ;Pixel Size: ( 16, 64) ;Char Size: ( 2, 8) ;Sort Priorities: X char, Char line, Y char ;Data Outputted: Gfx+Attr ;Interleave: Sprite ;Mask: No ;----------------------------------------------------------------------- bicho_gfx: DEFB 8,128, 4, 64, 0, 0, 7,224 DEFB 15, 80, 15, 80, 15,240, 7,224 DEFB 0, 0, 1, 64, 0, 32, 2, 0 DEFB 104, 22,112, 14, 56, 28, 0, 0 bicho_attrib: DEFB 70, 71, 67, 3 END 35000