Et justement, pour ce genre de fonction il faut des instructions lentes et petites
Il faudrait que je trouve une liste complète (et surtout vraie) des instructions z80 avec leur nombre de cycles.
Ok ok, moi je n'ai pas beaucoup de temps non plus, c'est pourquoi je n'avance pas énormément sur mes gros projets et plus sur les plus petits (comme celui-là)
Enfaite il n'y a quasiment rien en C dans cette lib, toutes les routines sont en asm.
Je veux bien (il suffit d'ajouter une constante que l'utilisateur (de)commentera pour choisir entre la taille et la vitesse, comme je le fait déjà pour spécifier les routines qu'on souhaite inclure à notre projet), mais il faudra trouver/créer ces routines.
Ok, par contre le code est très moche (notamment parce qu'on ne peut pas utiliser '$' pour le smc... :/) :
TL_large_clipped_sprite()
#if defined TL_LARGE_CLIPPED_SPRITE
char TL_large_clipped_sprite(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char *sprite, unsigned char logic){
#asm
; Clipped sprite routine by James Montelongo
ld hl,2
add hl,sp
inc hl
inc hl
ld e,(hl)
inc hl
ld d,(hl)
push de
pop ix
inc hl
ld b,(hl)
inc hl
inc hl
ld c,(hl)
inc hl
inc hl
ld e,(hl)
inc hl
inc hl
ld d,(hl)
; max size : 64x64
; ix = sprite
; b = height
; c = width in bytes
; d = x
; e = y
TL_large_clipped_sprite:
ld a,e
cp SCREEN_HEIGHT
ret p
add a,b
ret m
ret z
ld a,d
cp SCREEN_WIDTH
ret p
ld a,c
add a,a
add a,a
add a,a
add a,d
ret m
ret z
ld a,e
or a
jp p,TL_lcs_clip_bottom
neg
push de
ld hl,0
ld d,l
ld e,a
bit 2,c
jr z,TL_lcs_skip_1
add hl,de
TL_lcs_skip_1:
add hl,hl
bit 1,c
jr z,TL_lcs_skip_2
add hl,de
TL_lcs_skip_2:
add hl,hl
bit 0,c
jr z,TL_lcs_skip_3
add hl,de
TL_lcs_skip_3:
pop de
ex de,hl
add ix,de
ex de,hl
ld e,0
neg
add a,b
ld b,a
TL_lcs_clip_bottom:
ld a,e
add a,b
sub SCREEN_HEIGHT
jp m,TL_lcs_clip_left
neg
add a,b
ld b,a
TL_lcs_clip_left:
xor a
ld (TL_lcs_big_skip),a
ld a,TL_lcs_left_clip-(TL_lcs_do_left_clip+1)
ld (TL_lcs_do_left_clip),a
ld a,d
or a
jp p,TL_lcs_clip_right
cpl
and 0xf8
rra
rra
rra
ex de,hl
ld e,a
ld d,0
add ix,de
ld (TL_lcs_big_skip),a
ex de,hl
inc a
neg
add a,c
ld c,a
xor a
ld (TL_lcs_do_left_clip),a
ld a,d
and 0x07
ld d,a
TL_lcs_clip_right:
ld a,TL_lcs_right_clip-(TL_lcs_do_right_clip+1)
ld (TL_lcs_do_right_clip),a
ld a,c
add a,a
add a,a
add a,a
add a,d
sub SCREEN_WIDTH
jp m,TL_lcs_middle_clip
and 0xf8
rra
rra
rra
ld l,a
ld a,(TL_lcs_big_skip)
add a,l
inc a
ld (TL_lcs_big_skip),a
neg
add a,c
ld c,a
xor a
ld (TL_lcs_do_right_clip),a
TL_lcs_clip_middle:
xor a
ld (TL_lcs_do_middle_clip),a
ld a,c
or a
jp nz,TL_lcs_dont_skip_middle
ld a,TL_lcs_middle_clip-(TL_lcs_do_middle_clip+1)
ld (TL_lcs_do_middle_clip),a
TL_lcs_dont_skip_middle:
ld l,e
ld a,d
ld h,0
ld d,h
add hl,hl
add hl,de
add hl,hl
add hl,hl
ld e,a
and 0x07
xor 7
ld (TL_lcs_rotation_1),a
ld (TL_lcs_rotation_2),a
ld (TL_lcs_rotation_3),a
add a,a
ld (TL_lcs_clip_rotation1),a
ld a,0xff
defb 0x18 ; jr
TL_lcs_clip_rotation1:
defb 0xfe
srl a
srl a
srl a
srl a
srl a
srl a
srl a
srl e
srl e
srl e
add hl,de
ld de,gbuf
add hl,de
ld d,a
cpl
ld e,a
TL_lcs_row:
push bc
push hl
ld b,c
defb 0x18 ; jr
TL_lcs_do_left_clip:
defb 0x11
ld a,(ix)
inc ix
defb 0x18 ; jr
TL_lcs_rotation_1:
defb 0xfe
rrca
rrca
rrca
rrca
rrca
rrca
rrca
TL_lcs_big_mask_0:
and e
or (hl)
ld (hl),a
TL_lcs_left_clip:
defb 0x18 ; jr
TL_lcs_do_middle_clip:
defb 0
TL_lcs_loop:
ld a,(ix)
inc ix
defb 0x18 ; jr
TL_lcs_rotation_2:
defb 0xfe
rrca
rrca
rrca
rrca
rrca
rrca
rrca
ld c,a
TL_lcs_mask_1:
and d
or (hl)
ld (hl),a
inc hl
ld a,c
TL_lcs_mask_2:
and e
or (hl)
ld (hl),a
djnz TL_lcs_loop
TL_lcs_middle_clip:
defb 0x18 ; jr
TL_lcs_do_right_clip:
defb 0x0f
ld a,(ix)
defb 0x18 ; jr
TL_lcs_rotation_3:
defb 0xfe
rrca
rrca
rrca
rrca
rrca
rrca
rrca
TL_lcs_mask_3:
and d
or (hl)
ld (hl),a
TL_lcs_right_clip:
pop hl
ld bc,SCREEN_WIDTH/8
add hl,bc
defb 0x01 ; ld bc,word
TL_lcs_big_skip:
defw 0
add ix,bc
pop bc
djnz TL_lcs_row
#endasm
}
#endif