ajout à la fonction rectangle fill le remplissage par un pattern

This commit is contained in:
Frater 2026-02-03 17:16:06 +01:00
commit e7ec6211fd
3 changed files with 132 additions and 92 deletions

View file

@ -137,6 +137,7 @@ build_interface:
mov word [gs:si + widget.text_ofs], str_quit mov word [gs:si + widget.text_ofs], str_quit
mov word [gs:si + widget.text_seg], cs ; Texte est dans la ROM mov word [gs:si + widget.text_seg], cs ; Texte est dans la ROM
mov word [gs:si + widget.event_click], on_click_quit ; Fonction à appeler mov word [gs:si + widget.event_click], on_click_quit ; Fonction à appeler
mov byte [gs:si + widget.type], WIDGET_TYPE_BUTTON
; Créer Bouton 2 "HELLO" ; Créer Bouton 2 "HELLO"
call gui_alloc_widget call gui_alloc_widget
@ -148,6 +149,7 @@ build_interface:
mov word [gs:si + widget.h], 20 mov word [gs:si + widget.h], 20
mov word [gs:si + widget.text_ofs], str_hello mov word [gs:si + widget.text_ofs], str_hello
mov word [gs:si + widget.text_seg], cs mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_BUTTON
; Pas de callback ; Pas de callback
; Créer Slider (Drag) ; Créer Slider (Drag)
@ -159,6 +161,7 @@ build_interface:
mov word [gs:si + widget.h], 20 mov word [gs:si + widget.h], 20
mov word [gs:si + widget.text_ofs], str_drag mov word [gs:si + widget.text_ofs], str_drag
mov word [gs:si + widget.text_seg], cs mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
mov byte [gs:si + widget.drag_mode], 1 ; Horizontal mov byte [gs:si + widget.drag_mode], 1 ; Horizontal
mov word [gs:si + widget.drag_min], 10 mov word [gs:si + widget.drag_min], 10
mov word [gs:si + widget.drag_max], 200 mov word [gs:si + widget.drag_max], 200
@ -181,6 +184,7 @@ timer_isr:
push fs push fs
mov ax,BDA_DATA_SEG mov ax,BDA_DATA_SEG
mov fs,ax mov fs,ax
; exemple de fonctionnement:
; inc byte [fs:BDA_TIMER] ; inc byte [fs:BDA_TIMER]
mov al, PIC_EOI ; EOI master mov al, PIC_EOI ; EOI master
@ -209,5 +213,3 @@ reset_vector:
builddate: builddate:
db '06/01/2026' db '06/01/2026'
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins) times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins)

View file

