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 = {
'mouse_column': None,
'mouse_row': None,
'mouse_buttons': None,
'window_chain_head': None,
'redraw': None,
'memory_allocation_map': None,

View File

@ -88,44 +88,65 @@ mainloop:
.draw:
call draw_wallpaper
; Draw windows
xor ax, ax ; WM_PAINT
call window_event
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:
mov bx, [di - mouse_column + mouse_x]
shr bx, 1
mov cx, [di - mouse_column + mouse_y]
shr cx, 2
mov bh, cl
cmp [di], bx
jne .update_cursor
xor al, al
xchg byte [di - mouse_column + mouse_change], al
test al, al
jz .mouse_change_end
.mouse_change:
mov cx, [di - mouse_column + mouse_x]
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
jmp mainloop
.update_cursor:
call flip_mouse_cursor
mov [di], bx
call flip_mouse_cursor
jmp mainloop
initialize_mouse_error:
; https://www.ctyme.com/intr/rb-1601.htm
mov ax, 0xc201
int 0x15
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
; ------------------------------------------------------------------
@ -191,7 +212,7 @@ draw_wallpaper:
rep movsw
popa
ret
.ret: ret ; window_event needs this
; requires:
; di = mouse_column
@ -460,6 +481,8 @@ mouse_handler:
and bl, BUTTONS
mov [cs:di], bl
mov byte [cs:di + 1], 1 ; Mark that mouse state has updated
popa
retf
@ -486,6 +509,7 @@ resb 8 ; Rest of the memory allocation map
mouse_x resw 1
mouse_y resw 1 ; mouse_x + 2, do not touch
mouse_buttons resb 1 ; mouse_y + 2
mouse_change resb 1 ; mouse_buttons + 1
mouse_column resb 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
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"
struc window
.next resw 1
.width resw 1
.height resw 1
.x resw 1
.y resw 1
.data resw 1
.size:
endstruc
cpu 8086
bits 16
@ -26,20 +36,29 @@ initialize:
xor di, di ; read
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
add ax, 0x001
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
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
call request_redraw
; Temporary testing
mov ax, cs
@ -77,6 +96,11 @@ process_event:
call paint
.not_paint:
cmp ax, WM_MOUSE
jne .not_mouse
call mouse
.not_mouse:
pop es
pop ds
pop bp
@ -89,51 +113,106 @@ process_event:
retf
paint:
mov bp, cs
sub bx, bp
call get_window
cmp bx, 0x001
je .window1
cmp bx, 0x002
je .window2
mov bx, [si + window.next]
call forward_event
mov ax, bx
call hexprint16
call hang
; Draw a rectangle on-screen
mov bx, [si + window.width]
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:
mov bx, [next_window1]
call forward_event
ret
mov byte [window_1.number], '1'
mouse:
call get_window
; Draw a rectangle on-screen
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
push cx
; 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
.window2:
mov bx, [next_window2]
.outside:
pop cx
mov bx, [si + window.next]
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
; 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
; cx = height of window (>= 1)
; dx = width of window in characters
@ -293,44 +372,43 @@ strlen:
; in:
; bx = window ID
; out:
; clobbers di
; clobbers bp
forward_event:
cmp bx, 0
je .end
push cs ; Return segment
mov di, .end
push di ; Return offset
mov bp, .end
push bp ; Return offset
mov di, 0xf000
and di, bx
push di ; Call segment
xor di, di
push di ; Call offset
mov bp, 0xf000
and bp, bx
push bp ; Call segment
xor bp, bp
push bp ; Call offset
retf
.end:
ret
next_window1 dw 0
next_window2 dw 0
wallpaper_name db 'wallpaper.bin', 0
%include "debug.inc"
window_1:
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f,
.number db '*', 0x0f
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '1', 0x0f
times 8 db ' ', 0x0f
times 16 db ' ', 0xf0
times 16 db ' ', 0xf0
times 16 db ' ', 0xf0
window_2:
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f,
.number db '*', 0x0f
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '2', 0x0f
times 32 db ' ', 0x0f
times 40 db ' ', 0xf0
times 40 db ' ', 0xf0
times 40 db ' ', 0xf0
windows:
times window.size db 0
times window.size db 0