;---------------------------------------------------------------------------- ;--------------------------- putsprite -------------------------------------- ;---------------------------------------------------------------------------- ;in: de=(x,y); ix=sprite ;out: ix=behind sprite; hl:a=right below sprite; b=0; d=width; ce=destroyed putsprite: ld a,d ;a=X bit 7,d ;check sign bit of X jr z,CSpositive ;X>=0 neg ;a=|X| cp (ix) ;off screen? ret nc ;X<=-width: don't draw at all ld b,a ;b=|X|mod 8=1..7=bits to draw ld a,%11111111 ;all bits set (draw everything) CSclipleft: srl a ;remove first bit in a for each b dnz CSclipleft ;b=1: a=%01111111 ;b=2: a=%00111111 ;b=3: a=%00011111 ;b=4: a=%00001111 ;b=5: a=%00000111 ;b=6: a=%00000011 ;b=7: a=%00000001 res 7,d ;X+128 (right side of screen) dec e ;Y-- jr CSdisplay ;done clipping CSpositive: sub 129-8 ;minus (screen width - byte width) ld b,a ld a,%11111111 ;clipmask jr c,CSdisplay ;x+width<128 then entire sprite is on screen inc b ;b = number of pixels off screen CSclipright: add a,a ;remove last bit in a for each b dnz CSclipright ;b=1: a=%11111110 ;b=2: a=%11111100 ;b=3: a=%11111000 ;b=4: a=%11110000 ;b=5: a=%11100000 ;b=6: a=%11000000 ;b=7: a=%10000000 ;b>7: a=%00000000 = off screen CSdisplay: ;display the sprite ix at (d,e) masked ld (CSclipmask),a ;set mask cal findpixel ;convert de to screen location hl:a ld (CSbitmask),a ld d,(ix) ;width ld b,(ix+1) ;height CSyloop: psh bc ;save rows to go psh hl ;screen ld b,d ;width ld a,(ix+2) ;load image line and 255 ;mask CSclipmask =$-1 ld c,a ;c=image inc ix ;next CSbitmask =$+1 ld a,1 ;saved bitmask CSxloop: sla c ;test leftmost pixel jr nc,CSnodraw ;don't draw if it's 0 ld e,a ;psh af: save bitmask or (hl) ld (hl),a ;OR pixel with screen ld a,e ;pop af CSnodraw: rrca ;next bit jr nc,CSbitdrawn ;carry set if bit "jumped" inc hl ;next byte CSbitdrawn: dnz CSxloop pop hl ;screen at x-offset=0 ld bc,16 add hl,bc ;next line pop bc ;rows counter dnz CSyloop CSdone: ret ;------------------------------- findpixel ---------------------------------- ;based upon CLEM's fp | 131 cycles | 28 bytes | in:(d,e); out:hla; destr:de findpixel: ld a,e ;a=e=Y add a,a add a,a ;add a,a is 7 cycles faster than add hl,hl ld h,0 ;switch to hl now (Y<64) ld l,a ;hl=4*Y ld a,d ;a=d=X rra ;RRA: carry flag must be reset! add hl,hl ;that's what the adds are for :P rra add hl,hl ;hl=16*Y rra ;a=X/8 or l ld l,a ;hl=hl+a ld a,d and 7 ;a=X\8 cpl rlca rlca rlca ld (FPbit),a xor a FPbit =$+1 set 0,a ld de,VIDEO_MEM ;screen base position (where x+y=0) PutWhere =$-2 add hl,de ret ;May be replaced by any de-fp that doesn't destroy de ;Can be integrated in putsprite routine for better performance/smaller size ;---------------------------------------------------------------------------- ;------------------------------- sprites ------------------------------------ ;---------------------------------------------------------------------------- ;format: x-size<=8; y-size; sprite spr_enemy01: .db 6,6 .db %00111100 ; лллл .db %01110000 ; ллл .db %11110000 ; лллл .db %11110000 ; лллл .db %01110000 ; ллл .db %00111100 ; лллл