@ -114,6 +114,17 @@ graph_driver:
xchg ah,al xchg ah,al
%endmacro %endmacro
; =============================================================================
; SECTION : PATTERNS & FILL
; =============================================================================
align 8
pattern_black dq 0x0000000000000000
pattern_gray_dark dq 0xDDFF77FFDDFF77FF
pattern_gray_mid dq 0xDD77DD77DD77DD77
pattern_gray_light dq 0xAA55AA55AA55AA55
pattern_white dq 0xFFFFFFFFFFFFFFFF
; ------------------------------------------------------------ ; ------------------------------------------------------------
; initialise le mode graphique (via l'int 10h) ; initialise le mode graphique (via l'int 10h)
; ;
@ -312,6 +323,8 @@ cga_putc:
push fs push fs
push es push es
call cga_mouse_hide ; Protection souris
mov bx, VIDEO_SEG mov bx, VIDEO_SEG
mov es, bx mov es, bx
mov bx, BDA_DATA_SEG mov bx, BDA_DATA_SEG
@ -393,6 +406,8 @@ cga_putc:
inc word [fs:BDA_GFX + gfx.cur_offset] inc word [fs:BDA_GFX + gfx.cur_offset]
add word [fs:BDA_GFX + gfx.cur_x], 8 add word [fs:BDA_GFX + gfx.cur_x], 8
call cga_mouse_show ; Restauration souris
pop es pop es
pop fs pop fs
popa popa
@ -447,9 +462,8 @@ cga_write:
cga_putpixel: cga_putpixel:
push bp push bp
mov bp, sp mov bp, sp
pusha pusha
call cga_mouse_hide ; Protection souris
mov cx, .x mov cx, .x
mov dx, .y mov dx, .y
call cga_calc_addr call cga_calc_addr
@ -467,6 +481,7 @@ cga_putpixel:
and byte [es:di], ah and byte [es:di], ah
.done: .done:
call cga_mouse_show ; Restauration souris
popa popa
leave leave
ret ret
@ -526,24 +541,18 @@ cga_background:
rep stosd rep stosd
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; cga_line_vertical (x, y0, y1, color) ; cga_line_vertical (x, y0, y1, color)
; ;
; Dessine une ligne x, y0, y1, color ; Dessine une ligne x, y0, y1, color
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_line_vertical:
push bp
mov bp, sp
; --- Définition des arguments ---
%define .x word [bp+4] %define .x word [bp+4]
%define .y1 word [bp+6] %define .y1 word [bp+6]
%define .y2 word [bp+8] %define .y2 word [bp+8]
%define .color byte [bp+10] %define .color byte [bp+10]
cga_line_vertical:
push bp
mov bp, sp
pusha pusha
push es push es
@ -607,30 +616,26 @@ cga_line_vertical:
call cga_mouse_show call cga_mouse_show
pop es pop es
popa
leave ; Leave gère le 'mov sp, bp / pop bp'
ret
; clean defs ; clean defs
%undef .x %undef .x
%undef .y1 %undef .y1
%undef .y2 %undef .y2
%undef .color %undef .color
popa
leave ; Leave gère le 'mov sp, bp / pop bp'
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; cga_line_horizontal ; cga_line_horizontal
; Dessine une ligne horizontale de (x1, y) à (x2, y) ; Dessine une ligne horizontale de (x1, y) à (x2, y)
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_line_horizontal:
push bp
mov bp, sp
; --- Définition des arguments --- ; --- Définition des arguments ---
%define .x1 word [bp+4] %define .x1 word [bp+4]
%define .x2 word [bp+6] %define .x2 word [bp+6]
%define .y word [bp+8] %define .y word [bp+8]
%define .color byte [bp+10] %define .color byte [bp+10]
cga_line_horizontal:
push bp
mov bp, sp
pusha pusha
push es push es
@ -756,31 +761,27 @@ cga_line_horizontal:
.done: .done:
call cga_mouse_show call cga_mouse_show
pop es pop es
popa
leave
ret
; clean defs ; clean defs
%undef .x1 %undef .x1
%undef .x2 %undef .x2
%undef .y %undef .y
popa
leave
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; cga_draw_rect ; cga_draw_rect
; Dessine un rectangle vide (contour) ; Dessine un rectangle vide (contour)
; Entrée : x1, y1, x2, y2, color ; Entrée : x1, y1, x2, y2, color
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_draw_rect:
push bp
mov bp, sp
; Arguments ; Arguments
%define .x1 word [bp+4] %define .x1 word [bp+4]
%define .y1 word [bp+6] %define .y1 word [bp+6]
%define .x2 word [bp+8] %define .x2 word [bp+8]
%define .y2 word [bp+10] %define .y2 word [bp+10]
%define .color word [bp+12] ; word pour l'alignement pile (mais on utilise byte) %define .color word [bp+12] ; word pour l'alignement pile (mais on utilise byte)
cga_draw_rect:
push bp
mov bp, sp
pusha pusha
; 1. Ordonner X (x1 < x2) ; 1. Ordonner X (x1 < x2)
@ -803,6 +804,8 @@ cga_draw_rect:
mov .y2, bx mov .y2, bx
.y_ok: .y_ok:
call cga_mouse_hide
; 3. Dessiner les 4 lignes ; 3. Dessiner les 4 lignes
; Pour éviter les pixels en double dans les coins, on peut ajuster légèrement, ; 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. ; mais pour un driver simple, tracer les 4 lignes brutes est acceptable.
@ -813,29 +816,35 @@ cga_draw_rect:
GFX LINE_VERT, .x1, .y1, .y2, .color GFX LINE_VERT, .x1, .y1, .y2, .color
GFX LINE_VERT, .x2, .y1, .y2, .color GFX LINE_VERT, .x2, .y1, .y2, .color
call cga_mouse_show
popa
leave
ret
; clean defs ; clean defs
%undef .x1 %undef .x1
%undef .y1 %undef .y1
%undef .x2 %undef .x2
popa %undef .y2
leave %undef .color
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; cga_fill_rect ; cga_fill_rect
; Dessine un rectangle plein ; Dessine un rectangle plein
; Entrée : x1, y1, x2, y2, color ; Entrée : x1, y1, x2, y2, pattern_offset (CS:Offset)
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_fill_rect:
push bp
mov bp, sp
%define .x1 word [bp+4] %define .x1 word [bp+4]
%define .y1 word [bp+6] %define .y1 word [bp+6]
%define .x2 word [bp+8] %define .x2 word [bp+8]
%define .y2 word [bp+10] %define .y2 word [bp+10]
%define .color byte [bp+12] %define .pat word [bp+12]
; Variable locale pour l'index du motif (y % 8)
%define .pat_idx word [bp-2]
cga_fill_rect:
push bp
mov bp, sp
sub sp, 2 ; Reserve espace pour .pat_idx
pusha pusha
push es push es
@ -865,6 +874,11 @@ cga_fill_rect:
mov .y2, bx mov .y2, bx
.y_sorted: .y_sorted:
; --- Init Pattern Index ---
mov ax, .y1
and ax, 7
mov .pat_idx, ax
; --- 2. Calcul de la hauteur --- ; --- 2. Calcul de la hauteur ---
mov bx, .y2 mov bx, .y2
sub bx, .y1 sub bx, .y1
@ -904,13 +918,24 @@ cga_fill_rect:
; --- 5. Récupérer la hauteur dans un registre sûr --- ; --- 5. Récupérer la hauteur dans un registre sûr ---
pop bx ; RESTAURER HAUTEUR DANS BX [STACK A] pop bx ; RESTAURER HAUTEUR DANS BX [STACK A]
; BX est maintenant notre compteur de boucle. ; BX est maintenant notre compteur de boucle.
; BP reste intact, donc .color est accessible !
; --- BOUCLE VERTICALE --- ; --- BOUCLE VERTICALE ---
.row_loop: .row_loop:
push di ; Sauve début ligne push di ; Sauve début ligne
push si ; Sauve index byte push si ; Sauve index byte
; --- Récupérer le byte du motif pour cette ligne ---
push bx
mov bx, .pat_idx
push si
mov si, .pat
mov dl, [cs:si + bx] ; DL = Pattern Byte
pop si
pop bx
; Incrémenter index motif pour la prochaine ligne
inc word .pat_idx
and word .pat_idx, 7
; --- Remplissage Horizontal --- ; --- Remplissage Horizontal ---
; Cas Single Byte (Start == End) ; Cas Single Byte (Start == End)
@ -926,14 +951,7 @@ cga_fill_rect:
; Partie Centrale (Boucle tant que SI < CX) ; Partie Centrale (Boucle tant que SI < CX)
jmp .check_mid jmp .check_mid
.mid_loop: .mid_loop:
; Ici BP est valide, donc .color est correct mov byte [es:di], dl
cmp byte .color, 0
je .blk
mov byte [es:di], 0xFF
jmp .nxt
.blk:
mov byte [es:di], 0x00
.nxt:
inc di inc di
inc si inc si
.check_mid: .check_mid:
@ -971,24 +989,23 @@ cga_fill_rect:
leave leave
ret ret
; helper
.apply_mask_fill: .apply_mask_fill:
cmp byte .color, 0 push ax
jz .ap_black
or byte [es:di], al
ret
.ap_black:
not al not al
and byte [es:di], al and byte [es:di], al
pop ax
and al, dl ; Motif masqué
or byte [es:di], al ; Applique
ret ret
; Nettoyage des defines ; Nettoyage des defines
%undef .x1 %undef .x1
%undef .y1 %undef .y1
%undef .x2 %undef .x2
%undef .y2 %undef .y2
%undef .color %undef .pat_idx
; ; -----------------------------------------------------------------------------
; ------------------------------------------------------------ ; ------------------------------------------------------------
; GESTION DU CURSEUR ; GESTION DU CURSEUR
; ------------------------------------------------------------ ; ------------------------------------------------------------

