MC_POUR_P2=0 .386P .MODEL FLAT _TEXT Segment dword public 'code' Assume cs:_TEXT, ds:_DATA public Effacer_ecran_courant public Copier_image_dans_brosse public Permuter_dans_l_image_les_couleurs public Remap_general_LOWLEVEL public Scroll_picture public Clavier_americain public Clavier_de_depart public Recuperer_nb_lignes public Passer_en_mode_texte public Detection_souris public Get_input public Set_mouse_position public Clip_mouse public Sensibilite_souris public Attendre_fin_de_click public Set_color public Set_palette public Palette_64_to_256 public Palette_256_to_64 public Effacer_image_courante public Effacer_image_courante_Stencil public Wait_VBL public Tempo_jauge public Round_div public Palette_Compter_nb_couleurs_utilisees public Get_key public Pixel_dans_ecran_courant public Lit_pixel_dans_ecran_courant public Lit_pixel_dans_ecran_brouillon public Lit_pixel_dans_ecran_backup public Lit_pixel_dans_ecran_feedback public Pixel_dans_brosse public Lit_pixel_dans_brosse public Freespace public Type_de_lecteur_de_disquette public Disk_map public Disque_dur_present public Lecteur_CDROM_present public Ellipse_Calculer_limites public Pixel_dans_ellipse public Pixel_dans_cercle public Bit public Couleur_ILBM_line public Initialiser_chrono public Tester_chrono public Remplacer_une_couleur public Remplacer_toutes_les_couleurs_dans_limites public Meilleure_couleur public Meilleure_couleur_sans_exclusion public Effet_Colorize_interpole public Effet_Colorize_additif public Effet_Colorize_soustractif public Effet_Trame public Flip_X_LOWLEVEL public Flip_Y_LOWLEVEL public Rotate_90_deg_LOWLEVEL public Rotate_180_deg_LOWLEVEL public Zoomer_une_ligne public Copier_une_partie_d_image_dans_une_autre extrn Ecran_backup :dword extrn Largeur_ecran :word extrn Hauteur_ecran :word extrn Forcer_affichage_curseur :byte extrn Afficher_curseur :near extrn Effacer_curseur :near extrn Calculer_coordonnees_pinceau:near extrn Principal_Palette :dataptr extrn Exclude_color :dataptr ; Données pour le colorize extrn Table_de_multiplication_par_Facteur_A:dataptr extrn Table_de_multiplication_par_Facteur_B:dataptr extrn FX_Feedback_Ecran:dword ; Données pour les trames extrn Trame:dataptr ; Sprite de la trame extrn Trame_Largeur:word ; Largeur de la trame extrn Trame_Hauteur:word ; Hauteur de la trame ; Données sur l'image extrn Principal_Ecran :dword extrn Principal_Image_modifiee :byte extrn Principal_Largeur_image :word extrn Principal_Hauteur_image :word extrn Principal_Split :word extrn Principal_X_Zoom :word extrn Loupe_Mode:byte extrn Limite_Haut :word extrn Limite_Bas :word extrn Limite_Gauche :word extrn Limite_Droite :word ; Données sur le brouillon extrn Brouillon_Ecran :dword extrn Brouillon_Largeur_image :word extrn Brouillon_Hauteur_image :word ; Données sur la brosse extrn Brosse :dword extrn Brosse_Largeur :word extrn Brosse_Hauteur :word ; Données sur le menu extrn Menu_Ordonnee:word ; Données sur la souris extrn Mouse_X:word extrn Mouse_Y:word extrn Mouse_K:byte extrn INPUT_Nouveau_Mouse_X:word extrn INPUT_Nouveau_Mouse_Y:word extrn INPUT_Nouveau_Mouse_K:byte extrn Mouse_Facteur_de_correction_X:byte extrn Mouse_Facteur_de_correction_Y:byte extrn Operation_Taille_pile:byte extrn Operation_en_cours:word extrn Operation_dans_loupe:byte ; Données sur les touches extrn Touche :word extrn Touche_ASCII :byte extrn Config_Touche :dword extrn INPUT_Keyb_mode:byte extrn Autoriser_changement_de_couleur_pendant_operation:byte ; Données sur les ellipses et les cercles: extrn Table_des_carres :dataptr extrn Ellipse_Curseur_X :dword extrn Ellipse_Curseur_Y :dword extrn Ellipse_Rayon_vertical_au_carre :dword extrn Ellipse_Rayon_horizontal_au_carre:dword extrn Ellipse_Limite_High :dword extrn Ellipse_Limite_Low :dword extrn Cercle_Curseur_X :dword extrn Cercle_Curseur_Y :dword extrn Cercle_Limite :dword extrn LBM_Buffer:dataptr extrn HBPm1 :byte extrn MODE_X_Valeur_initiale_de_esi:dword ; Variables de travail (aucun extrn MODE_X_Valeur_initiale_de_edi:dword ; rapport avec leurs noms !!) extrn MC_Indice:dword ; pour indexer la table d'exclusion extrn MC_Table_differences:dword ; Table précalculée des différences extrn MC_DR:dword extrn MC_DV:dword extrn MC_DB:dword extrn Etat_chrono :byte extrn Chrono_cmp :dword extrn Chrono_delay:dword ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -- Néttoyer l'écran courant -- Effacer_ecran_courant proc near push edi mov edi,Principal_Ecran xor eax,eax xor ecx,ecx mov ax,Principal_Largeur_image mov cx,Principal_Hauteur_image mul ecx mov ecx,eax xor eax,eax ; On efface ECX pixels: shr ecx,1 jnc Effacer_ecran_courant_Longueur_multiple_de_2 stosb Effacer_ecran_courant_Longueur_multiple_de_2: shr ecx,1 jnc Effacer_ecran_courant_Longueur_multiple_de_4 stosw Effacer_ecran_courant_Longueur_multiple_de_4: rep stosd pop edi ret Effacer_ecran_courant endp ; -- Copier une partie de l'image dans la brosse -- Copier_image_dans_brosse proc near push ebp mov ebp,esp arg Debut_X:word,Debut_Y:word,Largeur:word,Hauteur:word,Largeur_image:word push ebx push esi push edi ; On place dans ESI l'adresse de départ de l'image: xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Debut_Y mov bx,Largeur_image mov cx,Debut_X mul ebx mov esi,Principal_Ecran add eax,ecx add esi,eax ; On place dans EDI l'adresse de départ de la brosse: mov edi,Brosse ; On place dans EAX la distance entre la fin d'une ligne de l'image et le ; début de la suivante: xor eax,eax mov ax,Largeur_image sub ax,Largeur ; On place dans DX le nombre de lignes à copier: mov dx,Hauteur xor ecx,ecx Copier_image_dans_brosse_Pour_chaque_ligne: ; On met dans CX le nombre de pixels à copier sur la ligne: mov cx,Largeur ; On recopie CX fois les pixels: shr cx,1 jnc Copier_image_dans_brosse_Largeur_multiple_de_2 movsb Copier_image_dans_brosse_Largeur_multiple_de_2: shr cx,1 jnc Copier_image_dans_brosse_Largeur_multiple_de_4 movsw Copier_image_dans_brosse_Largeur_multiple_de_4: rep movsd ; On rajoute à ESI la distance EAX add esi,eax ; On passe à la ligne suivante s'il y en a une: dec dx jnz Copier_image_dans_brosse_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Copier_image_dans_brosse endp ; -- Permuter deux couleurs dans l'image -- Permuter_dans_l_image_les_couleurs proc near push ebp mov ebp,esp arg Couleur_1:byte,Couleur_2:byte push ebx ; On place dans EBX l'adresse du début de l'image mov ebx,Principal_Ecran ; On place dans ECX le nb de pixels à traiter xor eax,eax xor ecx,ecx mov ax,Principal_Largeur_image mov cx,Principal_Hauteur_image mul ecx mov ecx,eax ; On place dans DL la 1ère couleur à échanger mov dl,Couleur_1 ; On place dans DH la 2ème couleur à échanger mov dh,Couleur_2 Permuter_dans_l_image_les_couleurs_Pour_chaque_pixel: ; On lit la couleur du pixel en cours: mov al,[ebx] ; Si le pixel est de Couleur_1 cmp al,dl jne Permuter_dans_l_image_les_couleurs_Test_1 ; On le met en Couleur_2 mov [ebx],dh jmp Permuter_dans_l_image_les_couleurs_Fin_des_tests Permuter_dans_l_image_les_couleurs_Test_1: ; Si le pixel est de Couleur_2 cmp al,dh jne Permuter_dans_l_image_les_couleurs_Fin_des_tests ; On le met en Couleur_1 mov [ebx],dl Permuter_dans_l_image_les_couleurs_Fin_des_tests: ; On passe au pixel suivant: dec ecx jnz Permuter_dans_l_image_les_couleurs_Pour_chaque_pixel pop ebx mov esp,ebp pop ebp ret Permuter_dans_l_image_les_couleurs endp ; -- Remplacer une couleur par une autre dans un buffer -- Remap_general_LOWLEVEL proc near push ebp mov ebp,esp arg Tab_conv:dword,Buffer:dword,Largeur:word,Hauteur:word,Largeur_buf:word push ebx push edi push esi xor esi,esi ; On place dans EBX l'adresse de la table de conversion mov ebx,Tab_conv ; On place dans EDI l'adresse du début de l'image mov edi,Buffer ; On place dans ESI la distance qu'il y a entre la fin d'une ligne de ; l'image et le début de la suivante: mov si,Largeur_buf xor eax,eax ; Ces deux initialisations sont faites ici pour éviter mov dx,Hauteur ; une pénalité sur la modificatione de SI sub si,Largeur Remap_general_Pour_chaque_ligne: mov cx,Largeur Remap_general_Pour_chaque_pixel: ; On lit la couleur du pixel en cours: mov al,[edi] ; On fait la conversion de la couleur à l'aide de la table de conversion mov al,[ebx+eax] ; On replace la nouvelle couleur à l'emplacement en cours mov [edi],al ; On passe au pixel suivant: inc edi dec cx jnz Remap_general_Pour_chaque_pixel ; On passe à la ligne suivante: add edi,esi dec dx jnz Remap_general_Pour_chaque_ligne pop esi pop edi pop ebx mov esp,ebp pop ebp ret Remap_general_LOWLEVEL endp Scroll_picture proc near push ebp mov ebp,esp arg Decalage_X:word,Decalage_Y:word push ebx push esi push edi ; On place dans ESI l'adresse du backup, qui sera la source de la copie mov esi,Ecran_backup ; On place dans EDI l'adresse de Principal_Ecran[Decalage_Y][Decalage_X] mov edi,Principal_Ecran xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,Decalage_Y mov bx,Principal_Largeur_image ; EBX contient la largeur de l'image mov cx,Decalage_X ; ECX contient le Decalage_X mul ebx add edi,eax add edi,ecx ; On place dans AX le nb de pixels à copier à la droite de ; (Decalage_X,Decalage_Y) mov ax,bx sub ax,cx ; On place dans DX le nb de lignes à copier sous (Decalage_X,Decalage_Y) mov dx,Principal_Hauteur_image sub dx,Decalage_Y jz Scroll_picture_Fin_de_traitement_Bas Scroll_picture_Pour_chaque_ligne_Bas: ; On place dans CX le nb de pixels à copier mov cx,ax ; On fait une copier 32 bits de CX pixels de ESI vers EDI shr cx,1 jnc Scroll_picture_Bas_Droite_Multiple_de_2 movsb Scroll_picture_Bas_Droite_Multiple_de_2: shr cx,1 jnc Scroll_picture_Bas_Droite_Multiple_de_4 movsw Scroll_picture_Bas_Droite_Multiple_de_4: rep movsd ; On replace EDI en tout début de ligne sub edi,ebx ; On place dans CX le nb de pixels à copier mov cx,Decalage_X ; On fait une copier 32 bits de CX pixels de ESI vers EDI shr cx,1 jnc Scroll_picture_Bas_Gauche_Multiple_de_2 movsb Scroll_picture_Bas_Gauche_Multiple_de_2: shr cx,1 jnc Scroll_picture_Bas_Gauche_Multiple_de_4 movsw Scroll_picture_Bas_Gauche_Multiple_de_4: rep movsd ; On passe à la ligne suivante ;; add esi,ebx add edi,ebx dec dx jnz Scroll_picture_Pour_chaque_ligne_Bas Scroll_picture_Fin_de_traitement_Bas: ; On vient de faire le traitement pour toutes les lignes placées sous ; Decalage_Y. On va maintenant s'occuper de la partie au-dessus. ; On place dans EDI l'adresse de Principal_Ecran[0][Decalage_X] movzx edi,Decalage_X add edi,Principal_Ecran ; On place dans DX le nb de lignes à copier au-dessus de ; (Decalage_X,Decalage_Y) mov dx,Decalage_Y cmp dx,0 je Scroll_picture_Fin_de_traitement_Haut Scroll_picture_Pour_chaque_ligne_Haut: ; On place dans CX le nb de pixels à copier mov cx,ax ; On fait une copier 32 bits de CX pixels de ESI vers EDI shr cx,1 jnc Scroll_picture_Haut_Droite_Multiple_de_2 movsb Scroll_picture_Haut_Droite_Multiple_de_2: shr cx,1 jnc Scroll_picture_Haut_Droite_Multiple_de_4 movsw Scroll_picture_Haut_Droite_Multiple_de_4: rep movsd ; On replace EDI en tout début de ligne sub edi,ebx ; On place dans CX le nb de pixels à copier mov cx,Decalage_X ; On fait une copier 32 bits de CX pixels de ESI vers EDI shr cx,1 jnc Scroll_picture_Haut_Gauche_Multiple_de_2 movsb Scroll_picture_Haut_Gauche_Multiple_de_2: shr cx,1 jnc Scroll_picture_Haut_Gauche_Multiple_de_4 movsw Scroll_picture_Haut_Gauche_Multiple_de_4: rep movsd ; On passe à la ligne suivante ;; add esi,ebx add edi,ebx dec dx jnz Scroll_picture_Pour_chaque_ligne_Haut Scroll_picture_Fin_de_traitement_Haut: pop edi pop esi pop ebx mov esp,ebp pop ebp ret Scroll_picture endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ---- Gestion du mode texte pour pouvoir repasser dans le mode d'origine ---- ; -- Récupérer les informations du mode texte initial -- Recuperer_nb_lignes proc near pushad mov ax,1130h xor bh,bh push es int 10h pop es inc dl mov [esp+28],dl popad ret Recuperer_nb_lignes endp ; -- Passer dans un mode texte 25 ou 50 lignes -- Passer_en_mode_texte proc near push ebp mov ebp,esp arg Nb_lignes:byte push ax push bx push dx mov ax,3 int 10h cmp Nb_lignes,50 jne pas_mode_50 mov ax,1112h xor bl,bl mov dl,50 int 10h pas_mode_50: pop dx pop bx pop ax mov esp,ebp pop ebp ret Passer_en_mode_texte endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ----------------------- Passer en clavier américain ------------------------ Clavier_americain proc near push ax push bx mov ax,0AD83h int 2Fh mov INPUT_Keyb_mode,bl mov ax,0AD82h xor bl,bl int 2Fh pop bx pop ax ret Clavier_americain endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -------------------- Repasser dans le clavier de départ -------------------- Clavier_de_depart proc near push ax push bx mov ax,0AD82h mov bl,INPUT_Keyb_mode int 2Fh pop bx pop ax ret Clavier_de_depart endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ---------------- Détection de la présence d'un driver souris --------------- Detection_souris proc near push bx xor ax,ax int 33h pop bx ret Detection_souris endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ------- Récupération des entrées de l'utilisateur (souris/clavier) --------- Get_input proc near pushad ; Gestion de la souris: ; Appel à l'interruption pour connaître les nouvelles coordonnées: mov ax,0003h int 33h ; CX = Position X ; DX = Position Y ; BL = Etat des boutons ; Dans le cas où les 2 boutons sont enfoncés... cmp bl,3 jb Get_input_Saut_inhibe_2_boutons ; ... on n'en considère aucun: xor bl,bl Get_input_Saut_inhibe_2_boutons: ; On transfère dans les variables les nouvelles valeurs: mov ax,cx mov cl,Mouse_Facteur_de_correction_X shr ax,cl mov cl,Mouse_Facteur_de_correction_Y shr dx,cl mov INPUT_Nouveau_Mouse_X,ax mov INPUT_Nouveau_Mouse_Y,dx mov INPUT_Nouveau_Mouse_K,bl ; Gestion des touches: ; Par défaut -> pas de touches enfoncées mov Touche,0 mov Touche_ASCII,0 ; Appel à l'interruption pour savoir si une touche est appuyée mov ah,11h int 16h ; ZERO -> Pas de touche ; S'il n'y en a pas, on se contente de la valeur par défaut et on sort jz Get_input_Pas_de_touche ; Sinon, appel à l'interruption pour connaître son scancode mov ah,10h int 16h ; AH = Scancode ; AL = Caractère ASCII ; On place le scan code dans la partie basse de [Touche] mov byte ptr[Touche],ah mov Touche_ASCII,al ; ... et le code ASCII dans Touche_ASCII ; Appel à l'interruption pour connaitre l'état des touches de contrôle mov ah,02h int 16h ; AL = Etat des touches de contrôle ; On oublie les informations sur Insert, CapsLock, NumLock et ScrollLock and al,00001111b ; On associe les deux Shifts (2 bits de poids faible) mov ah,al and ah,00000001b shr al,1 or al,ah ; On met le resultat dans la partie haute de [Touche] mov byte ptr[Touche+1],al ; On gère le cas où [Touche] est un déplacement du curseur mov ax,Touche ; Test [Touche] = Emulation de MOUSE UP cmp ax,word ptr[Config_Touche] jne Get_input_Pas_emulation_Haut cmp INPUT_Nouveau_Mouse_Y,0 je Get_input_Pas_de_touche dec INPUT_Nouveau_Mouse_Y jmp Get_input_Fin_emulation Get_input_Pas_emulation_Haut: ; Test [Touche] = Emulation de MOUSE DOWN cmp ax,word ptr[Config_Touche+2] jne Get_input_Pas_emulation_Bas mov ax,INPUT_Nouveau_Mouse_Y mov bx,Hauteur_ecran dec bx cmp ax,bx jae Get_input_Pas_de_touche inc ax mov INPUT_Nouveau_Mouse_Y,ax jmp Get_input_Fin_emulation Get_input_Pas_emulation_Bas: ; Test [Touche] = Emulation de MOUSE LEFT cmp ax,word ptr[Config_Touche+4] jne Get_input_Pas_emulation_Gauche cmp INPUT_Nouveau_Mouse_X,0 je Get_input_Pas_de_touche dec INPUT_Nouveau_Mouse_X jmp Get_input_Fin_emulation Get_input_Pas_emulation_Gauche: ; Test [Touche] = Emulation de MOUSE RIGHT cmp ax,word ptr[Config_Touche+6] jne Get_input_Pas_emulation_Droite mov ax,INPUT_Nouveau_Mouse_X mov bx,Largeur_ecran dec bx cmp ax,bx jae Get_input_Pas_de_touche inc ax mov INPUT_Nouveau_Mouse_X,ax jmp Get_input_Fin_emulation Get_input_Pas_emulation_Droite: ; Test [Touche] = Emulation de MOUSE CLICK LEFT cmp ax,word ptr[Config_Touche+8] jne Get_input_Pas_emulation_Click_gauche mov INPUT_Nouveau_Mouse_K,1 jmp Get_input_Pas_de_touche Get_input_Pas_emulation_Click_gauche: ; Test [Touche] = Emulation de MOUSE CLICK RIGHT cmp ax,word ptr[Config_Touche+10] jne Get_input_Pas_de_touche mov INPUT_Nouveau_Mouse_K,2 jmp Get_input_Pas_de_touche Get_input_Fin_emulation: mov cl,Mouse_Facteur_de_correction_X mov ax,INPUT_Nouveau_Mouse_X mov dx,INPUT_Nouveau_Mouse_Y shl ax,cl mov cl,Mouse_Facteur_de_correction_Y shl dx,cl mov cx,ax mov ax,0004h int 33h Get_input_Pas_de_touche: ; Gestion "avancée" du curseur: interdire la descente du curseur dans le ; menu lorsqu'on est en train de travailler dans l'image cmp Operation_Taille_pile,0 je Get_input_Pas_de_correction xor bl,bl ; BL va indiquer si on doit corriger la position du curseur ; Si le curseur ne se trouve plus dans l'image mov ax,Menu_Ordonnee cmp INPUT_Nouveau_Mouse_Y,ax jb Get_input_Fin_correction_Y ; On bloque le curseur en fin d'image dec ax ; La ligne !!au-dessus!! du menu inc bl mov INPUT_Nouveau_Mouse_Y,ax Get_input_Fin_correction_Y: cmp Loupe_Mode,0 jz Get_input_Fin_correction_X mov ax,INPUT_Nouveau_Mouse_X cmp Operation_dans_loupe,0 jnz Get_input_X_dans_loupe mov dx,Principal_Split cmp ax,dx jb Get_input_Fin_correction_X dec dx inc bl mov INPUT_Nouveau_Mouse_X,dx jmp Get_input_Fin_correction_X Get_input_X_dans_loupe: mov dx,Principal_X_Zoom cmp ax,dx jae Get_input_Fin_correction_X inc bl mov INPUT_Nouveau_Mouse_X,dx Get_input_Fin_correction_X: or bl,bl jz Get_input_Pas_de_correction_du_curseur mov cl,Mouse_Facteur_de_correction_X mov ax,INPUT_Nouveau_Mouse_X mov dx,INPUT_Nouveau_Mouse_Y shl ax,cl mov cl,Mouse_Facteur_de_correction_Y shl dx,cl mov cx,ax mov ax,0004h int 33h Get_input_Pas_de_correction_du_curseur: mov ax,Touche or ax,ax jz Get_input_Pas_de_correction ; Enfin, on inhibe les touches (sauf si c'est un changement de couleur ; ou de taille de pinceau lors d'une des operations suivantes: ; OPERATION_DESSIN_CONTINU, OPERATION_DESSIN_DISCONTINU, OPERATION_SPRAY cmp Autoriser_changement_de_couleur_pendant_operation,0 jz Get_input_Il_faut_inhiber_les_touches ; A ce stade là, on sait qu'on est dans une des 3 opérations supportant ; le changement de couleur ou de taille de pinceau. cmp ax,word ptr [Config_Touche+12] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+14] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+16] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+18] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+20] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+22] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+24] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+26] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+28] je Get_input_Pas_de_correction cmp ax,word ptr [Config_Touche+30] je Get_input_Pas_de_correction Get_input_Il_faut_inhiber_les_touches: mov word ptr Touche,0 Get_input_Pas_de_correction: ; On commence à mettre à jour les variables globales mov ax,INPUT_Nouveau_Mouse_X mov bx,INPUT_Nouveau_Mouse_Y mov cl,INPUT_Nouveau_Mouse_K cmp ax,Mouse_X jne Get_input_Affichage_curseur cmp bx,Mouse_Y jne Get_input_Affichage_curseur cmp cl,Mouse_K jne Get_input_Affichage_curseur cmp Forcer_affichage_curseur,0 je Get_input_Fin_Get_input Get_input_Affichage_curseur: mov Forcer_affichage_curseur,0 pushad call Effacer_curseur popad mov Mouse_X,ax mov Mouse_Y,bx mov Mouse_K,cl ; Calcul des coordonnées du pinceau: call Calculer_coordonnees_pinceau pushad call Afficher_curseur popad Get_input_Fin_Get_input: popad ret Get_input endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -------- Repositionner la souris en fonction de Mouse_X et Mouse_Y --------- Set_mouse_position proc near push ax push cx push dx mov cl,Mouse_Facteur_de_correction_X mov ax,Mouse_X mov dx,Mouse_Y shl ax,cl mov cl,Mouse_Facteur_de_correction_Y shl dx,cl mov cx,ax mov ax,0004h int 33h pop dx pop cx pop ax ret Set_mouse_position endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ---- Définir le champ de déplacement de la souris suivant la résolution ---- Clip_mouse proc near push ax push cx push dx ; Règle les dimensions de l'espace virtuel de la souris et corrige le ; programme pour une précision au pixel près. ; On règle le clip en hauteur: mov cl,Mouse_Facteur_de_correction_Y mov dx,Hauteur_ecran mov ax,0008h dec dx shl dx,cl xor cx,cx int 33h ; On règle le clip en largeur: mov cl,Mouse_Facteur_de_correction_X mov dx,Largeur_ecran mov ax,0007h dec dx shl dx,cl xor cx,cx int 33h pop dx pop cx pop ax ret Clip_mouse endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Sensibilite_souris proc near push ebp mov ebp,esp arg Sensibilite_X:word,Sensibilite_Y:word push ax push cx push dx ; Règlage de la sensibilité mov ax,0Fh mov cx,Sensibilite_X mov dx,Sensibilite_Y int 33h pop dx pop cx pop ax mov esp,ebp pop ebp ret Sensibilite_souris endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Attendre_fin_de_click proc near pushad Attendre_fin_de_click_Boucle: mov ax,0003h int 33h ; Fout en l'air AX,BC,CX et DX or bl,bl jnz Attendre_fin_de_click_Boucle mov Mouse_K,0 popad ret Attendre_fin_de_click endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; --------------------------- Définir une couleur ---------------------------- Set_color proc near push ebp mov ebp,esp arg Couleur:byte, Rouge:byte , Vert:byte, Bleu:byte mov dx,3C8h mov al,Couleur out dx,al inc dx mov al,Rouge out dx,al mov al,Vert out dx,al mov al,Bleu out dx,al mov esp,ebp pop ebp ret Set_color endp ; --------------------------- Définir une palette ---------------------------- Set_palette proc near push ebp mov ebp,esp arg Palette:dataptr push esi ; xor al,al ; Méthode rapide mais qui ne fonctionne pas avec ; mov dx,3C8h ; toutes les cartes vidéo. ; out dx,al ; ; inc dx ; mov esi,Palette ; mov ecx,768 ; rep outsb mov esi,Palette ; Méthode un peu plus lente mais qui fonctionne avec mov dx,3C9h ; toutes les cartes vidéo compatibles VGA. xor cl,cl Set_palette_Loop: dec dx mov al,cl out dx,al inc dx outsb outsb outsb inc cl ; On incrémente le numéro de couleur et jnz Set_palette_Loop ; s'il repasse à 0, c'est qu'on a terminé. pop esi mov esp,ebp pop ebp ret Set_palette endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ----------- Conversion d'une palette 6 bits en une palette 8 bits ---------- Palette_64_to_256 proc near push ebp mov ebp,esp arg Palette:dataptr pushad mov esi,Palette mov cx,768 Boucle_64_to_256: mov al,[esi] shl al,2 mov [esi],al inc esi dec cx jnz Boucle_64_to_256 popad mov esp,ebp pop ebp ret Palette_64_to_256 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ----------- Conversion d'une palette 8 bits en une palette 6 bits ---------- Palette_256_to_64 proc near push ebp mov ebp,esp arg Palette:dataptr pushad mov esi,Palette mov cx,768 Boucle_256_to_64: mov al,[esi] shr al,2 mov [esi],al inc esi dec cx jnz Boucle_256_to_64 popad mov esp,ebp pop ebp ret Palette_256_to_64 endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ------------ Effacer l'image courante avec une certaine couleur ------------ Effacer_image_courante proc near push ebp mov ebp,esp arg Couleur:byte push edi xor edx,edx xor eax,eax mov dx,Principal_Hauteur_image mov ax,Principal_Largeur_image mul edx mov ecx,eax mov dl,Couleur mov dh,dl mov ax,dx shl eax,16 mov ax,dx mov edi,Principal_Ecran shr ecx,1 jnc Effacer_image_Pair stosb ; On commence par se débarrasser du 1er byte ; en cas d'imparité Effacer_image_Pair: shr ecx,1 jnc Effacer_image_test_de_superiorite_a_3 stosw ; On se débarrasse des 2ème et 3ème bytes en ; cas de "non-multiplicité-de-4" Effacer_image_test_de_superiorite_a_3: ; copie 32 bits rep stosd pop edi mov esp,ebp pop ebp ret Effacer_image_courante endp ; ---- Effacer l'image courante avec une certaine couleur en mode Stencil ---- Effacer_image_courante_Stencil proc near push ebp mov ebp,esp arg Couleur:byte, Pochoir:dataptr push ebx push edi ; Dans ECX on met le nombre de pixels dans l'image xor edx,edx xor eax,eax mov dx,Principal_Hauteur_image mov ax,Principal_Largeur_image mul edx mov ecx,eax ; On met dans EBX l'adresse de la table de pochoir mov ebx,Pochoir ; On nettoie la partie haute de EDX xor edx,edx ; On met dans AL la couleur d'effacement mov al,Couleur ; On met dans EDI l'adresse de l'image à effacer mov edi,Principal_Ecran Effacer_image_Stencil_Pour_chaque_pixel: mov dl,[edi] cmp byte ptr [ebx+edx],0 jne Effacer_image_Stencil_Pas_de_modif mov [edi],al Effacer_image_Stencil_Pas_de_modif: inc edi dec ecx jnz Effacer_image_Stencil_Pour_chaque_pixel pop edi pop ebx mov esp,ebp pop ebp ret Effacer_image_courante_Stencil endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ----------------- Attendre un balayage vertical de l'écran ----------------- Wait_VBL proc near mov dx,3DAh VBL_Boucle: in al,dx test al,08h jnz VBL_Boucle VBL_Attente: in al,dx test al,08h jz VBL_Attente ret Wait_VBL endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ------ Attendre une certain laps de temps pour temporiser les jauges ------- Tempo_jauge proc near push ebp mov ebp,esp arg Vitesse:byte; mov cl,Vitesse Tempo_Boucle: call Wait_VBL dec cl jnz Tempo_Boucle mov esp,ebp pop ebp ret Tempo_jauge endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Round_div proc near push ebp mov ebp,esp arg Numerateur:dword,Diviseur:dword mov eax,Numerateur mov ecx,Diviseur xor edx,edx div ecx shr ecx,1 cmp edx,ecx jbe Round_div_Pas_arrondi_a_la_valeur_superieure inc ax Round_div_Pas_arrondi_a_la_valeur_superieure: mov esp,ebp pop ebp ret Round_div endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Palette_Compter_nb_couleurs_utilisees proc near push ebp mov ebp,esp arg Tableau:dataptr pushad ; On commence par mettre toutes les valeurs à 0 mov ecx,256 mov edi,Tableau xor eax,eax rep stosd ; On parcourt ensuite l'écran courant pour compter les utilisations des ; couleurs: ; Dans ECX on met le nombre de pixels dans l'image xor edx,edx xor eax,eax mov dx,Principal_Hauteur_image mov ax,Principal_Largeur_image mul edx mov ecx,eax ; On place dans ESI le début de l'image mov esi,Principal_Ecran ; On place dans EBX le début de la table d'utilisation des couleurs: mov ebx,Tableau ; On nettoie la partie haute de EAX xor eax,eax Compter_Pour_chaque_pixel: ; On lit la couleur dans AL (donc aussi dans EAX) mov al,[esi] ; On incrémente l'utilisation de la couleur AL: inc dword ptr[ebx+4*eax] ; On passe au pixel suivant inc esi dec ecx jnz Compter_Pour_chaque_pixel ; On va maintenant compter dans la table les couleurs utilisées: xor ax,ax ; On initialise le compteur à 0 mov cx,256 ; On initialise le compte à rebours à 256 xor edx,edx ; On initialise l'indice à 0 Compter_Pour_chaque_couleur: cmp dword ptr[ebx+4*edx],0 je Compter_Couleur_pas_utilisee inc ax Compter_Couleur_pas_utilisee: inc dx dec cx jnz Compter_Pour_chaque_couleur ; On stock le résultat (AX) dans la pile pour que le POPAD ne le détruise ; pas: mov [esp+28],ax popad mov esp,ebp pop ebp ret Palette_Compter_nb_couleurs_utilisees endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Get_key proc near mov ah,8 int 21h ret Get_key endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -- Afficher un pixel dans l'écran virtuel courant -- Pixel_dans_ecran_courant proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte xor eax,eax xor edx,edx xor ecx,ecx mov ax,Y mov dx,Principal_Largeur_image mov cx,X mul edx add eax,ecx mov dl,Couleur add eax,Principal_Ecran mov [eax],dl mov esp,ebp pop ebp ret Pixel_dans_ecran_courant endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -- Lire la couleur d'un pixel dans l'écran virtuel courant -- Lit_pixel_dans_ecran_courant proc near push ebp mov ebp,esp arg X:word,Y:word xor eax,eax xor edx,edx xor ecx,ecx mov ax,Y mov dx,Principal_Largeur_image mov cx,X mul edx add ecx,eax add ecx,Principal_Ecran mov al,[ecx] mov esp,ebp pop ebp ret Lit_pixel_dans_ecran_courant endp ; -- Lire la couleur d'un pixel dans l'écran virtuel brouillon -- Lit_pixel_dans_ecran_brouillon proc near push ebp mov ebp,esp arg X:word,Y:word xor eax,eax xor edx,edx xor ecx,ecx mov ax,Y mov dx,Brouillon_Largeur_image mov cx,X mul edx add ecx,eax add ecx,Brouillon_Ecran mov al,[ecx] mov esp,ebp pop ebp ret Lit_pixel_dans_ecran_brouillon endp ; -- Lire la couleur d'un pixel dans l'écran virtuel de sauvegarde -- Lit_pixel_dans_ecran_backup proc near push ebp mov ebp,esp arg X:word,Y:word xor ecx,ecx xor edx,edx xor eax,eax mov cx,X mov dx,Y mov ax,Principal_Largeur_image add ecx,Ecran_backup mul edx add ecx,eax mov al,[ecx] mov esp,ebp pop ebp ret Lit_pixel_dans_ecran_backup endp ; -- Lire la couleur d'un pixel dans l'écran de feedback -- Lit_pixel_dans_ecran_feedback proc near push ebp mov ebp,esp arg X:word,Y:word xor eax,eax xor edx,edx xor ecx,ecx mov ax,Y mov dx,Principal_Largeur_image mov cx,X mul edx add ecx,eax add ecx,FX_Feedback_Ecran mov al,[ecx] mov esp,ebp pop ebp ret Lit_pixel_dans_ecran_feedback endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -- Définir la couleur d'un pixel dans la brosse -- Pixel_dans_brosse proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte xor eax,eax xor edx,edx xor ecx,ecx mov ax,Y mov dx,Brosse_Largeur mov cx,X mul edx add eax,ecx mov dl,Couleur add eax,Brosse mov [eax],dl mov esp,ebp pop ebp ret Pixel_dans_brosse endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; -- Lire la couleur d'un pixel dans la brosse -- Lit_pixel_dans_brosse proc near push ebp mov ebp,esp arg X:word,Y:word xor eax,eax xor edx,edx xor ecx,ecx mov ax,Y mov dx,Brosse_Largeur mov cx,X mul edx add eax,ecx add eax,Brosse mov al,[eax] mov esp,ebp pop ebp ret Lit_pixel_dans_brosse endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Renseigne sur la quantité de place libre sur un lecteur quelconque ; ; Entrée: Octet = n° de lecteur (0:courant, 1:A, 2:B, 3:C, 4:D, ...) ; ; Sortie: Long = -1 : Lecteur invalide ; sinon : Place libre sur le lecteur Freespace proc near push ebp mov ebp,esp arg Numero_de_lecteur:byte push ebx push cx push edx ; On appelle l'interruption du DOS mov ah,36h mov dl,Numero_de_lecteur int 21h ; On regarde si AX = 0FFFFh (dans ce cas => Erreur) cmp ax,0FFFFh je Freespace_Erreur ; Sinon: mul bx ; DX:AX = AX*BX push ax ; EAX = DX:AX = AX*BX mov ax,dx shl eax,16 pop ax xor ebx,ebx ; EDX:EAX = AX*BX*CX mov bx,cx mul ebx jmp Freespace_Fin_de_traitement Freespace_Erreur: mov eax,0FFFFFFFFh Freespace_Fin_de_traitement: pop edx pop cx pop ebx mov esp,ebp pop ebp ret Freespace endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Renseigne sur un lecteur de disquette: ; ; Entrée: Octet = n° du lecteur de disquette (commence à 0) ; ; Sortie: Octet = 0 : Pas de lecteur ; 1 : Lecteur 360 Ko ; 2 : Lecteur 1.2 Mo ; 3 : Lecteur 720 Ko ; 4 : Lecteur 1.4 Mo ; 5 : Lecteur 2.8 Mo (???) ; 6 : Lecteur 2.8 Mo Type_de_lecteur_de_disquette proc near push ebp mov ebp,esp arg Numero_de_lecteur:byte xor eax,eax mov al,10h out 70h,al in al,71h cmp Numero_de_lecteur,0 jne Type_de_lecteur_de_disquette_B shr al,4 jmp Type_de_lecteur_de_disquette_Fin_de_traitement Type_de_lecteur_de_disquette_B: and al,0Fh Type_de_lecteur_de_disquette_Fin_de_traitement: mov esp,ebp pop ebp ret Type_de_lecteur_de_disquette endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Renseigne sur la lettre logique d'un lecteur ; (utile pour tester si un lecteur de disquette est A: ou B: aux yeux du DOS) ; ; Entrée: Octet = n° du lecteur (1=A, 2=B ...) ; ; Sortie: Octet = 0FFh : Pas de lecteur (???) ; sinon: numéro représentant la lettre logique du lecteur ; (commence à 1) Disk_map proc near push ebp mov ebp,esp arg Numero_de_lecteur:byte push bx xor eax,eax mov ax,440Eh mov bl,Numero_de_lecteur int 21h jnc Disk_map_OK mov al,0FFh jmp Disk_map_Fin Disk_map_OK: or al,al jnz Disk_map_Fin mov al,Numero_de_lecteur Disk_map_Fin: xor ah,ah pop bx mov esp,ebp pop ebp ret Disk_map endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Renseigne sur un disque dur: ; ; Entrée: Octet = n° du disque dur (0:C, 1:D, 2:E, ...) ; ; Sortie: Octet = 0 : Pas de lecteur ; 1 : Disque dur présent Disque_dur_present proc near push ebp mov ebp,esp arg Numero_de_disque:byte pushad ; On se renseigne sur le disque à l'aide de la fonction 08h de ; l'interruption 13h mov ah,08h mov dl,Numero_de_disque push es or dl,80h int 13h ; modifie ES! pop es ; POP du ES memorisé juste avant l'INT 13h ; Le disque est absent si CF ou si AH<>0 jc Disque_dur_present_Pas_de_disque or ah,ah jnz Disque_dur_present_Pas_de_disque ; Il peut arriver que ces tests soient insuffisants, il faut alors comparer ; le n° du drive avec le nb de disques durs installés (nb dans DL) mov ah,Numero_de_disque inc ah cmp ah,dl ja Disque_dur_present_Pas_de_disque ; On doit maintenant pouvoir supposer que le disque en question est bien ; installé mov byte ptr[esp+28],1 jmp Disque_dur_present_Fin_de_traitement Disque_dur_present_Pas_de_disque: mov byte ptr[esp+28],0 Disque_dur_present_Fin_de_traitement: popad mov esp,ebp pop ebp ret Disque_dur_present endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Renseigne sur un lecteur CD-ROM: ; ; Entrée : Octet = n° du lecteur (0:A, 1:B, 2:C, ...) ; ; Sortie : Octet = 0 : Le lecteur n'est pas un CD-ROM ; 1 : Le lecteur est un CD-ROM Lecteur_CDROM_present proc near push ebp mov ebp,esp arg Numero_de_lecteur:byte push bx push cx push dx ; Détection du n° de version de MSCDEX mov ax,150Ch int 2Fh cmp bh,2 jb Lecteur_CDROM_present_Mauvaise_version ; On est donc avec une version de MSCDEX assez récente (enfin, disons... ; ... pas trop obsolète). ; On demande des informations sur le lecteur de la part de MSCDEX v2.00 mov ax,150Bh xor ch,ch mov cl,Numero_de_lecteur int 2Fh ; On détermine maintenant si le lecteur est de type CD-ROM grâce aux ; résultats cmp bx,0ADADh jne Lecteur_CDROM_present_Pas_CDROM or ax,ax jz Lecteur_CDROM_present_Pas_CDROM jmp Lecteur_CDROM_present_CDROM_OK Lecteur_CDROM_present_Mauvaise_version: ; On va être obligé de traiter le problème avec une vieille version ; merdique de MSCDEX: ça me fait chier, plus personne ne devrait posséder ; des antiquités pareilles. Moi je dit que ce genre de personne ne mérite ; pas de pouvoir utiliser GRAFX 2 ! ; mais bon... comme je me trouve dans un bon jour, je vais faire un effort ; et je vais demander quelques informations à pépé MSCDEX. Mais faut pas ; abuser: le gars il a intérêt à avoir ses lecteurs CD-ROM les uns à la ; suite des autres... je ne m'amuserai pas à prendre en compte un cas ; aussi chiant... enfin tu me diras, le type est suffisamment emmerdant pour ; avoir une vieille version de MSCDEX, il serait bien du genre à mettre ses ; lecteurs CD-ROM dans n'importe quel ordre, le gars. mov ax,1500h xor bx,bx int 2Fh cmp Numero_de_lecteur,cl ; Si le lecteur demandé se trouve avant le premier lecteur CD, jb Lecteur_CDROM_present_Pas_CDROM ; c'est que c'est pas un lecteur CD-ROM add cx,bx cmp Numero_de_lecteur,cl ; Pareille, si le lecteur est après le dernier, jge Lecteur_CDROM_present_Pas_CDROM ; c'est que c'est pas un lecteur CD-ROM Lecteur_CDROM_present_CDROM_OK: mov ax,1 jmp Lecteur_CDROM_present_Fin_de_traitement Lecteur_CDROM_present_Pas_CDROM: xor ax,ax Lecteur_CDROM_present_Fin_de_traitement: pop dx pop cx pop bx mov esp,ebp pop ebp ret Lecteur_CDROM_present endp ; -- Calculer les variables globales nécessaires au tracé d'une ellipse -- Ellipse_Calculer_limites proc near push ebp mov ebp,esp arg Rayon_horizontal:word,Rayon_vertical:word push ebx mov ebx,offset Table_des_carres xor eax,eax xor ecx,ecx mov ax,Rayon_horizontal mov cx,Rayon_vertical mov eax,[ebx+4*eax] mov ecx,[ebx+4*ecx] mov Ellipse_Rayon_horizontal_au_carre,eax mov Ellipse_Rayon_vertical_au_carre,ecx mul ecx mov Ellipse_Limite_High,edx mov Ellipse_Limite_Low,eax pop ebx mov esp,ebp pop ebp ret Ellipse_Calculer_limites endp ; -- Teste si un point se trouve ou non dans l'ellipse en cours de tracé -- Pixel_dans_ellipse proc near push ebx push esi push edi ; On fait pointer EBX sur la table des puissances de 2: mov ebx,offset Table_des_carres ; On place dans ECX la valeur absolue de X mov ecx,Ellipse_Curseur_X or ecx,ecx jnl Pixel_dans_ellipse_X_positif neg ecx Pixel_dans_ellipse_X_positif: ; On place dans EAX la valeur X^2 mov eax,[ebx+4*ecx] ; On met dans EDX:EAX la valeur ( B^2 x X^2 ): mul dword ptr[Ellipse_Rayon_vertical_au_carre] ; On stock le résultat ( B^2 x X^2 ) dans EDI:ESI : mov edi,edx mov esi,eax ; On place dans ECX la valeur absolue de Y mov ecx,Ellipse_Curseur_Y or ecx,ecx jnl Pixel_dans_ellipse_Y_positif neg ecx Pixel_dans_ellipse_Y_positif: ; On place dans EAX la valeur Y^2 mov eax,[ebx+4*ecx] ; On met dans EDX:EAX la valeur ( A^2 x Y^2 ): mul dword ptr[Ellipse_Rayon_horizontal_au_carre] ; On fait la somme de ( B^2 x X^2 ) avec ( A^2 x Y^2 ) dans EDX:EAX : add eax,esi adc edx,edi ; On regarde si cette valeur est inferieure ou égale à la limite de ; l'ellipse: cmp edx,Ellipse_Limite_High je Pixel_dans_ellipse_Regarder_la_partie_basse setb al jmp Pixel_dans_ellipse_Fin_de_traitement Pixel_dans_ellipse_Regarder_la_partie_basse: cmp eax,Ellipse_Limite_Low setbe al Pixel_dans_ellipse_Fin_de_traitement: movzx eax,al pop edi pop esi pop ebx ret Pixel_dans_ellipse endp ; -- Teste si un point se trouve ou non dans le cercle en cours de tracé -- Pixel_dans_cercle proc near push ebx ; On fait pointer EBX sur la table des puissances de 2: mov ebx,offset Table_des_carres ; On place dans EAX et ECX les valeurs absolues de X et Y: mov eax,Cercle_Curseur_X mov ecx,Cercle_Curseur_Y or eax,eax jnl Pixel_dans_cercle_X_positif neg eax Pixel_dans_cercle_X_positif: or ecx,ecx jnl Pixel_dans_cercle_Y_positif neg ecx Pixel_dans_cercle_Y_positif: ; On place dans EAX et ECX les valeurs X^2 et Y^2 : mov eax,[ebx+4*eax] mov ecx,[ebx+4*ecx] ; On place dans EAX la somme ( X^2 + Y^2 ) : add eax,ecx ; On regarde si la distance est dans la limite du cercle: cmp eax,Cercle_Limite setbe al and eax,0FFh pop ebx ret Pixel_dans_cercle endp ; -- Extraire 1 bit d'un octet -- Bit proc near push ebp mov ebp,esp arg Octet:byte,Rang:byte mov al,Octet mov cl,Rang shr al,cl and al,1 mov esp,ebp pop ebp ret Bit endp ; -- Trouver la couleur du pixel (ILBM) à afficher en Pos_X -- Couleur_ILBM_line proc near push ebp mov ebp,esp arg Pos_X:word, Vraie_taille_ligne:word push bx push esi xor eax,eax mov ax,Pos_X ; CL sera le rang auquel on extrait les bits de la couleur mov cl,7 and al,7 sub cl,al ; ESI pointe sur le Buffer de ligne ILBM mov esi,LBM_Buffer xor bl,bl xor dh,dh mov dl,HBPm1 CIL_Loop: push dx mov ax,Vraie_taille_ligne mul dx add ax,Pos_X shr ax,3 mov bh,[esi+eax] shr bh,cl and bh,1 shl bl,1 add bl,bh pop dx dec dl jns CIL_Loop mov al,bl pop esi pop bx mov esp,ebp pop ebp ret Couleur_ILBM_line endp ; -- Démarrer le chrono -- Initialiser_chrono proc near push ebp mov ebp,esp arg Delai:dword mov eax,Delai mov Chrono_delay,eax xor ah,ah int 1Ah mov word ptr[Chrono_cmp+0],dx mov word ptr[Chrono_cmp+2],cx mov esp,ebp pop ebp ret Initialiser_chrono endp ; -- Met Etat_chrono à 1 si le compte à rebours est atteint -- Tester_chrono proc near xor ah,ah int 1Ah ; On transfère CX:DX dans EAX mov ax,cx shl eax,16 mov ax,dx sub eax,Chrono_delay cmp eax,Chrono_cmp jna Tester_Chrono_delay_pas_encore_atteint mov Etat_chrono,1 Tester_Chrono_delay_pas_encore_atteint: ret Tester_chrono endp ; -- Remplacement d'une couleur dans l'image par une autre -- Remplacer_une_couleur proc near push ebp mov ebp,esp arg Ancienne_couleur:byte, Nouvelle_couleur:byte push edi ; Dans ECX on met le nombre de pixels dans l'image xor edx,edx xor eax,eax mov dx,Principal_Hauteur_image mov ax,Principal_Largeur_image mul edx mov ecx,eax ; Dans AL on place la couleur que l'on veut remplacer et dans AH la couleur ; par laquelle on veut la remplacer mov al,Ancienne_couleur mov ah,Nouvelle_couleur ; EDI pointe sur le début de l'image mov edi,Principal_Ecran RUC_Pour_chaque_pixel: cmp al,[edi] jne RUC_Pas_de_changement mov [edi],ah RUC_Pas_de_changement: ; On change de pixel inc edi dec ecx jnz RUC_Pour_chaque_pixel pop edi mov esp,ebp pop ebp ret Remplacer_une_couleur endp ; -- Remplacement de toutes les couleurs dans l'image à l'aide d'une table -- ; -- et ceci en respectant les limites -- Remplacer_toutes_les_couleurs_dans_limites proc near push ebp mov ebp,esp arg Table_de_remplacement:dword push esi push edi push ebx xor ebx,ebx ; ESI pointe sur le début de la ligne d'écran actuelle mov esi,Principal_Ecran mov bx,Limite_Gauche add esi,ebx xor eax,eax mov bx,Limite_Haut mov ax,Principal_Largeur_image mul ebx add esi,eax ; EDI pointe sur la position actuelle dans l'écran mov edi,esi ; EBX pointe sur la table de remplacement mov ebx,Table_de_remplacement ; On place dans CX le nombre de lignes à traiter mov cx,Limite_Bas sub cx,Limite_Haut RTLCDL_Pour_chaque_ligne: ; On met dans DX le nombre de pixels à traiter et on nettoye la partie ; haute de EAX mov dx,Limite_Droite xor eax,eax sub dx,Limite_Gauche RTLCDL_Pour_chaque_pixel_de_ligne: mov al,[edi] mov al,[eax+ebx] mov [edi],al inc edi dec dx jns RTLCDL_Pour_chaque_pixel_de_ligne ; On change de ligne mov ax,Principal_Largeur_image add esi,eax mov edi,esi dec cx jns RTLCDL_Pour_chaque_ligne pop ebx pop edi pop esi mov esp,ebp pop ebp ret Remplacer_toutes_les_couleurs_dans_limites endp ;///////////////////////////////////////////////////////////////////////////// ;// Inclusion du fichier contenant les fonctions Meilleure_couleur* // ;///////////////////////////////////////////////////////////////////////////// IF MC_POUR_P2 INCLUDE mcpourp2.asm ELSE INCLUDE mcnormal.asm ENDIF ;///////////////////////////////////////////////////////////////////////////// ; -- Gestion de l'effet Colorize à l'aide de la méthode d'interpolation Effet_Colorize_interpole proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte push ebx push esi push edi ; Facteur_A=256*(100-Colorize_Opacite)/100 ; Facteur_B=256*( Colorize_Opacite)/100 ; ; (Couleur_dessous*Facteur_A+Couleur*Facteur_B)/256 ; On fait tout de suite pointer ESI sur les coordonnées (X,Y) dans l'image xor eax,eax xor edx,edx xor esi,esi mov ax,Y mov dx,Principal_Largeur_image mov si,X mul edx add esi,eax add esi,FX_Feedback_Ecran xor edx,edx xor ecx,ecx xor ebx,ebx xor eax,eax ; On place dans ESI 3*Couleur_dessous (ESI est la position dans la palette ; des teintes de la Couleur_dessous), et dans EDI 3*Couleur (EDI est la ; position dans la palette des teintes de la Couleur) mov al,[esi] mov bl,Couleur xor esi,esi xor edi,edi mov si,ax mov di,bx add si,si add di,di add si,ax add di,bx ; On fait pointer EDI et ESI correctement sur la palette add esi,offset Principal_Palette add edi,offset Principal_Palette ; ; On mémorise dans BL,CL,DL les 3 teintes de Couleur_dessous ; mov bl,[esi+0] ; mov cl,[esi+1] ; mov dl,[esi+2] ; ; ; On fait pointer ESI sur la table de multiplication par le Facteur_A ; mov esi,offset Table_de_multiplication_par_Facteur_A ; ; ; On mémorise dans BH,CH,DH les 3 teintes de Couleur ; mov bh,[edi+0] ; mov ch,[edi+1] ; mov dh,[edi+2] ; ; ; On fait pointer EDI sur la table de multiplication par le Facteur_B ; mov edi,offset Table_de_multiplication_par_Facteur_B ; On mémorise dans BL,CL,DL les 3 teintes de Couleur_dessous ; et dans BH,CH,DH les 3 teintes de Couleur mov bl,[esi] mov bh,[edi] inc esi inc edi mov cl,[esi] mov ch,[edi] inc esi inc edi mov dl,[esi] mov dh,[edi] ; On fait pointer ESI sur la table de multiplication par le Facteur_A ; et EDI sur la table de multiplication par le Facteur_B mov esi,offset Table_de_multiplication_par_Facteur_A mov edi,offset Table_de_multiplication_par_Facteur_B ; ; On va s'occuper de la composante bleue (DX) ; ; xor ah,ah ; mov al,dh ; mov ax,[edi+2*eax] ; AX = (Bleu *Facteur_B) ; xor dh,dh ; add ax,[esi+2*edx] ; AX += (Bleu_dessous*Facteur_A) ; shr ax,8 ; push eax ; ; ; On va s'occuper de la composante verte (CX) et rouge (BX) ; ; mov dl,ch ; mov al,bh ; mov dx,[edi+2*edx] ; DX = (Vert *Facteur_B) ; xor ch,ch ; add dx,[esi+2*ecx] ; DX += (Vert_dessous *Facteur_A) ; mov ax,[edi+2*eax] ; AX = (Rouge *Facteur_B) ; xor bh,bh ; add ax,[esi+2*ebx] ; AX += (Rouge_dessous*Facteur_A) ; shr dx,8 ; shr ax,8 ; push edx ; push eax ; On va s'occuper de la composante bleue (DX) xor eax,eax mov al,dh xor dh,dh add eax,eax add edx,edx add eax,offset Table_de_multiplication_par_Facteur_B add edx,offset Table_de_multiplication_par_Facteur_A mov ax,[eax] ; AX = (Bleu *Facteur_B) add ax,[edx] ; AX += (Bleu_dessous*Facteur_A) shr ax,8 push eax ; On va s'occuper de la composante verte (CX) et rouge (BX) xor eax,eax xor edx,edx mov al,ch mov dl,cl add eax,eax add edx,edx add eax,offset Table_de_multiplication_par_Facteur_B add edx,offset Table_de_multiplication_par_Facteur_A mov ax,[eax] ; AX = (Vert *Facteur_B) add ax,[edx] ; AX += (Vert_dessous*Facteur_A) shr ax,8 push eax xor eax,eax xor edx,edx mov al,bh mov dl,bl add eax,eax add edx,edx add eax,offset Table_de_multiplication_par_Facteur_B add edx,offset Table_de_multiplication_par_Facteur_A mov ax,[eax] ; AX = (Vert *Facteur_B) add ax,[edx] ; AX += (Vert_dessous*Facteur_A) shr ax,8 push eax call Meilleure_couleur add esp,12 pop edi pop esi pop ebx mov esp,ebp pop ebp ret Effet_Colorize_interpole endp ; -- Gestion de l'effet Colorize à l'aide de la méthode additive Effet_Colorize_additif proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte push ebx push esi push edi ; On fait tout de suite pointer ESI sur les coordonnées (X,Y) dans l'image xor eax,eax xor edx,edx xor esi,esi mov ax,Y mov dx,Principal_Largeur_image mov si,X mul edx add esi,eax add esi,FX_Feedback_Ecran xor edx,edx xor ecx,ecx xor ebx,ebx xor eax,eax ; On lit dans AL (EAX) la couleur en (X,Y) mov al,[esi] ; On met dans CL (ECX) la couleur à rajouter mov cl,Couleur ; On multiplie AX (EAX) par 3 mov dx,ax add ax,ax add ax,dx ; On multiplie CX (ECX) par 3 mov dx,cx add cx,cx add cx,dx ; On fait pointer EBX sur Principal_Palette mov ebx,offset Principal_Palette ; On va traiter la composante bleue: ; On place dans DL Principal_Palette[AL].B mov dl,[ebx+eax+2] ; On place dans DH Principal_Palette[CL].B mov dh,[ebx+ecx+2] cmp dh,dl ja Effet_Colorize_additif_Bleu_Superieur xor dh,dh jmp Effet_Colorize_additif_Bleu_Fin_de_traitement Effet_Colorize_additif_Bleu_Superieur: shr dx,8 Effet_Colorize_additif_Bleu_Fin_de_traitement: push edx ; On passe la composante bleue que l'on désire ; On va traiter la composante verte: ; On place dans DL Principal_Palette[AL].V mov dl,[ebx+eax+1] ; On place dans DH Principal_Palette[CL].V mov dh,[ebx+ecx+1] cmp dh,dl ja Effet_Colorize_additif_Vert_Superieur xor dh,dh jmp Effet_Colorize_additif_Vert_Fin_de_traitement Effet_Colorize_additif_Vert_Superieur: shr dx,8 Effet_Colorize_additif_Vert_Fin_de_traitement: push edx ; On passe la composante verte que l'on désire ; On va traiter la composante rouge: ; On place dans DL Principal_Palette[AL].R mov dl,[ebx+eax+0] ; On place dans DH Principal_Palette[CL].R mov dh,[ebx+ecx+0] cmp dh,dl ja Effet_Colorize_additif_Rouge_Superieur xor dh,dh jmp Effet_Colorize_additif_Rouge_Fin_de_traitement Effet_Colorize_additif_Rouge_Superieur: shr dx,8 Effet_Colorize_additif_Rouge_Fin_de_traitement: push edx ; On passe la composante rouge que l'on désire call Meilleure_couleur add esp,12 pop edi pop esi pop ebx mov esp,ebp pop ebp ret Effet_Colorize_additif endp ; -- Gestion de l'effet Colorize à l'aide de la méthode soustractive Effet_Colorize_soustractif proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte push ebx push esi push edi ; On fait tout de suite pointer ESI sur les coordonnées (X,Y) dans l'image xor eax,eax xor edx,edx xor esi,esi mov ax,Y mov dx,Principal_Largeur_image mov si,X mul edx add esi,eax add esi,FX_Feedback_Ecran xor edx,edx xor ecx,ecx xor ebx,ebx xor eax,eax ; On lit dans AL (EAX) la couleur en (X,Y) mov al,[esi] ; On met dans CL (ECX) la couleur à soustraire mov cl,Couleur ; On multiplie AX (EAX) par 3 mov dx,ax add ax,ax add ax,dx ; On multiplie CX (ECX) par 3 mov dx,cx add cx,cx add cx,dx ; On fait pointer EBX sur Principal_Palette mov ebx,offset Principal_Palette ; On va traiter la composante bleue: ; On place dans DL Principal_Palette[AL].B mov dl,[ebx+eax+2] ; On place dans DH Principal_Palette[CL].B mov dh,[ebx+ecx+2] cmp dh,dl jb Effet_Colorize_soustractif_Bleu_Superieur xor dh,dh jmp Effet_Colorize_soustractif_Bleu_Fin_de_traitement Effet_Colorize_soustractif_Bleu_Superieur: shr dx,8 Effet_Colorize_soustractif_Bleu_Fin_de_traitement: push edx ; On passe la composante bleue que l'on désire ; On va traiter la composante verte: ; On place dans DL Principal_Palette[AL].V mov dl,[ebx+eax+1] ; On place dans DH Principal_Palette[CL].V mov dh,[ebx+ecx+1] cmp dh,dl jb Effet_Colorize_soustractif_Vert_Superieur xor dh,dh jmp Effet_Colorize_soustractif_Vert_Fin_de_traitement Effet_Colorize_soustractif_Vert_Superieur: shr dx,8 Effet_Colorize_soustractif_Vert_Fin_de_traitement: push edx ; On passe la composante verte que l'on désire ; On va traiter la composante rouge: ; On place dans DL Principal_Palette[AL].R mov dl,[ebx+eax+0] ; On place dans DH Principal_Palette[CL].R mov dh,[ebx+ecx+0] cmp dh,dl jb Effet_Colorize_soustractif_Rouge_Superieur xor dh,dh jmp Effet_Colorize_soustractif_Rouge_Fin_de_traitement Effet_Colorize_soustractif_Rouge_Superieur: shr dx,8 Effet_Colorize_soustractif_Rouge_Fin_de_traitement: push edx ; On passe la composante rouge que l'on désire call Meilleure_couleur add esp,12 pop edi pop esi pop ebx mov esp,ebp pop ebp ret Effet_Colorize_soustractif endp ; -- Gestion des trames -- Effet_Trame proc near push ebp mov ebp,esp arg X:word,Y:word xor edx,edx ; renvoie Trame[X%Trame_Largeur][Y%Trame_Hauteur] mov ax,X div Trame_Largeur mov cx,dx ; CX contient X%Trame_Largeur mov ax,Y xor dx,dx div Trame_Hauteur ; DX contient Y%Trame_Hauteur shl cx,4 ; CX= (X%Trame_Largeur)*16 add dx,cx ; DX=((X%Trame_Largeur)*16)+(Y%Trame_Hauteur) add edx,offset Trame ; EDX pointe sur Trame[X%Trame_Largeur][Y%Trame_Hauteur] mov al,[edx] mov esp,ebp pop ebp ret Effet_Trame endp ; -- Effectuer une invertion de la brosse / une droite horizontale -- Flip_Y_LOWLEVEL proc near push ebx push esi push edi ; On va se servir de ESI pour pointer sur la partie supérieure de la brosse ; et de EDI pour pointer sur la partie basse. mov esi,Brosse xor eax,eax xor ebx,ebx mov ax,Brosse_Hauteur mov bx,Brosse_Largeur dec ax mov edi,Brosse mul ebx add edi,eax xor ecx,ecx Flip_Y_Tant_que: cmp edi,esi jbe Flip_Y_Fin_tant_que ; Il faut inverser les lignes de la brosse pointées par EDI et ESI ; ("Brosse_Largeur" octets en tout) mov cx,Brosse_Largeur ; On va se préparer à une inversion 32 bits de lignes. Pour cela, on ; traite tout de suite les excédants shr cx,1 jnc Flip_Y_Largeur_multiple_de_2 mov al,[esi] mov ah,[edi] mov [edi],al mov [esi],ah inc edi inc esi Flip_Y_Largeur_multiple_de_2: shr cx,1 jnc Flip_Y_Largeur_multiple_de_4 mov ax,[esi] mov bx,[edi] mov [edi],ax mov [esi],bx add edi,2 add esi,2 Flip_Y_Largeur_multiple_de_4: ; Avant de se mettre à faire de l'inversion 32 bits, on vérifie qu'il ; reste bien des dwords à traiter (cas d'une brosse trop étroite) or cx,cx jz Flip_Y_Fin_de_ligne Flip_Y_Pour_chaque_pixel: mov eax,[esi] mov ebx,[edi] mov [edi],eax mov [esi],ebx add edi,4 add esi,4 dec cx jnz Flip_Y_Pour_chaque_pixel Flip_Y_Fin_de_ligne: ; On change de ligne, il faut donc mettre à jour ESI et EDI: ESI doit ; pointer sur le début de la ligne suivante (ce qui est déja le cas), et ; EDI sur le début de la ligne précédente movzx ebx,Brosse_Largeur sub edi,ebx ; EDI se retrouve en début de la ligne en cours sub edi,ebx ; EDI se retrouve en début de ligne précédente jmp Flip_Y_Tant_que Flip_Y_Fin_tant_que: pop edi pop esi pop ebx ret Flip_Y_LOWLEVEL endp ; -- Effectuer une invertion de la brosse / une droite verticale -- Flip_X_LOWLEVEL proc near push esi push edi ; On va se servir de ESI pour pointer sur la partie gauche de la brosse et ; de EDI pour pointer sur la partie droite. mov esi,Brosse xor eax,eax mov edi,esi mov ax,Brosse_Largeur dec ax add edi,eax ; On met dans EDX la largeur d'une ligne de brosse xor edx,edx mov dx,Brosse_largeur Flip_X_Tant_que: ; On sauve les valeurs initiales des pointeurs pour les changements de ; colonne mov MODE_X_Valeur_initiale_de_esi,esi mov MODE_X_Valeur_initiale_de_edi,edi cmp edi,esi jbe Flip_X_Fin_tant_que ; Il faut inverser les colonnes de la brosse pointées par EDI et ESI ; ("Brosse_Hauteur" octets en tout) mov cx,Brosse_Hauteur Flip_X_Pour_chaque_ligne: mov al,[esi] mov ah,[edi] mov [edi],al mov [esi],ah add edi,edx add esi,edx dec cx jnz Flip_X_Pour_chaque_ligne ; On change de colonne, il faut donc mettre à jour ESI et EDI: ESI doit ; pointer sur la colonne suivante, et EDI sur la colonne précédente mov esi,MODE_X_Valeur_initiale_de_esi mov edi,MODE_X_Valeur_initiale_de_edi inc esi dec edi jmp Flip_X_Tant_que Flip_X_Fin_tant_que: pop edi pop esi ret Flip_X_LOWLEVEL endp ; -- Effectuer une rotation de 90° sur la brosse -- Rotate_90_deg_LOWLEVEL proc near push ebp mov ebp,esp arg Source:dword,Destination:dword ; Brosse_Largeur & Brosse_Hauteur doivent être les dimensions de la brosse ; Source push ebx push esi push edi ; On place ESI sur le point haut-droit de la brosse source: xor eax,eax mov esi,Source mov ax,Brosse_Largeur add esi,eax dec esi ; Et on mémorise son emplacement initial: mov MODE_X_Valeur_initiale_de_esi,esi ; On place EDI sur le point haut-gauche de la brosse destination: mov edi,Destination ; On place dans EBX la distance entre 2 lignes dans la source: xor ebx,ebx mov bx,Brosse_Largeur ; On place dans DX le nombre de lignes/destination (colonnes/source) à ; traiter: mov dx,bx Rotate_90_deg_Pour_chaque_ligne: mov esi,MODE_X_Valeur_initiale_de_esi ; On place dans CX le nombre de colonnes/destination (lignes/source) à ; traiter: mov cx,Brosse_Hauteur Rotate_90_deg_Pour_chaque_colonne: ; On transfert le pixel: mov al,[esi] mov [edi],al ; Et on passe à la colonne de destination suivante: add esi,ebx inc edi dec cx jnz Rotate_90_deg_Pour_chaque_colonne ; Et on passe à la ligne de destination suivante: dec MODE_X_Valeur_initiale_de_esi dec dx jnz Rotate_90_deg_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Rotate_90_deg_LOWLEVEL endp ; -- Effectuer une rotation de 180° sur la brosse (version compatible 386) -- Rotate_180_deg_LOWLEVEL proc near push ebx push esi push edi ; On va se servir de ESI pour pointer sur la partie supérieure de la brosse ; et de EDI pour pointer sur la partie basse. mov esi,Brosse xor eax,eax xor ebx,ebx mov ax,Brosse_Hauteur mov bx,Brosse_Largeur dec ax mov edi,Brosse mul ebx add edi,eax movzx edx,Brosse_Largeur ; EDX contient la largeur de la brosse Rotate_180_deg_Tant_que: cmp edi,esi jbe Rotate_180_deg_Fin_tant_que ; Il faut inverser les lignes de la brosse pointées par EDI et ESI ; (EDX octets en tout) mov ecx,edx ; Comme on fait pas un Flip_Y mais une rotation de 180°, on "ejecte" EDI ; au bout de sa ligne add edi,edx dec edi ; On va se préparer à une inversion 16 bits de lignes. Pour cela, on ; traite tout de suite les excédants shr cx,1 jnc Rotate_180_deg_Largeur_multiple_de_2 mov al,[esi] mov ah,[edi] mov [edi],al mov [esi],ah dec edi inc esi Rotate_180_deg_Largeur_multiple_de_2: ; On s'apprête à faire un traitement sur des words, on doit donc se ; laisser la place d'y accéder. dec edi ; Avant de se mettre à faire de l'inversion 16 bits, on vérifie qu'il ; reste bien des words à traiter (cas d'une brosse trop étroite) or cx,cx jz Rotate_180_deg_Fin_de_ligne Rotate_180_deg_Pour_chaque_pixel: mov ax,[esi] mov bx,[edi] xchg ah,al ; On doit permutter les 2 octets pour que l'inversion soit correcte xchg bh,bl ; On doit permutter les 2 octets pour que l'inversion soit correcte mov [edi],ax mov [esi],bx sub edi,2 add esi,2 dec cx jnz Rotate_180_deg_Pour_chaque_pixel Rotate_180_deg_Fin_de_ligne: ; On change de ligne, il faut donc mettre à jour ESI et EDI: ESI doit ; pointer sur le début de la ligne suivante (ce qui est déjà le cas), et ; EDI sur le début de la ligne précédente ; Note: EDI se retrouve déjà au début de la ligne en cours puisqu'on l'a ; éjecté (au début de traitement de la ligne) en fin de ligne, et ; qu'il a fait le parcours de la ligne en sens inverse. Seulement, ; il a légèrement débordé sur la gauche, c'est pourquoi on doit le ; corriger par une incrémentation de 2 (car on a traité des words). add edi,2 ; EDI se retrouve en debut de la ligne en cours sub edi,edx ; EDI se retrouve en début de ligne précédente jmp Rotate_180_deg_Tant_que Rotate_180_deg_Fin_tant_que: pop edi pop esi pop ebx ret Rotate_180_deg_LOWLEVEL endp ; Etirer une ligne selon un facteur donné vers un buffer Zoomer_une_ligne proc near push ebp mov ebp,esp arg Ligne_originale:dword,Ligne_zoomee:dword,Facteur:word,Largeur:word push esi push edi ; On place dans ESI l'adresse de la ligne orignale (à zoomer): mov esi,Ligne_originale ; On place dans EDI l'adresse de la ligne résultat (zoomée): mov edi,Ligne_zoomee ; On place dans DX le nombre de pixels à zoomer sur la ligne: mov dx,Largeur ; On nettoye la partie haute de ECX: xor ecx,ecx ZUL_Pour_chaque_pixel: ; On lit la couleur à recopier dans AL mov cl,[esi] mov ch,cl mov ax,cx shl eax,16 mov ax,cx ; On place dans ECX le facteur: mov cx,Facteur ; On recopie ECX fois AL dans EDI le + vite possible par copie 8/16/32 bits shr cx,1 jnc ZUL_ECX_multiple_de_2 stosb ZUL_ECX_multiple_de_2: shr cx,1 jnc ZUL_ECX_multiple_de_4 stosw ZUL_ECX_multiple_de_4: rep stosd ; On passe au pixel suivant: inc esi dec dx jnz ZUL_Pour_chaque_pixel pop edi pop esi mov esp,ebp pop ebp ret Zoomer_une_ligne endp ; -- Copier une partie d'une image vers une autre -- Copier_une_partie_d_image_dans_une_autre proc near push ebp mov ebp,esp arg Source:dword,S_Pos_X:word,S_Pos_Y:word,Largeur:word,Hauteur:word,Largeur_source:word,Destination:dword,D_Pos_X:word,D_Pos_Y:word,Largeur_destination:word push ebx push esi push edi ; On place dans ESI l'adresse de la source en (S_Pos_X,S_Pos_Y) xor eax,eax xor ebx,ebx xor ecx,ecx mov ax,S_Pos_Y mov bx,Largeur_source mov cx,S_Pos_X mul ebx mov esi,Source add eax,ecx add esi,eax ; On place dans EDI l'adresse de la destination en (D_Pos_X,D_Pos_Y) xor eax,eax mov ax,D_Pos_Y mov bx,Largeur_destination mov cx,D_Pos_X mul ebx mov edi,Destination add eax,ecx add edi,eax ; On place dans EAX la distance entre la fin d'une ligne de l'image source ; et le début de la suivante à l'abscisse S_Pos_X: xor eax,eax mov ax,Largeur_source sub ax,Largeur ; On place dans EBX la distance entre la fin d'une ligne de l'image ; destination et le début de la suivante à l'abscisse D_Pos_X: xor ebx,ebx mov bx,Largeur_destination sub bx,Largeur ; On place dans DX le nombre de lignes à traiter mov dx,Hauteur CUPDIDUA_Pour_chaque_ligne: ; On place dans CX le nombre de pixels à traiter sur la ligne: mov cx,Largeur ; On fait une copie au mieux par 8/16/32 bits: shr cx,1 jnc CUPDIDUA_CX_multiple_de_2 movsb CUPDIDUA_CX_multiple_de_2: shr cx,1 jnc CUPDIDUA_CX_multiple_de_4 movsw CUPDIDUA_CX_multiple_de_4: repnz movsd ; On passe à la ligne suivante: add esi,eax add edi,ebx dec dx jnz CUPDIDUA_Pour_chaque_ligne pop edi pop esi pop ebx mov esp,ebp pop ebp ret Copier_une_partie_d_image_dans_une_autre endp _TEXT ENDS END ; -- Gestion de l'effet Smooth Effet_Smooth2 proc near push ebp mov ebp,esp arg X:word,Y:word,Couleur:byte push ebx push esi push edi ; On fait tout de suite pointer ESI sur les coordonnées (X,Y) dans l'image xor eax,eax xor edx,edx xor esi,esi mov ax,Y mov dx,Principal_Largeur_image mov si,X mul edx add esi,eax add esi,FX_Feedback_Ecran ; On vérifie d'abord que le point ne soit pas à la périphérie de l'image cmp X,0 je Effet_Smooth_Sur_la_peripherie cmp Y,0 je Effet_Smooth_Sur_la_peripherie mov ax,Principal_Largeur_image mov dx,Principal_Hauteur_image dec ax dec dx cmp X,ax je Effet_Smooth_Sur_la_peripherie cmp Y,dx jne Effet_Smooth_Traitement_normal Effet_Smooth_Sur_la_peripherie: ; On est sur la périphérie, donc on ne modifie pas la couleur du point de ; l'image. mov al,[esi] jmp Effet_Smooth_Fin_de_traitement Effet_Smooth_Traitement_normal: ; On va se servir de BX,CX et DX comme cumuleurs de Rouge,Vert et Bleu xor edi,edi xor ah,ah mov al,[esi] ; AX = couleur du pixel en (X,Y) mov di,ax ; DI = couleur du pixel en (X,Y) add ax,ax ; AX = 2 * couleur du pixel en (X,Y) add di,ax ; DI = 3 * couleur du pixel en (X,Y) add edi,offset Principal_Palette ; EDI pointe sur la palette[Couleur du pixel en (X,Y)].R xor ah,ah mov al,[edi+0] mov bx,ax mov al,[edi+1] mov cx,ax mov al,[edi+2] mov dx,ax add bx,bx ; On double la valeur rouge du point (X,Y) add cx,cx ; On double la valeur verte du point (X,Y) add dx,dx ; On double la valeur bleue du point (X,Y) inc esi ; On fait pointer ESI sur (X+1,Y) xor edi,edi xor ah,ah mov al,[esi] ; AX = couleur du pixel en (X+1,Y) mov di,ax ; DI = couleur du pixel en (X+1,Y) add ax,ax ; AX = 2 * couleur du pixel en (X+1,Y) add di,ax ; DI = 3 * couleur du pixel en (X+1,Y) add edi,offset Principal_Palette ; EDI pointe sur la palette[Couleur du pixel en (X+1,Y)].R xor ah,ah ; \_ AX = Palette[Couleur du pixel en (X+1,Y)].R mov al,[edi+0] ; / add bx,ax ; On cumule les rouges dans BX mov al,[edi+1] ; AX = Palette[Couleur du pixel en (X+1,Y)].V add cx,ax ; On cumule les verts dans CX mov al,[edi+2] ; AX = Palette[Couleur du pixel en (X+1,Y)].B add dx,ax ; On cumule les bleus dans DX sub esi,2 ; On fait pointer ESI sur (X-1,Y) xor edi,edi xor ah,ah mov al,[esi] ; AX = couleur du pixel en (X-1,Y) mov di,ax ; DI = couleur du pixel en (X-1,Y) add ax,ax ; AX = 2 * couleur du pixel en (X-1,Y) add di,ax ; DI = 3 * couleur du pixel en (X-1,Y) add edi,offset Principal_Palette ; EDI pointe sur la palette[Couleur du pixel en (X-1,Y)].R xor ah,ah ; \_ AX = Palette[Couleur du pixel en (X-1,Y)].R mov al,[edi+0] ; / add bx,ax ; On cumule les rouges dans BX mov al,[edi+1] ; AX = Palette[Couleur du pixel en (X-1,Y)].V add cx,ax ; On cumule les verts dans CX mov al,[edi+2] ; AX = Palette[Couleur du pixel en (X-1,Y)].B add dx,ax ; On cumule les bleus dans DX add esi,1025 ; On fait pointer ESI sur (X,Y+1) xor edi,edi xor ah,ah mov al,[esi] ; AX = couleur du pixel en (X,Y+1) mov di,ax ; DI = couleur du pixel en (X,Y+1) add ax,ax ; AX = 2 * couleur du pixel en (X,Y+1) add di,ax ; DI = 3 * couleur du pixel en (X,Y+1) add edi,offset Principal_Palette ; EDI pointe sur la palette[Couleur du pixel en (X,Y+1)].R xor ah,ah ; \_ AX = Palette[Couleur du pixel en (X,Y+1)].R mov al,[edi+0] ; / add bx,ax ; On cumule les rouges dans BX mov al,[edi+1] ; AX = Palette[Couleur du pixel en (X,Y+1)].V add cx,ax ; On cumule les verts dans CX mov al,[edi+2] ; AX = Palette[Couleur du pixel en (X,Y+1)].B add dx,ax ; On cumule les bleus dans DX sub esi,2048 ; On fait pointer ESI sur (X,Y-1) xor edi,edi xor ah,ah mov al,[esi] ; AX = couleur du pixel en (X,Y-1) mov di,ax ; DI = couleur du pixel en (X,Y-1) add ax,ax ; AX = 2 * couleur du pixel en (X,Y-1) add di,ax ; DI = 3 * couleur du pixel en (X,Y-1) add edi,offset Principal_Palette ; EDI pointe sur la palette[Couleur du pixel en (X,Y-1)].R xor ah,ah ; \_ AX = Palette[Couleur du pixel en (X,Y-1)].R mov al,[edi+0] ; / add bx,ax ; On cumule les rouges dans BX mov al,[edi+1] ; AX = Palette[Couleur du pixel en (X,Y-1)].V add cx,ax ; On cumule les verts dans CX mov al,[edi+2] ; AX = Palette[Couleur du pixel en (X,Y-1)].B add dx,ax ; On cumule les bleus dans DX mov di,6 mov ax,dx ; On passe le paramètre (Cumul_bleu / 6) xor dx,dx div di cmp ah,3 jb Effet_Smooth_Pas_plus_bleu inc al Effet_Smooth_Pas_plus_bleu: push eax mov ax,cx ; On passe le paramètre (Cumul_vert / 6) xor dx,dx div di cmp ah,3 jb Effet_Smooth_Pas_plus_vert inc al Effet_Smooth_Pas_plus_vert: push eax mov ax,bx ; On passe le paramètre (Cumul_rouge / 6) xor dx,dx div di cmp ah,3 jb Effet_Smooth_Pas_plus_rouge inc al Effet_Smooth_Pas_plus_rouge: push eax call Meilleure_couleur add esp,12 ; 12 = 3 paramètres codés sur 4 octets Effet_Smooth_Fin_de_traitement: pop edi pop esi pop ebx mov esp,ebp pop ebp ret Effet_Smooth2 endp ; -- Remplacer une couleur par une autre dans la brosse -- Remap_brush_LOWLEVEL proc near push ebp mov ebp,esp arg Table_de_conversion:dword push ebx push edi ; On place dans EDI l'adresse du début de la brosse mov edi,Brosse ; On place dans EAX le nombre total de pixels à convertir xor eax,eax xor ecx,ecx mov ax,Brosse_Largeur mov cx,Brosse_Hauteur mul ecx ; On place dans ECX le nb de pixels à traiter mov ecx,eax ; On place dans EBX l'adresse de la table de conversion mov ebx,Table_de_conversion ; On nettoie la partie haute de EAX pour qu'après chaque lecture de AL, ; EAX puisse servir d'index dans la table de conversion pointée par EBX xor eax,eax Remap_brush_Pour_chaque_pixel: ; On lit la couleur du pixel en cours: mov al,[edi] ; On fait la conversion de la couleur à l'aide de la table de conversion mov al,[ebx+eax] ; On replace la nouvelle couleur à l'emplacement en cours mov [edi],al ; On passe au pixel suivant: inc edi dec ecx jnz Remap_brush_Pour_chaque_pixel pop edi pop ebx mov esp,ebp pop ebp ret Remap_brush_LOWLEVEL endp