fix split function
This commit is contained in:
parent
e7ec6211fd
commit
25925f2928
4 changed files with 224 additions and 126 deletions
11
src/boot.asm
11
src/boot.asm
|
|
@ -157,14 +157,17 @@ build_interface:
|
|||
jc .mem_full
|
||||
mov word [gs:si + widget.x], 10
|
||||
mov word [gs:si + widget.y], 100
|
||||
mov word [gs:si + widget.w], 20
|
||||
mov word [gs:si + widget.w], 150
|
||||
mov word [gs:si + widget.h], 20
|
||||
mov word [gs:si + widget.text_ofs], str_drag
|
||||
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 word [gs:si + widget.drag_min], 10
|
||||
mov word [gs:si + widget.drag_max], 200
|
||||
mov byte [gs:si + widget.attr_mode], 1 ; Horizontal
|
||||
mov word [gs:si + widget.attr_min], 10 ; X Min
|
||||
mov word [gs:si + widget.attr_max], 140 ; X Max (Widget.x + W - ThumbW)
|
||||
mov word [gs:si + widget.attr_val], 10 ; Position initiale
|
||||
mov byte [gs:si + widget.thumb_pct], 15 ; Curseur fait 15% de la largeur
|
||||
; mov word [gs:si + widget.event_drag], on_drag_slider
|
||||
|
||||
.mem_full:
|
||||
ret
|
||||
|
|
|
|||
|
|
@ -118,13 +118,14 @@ graph_driver:
|
|||
; =============================================================================
|
||||
; 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_light dq 0x8800220088002200
|
||||
pattern_white dq 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
; ------------------------------------------------------------
|
||||
; initialise le mode graphique (via l'int 10h)
|
||||
;
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ mouse_reset:
|
|||
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
|
||||
mov byte [fs:BDA_MOUSE + mouse.status],0
|
||||
|
||||
mov word [fs:BDA_MOUSE + mouse.x],497 ; vous pouvez aussi préciser le centre
|
||||
mov word [fs:BDA_MOUSE + mouse.y],5 ; vous pouvez aussi préciser le centre
|
||||
mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre
|
||||
mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre
|
||||
|
||||
mov byte [fs:BDA_MOUSE + mouse.cur_counter], 0
|
||||
mov word [fs:BDA_MOUSE + mouse.cur_x], 0
|
||||
|
|
|
|||
|
|
@ -36,16 +36,6 @@
|
|||
%define WIDGET_TYPE_SLIDER 1
|
||||
%define WIDGET_TYPE_LABEL 2
|
||||
|
||||
; --- Event mask ---
|
||||
%define EVENT_NONE 00000000b
|
||||
%define EVENT_HOVER 00000001b
|
||||
%define EVENT_LEFT_CLICK 00000010b
|
||||
%define EVENT_RIGHT_CLICK 00000100b
|
||||
%define EVENT_MIDDLE_CLICK 00001000b
|
||||
%define EVENT_LEFT_RELEASE 00010000b
|
||||
%define EVENT_RIGHT_RELEASE 00100000b
|
||||
%define EVENT_ENTER 10000000b
|
||||
|
||||
; --- Structure d'un OBJET (Bouton, etc) ---
|
||||
struc widget
|
||||
.state resb 1 ; État (0=libre, >0=utilisé)
|
||||
|
|
@ -58,16 +48,20 @@ struc widget
|
|||
.h resw 1 ; Hauteur
|
||||
.text_ofs resw 1 ; Offset du texte
|
||||
.text_seg resw 1 ; Segment du texte
|
||||
.event resb 1 ; found events (0 = none)
|
||||
.event_click resw 1 ; adresse de la fonction "on click"
|
||||
.drag_mode resb 1 ; 0=None, 1=Horiz, 2=Vert
|
||||
.drag_min resw 1 ; Limite Min
|
||||
.drag_max resw 1 ; Limite Max
|
||||
.drag_anchor resw 1 ; Offset souris au clic
|
||||
; .event_hover resw 1 ; adresse de la fonction "on hover"
|
||||
; .event_release resw 1 ; adresse de la fonction "on release"
|
||||
; .event_disable resw 1 ; adresse de la fonction "on disable"
|
||||
; .event_enable resw 1 ; adresse de la fonction "on enable"
|
||||
.event_drag resw 1 ; adresse de la fonction "on drag"
|
||||
|
||||
.attr_mode resb 1 ; 0=None, 1=Horiz, 2=Vert
|
||||
.attr_min resw 1 ; Valeur/Position Min
|
||||
.attr_max resw 1 ; Valeur/Position Max
|
||||
.attr_val resw 1 ; Valeur/Position Actuelle
|
||||
.attr_anchor resw 1 ; Offset interne pour le drag
|
||||
.thumb_pct resb 1 ; Taille du curseur en % (1-100)
|
||||
|
||||
alignb 2 ; Alignement mémoire pour performance
|
||||
endstruc
|
||||
|
||||
|
|
@ -90,10 +84,9 @@ gui_init_system:
|
|||
mov es, ax
|
||||
|
||||
xor di, di
|
||||
mov cx, (widget_size * GUI_MAX_WIDGETS)
|
||||
shl cx, 2 ; cx / 4
|
||||
xor eax, eax
|
||||
rep stosd ; Remplit tout de 0
|
||||
mov cx, (widget_size * GUI_MAX_WIDGETS) / 2
|
||||
xor ax, ax
|
||||
rep stosw ; Plus sûr en mode 16 bits pour l'alignement
|
||||
|
||||
pop di
|
||||
pop es
|
||||
|
|
@ -138,6 +131,8 @@ gui_alloc_widget:
|
|||
|
||||
; Reset des champs critiques pour éviter les déchets
|
||||
mov word [gs:si + widget.event_click], 0
|
||||
mov word [gs:si + widget.event_drag], 0
|
||||
mov byte [gs:si + widget.thumb_pct], 10 ; 10% par défaut
|
||||
|
||||
clc ; Clear Carry Flag
|
||||
.done:
|
||||
|
|
@ -193,6 +188,13 @@ gui_process_all:
|
|||
mov ax, GUI_RAM_SEG
|
||||
mov gs, ax
|
||||
|
||||
; Charger l'état de la souris pour toute la passe
|
||||
push ds
|
||||
mov ax, BDA_DATA_SEG
|
||||
mov ds, ax
|
||||
mov bl, [BDA_MOUSE + mouse.status]
|
||||
pop ds
|
||||
|
||||
mov si, 0 ; Pointeur début tableau
|
||||
mov di, GUI_MAX_WIDGETS ; Compteur
|
||||
|
||||
|
|
@ -263,8 +265,6 @@ gui_update_logic:
|
|||
mov cx, [BDA_MOUSE + mouse.x]
|
||||
mov dx, [BDA_MOUSE + mouse.y]
|
||||
|
||||
mov byte [gs:si + widget.event], 0 ; no event found]
|
||||
|
||||
; --- Hit Test ---
|
||||
cmp cx, [gs:si + widget.x]
|
||||
jl .miss ; mouse.x < widget.x ?
|
||||
|
|
@ -280,52 +280,15 @@ gui_update_logic:
|
|||
cmp dx, bx
|
||||
jg .miss ; mouse.y >= widget.y ?
|
||||
|
||||
; --- on est au moins dans le widget ---
|
||||
; Pour savoir si on vient d'entrer (ENTER), on regarde l'état PRÉCÉDENT (avant ce frame).
|
||||
; Si l'état n'était ni HOVER ni PRESSED, c'est qu'on vient d'arriver.
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_HOVER
|
||||
je .already_hover
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
je .already_hover
|
||||
; Dispatch selon le type
|
||||
cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
|
||||
je .call_slider_logic
|
||||
|
||||
; Nouvel arrivant
|
||||
or byte [gs:si + widget.event], EVENT_ENTER
|
||||
|
||||
.already_hover:
|
||||
or byte [gs:si + widget.event], EVENT_HOVER
|
||||
|
||||
; --- Hit: Souris sur le widget ---
|
||||
test bl, 1 ; Clic gauche ?
|
||||
jz .released
|
||||
|
||||
; Clic enfoncé
|
||||
mov byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
or byte [gs:si + widget.event], EVENT_LEFT_CLICK
|
||||
|
||||
; Calcul de l'ancrage pour le drag (Mouse - WidgetPos)
|
||||
mov ax, cx
|
||||
sub ax, [gs:si + widget.x]
|
||||
mov [gs:si + widget.drag_anchor], ax ; Save X anchor
|
||||
cmp byte [gs:si + widget.drag_mode], 2
|
||||
jne .done
|
||||
mov ax, dx
|
||||
sub ax, [gs:si + widget.y]
|
||||
mov [gs:si + widget.drag_anchor], ax ; Save Y anchor
|
||||
call gui_logic_button
|
||||
jmp .done
|
||||
|
||||
.released:
|
||||
; Bouton relâché. Était-il pressé avant ?
|
||||
and byte [gs:si + widget.event], ~EVENT_LEFT_CLICK
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
jne .hover
|
||||
|
||||
; Clic validé !
|
||||
mov al, 1
|
||||
mov byte [gs:si + widget.state], GUI_STATE_HOVER
|
||||
jmp .done
|
||||
|
||||
.hover:
|
||||
mov byte [gs:si + widget.state], GUI_STATE_HOVER
|
||||
.call_slider_logic:
|
||||
call gui_logic_slider
|
||||
jmp .done
|
||||
|
||||
.miss:
|
||||
|
|
@ -333,56 +296,125 @@ gui_update_logic:
|
|||
cmp byte [gs:si + widget.state], GUI_STATE_NORMAL
|
||||
je .done ; Déjà normal, rien à faire
|
||||
|
||||
; Cas particulier : si c'est un slider en cours de drag, on continue la logique
|
||||
cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
|
||||
jne .reset_state
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
je .call_slider_logic
|
||||
|
||||
.reset_state:
|
||||
mov byte [gs:si + widget.state], GUI_STATE_NORMAL
|
||||
and byte [gs:si + widget.event], ~EVENT_HOVER
|
||||
jmp .done
|
||||
xor ax, ax
|
||||
|
||||
.logic_pressed:
|
||||
; Si le bouton est relâché, on sort du mode Drag/Pressed
|
||||
test bl, 1
|
||||
jz .released ; On saute vers la logique de relâchement standard (HitTest)
|
||||
.done:
|
||||
pop ds
|
||||
ret
|
||||
|
||||
; --- Logique spécifique Bouton ---
|
||||
gui_logic_button:
|
||||
test bl, 1 ; Clic gauche ?
|
||||
jz .released
|
||||
|
||||
; Clic enfoncé
|
||||
mov byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
.released:
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
jne .hover
|
||||
|
||||
; Clic validé !
|
||||
mov al, 1
|
||||
mov byte [gs:si + widget.state], GUI_STATE_HOVER
|
||||
ret
|
||||
|
||||
.hover:
|
||||
mov byte [gs:si + widget.state], GUI_STATE_HOVER
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
; --- Logique spécifique Slider ---
|
||||
gui_logic_slider:
|
||||
test bl, 1 ; Bouton enfoncé ?
|
||||
jz .released
|
||||
|
||||
; Si on vient de cliquer (pas encore PRESSED), on initialise l'ancrage
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
je .do_drag
|
||||
|
||||
mov byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
|
||||
; Calcul de l'ancrage
|
||||
mov ax, cx
|
||||
sub ax, [gs:si + widget.attr_val]
|
||||
mov [gs:si + widget.attr_anchor], ax
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
jne .do_drag
|
||||
mov ax, dx
|
||||
sub ax, [gs:si + widget.attr_val]
|
||||
mov [gs:si + widget.attr_anchor], ax
|
||||
|
||||
.do_drag:
|
||||
; --- LOGIQUE DE DÉPLACEMENT ---
|
||||
cmp byte [gs:si + widget.drag_mode], 1
|
||||
cmp byte [gs:si + widget.attr_mode], 1
|
||||
je .drag_h
|
||||
cmp byte [gs:si + widget.drag_mode], 2
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
je .drag_v
|
||||
jmp .done
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
.drag_h:
|
||||
mov ax, cx
|
||||
sub ax, [gs:si + widget.drag_anchor] ; X = MouseX - Anchor
|
||||
sub ax, [gs:si + widget.attr_anchor] ; Nouvelle pos = MouseX - Anchor
|
||||
; Clamp Min
|
||||
cmp ax, [gs:si + widget.drag_min]
|
||||
cmp ax, [gs:si + widget.attr_min]
|
||||
jge .chk_max_h
|
||||
mov ax, [gs:si + widget.drag_min]
|
||||
mov ax, [gs:si + widget.attr_min]
|
||||
.chk_max_h:
|
||||
; Clamp Max
|
||||
cmp ax, [gs:si + widget.drag_max]
|
||||
cmp ax, [gs:si + widget.attr_max]
|
||||
jle .apply_pos
|
||||
mov ax, [gs:si + widget.drag_max]
|
||||
mov ax, [gs:si + widget.attr_max]
|
||||
jmp .apply_pos
|
||||
|
||||
.drag_v:
|
||||
mov ax, dx
|
||||
sub ax, [gs:si + widget.drag_anchor] ; Y = MouseY - Anchor
|
||||
; Clamp (Simplifié, on pourrait ajouter drag_min_y)
|
||||
; Ici on utilise les mêmes champs min/max pour l'axe choisi
|
||||
sub ax, [gs:si + widget.attr_anchor]
|
||||
; Clamp Min
|
||||
cmp ax, [gs:si + widget.attr_min]
|
||||
jge .chk_max_v
|
||||
mov ax, [gs:si + widget.attr_min]
|
||||
|
||||
.chk_max_v:
|
||||
; Clamp Max
|
||||
cmp ax, [gs:si + widget.attr_max]
|
||||
jle .apply_pos
|
||||
mov ax, [gs:si + widget.attr_max]
|
||||
jmp .apply_pos
|
||||
|
||||
.apply_pos:
|
||||
; Mise à jour position (si changement)
|
||||
cmp byte [gs:si + widget.drag_mode], 1
|
||||
je .upd_x
|
||||
mov [gs:si + widget.y], ax
|
||||
jmp .force_redraw
|
||||
.upd_x:
|
||||
mov [gs:si + widget.x], ax
|
||||
cmp ax, [gs:si + widget.attr_val]
|
||||
je .no_change
|
||||
mov [gs:si + widget.attr_val], ax
|
||||
|
||||
; Appel du callback on_drag
|
||||
cmp word [gs:si + widget.event_drag], 0
|
||||
je .force_redraw
|
||||
pusha
|
||||
call word [gs:si + widget.event_drag]
|
||||
popa
|
||||
|
||||
.force_redraw:
|
||||
mov byte [gs:si + widget.oldstate], 255 ; Force le redessin
|
||||
|
||||
.done:
|
||||
pop ds
|
||||
.no_change:
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
.released:
|
||||
mov byte [gs:si + widget.state], GUI_STATE_HOVER
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
; (Interne) Dessine le widget pointé par SI
|
||||
|
|
@ -391,7 +423,7 @@ gui_draw_single_widget:
|
|||
|
||||
mov al, [gs:si + widget.state]
|
||||
cmp al, [gs:si + widget.oldstate]
|
||||
je .skip_draw
|
||||
je .done
|
||||
|
||||
mov [gs:si + widget.oldstate], al ; marque comme à jour
|
||||
|
||||
|
|
@ -405,13 +437,77 @@ gui_draw_single_widget:
|
|||
add cx, ax
|
||||
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
|
||||
jne .not_slider
|
||||
call draw_slider
|
||||
jmp .done
|
||||
|
||||
.not_slider:
|
||||
cmp byte [gs:si + widget.type], WIDGET_TYPE_BUTTON
|
||||
jne .done
|
||||
call draw_button
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
draw_slider:
|
||||
; 1. Dessiner la piste (Track)
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_gray_mid
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0
|
||||
|
||||
; 2. Calculer la taille du curseur (Thumb)
|
||||
push ax ; Sauvegarde coords track (X1, Y1, X2, Y2)
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
je .calc_v
|
||||
|
||||
; --- Horizontal ---
|
||||
mov ax, [gs:si + widget.w]
|
||||
xor bh, bh
|
||||
mov bl, [gs:si + widget.thumb_pct]
|
||||
mul bx
|
||||
mov bx, 100
|
||||
div bx ; AX = Thumb Width
|
||||
|
||||
mov bx, [gs:si + widget.y] ; BX = Y1
|
||||
mov dx, bx
|
||||
add dx, [gs:si + widget.h] ; DX = Y2
|
||||
mov cx, [gs:si + widget.attr_val] ; CX = X1
|
||||
add ax, cx ; AX = X1 + Width = X2
|
||||
xchg ax, cx ; AX = X1, CX = X2
|
||||
jmp .draw_thumb
|
||||
|
||||
.calc_v:
|
||||
; --- Vertical ---
|
||||
mov ax, [gs:si + widget.h]
|
||||
xor bh, bh
|
||||
mov bl, [gs:si + widget.thumb_pct]
|
||||
mul bx
|
||||
mov bx, 100
|
||||
div bx ; AX = Thumb Height
|
||||
|
||||
mov bx, [gs:si + widget.attr_val] ; BX = Y1
|
||||
mov dx, bx
|
||||
add dx, ax ; DX = Y2
|
||||
mov ax, [gs:si + widget.x] ; AX = X1
|
||||
mov cx, ax
|
||||
add cx, [gs:si + widget.w] ; CX = X2
|
||||
|
||||
.draw_thumb:
|
||||
; 3. Dessiner le curseur (Thumb)
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_white
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0
|
||||
add sp, 8 ; Nettoyer la pile des push ax..dx
|
||||
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
|
||||
call draw_text
|
||||
ret
|
||||
|
||||
draw_button:
|
||||
; Dispatch selon état
|
||||
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
je .paint_pressed
|
||||
|
|
@ -419,38 +515,40 @@ gui_draw_single_widget:
|
|||
je .paint_hover
|
||||
|
||||
.paint_normal:
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_white
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir
|
||||
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
|
||||
jmp .text
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_white
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir
|
||||
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
|
||||
call draw_text
|
||||
jmp .done
|
||||
|
||||
.paint_hover:
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_gray_mid ; pattern_white
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir
|
||||
; Effet gras
|
||||
inc ax
|
||||
inc bx
|
||||
dec cx
|
||||
dec dx
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_gray_mid ; pattern_white
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 ; Bord Noir
|
||||
; Effet gras
|
||||
inc ax
|
||||
inc bx
|
||||
dec cx
|
||||
dec dx
|
||||
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0
|
||||
|
||||
; Restauration coords pour le texte
|
||||
mov ax, [gs:si + widget.x]
|
||||
mov bx, [gs:si + widget.y]
|
||||
jmp .text_setup
|
||||
; Restauration coords pour le texte
|
||||
mov ax, [gs:si + widget.x]
|
||||
mov bx, [gs:si + widget.y]
|
||||
call draw_text
|
||||
jmp .done
|
||||
|
||||
.paint_pressed:
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_black
|
||||
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
|
||||
jmp .text
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_black
|
||||
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
|
||||
; Recharger les coordonnées car GFX a pu modifier les registres
|
||||
mov ax, [gs:si + widget.x]
|
||||
mov bx, [gs:si + widget.y]
|
||||
call draw_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
|
||||
jmp .text
|
||||
.done
|
||||
ret
|
||||
|
||||
.text_setup:
|
||||
draw_text:
|
||||
; Petit hack pour recentrer le texte après l'effet gras
|
||||
mov cx, [gs:si + widget.w]
|
||||
mov dx, [gs:si + widget.h]
|
||||
|
|
@ -474,10 +572,10 @@ gui_draw_single_widget:
|
|||
mov ax, [gs:si + widget.w]
|
||||
sub ax, cx
|
||||
shr ax, 1
|
||||
pop bx ; Récupère X original dans BX (oups, on veut ajouter)
|
||||
add ax, bx ; X final
|
||||
pop dx ; Récupère X original (poussé depuis AX)
|
||||
add ax, dx ; AX = X final centré
|
||||
|
||||
push ax ; X final prêt
|
||||
push ax ; Sauvegarde X final pour GOTOXY
|
||||
|
||||
mov bx, [gs:si + widget.h]
|
||||
sub bx, 8
|
||||
|
|
@ -491,8 +589,4 @@ gui_draw_single_widget:
|
|||
mov dx, [gs:si + widget.text_seg]
|
||||
mov ax, [gs:si + widget.text_ofs]
|
||||
GFX WRITE, dx, ax
|
||||
|
||||
.done:
|
||||
.skip_draw:
|
||||
popa
|
||||
ret
|
||||
ret
|
||||
|
|
|
|||
Loading…
Reference in a new issue