View file

@ -31,6 +31,11 @@
%define GUI_STATE_PRESSED 3 ; Clic enfoncé %define GUI_STATE_PRESSED 3 ; Clic enfoncé
%define GUI_STATE_DISABLED 4 ; Grisé %define GUI_STATE_DISABLED 4 ; Grisé
; --- Types de Widgets ---
%define WIDGET_TYPE_BUTTON 0
%define WIDGET_TYPE_SLIDER 1
%define WIDGET_TYPE_LABEL 2
; --- Event mask --- ; --- Event mask ---
%define EVENT_NONE 00000000b %define EVENT_NONE 00000000b
%define EVENT_HOVER 00000001b %define EVENT_HOVER 00000001b
@ -44,6 +49,7 @@
; --- Structure d'un OBJET (Bouton, etc) --- ; --- Structure d'un OBJET (Bouton, etc) ---
struc widget struc widget
.state resb 1 ; État (0=libre, >0=utilisé) .state resb 1 ; État (0=libre, >0=utilisé)
.type resb 1 ; Type (0=Button, 1=Slider...)
.oldstate resb 1 ; widget a-t-il été modifié ? .oldstate resb 1 ; widget a-t-il été modifié ?
.user_id resb 1 ; ID unique utilisateur .user_id resb 1 ; ID unique utilisateur
.x resw 1 ; Position X .x resw 1 ; Position X
@ -127,6 +133,7 @@ gui_alloc_widget:
.found: .found:
; On initialise le slot trouvé ; On initialise le slot trouvé
mov byte [gs:si + widget.state], GUI_STATE_NORMAL ; Marquer comme occupé mov byte [gs:si + widget.state], GUI_STATE_NORMAL ; Marquer comme occupé
mov byte [gs:si + widget.type], WIDGET_TYPE_BUTTON ; Type par défaut
mov byte [gs:si + widget.oldstate], 0 ; doit etre dessiné mov byte [gs:si + widget.oldstate], 0 ; doit etre dessiné
; Reset des champs critiques pour éviter les déchets ; Reset des champs critiques pour éviter les déchets
@ -384,7 +391,7 @@ gui_draw_single_widget:
mov al, [gs:si + widget.state] mov al, [gs:si + widget.state]
cmp al, [gs:si + widget.oldstate] cmp al, [gs:si + widget.oldstate]
je .done je .skip_draw
mov [gs:si + widget.oldstate], al ; marque comme à jour mov [gs:si + widget.oldstate], al ; marque comme à jour
@ -398,6 +405,13 @@ gui_draw_single_widget:
add cx, ax add cx, ax
add dx, bx add dx, bx
; GFX MOUSE_HIDE ; éviter que la souris ne laisse des traces
; Dispatch selon le type
cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
je .draw_slider
; Par défaut (Button, Label...) -> continue vers .paint_normal/pressed
; Dispatch selon état ; Dispatch selon état
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
je .paint_pressed je .paint_pressed
@ -405,13 +419,13 @@ gui_draw_single_widget:
je .paint_hover je .paint_hover
.paint_normal: .paint_normal:
GFX RECTANGLE_FILL, ax, bx, cx, dx, 1 ; Blanc GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_white
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
jmp .text jmp .text
.paint_hover: .paint_hover:
GFX RECTANGLE_FILL, ax, bx, cx, dx, 1 ; Blanc GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_gray_mid ; pattern_white
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir
; Effet gras ; Effet gras
inc ax inc ax
@ -426,7 +440,13 @@ gui_draw_single_widget:
jmp .text_setup jmp .text_setup
.paint_pressed: .paint_pressed:
GFX RECTANGLE_FILL, ax, bx, cx, dx, 0 ; Noir GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_black
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
jmp .text
.draw_slider:
; Dessin spécifique Slider (Inverse vidéo pour l'exemple)
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 1 ; Bord Blanc
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
jmp .text jmp .text
@ -473,5 +493,6 @@ gui_draw_single_widget:
GFX WRITE, dx, ax GFX WRITE, dx, ax
.done: .done:
.skip_draw:
popa popa
ret ret