ponydos/viewer.asm

1279 lines
22 KiB
NASM
Raw Permalink Normal View History

2023-03-25 22:53:02 +00:00
%include "ponydos.inc"
cpu 8086
bits 16
WINDOW_STATUS_NORMAL equ 0
WINDOW_STATUS_MOVE equ 1
WINDOW_STATUS_RESIZE equ 2
; Resize button, title, space, close button
WINDOW_MIN_WIDTH equ 1 + 8 + 1 + 1
WINDOW_MIN_HEIGHT equ 3
2023-03-25 22:53:02 +00:00
; 0x0000
jmp near process_event
; 0x0003 PROC_INITIALIZE_ENTRYPOINT
; initialize needs to preserve ds
initialize:
push ds
; On entry, ds and es will not be set correctly for us
mov bp, cs
mov es, bp
mov ds, bp
call hook_self_onto_window_chain
call render_window
; We must explicitly request redraw from the compositor
call request_redraw
pop ds
retf
; process_event needs to preserve all registers other than ax
; in:
; al = event
; bx = window ID
; cx, dx = event-specific
; out:
; ax = event-specific
process_event:
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
; On entry, ds and es will not be set correctly for us
; WM_OPEN_FILE needs ds to be left-as is
cmp al, WM_OPEN_FILE
je .no_set_ds
push cs
pop ds
.no_set_ds:
push cs
pop es
2023-03-25 22:53:02 +00:00
cmp al, WM_PAINT
jne .not_paint
call event_paint
jmp .end
.not_paint:
cmp al, WM_MOUSE
jne .not_mouse
call event_mouse
jmp .end
.not_mouse:
cmp al, WM_KEYBOARD
jne .not_keyboard
call event_keyboard
jmp .end
.not_keyboard:
cmp al, WM_UNHOOK
jne .not_unhook
call event_unhook
jmp .end
.not_unhook:
cmp al, WM_OPEN_FILE
jne .not_open_file
call event_open_file
jmp .end
.not_open_file:
2023-03-25 22:53:02 +00:00
.end:
cmp byte [exiting], 0
je .not_exiting
call deallocate_own_memory
.not_exiting:
2023-03-25 22:53:02 +00:00
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
retf
; ------------------------------------------------------------------
; Filename handling
; ------------------------------------------------------------------
; in:
; cl = typed character
; ch = pressed key
; out:
; clobbers bx
filename_char_add:
cmp word [cur_filename_address], filename_window_data.filename + 2*(FS_DIRENT_NAME_SIZE-1)
je .done
mov bx, [cur_filename_address]
mov byte [bx], cl
add word [cur_filename_address], 2
call request_redraw
.done:
ret
; out:
; clobbers bx
filename_char_del:
cmp word [cur_filename_address], filename_window_data.filename
je .done
mov bx, [cur_filename_address]
mov byte [bx - 2], 0x00
sub word [cur_filename_address], 2
call request_redraw
.done:
ret
; out:
; clobbers everything
filename_ok:
; Just ignore if there's no filename.
cmp byte [filename_window_data.filename], 0
je .end
mov cx, FS_DIRENT_NAME_SIZE
mov di, window_title
mov si, filename_window_data.filename
.loop:
lodsb
stosb
inc si
loop .loop
mov si, window_title
xor dx, dx ; do create empty file
call PONYDOS_SEG:SYS_OPEN_FILE
test ax, ax
jnz .got_file
mov si, ood_window
call raise_error
ret
.got_file:
call allocate_segment
test dx, dx
jnz .got_memory
mov si, oom_window
call raise_error
ret
.got_memory:
mov [cur_file_address + 2], dx
mov word [cur_file_address], 0
mov word [beg_file_address], 0
push es
mov es, dx
xor bx, bx
xor di, di ; read
call PONYDOS_SEG:SYS_MODIFY_SECTORS
pop es
mov ch, cl
xor cl, cl
shl cx, 1 ; Multiply by 512
mov [end_file_address], cx
mov si, text_window
mov di, window
mov cx, window_struc.size
rep movsb
mov byte [file_opened], 1
call render_window
call request_redraw
.end:
ret
; ------------------------------------------------------------------
; Text file handling
2023-03-25 22:53:02 +00:00
; ------------------------------------------------------------------
; in:
; es:di = where to start printing on screen
print_file:
push ax
push bx
push cx
push dx
push si
push di
push ds
lds si, [cur_file_address]
mov cx, [cs:window.height]
2023-03-25 22:53:02 +00:00
dec cx
mov dx, [cs:window.width]
2023-03-25 22:53:02 +00:00
mov bl, 1 ; Haven't read anything yet
.window_loop:
push di
.line_loop:
cmp si, [cs:end_file_address]
jne .not_end_file
test bl, bl
jz .end_window_loop ; Need to have read something to hit end-of-file
.not_end_file:
lodsb
xor bl, bl ; Have read something
; Special byte handling
cmp al, 0x0A ; \n
je .next_line
cmp al, 0x09 ; \t
jne .null_check
add di, 8
sub dx, 4
jc .next_line
jz .next_line
jmp .line_loop
.null_check:
test al, al
jz .end_window_loop
stosb
inc di
dec dx
jnz .line_loop
.next_line:
mov dx, [cs:window.width]
2023-03-25 22:53:02 +00:00
pop di
add di, [cs:window.width]
add di, [cs:window.width]
2023-03-25 22:53:02 +00:00
loop .window_loop
.ret:
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
2023-03-25 22:53:02 +00:00
.end_window_loop:
pop di
jmp .ret
; out:
; dx = non-zero if cur_file_address is updated
file_next_line:
push ax
push si
push ds
xor dx, dx
lds si, [cur_file_address]
.loop:
lodsb
cmp al, 0x0A ; \n
je .found_next_line
test al, al
jz .ret
cmp si, [cs:end_file_address]
je .ret
jmp .loop
.found_next_line:
cmp si, [cs:end_file_address]
je .ret
cmp byte [ds:si], 0
je .ret
not dx
mov [cs:cur_file_address], si
.ret:
pop ds
pop si
pop ax
ret
; out:
; dx = non-zero if cur_file_address is updated
file_prev_line:
push ax
push si
push ds
std
xor dx, dx
lds si, [cur_file_address]
cmp si, [cs:beg_file_address] ; Already at the beginning?
je .ret
dec si
cmp si, [cs:beg_file_address] ; Last line was empty?
je .ret
dec si
.loop:
cmp si, [cs:beg_file_address]
je .found_prev_line
lodsb
cmp al, 0x0A ; \n
jne .loop
inc si
inc si
.found_prev_line:
not dx
mov [cs:cur_file_address], si
.ret:
cld
pop ds
pop si
pop ax
ret
; ------------------------------------------------------------------
; Event handlers
; ------------------------------------------------------------------
; in:
; al = WM_PAINT
; bx = window ID
; out:
; clobbers everything
event_paint:
; Forward the paint event to the next window in the chain
; We must do this before we paint ourselves, because painting must
; happen from the back to the front
; Because we only have one window, we don't need to save our own ID
mov bx, [window_next]
call send_event
mov bx, [window.width] ; Buffer width, usually same as window width
mov cx, [window.width]
mov dx, [window.height]
mov di, [window.x]
mov bp, [window.y]
mov si, [window.data_address]
2023-03-25 22:53:02 +00:00
cmp di, 0
jge .not_clip_left
.clip_left:
; Adjust the start of buffer to point to the first cell
; that is on screen
sub si, di
sub si, di
; Adjust window width to account for non-rendered area
; that is off screen
add cx, di
; Set X to 0
xor di, di
.not_clip_left:
mov ax, di
add ax, cx
cmp ax, COLUMNS
jle .not_clip_right
.clip_right:
; Adjust the width to only go as far as the right edge
sub ax, COLUMNS
sub cx, ax
.not_clip_right:
mov ax, bp
add ax, dx
cmp ax, ROWS
jle .not_clip_bottom
.clip_bottom:
; Adjust the height to only go as far as the bottom edge
sub ax, ROWS
sub dx, ax
.not_clip_bottom:
call PONYDOS_SEG:SYS_DRAW_RECT
ret
; in:
; al = WM_MOUSE
; bx = window ID
; cl = X
; ch = Y
; dl = mouse buttons held down
; out:
; clobbers everything
event_mouse:
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
jnz .not_end_window_change
; If we were moving or resizing the window, releasing the
; button signals the end of the action
mov byte [window_status], WINDOW_STATUS_NORMAL
.not_end_window_change:
; Expand X and Y to 16 bits for easier calculations
; Because we only have one window, we don't need to save our own ID
xor bx, bx
mov bl, ch
xor ch, ch
; Are we moving the window at the moment?
cmp byte [window_status], WINDOW_STATUS_MOVE
jne .not_moving
call move_window
.not_moving:
; Are we resizing the window at the moment?
cmp byte [window_status], WINDOW_STATUS_RESIZE
jne .not_resizing
call resize_window
.not_resizing:
; Check if the mouse is outside our window
cmp cx, [window.x]
2023-03-25 22:53:02 +00:00
jl .outside ; x < window_x
cmp bx, [window.y]
2023-03-25 22:53:02 +00:00
jl .outside ; y < window_y
mov ax, [window.x]
add ax, [window.width]
2023-03-25 22:53:02 +00:00
cmp ax, cx
jle .outside ; window_x + window_width <= x
mov ax, [window.y]
add ax, [window.height]
2023-03-25 22:53:02 +00:00
cmp ax, bx
jle .outside ; window_y + window_height <= y
.inside:
cmp byte [window_mouse_released_inside], 0
je .not_click
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
jz .not_click
.click:
call event_click
.not_click:
; We need to keep track of if the mouse has been inside our
; window without the buttons held, in order to avoid
; generating click events in cases where the cursor is
; dragged into our window while buttons are held
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
jz .buttons_not_held
.buttons_held:
mov byte [window_mouse_released_inside], 0
jmp .buttons_end
.buttons_not_held:
mov byte [window_mouse_released_inside], 1
.buttons_end:
; We must forward the event even if it was inside our
; window, to make sure other windows know when the mouse
; leaves them
; Set x and y to 255 so that windows below ours don't think
; the cursor is inside them
; Also clear the mouse buttons not absolutely necessary
; but it's cleaner if other windows don't get any
; information about the mouse
mov al, WM_MOUSE
mov bx, [window_next]
mov cx, 0xffff
xor dl, dl
call send_event
ret
.outside:
mov byte [window_mouse_released_inside], 0
; Not our window, forward the event
mov al, WM_MOUSE
mov ch, bl ; Pack the X and Y back into cx
mov bx, [window_next]
call send_event
ret
ret
; in:
; bx = Y
; cx = X
; dl = mouse buttons
event_click:
2023-03-25 22:54:48 +00:00
push ax
2023-03-25 22:53:02 +00:00
; This is not a true event passed into our event handler, but
; rather one we've synthetized from the mouse event
; The reason we synthetize this event is because most interface
; elements react to clicks specifically, so having this event
; making implementing them easier
; Raising a window is done by first unhooking, then rehooking it to
; the window chain
call unhook_self_from_window_chain
call hook_self_onto_window_chain
call request_redraw
; Did the user click the title bar?
cmp [window.y], bx
2023-03-25 22:53:02 +00:00
jne .not_title_bar
.title_bar:
; Did the user click the window close button?
mov ax, [window.x]
add ax, [window.width]
2023-03-25 22:53:02 +00:00
dec ax
cmp ax, cx
jne .not_close
.close:
call close_window
jmp .end
2023-03-25 22:53:02 +00:00
.not_close:
; Did the user click on the resize button?
cmp byte [file_opened], 0
je .not_resize ; Can't resize while entering filename
cmp [window.x], cx
2023-03-25 22:53:02 +00:00
jne .not_resize
.resize:
mov byte [window_status], WINDOW_STATUS_RESIZE
jmp .end
2023-03-25 22:53:02 +00:00
.not_resize:
; Clicking on the title bar signals beginning of a window
; move
mov byte [window_status], WINDOW_STATUS_MOVE
mov ax, [window.x]
2023-03-25 22:53:02 +00:00
sub ax, cx
mov [window_move_x_offset], ax
jmp .end
2023-03-25 22:53:02 +00:00
.not_title_bar:
cmp byte [file_opened], 0
jne .not_filename_window
.filename_window:
sub bx, [window.y]
sub cx, [window.x]
mov ax, [window.width]
shl ax, 1
mul bx
add ax, cx
add ax, cx
add ax, filename_window_data
mov bx, ax
inc bx
cmp byte [bx], CANCEL_COLOR
jne .not_cancel
.cancel:
call unhook_self_from_window_chain
mov byte [exiting], 1
jmp .end
.not_cancel:
cmp byte [bx], OK_COLOR
jne .not_ok
.ok:
call filename_ok
.not_ok:
jmp .end
.not_filename_window:
mov ax, [window.x]
add ax, [window.width]
dec ax
cmp ax, cx
jne .not_scroll_bar
; Scroll up button?
mov ax, [window.y]
inc ax
cmp ax, bx
jne .not_scroll_up
.scroll_up:
call file_prev_line
test dx, dx
jz .end
call render_window
call request_redraw
jmp .end
.not_scroll_up:
; Scroll down button?
add ax, [window.height]
dec ax
dec ax
cmp ax, bx
jne .not_scroll_down
.scroll_down:
call file_next_line
test dx, dx
jz .end
call render_window
call request_redraw
.not_scroll_down:
2023-03-25 22:53:02 +00:00
.not_scroll_bar:
2023-03-25 22:53:02 +00:00
.end:
2023-03-25 22:54:48 +00:00
pop ax
2023-03-25 22:53:02 +00:00
ret
; in:
; al = WM_KEYBOARD
; bx = window ID
; cl = typed character
; ch = pressed key
; out:
; clobbers everything
event_keyboard:
cmp byte [file_opened], 0
jne .file_opened
cmp word [window.data_address], filename_window_data
jne .ret ; error windows
.file_not_opened:
cmp ch, 0x0e
jne .not_backspace
.backspace:
call filename_char_del
ret
.not_backspace:
cmp ch, 0x1c
jne .not_enter
.enter:
call filename_ok
ret
.not_enter:
call filename_char_add
ret
.file_opened:
2023-03-25 22:53:02 +00:00
cmp ch, 0x50 ; down key
jne .up_key_check
.down_key:
call file_next_line
test dx, dx
jz .ret
call render_window
call request_redraw
ret
2023-03-25 22:53:02 +00:00
.up_key_check:
cmp ch, 0x48 ; up key
jne .space_check
.up_key:
call file_prev_line
test dx, dx
jz .ret
call render_window
call request_redraw
ret
.space_check:
cmp cl, ' '
2023-03-25 22:53:02 +00:00
jne .ret
.space:
; Go down eight lines
xor ax, ax
mov cx, 8
.loop:
call file_next_line
or ax, dx
loop .loop
test ax, ax
jz .ret
call render_window
call request_redraw
2023-03-25 22:53:02 +00:00
.ret:
ret
; in:
; al = WM_UNHOOK
; bx = window ID
; cx = window ID of the window to unhook from the window chain
; out:
; ax = own window ID if we did not unhook
; next window ID if we did
; clobbers everything else
event_unhook:
cmp bx, cx
je .unhook_self
; Save our own ID
push bx
; Propagate the event
mov bx, [window_next]
call send_event
; Update window_next in case the next one unhooked
mov [window_next], ax
; Return our own ID
pop ax
ret
.unhook_self:
; Return window_next to the caller, unhooking us from the
; chain
mov ax, [window_next]
ret
; in:
; al = WM_OPEN_FILE
; ds:cx = filename
; ds ≠ cs
; out:
; ds = cs
; clobbers everything
event_open_file:
; Copy the file name over
mov si, cx
mov di, [es:cur_filename_address]
.copy_filename:
lodsb
test al, al
jz .copy_end
stosb
inc di
jmp .copy_filename
.copy_end:
mov [es:cur_filename_address], di
; Set ds to be as expected by most of the program
push cs
pop ds
; Mark that the filename came from WM_OPEN_FILE
mov byte [filename_from_wm_open_file], 1
call filename_ok
ret
2023-03-25 22:53:02 +00:00
; ------------------------------------------------------------------
; Event handler subroutines
; ------------------------------------------------------------------
; out:
; clobbers si, di, cx
close_window:
; If filename was from WM_OPEN_FILE event instead of user input,
; exit the app instead of going to name input dialog
cmp byte [filename_from_wm_open_file], 0
jne .exit_app
cmp word [window.data_address], oom_window_data
je .error_window
cmp word [window.data_address], ood_window_data
je .error_window
.exit_app:
call unhook_self_from_window_chain
mov byte [exiting], 1
ret
.error_window:
mov si, filename_window
mov di, window
mov cx, window_struc.size
rep movsb
call request_redraw
ret
2023-03-25 22:53:02 +00:00
; in:
; bx = Y
; cx = X
move_window:
push ax
; Offset the X coördinate so that the apparent drag position
; remains the same
mov ax, cx
add ax, [window_move_x_offset]
; Only do an update if something has changed. Reduces flicker
cmp [window.x], ax
2023-03-25 22:53:02 +00:00
jne .update_location
cmp [window.y], bx
2023-03-25 22:53:02 +00:00
jne .update_location
jmp .end
.update_location:
mov [window.x], ax
mov [window.y], bx
2023-03-25 22:53:02 +00:00
call request_redraw
.end:
pop ax
ret
; in:
; bx = Y
; cx = X
resize_window:
push ax
push bx
push bp
; Calculate new width
mov ax, [window.width]
add ax, [window.x]
2023-03-25 22:53:02 +00:00
sub ax, cx
cmp ax, WINDOW_MIN_WIDTH
jge .width_large_enough
mov ax, WINDOW_MIN_WIDTH
.width_large_enough:
cmp ax, COLUMNS
jle .width_small_enough
mov ax, COLUMNS
.width_small_enough:
; Calculate new height
mov bp, [window.height]
add bp, [window.y]
2023-03-25 22:53:02 +00:00
sub bp, bx
cmp bp, WINDOW_MIN_HEIGHT
jge .height_large_enough
mov bp, WINDOW_MIN_HEIGHT
.height_large_enough:
cmp bp, ROWS
jle .height_small_engough
mov bp, ROWS
.height_small_engough:
; Only do an update if something has changed. Reduces flicker
cmp [window.width], ax
2023-03-25 22:53:02 +00:00
jne .update_size
cmp [window.height], bp
2023-03-25 22:53:02 +00:00
jne .update_size
jmp .end
.update_size:
mov bx, [window.x]
add bx, [window.width]
2023-03-25 22:53:02 +00:00
sub bx, ax
mov [window.x], bx
mov [window.width], ax
2023-03-25 22:53:02 +00:00
mov bx, [window.y]
add bx, [window.height]
2023-03-25 22:53:02 +00:00
sub bx, bp
mov [window.y], bx
mov [window.height], bp
2023-03-25 22:53:02 +00:00
call render_window
call request_redraw
.end:
pop bp
pop bx
pop ax
render_window:
push ax
push cx
push dx
push si
push di
; Clear window to be black-on-white
mov di, text_window_data
mov ax, [window.width]
mov cx, [window.height]
2023-03-25 22:53:02 +00:00
mul cx
mov cx, ax
mov ax, 0xf000 ; Attribute is in the high byte
rep stosw
; Set title bar to be white-on-black
mov di, text_window_data
2023-03-25 22:53:02 +00:00
mov ax, 0x0f00
mov cx, [window.width]
2023-03-25 22:53:02 +00:00
rep stosw
; Add title bar buttons
mov di, text_window_data
2023-03-25 22:53:02 +00:00
mov byte [di], 0x17 ; Resize arrow
add di, [window.width]
add di, [window.width]
2023-03-25 22:53:02 +00:00
sub di, 2
mov byte [di], 'x' ; Close button
; Add window title
mov di, text_window_data
2023-03-25 22:53:02 +00:00
add di, 2
mov si, window_title
mov cx, [window.width]
2023-03-25 22:53:02 +00:00
dec cx
dec cx
cmp cx, FS_DIRENT_NAME_SIZE
jle .copy_title
mov cx, FS_DIRENT_NAME_SIZE
.copy_title:
lodsb
stosb
inc di
loop .copy_title
; Print text
mov di, text_window_data
add di, [window.width]
add di, [window.width]
2023-03-25 22:53:02 +00:00
call print_file
add di, [window.width]
add di, [window.width]
sub di, 2
mov byte [di], 0x1E ; up
mov ax, [window.width]
mov cx, [window.height]
sub cx, 2
shl cx, 1
mul cx
add di, ax
mov byte [di], 0x1F ; down
2023-03-25 22:53:02 +00:00
pop di
pop si
pop dx
pop cx
pop ax
ret
; ------------------------------------------------------------------
; Window chain
; ------------------------------------------------------------------
; in:
; al = event
; bx = window to send the event to
; cx, dx = event-specific
; out:
; ax = event-specific, 0 if bx=0
send_event:
test bx, bx
jnz .non_zero_id
; Returning 0 if the window ID is 0 makes window unhooking simpler
xor ax, ax
ret
.non_zero_id:
push bp
; Push the return address
push cs
mov bp, .end
push bp
; Push the address we're doing a far-call to
mov bp, bx
and bp, 0xf000 ; Highest nybble of window ID marks the segment
push bp
xor bp, bp ; Event handler is always at address 0
push bp
retf
.end:
pop bp
ret
hook_self_onto_window_chain:
push ax
push es
mov ax, PONYDOS_SEG
mov es, ax
; Window ID is made of the segment (top nybble) and an arbitrary
; process-specific part (lower three nybbles). Since we only have
; one window, we can leave the process-specific part as zero
mov ax, cs
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
; Save the old head of the chain, so that we can propagate events
; down to it
mov [window_next], ax
pop es
pop ax
ret
unhook_self_from_window_chain:
push bx
push cx
push es
mov ax, PONYDOS_SEG
mov es, ax
mov al, WM_UNHOOK
mov bx, [es:GLOBAL_WINDOW_CHAIN_HEAD]
; Our window ID is just our segment, see the comment in
; hook_self_onto_window_chain
mov cx, cs
call send_event
; Update the head of the chain, in case we were at the head
mov [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
pop es
pop cx
pop bx
ret
; ------------------------------------------------------------------
; Error handling
; ------------------------------------------------------------------
; in:
; si = window of error type
; out:
; clobbers si, di, cx
raise_error:
mov di, window
mov cx, window_struc.size
rep movsb
call request_redraw
ret
2023-03-25 22:53:02 +00:00
; ------------------------------------------------------------------
; Memory management
; ------------------------------------------------------------------
; out:
; dx = segment, 0 for none found
allocate_segment:
push ax
push cx
push si
push es
mov ax, PONYDOS_SEG
mov es, ax
mov si, GLOBAL_MEMORY_ALLOCATION_MAP
mov cx, MEM_ALLOCATION_MAP_SIZE
.find_free_segment:
mov al, [es:si]
test al, al
jz .found_free_segment
inc si
loop .find_free_segment
xor dx, dx
jmp .end
.found_free_segment:
mov byte [es:si], 1 ; Mark as used
; Set up ax to point to the allocated segment
sub si, GLOBAL_MEMORY_ALLOCATION_MAP
mov cl, 12
shl si, cl
mov dx, si
.end:
pop es
pop si
pop cx
pop ax
ret
2023-03-25 22:53:02 +00:00
deallocate_own_memory:
push bx
push cx
push es
mov bx, PONYDOS_SEG
mov es, bx
cmp byte [file_opened], 0
je .file_not_opened
.file_opened:
mov bx, [cur_file_address + 2]
mov cl, 12
shr bx, cl
mov byte [es:GLOBAL_MEMORY_ALLOCATION_MAP + bx], 0
.file_not_opened:
2023-03-25 22:53:02 +00:00
mov bx, cs
mov cl, 12
shr bx, cl
mov byte [es:GLOBAL_MEMORY_ALLOCATION_MAP + bx], 0
pop es
pop cx
pop bx
ret
; ------------------------------------------------------------------
; Painting
; ------------------------------------------------------------------
request_redraw:
push ax
push es
mov ax, PONYDOS_SEG
mov es, ax
mov byte [es:GLOBAL_REDRAW], 1
pop es
pop ax
ret
; ------------------------------------------------------------------
; Variables
; ------------------------------------------------------------------
filename_from_wm_open_file db 0
exiting db 0
window_title times FS_DIRENT_NAME_SIZE db 0
2023-03-25 22:53:02 +00:00
cur_file_address: dw 0
dw 0 ; Segment
beg_file_address dw 0
end_file_address dw 0
2023-03-25 22:53:02 +00:00
window:
.x dw 24
.y dw 9
.width dw FS_DIRENT_NAME_SIZE + 2
.height dw 6
.data_address dw filename_window_data
struc window_struc
.x resw 1
.y resw 1
.width resw 1
.height resw 1
.data_address resw 1
.size:
endstruc
filename_window:
.x dw 24
.y dw 9
.width dw FS_DIRENT_NAME_SIZE + 2
.height dw 6
.data_address dw filename_window_data
text_window:
.x dw 17
.y dw 7
.width dw 52
.height dw 16
.data_address dw text_window_data
oom_window:
.x dw 30
.y dw 10
.width dw 13
.height dw 2
.data_address dw oom_window_data
ood_window:
.x dw 36
.y dw 13
.width dw 17
.height dw 2
.data_address dw ood_window_data
2023-03-25 22:53:02 +00:00
window_next dw 0xffff
2023-03-25 22:53:02 +00:00
window_mouse_released_inside db 0
window_status db WINDOW_STATUS_NORMAL
window_move_x_offset dw 0
cur_filename_address dw filename_window_data.filename
file_opened db 0
; pre-built windows
CANCEL_COLOR equ 0x8f
OK_COLOR equ 0x20
filename_window_data:
; header
db 'V', 0x0f, 'i', 0x0f, 'e', 0x0f, 'w', 0x0f, 'e', 0x0f, 'r', 0x0f
times FS_DIRENT_NAME_SIZE + 2 - 7 db 0, 0x0f
db 'x', 0x0f
; blank line
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
; filename
db 0, 0x70
.filename:
times FS_DIRENT_NAME_SIZE db 0, 0xf0
db 0, 0x70
; blank line
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
; buttons line
times 7 db 0, 0x70
db 0, 0x8f, 'C', 0x8f, 'a', 0x8f, 'n', 0x8f, 'c', 0x8f, 'e', 0x8f, 'l', 0x8f, 0, 0x8f
times 5 db 0, 0x70
db 0, 0x20, 'O', 0x20, 'K', 0x20, 0x, 0x20
times 8 db 0, 0x70
; blank line
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
oom_window_data:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f
times 13-5-1 db 0x00, 0x0f
db 'x', 0x0f
db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0
db ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0
db 'y', 0xf0
ood_window_data:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f
times 17-5-1 db 0x00, 0x0f
db 'x', 0x0f
db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0
db ' ', 0xf0, 'd', 0xf0, 'i', 0xf0, 's', 0xf0, 'k', 0xf0, ' ', 0xf0
db 's', 0xf0, 'p', 0xf0, 'a', 0xf0, 'c', 0xf0, 'e', 0xf0
2023-03-25 22:53:02 +00:00
section .bss
text_window_data resw ROWS*COLUMNS