From 744da780f3a5260685945e77b500d4c5a73e5e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Mon, 20 Mar 2023 20:18:49 +0200 Subject: [PATCH] Implement mouse events --- extract_symbols.py | 3 - ponydos.asm | 74 +++++++++++------ ponydos_static.inc | 4 + shell.asm | 196 +++++++++++++++++++++++++++++++-------------- 4 files changed, 190 insertions(+), 87 deletions(-) diff --git a/extract_symbols.py b/extract_symbols.py index 1768712..fb60a75 100644 --- a/extract_symbols.py +++ b/extract_symbols.py @@ -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, diff --git a/ponydos.asm b/ponydos.asm index b3c6bb5..6aaf872 100644 --- a/ponydos.asm +++ b/ponydos.asm @@ -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 diff --git a/ponydos_static.inc b/ponydos_static.inc index 034c970..b077515 100644 --- a/ponydos_static.inc +++ b/ponydos_static.inc @@ -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 diff --git a/shell.asm b/shell.asm index 217f98e..a6c4bda 100644 --- a/shell.asm +++ b/shell.asm @@ -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