041cf206ec
Using a LIFO stack for events was a dumb idea in the first place, this should've been a FIFO queue from the beginning. This allows the system to respond to events in the same order that they are generated, instead of always responding to the newest event first.
222 lines
7.3 KiB
NASM
222 lines
7.3 KiB
NASM
; menu bar routines
|
|
|
|
; clear menu bar
|
|
; inputs:
|
|
; none
|
|
; outputs:
|
|
; none
|
|
clear_menu_bar:
|
|
push r0
|
|
push r1
|
|
push r2
|
|
push r3
|
|
push r4
|
|
push r5
|
|
push r31
|
|
|
|
mov r31, 80
|
|
movz.8 r0, ' '
|
|
mov r1, 0
|
|
mov r2, 0
|
|
mov r3, 0xFF000000
|
|
mov r4, 0xFFFFFFFF
|
|
mov r5, 30
|
|
clear_menu_bar_loop:
|
|
call draw_font_tile_to_overlay
|
|
add r1, 8
|
|
loop clear_menu_bar_loop
|
|
|
|
pop r31
|
|
pop r5
|
|
pop r4
|
|
pop r3
|
|
pop r2
|
|
pop r1
|
|
pop r0
|
|
ret
|
|
|
|
|
|
; draw root menu bar items
|
|
; inputs:
|
|
; r0: pointer to menu bar root struct
|
|
; r1: selected root menu item (or 0xFFFFFFFF for none)
|
|
; outputs:
|
|
; none
|
|
draw_menu_bar_root_items:
|
|
push r0
|
|
push r1
|
|
push r2
|
|
push r3
|
|
push r4
|
|
push r5
|
|
push r6
|
|
push r29
|
|
push r30
|
|
push r31
|
|
|
|
movz.8 r31, [r0] ; load number of root menu items into r31 for looping
|
|
mov r30, r1 ; r30: number of the selected item
|
|
mov r29, 0 ; counter of how many menu items drawn so far
|
|
mov r6, r0
|
|
add r6, 5 ; point to start of root menu items text pointer
|
|
mov r1, 16 ; X = 16
|
|
mov r2, 0 ; Y = 0
|
|
mov r5, 30 ; overlay 30
|
|
draw_menu_bar_root_items_loop:
|
|
cmp r30, r29
|
|
ifz mov r3, 0xFFFFFFFF ; foreground color: white
|
|
ifz mov r4, 0xFF000000 ; background color: black
|
|
ifnz mov r3, 0xFF000000 ; foreground color: black
|
|
ifnz mov r4, 0xFFFFFFFF ; background color: white
|
|
|
|
; draw colored space before text
|
|
sub r1, 8
|
|
movz.8 r0, ' '
|
|
call draw_font_tile_to_overlay
|
|
add r1, 8
|
|
|
|
mov r0, [r6] ; get pointer to text
|
|
inc r0 ; increment past length byte
|
|
call draw_str_to_overlay ; draw menu item text
|
|
|
|
; draw colored space after text
|
|
movz.8 r0, ' '
|
|
call draw_font_tile_to_overlay
|
|
|
|
add r1, 16 ; add some space next to this menu item
|
|
add r6, 8 ; increment pointer to text pointer
|
|
inc r29
|
|
loop draw_menu_bar_root_items_loop
|
|
|
|
pop r31
|
|
pop r30
|
|
pop r29
|
|
pop r6
|
|
pop r5
|
|
pop r4
|
|
pop r3
|
|
pop r2
|
|
pop r1
|
|
pop r0
|
|
ret
|
|
|
|
; handle menu bar click
|
|
; inputs:
|
|
; r0: pointer to menu bar root struct
|
|
; r1: X position where the menu bar was clicked
|
|
; outputs:
|
|
; none
|
|
menu_bar_click_event:
|
|
push r0
|
|
push r1
|
|
push r2
|
|
push r3
|
|
push r4
|
|
push r5
|
|
push r6
|
|
push r7
|
|
push r28
|
|
push r29
|
|
push r30
|
|
push r31
|
|
|
|
; move the X coordinate to r3
|
|
mov r3, r1
|
|
push r0
|
|
; the user might've clicked on a root menu item, check to see if they did and what button they clicked
|
|
movz.8 r31, [r0] ; load number of root menu items into r31 for looping
|
|
mov r30, 0 ; use r30 as an incrementing counter of menu item lengths calculated so far
|
|
mov r29, 16 ; use r29 as the starting X coord of the current menu item
|
|
;mov r28, 0 ; use r28 as the ending X coord of the current menu item
|
|
mov r4, r0
|
|
add r4, 5 ; point to start of root menu items text pointer
|
|
menu_bar_click_event_loop:
|
|
mov r0, [r4] ; get pointer to text
|
|
movz.8 r1, [r0] ; get length byte
|
|
mul r1, 8 ; calculate the length in pixels
|
|
mov r28, r1
|
|
add r28, r29 ; use r28 as the ending X coord of the current menu item
|
|
mov r2, r1
|
|
; now we need to check if the mouse's X coord is between the values of r29 and r28
|
|
; if carry flag is set, value is less than
|
|
; if carry flag is clear, value is greater than or equal to
|
|
mov r1, r3
|
|
; this is a trick to check if a value is within a certain range
|
|
; see https://stackoverflow.com/questions/5196527/double-condition-checking-in-assembly for info
|
|
sub r1, r29
|
|
sub r28, r29
|
|
cmp r28, r1
|
|
ifnc jmp menu_bar_click_event_found_item
|
|
inc r30 ; increment counter of menu item lengths calculated so far
|
|
add r29, r2 ; add the size in pixels of the current root menu item to the counter
|
|
add r29, 16 ; add 16 pixels to account for the space between the menu items
|
|
add r4, 8 ; increment pointer to text pointer
|
|
loop menu_bar_click_event_loop
|
|
; if we reach this point, then the user didn't click on any root menu items
|
|
; redraw the root menu items without anything selected
|
|
pop r0
|
|
;mov r1, 0xFFFFFFFF
|
|
;call draw_menu_bar_root_items ; close_submenu already calls this
|
|
call close_submenu
|
|
jmp menu_bar_click_event_end
|
|
menu_bar_click_event_found_item:
|
|
; r30 contains the clicked root menu item (starting at 0)
|
|
pop r0
|
|
mov r1, r30
|
|
mov r2, 0xFFFFFFFF
|
|
call draw_menu_bar_root_items
|
|
call draw_submenu_items
|
|
|
|
; push a submenu_update_event_type event to the event stack
|
|
mov r1, r0 ; event parameter 0: pointer to menu bar root struct
|
|
mov r2, r30 ; event parameter 1: selected root menu item
|
|
mov r3, 0xFFFFFFFF ; event parameter 2: hovering submenu item (or 0xFFFFFFFF for none)
|
|
mov r4, 0
|
|
mov r5, 0
|
|
mov r6, 0
|
|
mov r7, 0
|
|
mov r0, submenu_update_event_type
|
|
call new_event
|
|
menu_bar_click_event_end:
|
|
pop r31
|
|
pop r30
|
|
pop r29
|
|
pop r28
|
|
pop r7
|
|
pop r6
|
|
pop r5
|
|
pop r4
|
|
pop r3
|
|
pop r2
|
|
pop r1
|
|
pop r0
|
|
ret
|
|
|
|
;menu_items_root:
|
|
; data.8 3 ; number of submenus
|
|
; data.32 menu_items_file_list data.32 menu_items_file_name ; pointer to submenu list, pointer to submenu name
|
|
; data.32 menu_items_edit_list data.32 menu_items_edit_name ; pointer to submenu list, pointer to submenu name
|
|
; data.32 menu_items_system_list data.32 menu_items_system_name ; pointer to submenu list, pointer to submenu name
|
|
;menu_items_file_name:
|
|
; data.8 4 data.str "File" data.8 0x00 ; text length, text, null-terminator
|
|
;menu_items_file_list:
|
|
; data.8 2 ; number of items
|
|
; data.8 6 ; submenu width (in number of characters)
|
|
; data.8 6 data.str "Test 1" data.8 0x00 ; text length, text, null-terminator
|
|
; data.8 6 data.str "Test 2" data.8 0x00 ; text length, text, null-terminator
|
|
;menu_items_edit_name:
|
|
; data.8 4 data.str "Edit" data.8 0x00 ; text length, text, null-terminator
|
|
;menu_items_edit_list:
|
|
; data.8 2 ; number of items
|
|
; data.8 6 ; submenu width (in number of characters)
|
|
; data.8 6 data.str "Test 3" data.8 0x00 ; text length, text, null-terminator
|
|
; data.8 6 data.str "Test 4" data.8 0x00 ; text length, text, null-terminator
|
|
;menu_items_system_name:
|
|
; data.8 6 data.str "System" data.8 0x00 ; text length, text, null-terminator
|
|
;menu_items_system_list:
|
|
; data.8 4 ; number of items
|
|
; data.8 6 ; submenu width (in number of characters)
|
|
; data.8 6 data.str "Test 5" data.8 0x00 ; text length, text, null-terminator
|
|
; data.8 6 data.str "Test 6" data.8 0x00 ; text length, text, null-terminator
|
|
; data.8 6 data.str "Test 7" data.8 0x00 ; text length, text, null-terminator
|
|
; data.8 6 data.str "Test 8" data.8 0x00 ; text length, text, null-terminator |