diff --git a/src/boot.asm b/src/boot.asm index f86bf11..cbce61a 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -104,52 +104,24 @@ reset: ; on active le mode graphique GFX INIT - - ; DEMO - - GFX GOTOXY, 290, 80 - GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT - - GFX WRITE, cs, W_T - - GFX GOTOXY, 290, 90 - GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT - GFX WRITE, cs, B_T - - GFX GOTOXY, 290, 100 - GFX TXT_MODE, GFX_TXT_WHITE - GFX WRITE, cs, W_B - - GFX GOTOXY, 290, 110 - GFX TXT_MODE, GFX_TXT_BLACK - GFX WRITE, cs, B_W - - ; call mouse_reset call mouse_init - - GFX TXT_MODE, GFX_TXT_BLACK - GFX GOTOXY, 0, 0 - GFX WRITE, cs, cpt_txt - - GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT - GFX GOTOXY, 8,8 - GFX WRITE, cs, helloworld - GFX MOUSE_MOVE + GFX MOUSE_SHOW - GFX LINE_VERT, 55, 30, 147, 1 - GFX LINE_VERT, 54, 31, 148, 0 + push cs + pop ds + + GUI WINDOW, 50,50,250,100,helloworld + + ; GFX RECTANGLE_DRAW, 50,50,250,100,0 + + ;GFX LINE_VERT, 50, 50, 100, 0 + ;GFX LINE_VERT, 300, 50, 100, 0 + + ;GFX LINE_HORIZ, 50, 300, 50, 0 + ;GFX LINE_HORIZ, 50, 300, 100, 0 - mov cx,8 - mov dx,24 -.loopshift: - GFX GOTOXY, cx, dx - GFX WRITE, cs, helloworld - add dx,8 - inc cx - cmp cx,16 - jbe .loopshift mov ax,BDA_DATA_SEG mov ds,ax diff --git a/src/drivers/gfx_cgam.asm b/src/drivers/gfx_cgam.asm index f40cdcc..b726fb3 100644 --- a/src/drivers/gfx_cgam.asm +++ b/src/drivers/gfx_cgam.asm @@ -77,8 +77,8 @@ %define WRITE 6 %define LINE_VERT 7 %define LINE_HORIZ 8 -%define DRAW_RECT 9 -%define FILL_RECT 10 +%define RECTANGLE_DRAW 9 +%define RECTANGLE_FILL 10 %define MOUSE_HIDE 11 %define MOUSE_SHOW 12 %define MOUSE_MOVE 13 @@ -110,12 +110,6 @@ graph_driver: dw cga_mouse_show ; déplacement du curseur dw cga_mouse_cursor_move ; déplacement du curseur - - -; jmp gfx_fill_rect ; Remplissage rectangle (Nouveau) -; jmp gfx_invert_rect ; Offset +12: Inversion (Nouveau pour Menus) -; jmp gfx_draw_hline ; Offset +15: Ligne horizontale rapide (Nouveau) - %include "./common/cursor.asm" %include "./common/chartable.asm" @@ -643,25 +637,21 @@ cga_line_horizontal: .x_sorted: ; 2. Calculer l'adresse de départ - ; On a besoin de l'adresse de l'octet contenant AX. - ; AX (X_Start) et BX (X_End) sont conservés. - mov cx, ax ; CX = X_Start pour cga_calc_addr mov dx, .y ; DX = Y - push bx ; Sauvegarde X_End [1] - call cga_calc_addr ; DI = Offset VRAM, AH = BitMask (on ne servira pas de AH ici) - pop bx ; Récupère X_End [1] + push bx ; Sauve X_End + push ax ; <--- AJOUT CRITIQUE : Sauve X_Start (AX) + call cga_calc_addr ; DI = Offset VRAM (AX est détruit ici !) + pop ax ; <--- RESTAURATION : On récupère le bon X1 + pop bx ; Restaure X_End ; 3. Préparer la couleur - mov dl, .color ; DL = Couleur (0 ou 1) + mov dl, .color ; DL = Couleur ; --- ANALYSE DES OCTETS --- - ; Index Octet Début = X1 >> 3 - ; Index Octet Fin = X2 >> 3 - mov si, ax - shr si, 3 ; SI = Index octet start + shr si, 3 ; SI = Index octet start (Calcul correct maintenant) mov cx, bx shr cx, 3 ; CX = Index octet end @@ -675,30 +665,26 @@ cga_line_horizontal: ; ============================================ ; --- A. PARTIE GAUCHE (Start) --- - ; On doit dessiner du bit (AX&7) jusqu'au bit 0 (droite de l'octet) - ; Masque = 0xFF >> (AX & 7) - push cx ; Sauve Index End mov cx, ax and cx, 7 ; CL = X1 % 8 mov dh, 0xFF - shr dh, cl ; DH = Masque Gauche (ex: 00111111) + shr dh, cl ; DH = Masque Gauche - call .apply_mask ; Applique DH sur [ES:DI] selon couleur DL + call .apply_mask ; Applique DH sur [ES:DI] inc di ; Octet suivant inc si ; Index suivant pop cx ; Restaure Index End ; --- B. PARTIE CENTRALE (Full Bytes) --- - ; Tant que SI < CX, on remplit tout l'octet cmp si, cx - jge .do_right_part ; Si on a atteint le dernier octet, on saute + jge .do_right_part - mov al, 0x00 ; Couleur Noir par défaut + mov al, 0x00 ; Noir cmp dl, 0 jz .fill_loop - mov al, 0xFF ; Couleur Blanc + mov al, 0xFF ; Blanc .fill_loop: mov byte [es:di], al @@ -709,54 +695,49 @@ cga_line_horizontal: .do_right_part: ; --- C. PARTIE DROITE (End) --- - ; On doit dessiner du bit 7 jusqu'au bit (BX&7) - ; Masque = ~(0xFF >> ((BX & 7) + 1)) - mov cx, bx and cx, 7 - inc cx ; +1 car on veut inclure le pixel + inc cx mov dh, 0xFF shr dh, cl - not dh ; DH = Masque Droite (ex: 11100000) + not dh ; DH = Masque Droite call .apply_mask jmp .done ; ============================================ - ; CAS SINGLE BYTE (Début et Fin dans le même octet) + ; CAS SINGLE BYTE ; ============================================ .single_byte: - ; Masque Gauche = 0xFF >> (X1 & 7) + ; Masque Gauche mov cx, ax and cx, 7 mov dh, 0xFF shr dh, cl - ; Masque Droite = ~(0xFF >> ((X2 & 7) + 1)) + ; Masque Droite mov cx, bx and cx, 7 inc cx - mov ah, 0xFF ; Utilise AH temporaire + mov ah, 0xFF shr ah, cl not ah - ; Intersection des masques - and dh, ah ; DH = Masque Final (ex: 00011100) - + ; Intersection + and dh, ah call .apply_mask jmp .done - ; --- Helper local : Applique le masque DH sur [ES:DI] --- - ; Entrée : DH = Masque, DL = Couleur, DI = Adresse + ; --- Helper local --- .apply_mask: cmp dl, 0 jz .apply_black - or byte [es:di], dh ; Blanc : OR + or byte [es:di], dh ret .apply_black: not dh - and byte [es:di], dh ; Noir : AND ~Masque - not dh ; Restaure le masque (optionnel si non réutilisé) + and byte [es:di], dh + not dh ret .done: @@ -808,37 +789,11 @@ cga_draw_rect: ; Pour éviter les pixels en double dans les coins, on peut ajuster légèrement, ; mais pour un driver simple, tracer les 4 lignes brutes est acceptable. - ; Haut (x1,y1 -> x2,y1) - push word .color - push word .y1 - push word .x2 - push word .x1 - call cga_line_horizontal - add sp, 8 + GFX LINE_HORIZ, .x1, .x2, .y1, .color + GFX LINE_HORIZ, .x1, .x2, .y2, .color - ; Bas (x1,y2 -> x2,y2) - push word .color - push word .y2 - push word .x2 - push word .x1 - call cga_line_horizontal - add sp, 8 - - ; Gauche (x1,y1 -> x1,y2) - push word .color - push word .y2 - push word .y1 - push word .x1 - call cga_line_vertical - add sp, 8 - - ; Droite (x2,y1 -> x2,y2) - push word .color - push word .y2 - push word .y1 - push word .x2 - call cga_line_vertical - add sp, 8 + GFX LINE_VERT, .x1, .y1, .y2, .color + GFX LINE_VERT, .x2, .y1, .y2, .color popa leave diff --git a/src/services/gui_window.asm b/src/services/gui_window.asm index 262f122..ee8b267 100644 --- a/src/services/gui_window.asm +++ b/src/services/gui_window.asm @@ -56,7 +56,7 @@ ; ------------------------------------------------------------ gui_driver: - dw draw_white + dw draw_window ; ============================================================================= ; Fonction : draw_window @@ -68,7 +68,7 @@ gui_driver: ; Arg4 : Hauteur (Word) ; Arg5 : Pointeur vers titre (DS:Offset) (Word) ; ============================================================================= -draw_window: +draw_window_source: push bp mov bp, sp @@ -118,7 +118,6 @@ draw_window: ; ---------------------------------------------------- ; On dessine un rectangle BLANC par dessus l'ombre ; Cela crée le corps et "découpe" l'ombre pour ne laisser que le bord visible. - mov bx, .x add bx, .w ; BX = x2 mov dx, .y @@ -310,6 +309,46 @@ draw_window: call cga_write add sp, 6 + popa + leave + ret + + +draw_window: + push bp + mov bp, sp + + ; --- Arguments --- + %define .x word [bp+4] + %define .y word [bp+6] + %define .w word [bp+8] + %define .h word [bp+10] + %define .title word [bp+12] + ; ---- Variables Locales --- + + pusha + ; ---------------------------------------------------- + ; Ombre Portée (Drop Shadow) + ; ---------------------------------------------------- + ; On dessine un rectangle noir décalé de +1,+1 + ; x1+1, y1+1, x2+1, y2+1 -> NOIR + mov ax, .x + add ax, .w + inc ax ; x2 + 1 + mov bx, ax ; BX = right limit + + mov ax, .y + add ax, .h + inc ax ; y2 + 1 + mov dx, ax ; DX = bottom limit + + mov ax, .x + inc ax ; x1 + 1 + mov cx, .y + inc cx ; y1 + 1 + + GFX RECTANGLE_DRAW, ax, cx, bx, dx, 0 + popa leave ret \ No newline at end of file