BUILDSNA : BANKSET 0
ORG #38 : EI : RET
ORG #100 : RUN #100
ld sp,#100 : ei
ld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0
ld hl,palette : ld bc,#7F00
setPalette out (c),c : inc c : inc b : outi : ld a,(hl) : or a : jr nz,setPalette
ld bc,#C000+#FC : ld hl,60 ; à quatre octets du bord gauche
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
ld bc,#C000+76 : ld hl,100 ; à quatre octets du bord
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
ld bc,#C000+26 : ld hl,-18 ; à moitié
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
ld bc,#C000+46 : ld hl,184 ; à moitié
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
; Et maintenant les coins!!!
ld bc,#C000+#FC : ld hl,-18 ; à quatre octets du bord gauche
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
ld bc,#C000+#FC : ld hl,184 ; à quatre octets du bord gauche
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
ld bc,#C000+76 : ld hl,-18 ; à quatre octets du bord gauche
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
ld bc,#C000+76 : ld hl,184 ; à quatre octets du bord gauche
ld xl,9 : ld xh,36 : ld de,donnees_sprite ; dimensions du sprite largeur/lignes
call AfficheSprite
jr $
AfficheSprite
; BC=page + coordonnée X (0-79) / HL=coordonnée Y (0-199) / DE=adresse des données du sprite
; XL=largeur du sprite en octets / XH=hauteur du sprite en nombre de lignes
bit 7,h : jr z,.pasClipHaut ; si le Y est positif ou nul, pas de clipping en haut
; XH est la hauteur affichable, on soustrait le Y négatif
push hl : ld a,xh : add l : ld l,a : ld a,h : adc 0 : ld h,a : ld a,l : ld xh,a : pop hl
; vu qu'on saute des lignes, il faut avancer le pointeur de données
ld a,l : ex hl,de : ld d,0 : ld e,xl
.sauteLignes add hl,de : inc a : jr nz,.sauteLignes ; +simple qu'une multiplication
ex hl,de ; remettre le pointeur dans DE
ld hl,0 ; tout est corrigé, on dit qu'on part maintenant de la ligne 0
.pasClipHaut
; pour rester sur des comparaisons 8 bits, on peut soustraire sprHauteur à hauteur et comparer à sprY
ld a,200 : sub xh : cp l : jr nc,.pasClipBas ;
ld a,200 : sub l : ld xh,a ; nouvelle hauteur +petite
.pasClipBas
xor a ; offsetDebut par défaut
bit 7,c : jr z,.pasClipGauche
ld a,c : add xl : ld xl,a ; nouvelle largeur
ld a,c : neg ; nouvel offsetDebut
ld c,0 ; nouveau X en zéro
.pasClipGauche
ld (offsetDebut),a ; soit zéro, soit celui calculé lors du clipping
ld a,c : add xl : cp 81 ; largeur+1 rapport à la comparaison souhaitée
ld a,0 : jr c,.pasClipDroite ; A=0 au cas où on n'ait pas de clipping, pour reset offsetFin
ld a,xl : exa ; on met la largeur du sprite de côté
ld a,80 : sub c : ld xl,a ; nouvelle largeur de sprite
exa ; on récupère la largeur d'origine
sub xl
.pasClipDroite
ld (offsetFin),a
call CalculeAdressePixel
; HL=destination écran
; DE=toujours l'adresse source des données
ld bc,hl ; on utilise BC comme destination écran
ld h,hi(tableTransparence)
.afficheLignes
ld a,xl : ld yl,a ; chargeur la largeur d'une ligne dans YL
push bc ; on met l'adresse de début de la ligne de côté
ld a,e : add #12 : offsetDebut=$-1 : ld e,a : ld a,d : adc 0 : ld d,a
.pixelMasque
ld a,(de) ; lire le sprite
ld l,a ; octet du sprite dans L
ld a,(bc) ; on récupère l'octet de l'écran
and (hl) ; on applique le masque
or l ; on fusionne avec la donnée du sprite
ld (bc),a ; on remet dans l'écran
inc bc
inc de ; et on incrémente data+ecran
dec yl
jr nz,.pixelMasque
ld a,e : add #12 : offsetFin=$-1 : ld e,a : ld a,d : adc 0 : ld d,a
pop bc ; on récupère l'adresse du début de ligne
; et on calcule le passage à la ligne suivante
; notre routine de passage à la ligne suivante, adaptée pour BC
ld a,b : add 8 : ld b,a ; ajouter #800 à DE
and #38 ; on teste si on déborde de la bank (passage de page+#3800 à page+#0000)
jr nz,.nextLine ; pas zéro, on est toujours dans le même bloc de lignes
ld a,80 : add c : ld c,a ; on ajoute 80 (largeur d'une ligne en octets) pour passer au bloc suivant
ld a,#C0 : adc b : ld b,a ; et on enlève #4000 (additionner #C000 c'est comme enlever #4000)
.nextLine
dec xh ; notre compteur de lignes
jr nz,.afficheLignes
ret
CalculeAdressePixel
; B=page vidéo #00, #40, #80 ou #C0
; C=coordonnée X (0-79)
; HL=coordonnée Y (0-199)
; adresse de la ligne dans HL en résultat
add hl,hl ; adresses 16 bits, il faut indexer de 2 en 2
ld a,lo(tableau) : add l : ld l,a : ld a,h : adc hi(tableau): ld h,a
ld a,(hl) : inc hl
ld h,(hl) : ld l,a
add hl,bc ; ajouter la position X en octets et la page!
ret
;-------------------
adresse_ecran=#0000
largeur_ecran=80
tableau
repeat 25
repeat 8
defw adresse_ecran
adresse_ecran+=#800
rend
adresse_ecran+=largeur_ecran
adresse_ecran-=#4000
rend
align 256
tableTransparence
repeat 256,x
px=x-1 ; car le compteur va par défaut de 1 à 256 et non 0 à 255
masque=0
if (px & (128|32|8|2))==0
masque|=128|32|8|2 ; pour cet octet on conservera les données écran
endif
if (px & (64|16|4|1))==0
masque|=64|16|4|1 ; pour cet octet on conservera les données écran
endif
defb masque
rend
palette defb #4D,#54,#56,#5C,#46,#5E,#40,#47,#43,#4E,#4B,#4C,0 ; Rose en zéro
donnees_sprite incbin 'hibouZero.bin'
org #C000 : incbin 'foretZero.bin'
|