Implement mouse events

This commit is contained in:
Juhani Krekelä 2023-03-20 20:18:49 +02:00
parent ae17e6380f
commit 744da780f3
4 changed files with 190 additions and 87 deletions

View File

@ -7,9 +7,6 @@ syscalls = {
} }
variables = { variables = {
'mouse_column': None,
'mouse_row': None,
'mouse_buttons': None,
'window_chain_head': None, 'window_chain_head': None,
'redraw': None, 'redraw': None,
'memory_allocation_map': None, 'memory_allocation_map': None,

View File

@ -88,44 +88,65 @@ mainloop:
.draw: .draw:
call draw_wallpaper call draw_wallpaper
; Draw windows
xor ax, ax ; WM_PAINT
call window_event
call flip_mouse_cursor call flip_mouse_cursor
; Draw windows
push cs ; Return segment
push word .draw_end ; Return offset
mov bx, [di - mouse_column + window_chain_head]
mov ax, 0xf000
and ax, bx
push ax ; Call segment
;push word 0 ; Call offset
push cs ; Call offset
xor ax, ax ; WM_PAINT
retf
.draw_end: .draw_end:
mov bx, [di - mouse_column + mouse_x] xor al, al
shr bx, 1 xchg byte [di - mouse_column + mouse_change], al
mov cx, [di - mouse_column + mouse_y] test al, al
shr cx, 2 jz .mouse_change_end
mov bh, cl .mouse_change:
cmp [di], bx mov cx, [di - mouse_column + mouse_x]
jne .update_cursor shr cx, 1
mov bx, [di - mouse_column + mouse_y]
shr bx, 2
mov ch, bl
call flip_mouse_cursor
mov [di], cx
call flip_mouse_cursor
mov dl, [di - mouse_column + mouse_buttons]
mov ax, WM_MOUSE
call window_event
.mouse_change_end:
hlt hlt
jmp mainloop jmp mainloop
.update_cursor:
call flip_mouse_cursor
mov [di], bx
call flip_mouse_cursor
jmp mainloop
initialize_mouse_error: initialize_mouse_error:
; https://www.ctyme.com/intr/rb-1601.htm ; https://www.ctyme.com/intr/rb-1601.htm
mov ax, 0xc201 mov ax, 0xc201
int 0x15 int 0x15
jmp initialize_mouse jmp initialize_mouse
; requires:
; ds = 0
; di = mouse_column
; in:
; ax = event
; out:
; clobbers bx
window_event:
push cs ; Return segment
push word draw_wallpaper.ret ; Return offset
mov bx, [di - mouse_column + window_chain_head]
mov bp, 0xf000
and bp, bx
push bp ; Call segment
;push word 0 ; Call offset
push cs ; Call offset
retf
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
; Drawing subroutines ; Drawing subroutines
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
@ -191,7 +212,7 @@ draw_wallpaper:
rep movsw rep movsw
popa popa
ret .ret: ret ; window_event needs this
; requires: ; requires:
; di = mouse_column ; di = mouse_column
@ -460,6 +481,8 @@ mouse_handler:
and bl, BUTTONS and bl, BUTTONS
mov [cs:di], bl mov [cs:di], bl
mov byte [cs:di + 1], 1 ; Mark that mouse state has updated
popa popa
retf retf
@ -486,6 +509,7 @@ resb 8 ; Rest of the memory allocation map
mouse_x resw 1 mouse_x resw 1
mouse_y resw 1 ; mouse_x + 2, do not touch mouse_y resw 1 ; mouse_x + 2, do not touch
mouse_buttons resb 1 ; mouse_y + 2 mouse_buttons resb 1 ; mouse_y + 2
mouse_change resb 1 ; mouse_buttons + 1
mouse_column resb 1 mouse_column resb 1
mouse_row resb 1 ; mouse_column + 1 mouse_row resb 1 ; mouse_column + 1

View File

@ -7,3 +7,7 @@ FS_DIRENT_SIZE equ 32
FS_FILE_MAX_SIZE equ 128 FS_FILE_MAX_SIZE equ 128
WM_PAINT equ 0 WM_PAINT equ 0
WM_MOUSE equ 1
MOUSE_PRIMARY equ 0x01
MOUSE_SECONDARY equ 0x02

196
shell.asm
View File

@ -1,5 +1,15 @@
%include "ponydos.inc" %include "ponydos.inc"
struc window
.next resw 1
.width resw 1
.height resw 1
.x resw 1
.y resw 1
.data resw 1
.size:
endstruc
cpu 8086 cpu 8086
bits 16 bits 16
@ -26,20 +36,29 @@ initialize:
xor di, di ; read xor di, di ; read
call PONYDOS_SEG:SYS_MODIFY_SECTORS call PONYDOS_SEG:SYS_MODIFY_SECTORS
; Put window 1 in the window chain ; Create window 1
mov ax, cs
add ax, 0x000
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
mov [windows + 0*window.size + window.next], ax
mov word [windows + 0*window.size + window.width], 16
mov word [windows + 0*window.size + window.height], 4
mov word [windows + 0*window.size + window.x], 10
mov word [windows + 0*window.size + window.y], 3
mov word [windows + 0*window.size + window.data], window_1
; Create window 2
mov ax, cs mov ax, cs
add ax, 0x001 add ax, 0x001
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
mov [next_window1], ax mov [windows + 1*window.size + window.next], ax
mov word [windows + 1*window.size + window.width], 40
mov word [windows + 1*window.size + window.height], 4
mov word [windows + 1*window.size + window.x], 14
mov word [windows + 1*window.size + window.y], 6
mov word [windows + 1*window.size + window.data], window_2
; Put window 2 in the window chain call request_redraw
mov ax, cs
add ax, 0x002
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
mov [next_window2], ax
; Request repaint
mov byte [es:GLOBAL_REDRAW], 1
; Temporary testing ; Temporary testing
mov ax, cs mov ax, cs
@ -77,6 +96,11 @@ process_event:
call paint call paint
.not_paint: .not_paint:
cmp ax, WM_MOUSE
jne .not_mouse
call mouse
.not_mouse:
pop es pop es
pop ds pop ds
pop bp pop bp
@ -89,51 +113,106 @@ process_event:
retf retf
paint: paint:
mov bp, cs call get_window
sub bx, bp
cmp bx, 0x001 mov bx, [si + window.next]
je .window1 call forward_event
cmp bx, 0x002
je .window2
mov ax, bx ; Draw a rectangle on-screen
call hexprint16 mov bx, [si + window.width]
call hang mov cx, bx
mov dx, [si + window.height]
mov di, [si + window.x]
mov bp, [si + window.y]
mov si, [si + window.data]
call PONYDOS_SEG:SYS_DRAW_RECT
.window1: ret
mov bx, [next_window1]
call forward_event
mov byte [window_1.number], '1' mouse:
call get_window
; Draw a rectangle on-screen push cx
mov bx, 16
mov cx, 16
mov dx, 4
mov si, window_1
mov di, 10
mov bp, 3
call PONYDOS_SEG:SYS_DRAW_RECT
; Y
xor bx, bx
mov bl, ch
; X
xor ch, ch
cmp cx, [si + window.x]
jl .outside
cmp bx, [si + window.y]
jl .outside
sub cx, [si + window.x]
cmp [si + window.width], cx
jle .outside
sub bx, [si + window.y]
cmp [si + window.height], bx
jle .outside
mov si, [si + window.data]
add si, 18
test dl, MOUSE_PRIMARY
jz .not_clicking
.clicking:
mov al, '*'
xchg byte [si], al
cmp al, '*'
je .end
call request_redraw
jmp .end
.not_clicking:
mov al, ' '
xchg byte [si], al
cmp al, ' '
je .end
call request_redraw
.end:
pop cx
ret ret
.window2: .outside:
mov bx, [next_window2] pop cx
mov bx, [si + window.next]
call forward_event call forward_event
mov byte [window_2.number], '2'
mov bx, 40
mov cx, 40
mov dx, 4
mov si, window_2
mov di, 14
mov bp, 6
call PONYDOS_SEG:SYS_DRAW_RECT
ret ret
; in:
; bx = valid window id for this process
; out:
; si = pointer to window's data block
get_window:
mov si, cs
sub bx, si
mov si, windows
push ax
push dx
mov ax, window.size
mul bx
add si, ax
pop dx
pop ax
ret
request_redraw:
push es
push bp
mov bp, PONYDOS_SEG
mov es, bp
mov byte [es:GLOBAL_REDRAW], 1
pop bp
pop es
ret
; in ; in
; cx = height of window (>= 1) ; cx = height of window (>= 1)
; dx = width of window in characters ; dx = width of window in characters
@ -293,44 +372,43 @@ strlen:
; in: ; in:
; bx = window ID ; bx = window ID
; out: ; out:
; clobbers di ; clobbers bp
forward_event: forward_event:
cmp bx, 0 cmp bx, 0
je .end je .end
push cs ; Return segment push cs ; Return segment
mov di, .end mov bp, .end
push di ; Return offset push bp ; Return offset
mov di, 0xf000 mov bp, 0xf000
and di, bx and bp, bx
push di ; Call segment push bp ; Call segment
xor di, di xor bp, bp
push di ; Call offset push bp ; Call offset
retf retf
.end: .end:
ret ret
next_window1 dw 0
next_window2 dw 0
wallpaper_name db 'wallpaper.bin', 0 wallpaper_name db 'wallpaper.bin', 0
%include "debug.inc" %include "debug.inc"
window_1: window_1:
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '1', 0x0f
.number db '*', 0x0f
times 8 db ' ', 0x0f times 8 db ' ', 0x0f
times 16 db ' ', 0xf0 times 16 db ' ', 0xf0
times 16 db ' ', 0xf0 times 16 db ' ', 0xf0
times 16 db ' ', 0xf0 times 16 db ' ', 0xf0
window_2: window_2:
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '2', 0x0f
.number db '*', 0x0f
times 32 db ' ', 0x0f times 32 db ' ', 0x0f
times 40 db ' ', 0xf0 times 40 db ' ', 0xf0
times 40 db ' ', 0xf0 times 40 db ' ', 0xf0
times 40 db ' ', 0xf0 times 40 db ' ', 0xf0
windows:
times window.size db 0
times window.size db 0