; Sprites 8x8 con máscara ORG 35000 call ClearScreen_Pattern ; Establecemos los parametros de entrada a la rutina ; Los 2 primeros se pueden establecer una unica vez ld hl, cara_gfx ld (DS_SPRITES), hl ld hl, cara_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_8x8_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 ;----------------------------------------------------------------------- ;GRAPHIC DATA: ;Sort Priorities: Mask, X Char, Char line, Y Char ;Con ancho=1, aparece: Mask, Char line ;Data Outputted: Gfx+Attr ;Interleave: Sprite ;Mask: Yes, before graphic cara_gfx: DEFB 227, 28, 193, 62, 128, 107, 128, 127 DEFB 128, 93, 128, 99, 193, 62, 227, 28 cara_attrib: DEFB 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_8x8_MASK: ; Imprime un sprite de 8x8 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_8x8_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 ; Ya tenemos la parte alta calculada (010TT000) ld a, b ; Ahora calculamos la parte baja and 7 rrca rrca rrca ; A = NNN00000b add a, c ; Sumamos COLUMNA -> A = NNNCCCCCb ld e, a ; Lo cargamos en la parte baja de la direccion ; DE contiene ahora la direccion destino. ;;; Calcular posicion origen (array sprites) en HL como: ;;; direccion = base_sprites + (NUM_SPRITE*16) ld bc, (DS_SPRITES) ld a, (DS_NUMSPR) ld h, 0 ld l, a ; HL = DS_NUMSPR add hl, hl ; HL = HL * 2 add hl, hl ; HL = HL * 4 add hl, hl ; HL = HL * 8 add hl, hl ; HL = HL * 16 = DS_NUMSPR * 16 add hl, bc ; HL = BC + HL = DS_SPRITES + (DS_NUMSPR * 16) ; 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 drawspr8x8_loop: 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 h ; Incrementamos puntero en pantalla (siguiente scanline) djnz drawspr8x8_loop ;;; En este punto, los 8 scanlines del sprite estan dibujados. ld a, h sub 8 ; Recuperamos la posicion de memoria del ld b, a ; scanline inicial donde empezamos a dibujar ld c, l ; BC = HL - 8 ;;; 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 = Origen de atributo ;;; Copiar (HL) en (DE) -> Copiar atributo de sprite a pantalla ld a, (hl) ld (de), a ; Mas rapido que ldi (7+7 vs 16 t-estados) ret ; porque no necesitamos incrementar HL y DE END 35000