; Programme pour l'illustrer l'animation par plan de bits. Réalise une ; animation sans vacillement avec transparence d'image et ; priorité d'image à travers 4 plans distincts, avec ; 13 images 32x32 mouvantes à la fois. ; ; Testé avec TASM 4.0 par Jim Mischel 12/16/94. ; ; Paramétrer à des valeurs plus élevées pour ralentir des ordinateurs plus ; rapides.0 convient bien à un PC. 500 est un paramètre correct pour un AT. ; Ralentir davantage l'animation permet de bien voir la transparence et ; l'absence de vacillement ainsi que les effets de couleur lorsque les images ; se croisent. ; SLOWDOWN equ 10000 ; ; Sélectionne les plans pour les 4 couleurs que nous utilisons. ; RED equ 01h GREEN equ 02h BLUE equ 04h WHITE equ 08h ; VGA_SEGMENT equ 0a000h ;segment de la mémoire vidéo ; en mode 10h SC_INDEX equ 3c4h ;registre Sequence Controller ; Index MAP_MASK equ 2 ;index du registre Map Mask dans ; Sequence Controller SCREEN_WIDTH equ 80 ;nombre d'octets à travers l'octet SCREEN_HEIGHT equ 350 ;nombre de lignes d'affichage sur l'écran WORD_OUTS_OK equ 1 ;à 0 pour assembler pour ; les ordinateurs ne pouvant pas ; traiter les outs de mot ; dans les registres indexés de VGA ; stack segment para stack 'STACK' db 512 dup (?) stack ends ; ; Info complète sur un objet que nous animons. ; ObjectStructure struc Delay dw ? ;utilisé pour retarder de n passes ; à travers la boucle pour ; contrôler la vitesse de l'animation BaseDelay dw ? ;réinitialise la valeur de Delay Image dw ? ;pointeur sur l'info d'affichage ; de l'objet XCoord dw ? ;emplacement X de l'objet en pixels XInc dw ? ;nombre de pixels à incrementer ; emplacement dans la direction X ; à chaque déplacement XLeftLimit dw ? ;limite gauche du déplacement X XRightLimit dw ? ;limite droite du déplacement X YCoord dw ? ;emplacement Y de l'objet en pixels YInc dw ? ;nombre de pixels à incrementer ; emplacement dans la direction Y ; à chaque déplacement YTopLimit dw ? ;limite haute du déplacement Y YBottomLimit dw ? ;limite basse du déplacement Y PlaneSelect db ? ;masque pour sélectionner le plan ; dans lequel l'objet est affiché db ? ;pour faire un nombre pair de longueur ;de mots, en vue d'une meilleure ; performance sur 286(garde la structure ; suivante alignée sur ;un mot) ObjectStructure ends ; Data segment word 'DATA' ; ; Paramètres de la palette pour donner la priorité au plan 0, suivi des ; plans 1, 2, et 3. Le plan 3 est de moindre priorité (est caché par ; tout autre plan), alors que le plan 0 est de première priorité ; (est affiché devant tout autre plan). ; Colors db 000h ;couleur de fond =noir db 03ch ;plan 0 seul=rouge db 03ah ;plan 1 seul=vert db 03ch ;plans 0&1=rouge (plan 0 prioritaire) db 039h ;plan 2 seul=bleu db 03ch ;plans 0&2=rouge (plan 0 prioritaire) db 03ah ;plans 1&2=vert (plan 1 prioritaire) db 03ch ;plans 0&1&2=rouge (plan 0 prioritaire) db 03fh ;plan 3 seul=blanc db 03ch ;plans 0&3=rouge (plan 0 prioritaire) db 03ah ;plans 1&3=vert (plan 1 prioritaire) db 03ch ;plans 0&1&3=rouge (plan 0 prioritaire) db 039h ;plans 2&3=bleu (plan 2 prioritaire) db 03ch ;plans 0&2&3=rouge (plan 0 prioritaire) db 03ah ;plans 1&2&3=vert (plan 1 prioritaire) db 03ch ;plans 0&1&2&3=rouge (plan 0 prioritaire) db 000h ;border couleur=noir , Carré Square label byte dw 48,6 ;hauteur en pixels, largeur en octets rept 8 db 0,0,0,0,0,0 ;top blank border endm .radix 2 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,00000000,00000000,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 db 0,11111111,11111111,11111111,11111111,0 .radix 10 rept 8 db 0,0,0,0,0,0 ; endm ; ; Diamant Diamond label byte dw 48,6 ;hauteur en pixels, largeur en octets rept 8 db 0,0,0,0,0,0 ; endm .radix 2 db 0,00000000,00000001,10000000,00000000,0 db 0,00000000,00000011,11000000,00000000,0 db 0,00000000,00000111,11100000,00000000,0 db 0,00000000,00001111,11110000,00000000,0 db 0,00000000,00011111,11111000,00000000,0 db 0,00000000,00111110,01111100,00000000,0 db 0,00000000,01111100,00111110,00000000,0 db 0,00000000,11111000,00011111,00000000,0 db 0,00000001,11110000,00001111,10000000,0 db 0,00000011,11100000,00000111,11000000,0 db 0,00000111,11000000,00000011,11100000,0 db 0,00001111,10000001,10000001,11110000,0 db 0,00011111,00000011,11000000,11111000,0 db 0,00111110,00000111,11100000,01111100,0 db 0,01111100,00001111,11110000,00111110,0 db 0,11111000,00011111,11111000,00011111,0 db 0,11111000,00011111,11111000,00011111,0 db 0,01111100,00001111,11110000,00111110,0 db 0,00111110,00000111,11100000,01111100,0 db 0,00011111,00000011,11000000,11111000,0 db 0,00001111,10000001,10000001,11110000,0 db 0,00000111,11000000,00000011,11100000,0 db 0,00000011,11100000,00000111,11000000,0 db 0,00000001,11110000,00001111,10000000,0 db 0,00000000,11111000,00011111,00000000,0 db 0,00000000,01111100,00111110,00000000,0 db 0,00000000,00111110,01111100,00000000,0 db 0,00000000,00011111,11111000,00000000,0 db 0,00000000,00001111,11110000,00000000,0 db 0,00000000,00000111,11100000,00000000,0 db 0,00000000,00000011,11000000,00000000,0 db 0,00000000,00000001,10000000,00000000,0 .radix 10 rept 8 db 0,0,0,0,0,0 ; endm ; ; Liste des objets à animer. ; even ;alignement sur un mot en vue de meilleures performances sur 286 ; ObjectList label ObjectStructure ObjectStructure <1,21,Diamond,88,8,80,512,16,0,0,350,RED> ObjectStructure <1,15,Square,296,8,112,480,144,0,0,350,RED> ObjectStructure <1,23,Diamond,88,8,80,512,256,0,0,350,RED> ObjectStructure <1,13,Square,120,0,0,640,144,4,0,280,BLUE> ObjectStructure <1,11,Diamond,208,0,0,640,144,4,0,280,BLUE> ObjectStructure <1,8,Square,296,0,0,640,144,4,0,288,BLUE> ObjectStructure <1,9,Diamond,384,0,0,640,144,4,0,288,BLUE> ObjectStructure <1,14,Square,472,0,0,640,144,4,0,280,BLUE> ObjectStructure <1,8,Diamond,200,8,0,576,48,6,0,280,GREEN> ObjectStructure <1,8,Square,248,8,0,576,96,6,0,280,GREEN> ObjectStructure <1,8,Diamond,296,8,0,576,144,6,0,280,GREEN> ObjectStructure <1,8,Square,344,8,0,576,192,6,0,280,GREEN> ObjectStructure <1,8,Diamond,392,8,0,576,240,6,0,280,GREEN> ObjectListEnd label ObjectStructure ; Data ends ; ; Macro pour diriger une valeur de mot sur un port. ; OUT_WORD macro if WORD_OUTS_OK out dx,ax else out dx,al inc dx xchg ah,al out dx,al dec dx xchg ah,al endif endm ; ; Macro pour diriger une valeur constante sur un registre indexé du VGA. ; CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, INDEX, VALUE mov dx,ADDRESS mov ax,(VALUE shl 8) + INDEX OUT_WORD endm ; Code segment assume cs:Code, ds:Data Start proc near cld mov ax,Data mov ds,ax ; ; Set 640x350 16-color mode. ; mov ax,0010h ;AH=0 mode de sélection ;AL=10h sélection du ; mode 10h int 10h ;interruption vidéo du BIOS ; ; Configure la palette pour donner la priorité aux plans de bits. si ; les plans 0 & 1se chevauchent, la couleur du plan 0 sera visible; ; si les plans 1 & 2se chevauchent, la couleur du plan 1 sera ; visible; et ainsi de suite. ; mov ax,(10h shl 8) + 2 ;AH = 10h fn ; des paramètres des ; registres palette ;AL = 2 paramètre ; tous les registres ; palette push ds ;ES:DX pointe sur pop es ; les paramètres de mov dx,offset Colors ; la palette int 10h ;appelle BIOS pour ; paramétrer la palette ; ; Affiche l'arrière-plan statique dans le plan 3. Toutes les images ; mouvantes sembleront être devant cet arrière-plan, car le plan 3 ; est de moindre priorité selon la configuration de la palette. ; CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 08h ;permet aux données de n'aller ; que sur le plan 3 ; ; ES pointe sur la mémoire vidéo pour le reste du programme. ; mov ax,VGA_SEGMENT mov es,ax ; sub di,di mov bp,SCREEN_HEIGHT/16 ;remplit 16 lignes ; à la fois dans l'écran BackdropBlockLoop: call DrawGridCross ;affiche une partie du croisement call DrawGridVert ;affiche le reste ; 1d'un bloc de hauteur 15 dec bp jnz BackdropBlockLoop call DrawGridCross ;ligne du bas de la grille ; ;Début de l'animation! ; AnimationLoop: mov bx,offset ObjectList ;pointe sur le premier ; objet dans la liste ; ;Pour chaque objet, vérifier s'il est temps de déplacer et d'afficher ; cet objet. ; ObjectLoop: ; ; Vérifie s'il est temps de déplacer cet objet. ; dec [bx+Delay] ;décompte le retard jnz DoNextObject ;encore en attente -ne pas déplacer mov ax,[bx+BaseDelay] mov [bx+Delay],ax ;réinitialise l'attente pour la prochaine fois ; ; Sélectionne le plan dans lequel sera affiché cet objet. ; mov dx,SC_INDEX mov ah,[bx+PlaneSelect] mov al,MAP_MASK OUT_WORD ; ; Avance la coordonnée X, en inversant la direction si l'une des ; marges X a été atteinte. ; mov cx,[bx+XCoord] ;emplacement X courant cmp cx,[bx+XLeftLimit] ;à la limite gauche? ja CheckXRightLimit ;non neg [bx+XInc] ;oui -inversons CheckXRightLimit: cmp cx,[bx+XRightLimit] ;à la limite droite? jb SetNewX ;non neg [bx+XInc] ;oui -inversons SetNewX: add cx,[bx+XInc] ;déplace la coordonnée X mov [bx+XCoord],cx ; & la sauve ; ; Avance la coordonnée Y, en inversant la direction si l'une des ; marges a été atteinte. ; mov dx,[bx+YCoord] ;emplacement Y courant cmp dx,[bx+YTopLimit] ;à la limite haute? ja C heckYBottomLimit ;non neg [bx+YInc] ;oui -inversons CheckYBottomLimit: cmp dx,[bx+YBottomLimit] ;à la limite basse? jb SetNewY ;non neg [bx+YInc] ;oui -inversons SetNewY: add dx,[bx+YInc] ;déplace la coordonnée Y mov [bx+YCoord],dx ; & la sauve ; ;Affiche au nouvel emplacement. En raison de la sélection du plan ci-dessus ;un seul plan sera affecté. ; mov si,[bx+Image] ;pointe sur ; l'info d'image ; de l'objet call DrawObject ; ; Pointe sur le prochain objet dans la liste jusqu'à ce que n'ayons plus ; d'objets. ; DoNextObject: add bx,size ObjectStructure cmp bx,offset ObjectListEnd jb ObjectLoop ; ;Délai comme spécifié pour ralentir le mouvement. ; if SLOWDOWN mov cx,SLOWDOWN DelayLoop: loop DelayLoop endif ; ;Si une touche clavier est pressée, nous avons fini, sinon ; relançons l'animation. ; CheckKey: mov ah,1 int 16h ;attente touche clavier? jz AnimationLoop ;non sub ah,ah int 16h ;oui -termine ; ; Back to text mode. ; mov ax,0003h ;AL=03h sélection du ; mode 03h int 10h ; ; Back to DOS. ; mov ah,4ch ;fonction terminer de DOS int 21h ; terminer ; Start endp ; ; Affiche un seul élément de croisement de grille à l'emplacement de la ; mémoire vidéo pointé par ES:DI. 1 ligne horizontale est affichée ;à travers l'écran. ; ;Entrée: ES:DI pointe sur l'adresse où afficher ; ;Sortie: ES:DI pointe sur l'adresse suivant la ligne ; affichée ; ; Registres altérés: AX, CX, DI ; DrawGridCross proc near mov ax,0ffffh ;affiche une ligne solide mov cx,SCREEN_WIDTH/2-1 rep stosw ;affiche tout excepté l'edge ; le plus à droite mov ax,0080h stosw ;affiche l'edge droit de ;la grille ret DrawGridCross endp ; ; Affiche la partie non coupée de la grille à l'emplacement de la ; mémoire vidéo pointé par ES:DI. 15 lignes d'affichage sont remplies. ; ;Entrée: ES:DI pointe sur l'adresse où afficher ; ;Sortie: ES:DI pointe sur l'adresse suivant la ; partie de la grille affichée ; ; Registres alterés: AX, CX, DX, DI ; DrawGridVert proc near mov ax,0080h ;motif pour une ligne verticale mov dx,15 ;affiche 15 lignes d'affichage(toute la grille ; excepté la ligne ;de croisement) BackdropRowLoop: mov cx,SCREEN_WIDTH/2 rep stosw ;affiche le bit de cette ligne d'affichage ; de toutes les lignes verticales ; à l'écran dec dx jnz BackdropRowLoop ret DrawGridVert endp ; ; Affiche l'image spécifiée à l'emplacement spécifié. ; Les images sont affichées horizontalement sur les limites d'octets, ; verticalement sur les limites de pixel. ; Le registre Map Mask doit déjà être positionné pour permettre ; l'accès au plan désiré. ; ;Entrée: ; CX - coordonnée X du coin supérieur gauche ; DX - coordonnée Y du coin supérieur gauche ; DS:SI - pointeur sur l'info d'affichage de l'image ; ES - segment de la mémoire vidéo ; ;Sortie: aucune ; ; Registres alterés: AX, CX, DX, SI, DI, BP ; DrawObject proc near mov ax,SCREEN_WIDTH mul dx ; calcule l'offset de départ dans ; la mémoire vidéo là où rangé de ; l'image sera affichée shr cx,1 shr cx,1 shr cx,1 ;divise la coordonnée X en pixels ; par 8 pour obtenir la coordonnée X ; en octets add ax,cx ; offset de destination dans la mémoire ; vidéo pour l'image mov di,ax ; ES:DI pointe sur l'adresse où ; l'image sera copiée dans la ; mémoire vidéo lodsw mov dx,ax ;nombre de lignes dans l'image lodsw ;nombre d'octets à travers l'image mov bp,SCREEN_WIDTH sub bp,ax ; nombre d'octets à ajouter à l'offset ; de la mémoire vidéo après avoir copié ; une ligne de l'image dans la mémoire vidéo ; pour pointer sur l'adresse où ira la prochaine ; ligne de l'image ; dans la mémoire vidéo DrawLoop: mov cx,ax ;largeur de l'image rep movsb ;copie la prochaine ligne de l'image ; dans la mémoire vidéo add di,bp ;pointe sur l'adresse où ; ira la prochaine ligne dans ; la mémoire vidéo dec dx ;décompte les lignes de l'image jnz DrawLoop ret DrawObject endp ; Code ends end Start