Better handlng of recycled icons, dedupe code.

This commit is contained in:
Joshua Bell 2019-03-30 20:08:21 -07:00
parent 1abe9dec39
commit 9b2b361e90
2 changed files with 159 additions and 206 deletions

View File

@ -584,7 +584,10 @@ start: jsr clear_selection
;; window and desktop can have selections.) ;; window and desktop can have selections.)
ldx findwindow_window_id ldx findwindow_window_id
dex dex
copy window_to_dir_icon_table,x, icon_param lda window_to_dir_icon_table,x
bmi continue ; $FF = dir icon freed
sta icon_param
lda icon_param lda icon_param
jsr icon_entry_lookup jsr icon_entry_lookup
stax ptr stax ptr
@ -1883,80 +1886,13 @@ dir_count:
;;; ============================================================ ;;; ============================================================
.proc cmd_close .proc cmd_close
icon_ptr := $06
lda active_window_id lda active_window_id
bne L4E78 bne :+
rts rts
L4E78: jsr clear_selection : jmp close_window
dec num_open_windows
jsr LoadActiveWindowIconTable
ldx active_window_id
dex
lda win_view_by_table,x
bmi iter ; list view, not icons
;; View by icon
DESKTOP_RELAY_CALL DT_CLOSE_WINDOW, active_window_id
lda icon_count
sec
sbc cached_window_icon_count
sta icon_count
ldx #0
: cpx cached_window_icon_count
beq iter
lda cached_window_icon_list,x
jsr FreeIcon
inx
jmp :-
iter: ldx #$00
txa
: sta cached_window_icon_list,x
cpx cached_window_icon_count
beq L4EC3
inx
jmp :-
L4EC3: sta cached_window_icon_count
jsr StoreWindowIconTable
jsr LoadDesktopIconTable
MGTK_RELAY_CALL MGTK::CloseWindow, active_window_id
ldx active_window_id
dex
lda window_to_dir_icon_table,x
sta icon_param
jsr icon_entry_lookup
stax $06
ldy #IconEntry::win_type
lda ($06),y
and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag
sta ($06),y
and #icon_entry_winid_mask
sta selected_window_index
jsr zero_grafport5_coords
DESKTOP_RELAY_CALL DT_HIGHLIGHT_ICON, icon_param
jsr reset_grafport3
copy #1, selected_icon_count
copy icon_param, selected_icon_list
ldx active_window_id
dex
lda window_to_dir_icon_table,x
jsr L7345
ldx active_window_id
dex
copy #0, window_to_dir_icon_table,x
MGTK_RELAY_CALL MGTK::FrontWindow, active_window_id
lda active_window_id
bne L4F3C
DESKTOP_RELAY_CALL DT_REDRAW_ICONS
L4F3C: lda #MGTK::checkitem_uncheck
sta checkitem_params::check
MGTK_RELAY_CALL MGTK::CheckItem, checkitem_params
jsr update_window_menu_items
jmp reset_grafport3
.endproc .endproc
;;; ============================================================ ;;; ============================================================
@ -1964,7 +1900,7 @@ L4F3C: lda #MGTK::checkitem_uncheck
.proc cmd_close_all .proc cmd_close_all
lda active_window_id ; current window lda active_window_id ; current window
beq done ; nope, done! beq done ; nope, done!
jsr cmd_close ; close it... jsr close_window ; close it...
jmp cmd_close_all ; and try again jmp cmd_close_all ; and try again
done: rts done: rts
.endproc .endproc
@ -2469,14 +2405,8 @@ L5265: .byte 0
sec sec
sbc cached_window_icon_count sbc cached_window_icon_count
sta icon_count sta icon_count
ldx #0
loop: cpx cached_window_icon_count jsr free_cached_window_icons
beq done
lda cached_window_icon_list,x
jsr FreeIcon
copy #0, cached_window_icon_list,x
inx
jmp loop
done: jsr StoreWindowIconTable done: jsr StoreWindowIconTable
jmp LoadDesktopIconTable jmp LoadDesktopIconTable
@ -2484,6 +2414,35 @@ done: jsr StoreWindowIconTable
;;; ============================================================ ;;; ============================================================
.proc free_cached_window_icons
copy #0, index
loop: ldx index
cpx cached_window_icon_count
beq done
lda cached_window_icon_list,x
pha
jsr FreeIcon
pla
jsr find_window_for_dir_icon
bne :+
copy #$FF, window_to_dir_icon_table,x ; $FF = dir icon freed
: ldx index
copy #0, cached_window_icon_list,x
inc index
bne loop
done: rts
index: .byte 0
.endproc
;;; ============================================================
;;; Set after format, erase, failed open, etc. ;;; Set after format, erase, failed open, etc.
;;; Used by 'cmd_check_single_drive_by_XXX'; may be unit number ;;; Used by 'cmd_check_single_drive_by_XXX'; may be unit number
;;; or device index depending on call site. ;;; or device index depending on call site.
@ -2599,8 +2558,10 @@ next_icon:
not_done: not_done:
tax tax
lda selected_icon_list,x lda selected_icon_list,x
jsr L5431 jsr find_window_for_dir_icon
bmi next_icon bne next_icon ; not found
inx ; 0-based index to 1-based window_id
txa
jsr window_path_lookup jsr window_path_lookup
stax $06 stax $06
ldy #0 ldy #0
@ -2644,16 +2605,6 @@ selected_vol_icon_count:
selected_vol_icon_list: selected_vol_icon_list:
.res 9, 0 .res 9, 0
L5431: ldx #7
L5433: cmp window_to_dir_icon_table,x
beq L543E
dex
bpl L5433
return #$FF
L543E: inx
txa
rts
.endproc .endproc
;;; ============================================================ ;;; ============================================================
@ -2967,7 +2918,7 @@ L5708: sta $800
ldy #$01 ldy #$01
ldx #0 ldx #0
L570F: lda window_to_dir_icon_table,x L570F: lda window_to_dir_icon_table,x
beq L5720 beq L5720 ; 0 = window free
inx inx
cpx active_window_id cpx active_window_id
beq L5721 beq L5721
@ -3064,7 +3015,7 @@ loop: cpx #8
bne :+ bne :+
ldx #0 ldx #0
: lda window_to_dir_icon_table,x : lda window_to_dir_icon_table,x
bne found bne found ; 0 = window free
inx inx
bne loop ; always bne loop ; always
@ -3293,6 +3244,7 @@ L5916: lda cached_window_icon_list,x
beq L5942 beq L5942
txa txa
pha pha
lda cached_window_icon_list,x lda cached_window_icon_list,x
sta icon_param sta icon_param
copy #0, cached_window_icon_list,x copy #0, cached_window_icon_list,x
@ -3301,6 +3253,7 @@ L5916: lda cached_window_icon_list,x
jsr FreeIcon jsr FreeIcon
dec cached_window_icon_count dec cached_window_icon_count
dec icon_count dec icon_count
pla pla
tax tax
L5942: dex L5942: dex
@ -3486,6 +3439,7 @@ not_in_map:
lda devlst_index lda devlst_index
tay tay
pha pha
lda device_to_icon_map,y lda device_to_icon_map,y
sta icon_param sta icon_param
beq :+ beq :+
@ -3501,6 +3455,7 @@ not_in_map:
sta previous_icon_count sta previous_icon_count
inc cached_window_icon_count inc cached_window_icon_count
inc icon_count inc icon_count
pla pla
tay tay
lda DEVLST,y lda DEVLST,y
@ -4026,6 +3981,7 @@ L5E77: .byte 0
ldx active_window_id ldx active_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
;; BUG: What if dir icon is freed? ($FF)
pha pha
jsr L7345 jsr L7345
lda window_id lda window_id
@ -4294,50 +4250,52 @@ handle_close_click:
jsr LoadActiveWindowIconTable jsr LoadActiveWindowIconTable
jsr clear_selection jsr clear_selection
ldx active_window_id ldx active_window_id
dex dex
lda win_view_by_table,x lda win_view_by_table,x
bmi iter ; list view, not icons bmi iter ; list view, not icons
lda icon_count lda icon_count
sec sec
sbc cached_window_icon_count sbc cached_window_icon_count
sta icon_count sta icon_count
DESKTOP_RELAY_CALL DT_CLOSE_WINDOW, active_window_id DESKTOP_RELAY_CALL DT_CLOSE_WINDOW, active_window_id
ldx #$00
L6206: cpx cached_window_icon_count jsr free_cached_window_icons
beq iter
lda cached_window_icon_list,x
jsr FreeIcon
inx
jmp L6206
iter: dec num_open_windows iter: dec num_open_windows
ldx #$00 ldx #0
txa txa
L621B: sta cached_window_icon_list,x : sta cached_window_icon_list,x
cpx cached_window_icon_count cpx cached_window_icon_count
beq L6227 beq cont
inx inx
jmp L621B jmp :-
L6227: sta cached_window_icon_count cont: sta cached_window_icon_count
jsr StoreWindowIconTable jsr StoreWindowIconTable
MGTK_RELAY_CALL MGTK::CloseWindow, active_window_id MGTK_RELAY_CALL MGTK::CloseWindow, active_window_id
;; Unhilight dir (vol/folder) icon, if present
ldx active_window_id ldx active_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
bmi no_icon ; $FF = dir icon freed
sta icon_param sta icon_param
jsr icon_entry_lookup jsr icon_entry_lookup
stax $06 stax icon_ptr
ldy #1
lda ($06),y ldy #IconEntry::state
and #$0F lda (icon_ptr),y
beq L6276 and #icon_entry_winid_mask
beq no_icon ; ???
ldy #IconEntry::win_type ldy #IconEntry::win_type
lda ($06),y lda (icon_ptr),y
and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag
sta ($06),y sta (icon_ptr),y
and #icon_entry_winid_mask and #icon_entry_winid_mask
sta selected_window_index sta selected_window_index
jsr zero_grafport5_coords jsr zero_grafport5_coords
@ -4345,20 +4303,26 @@ L6227: sta cached_window_icon_count
jsr reset_grafport3 jsr reset_grafport3
copy #1, selected_icon_count copy #1, selected_icon_count
copy icon_param, selected_icon_list copy icon_param, selected_icon_list
L6276: ldx active_window_id
ldx active_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
jsr L7345 jsr L7345
;; Animate closing into dir (vol/folder) icon
ldx active_window_id ldx active_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
inx inx
jsr animate_window_close jsr animate_window_close
no_icon:
ldx active_window_id ldx active_window_id
dex dex
lda #$00 lda #0
sta window_to_dir_icon_table,x sta window_to_dir_icon_table,x ; 0 = window free
sta win_view_by_table,x sta win_view_by_table,x
MGTK_RELAY_CALL MGTK::FrontWindow, active_window_id MGTK_RELAY_CALL MGTK::FrontWindow, active_window_id
jsr LoadDesktopIconTable jsr LoadDesktopIconTable
lda #MGTK::checkitem_uncheck lda #MGTK::checkitem_uncheck
@ -5059,11 +5023,10 @@ L6A3E: .byte 0
ptr := $6 ptr := $6
path_buf := $220 path_buf := $220
ldx #7 jsr find_window_for_dir_icon
: cmp window_to_dir_icon_table,x beq L6A80 ; found
beq L6A80
dex ;; Not in the map. Look for related windows.
bpl :-
jsr icon_entry_lookup jsr icon_entry_lookup
addax #IconEntry::len, ptr addax #IconEntry::len, ptr
ldy #0 ldy #0
@ -5085,6 +5048,7 @@ L6A5C: lda (ptr),y
ldy path_buf ldy path_buf
jmp update_vol_used_free_for_found_windows jmp update_vol_used_free_for_found_windows
;; Found it in the map.
L6A80: inx L6A80: inx
txa txa
pha pha
@ -5124,35 +5088,9 @@ found_win:
: stx cached_window_id : stx cached_window_id
jsr LoadWindowIconTable jsr LoadWindowIconTable
jsr update_icon
lda icon_params2 lda icon_params2
jsr icon_entry_lookup
stax ptr
ldy #IconEntry::win_type
lda (ptr),y
ora #icon_entry_open_mask ; set open_flag
sta (ptr),y
ldy #IconEntry::win_type ; get window id
lda (ptr),y
and #icon_entry_winid_mask
sta getwinport_params2::window_id
beq :+ ; window 0 = desktop
cmp active_window_id ; prep to redraw windowed (file) icon
bne skip ; but only if active window
jsr get_set_port2
lda icon_params2
jsr icon_screen_to_window
: DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_params2
lda getwinport_params2::window_id
beq skip ; skip if on desktop
lda icon_params2 ; restore from drawing
jsr icon_window_to_screen
jsr reset_grafport3
skip: lda icon_params2
ldx LE1F1 ldx LE1F1
dex dex
: cmp LE1F1+1,x : cmp LE1F1+1,x
@ -5187,7 +5125,7 @@ no_win:
;; Search window-icon map to find an unused window. ;; Search window-icon map to find an unused window.
: ldx #0 : ldx #0
: lda window_to_dir_icon_table,x : lda window_to_dir_icon_table,x
beq :+ beq :+ ; 0 = window free
inx inx
jmp :- jmp :-
@ -5220,37 +5158,10 @@ update_view:
sta checkitem_params::check sta checkitem_params::check
jsr check_item jsr check_item
;; Update icon jsr update_icon
lda icon_params2
jsr icon_entry_lookup
stax ptr
ldy #IconEntry::win_type ;; Set path, size, contents, and volume free/used.
lda (ptr),y jsr prepare_new_window
ora #icon_entry_open_mask ; set open_flag
sta (ptr),y
ldy #IconEntry::win_type ; get window id
lda (ptr),y
and #icon_entry_winid_mask
sta getwinport_params2::window_id
beq :+ ; 0 = desktop
cmp active_window_id ; prep to redraw windowed (file) icon
bne skip2 ; but only if active window
jsr get_set_port2
jsr offset_grafport2_and_set
lda icon_params2
jsr icon_screen_to_window
: DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_params2
lda getwinport_params2::window_id
beq skip2 ; skip if on desktop
lda icon_params2 ; restore from drawing
jsr icon_window_to_screen
jsr reset_grafport3
skip2: jsr prepare_new_window
;; Create the window ;; Create the window
lda cached_window_id lda cached_window_id
@ -5285,6 +5196,40 @@ done: copy cached_window_id, active_window_id
jsr LoadDesktopIconTable jsr LoadDesktopIconTable
jmp reset_grafport3 jmp reset_grafport3
;;; Common code to update the dir (vol/folder) icon.
.proc update_icon
lda icon_params2
jsr icon_entry_lookup
stax ptr
ldy #IconEntry::win_type
lda (ptr),y
ora #icon_entry_open_mask ; set open_flag
sta (ptr),y
ldy #IconEntry::win_type ; get window id
lda (ptr),y
and #icon_entry_winid_mask
sta getwinport_params2::window_id
beq :+ ; window 0 = desktop
cmp active_window_id ; prep to redraw windowed (file) icon
bne done ; but only if active window
jsr get_set_port2
jsr offset_grafport2_and_set
lda icon_params2
jsr icon_screen_to_window
: DESKTOP_RELAY_CALL DT_REDRAW_ICON, icon_params2
lda getwinport_params2::window_id
beq done ; skip if on desktop
lda icon_params2 ; restore from drawing
jsr icon_window_to_screen
jsr reset_grafport3
done: rts
.endproc
num: .byte 0 num: .byte 0
.endproc .endproc
@ -5322,7 +5267,8 @@ L6C25: jsr push_pointers
: ldx cached_window_id : ldx cached_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
ldx #$00 ;; BUG: What if dir icon is freed? ($FF)
ldx #0
L6C53: cmp LE1F1+1,x L6C53: cmp LE1F1+1,x
beq L6C5F beq L6C5F
inx inx
@ -6134,6 +6080,7 @@ get_vol_free_used:
get_vol_free_used := open_directory::get_vol_free_used get_vol_free_used := open_directory::get_vol_free_used
;;; ============================================================ ;;; ============================================================
;;; ???
.proc L7345 .proc L7345
sta L7445 sta L7445
@ -6254,14 +6201,7 @@ L7449: .word 0
sta (title_ptr),y sta (title_ptr),y
iny iny
dex dex
bne :- bpl :-
lda #' '
sta (title_ptr),y
ldy #IconEntry::win_type
lda (title_ptr),y
and #%11011111 ; upcase first letter
sta (title_ptr),y
jsr pop_pointers jsr pop_pointers
@ -6289,7 +6229,7 @@ L7449: .word 0
bcc :+ bcc :+
inc icon_ptr+1 inc icon_ptr+1
: ldy #0 : ldy #0
lda ($06),y lda (icon_ptr),y
tay ; Y = length tay ; Y = length
;; Copy, including leading/trailing spaces ;; Copy, including leading/trailing spaces
@ -6328,7 +6268,6 @@ L7449: .word 0
has_parent: has_parent:
tay tay
copy #$00, L7620 ; ???
jsr push_pointers jsr push_pointers
tya tya
pha pha
@ -6364,7 +6303,6 @@ has_parent:
;; Suffix with '/' ;; Suffix with '/'
lda #'/' lda #'/'
sta open_dir_path_buf+1
inc open_dir_path_buf inc open_dir_path_buf
ldx open_dir_path_buf ldx open_dir_path_buf
sta open_dir_path_buf,x sta open_dir_path_buf,x
@ -6455,7 +6393,7 @@ common:
lda (winfo_ptr),y lda (winfo_ptr),y
and #AS_BYTE(~MGTK::Scroll::option_active) and #AS_BYTE(~MGTK::Scroll::option_active)
sta (winfo_ptr),y sta (winfo_ptr),y
iny iny ; vscroll
lda (winfo_ptr),y lda (winfo_ptr),y
and #AS_BYTE(~MGTK::Scroll::option_active) and #AS_BYTE(~MGTK::Scroll::option_active)
sta (winfo_ptr),y sta (winfo_ptr),y
@ -6470,11 +6408,11 @@ common:
;; -------------------------------------------------- ;; --------------------------------------------------
lda icon_params2 lda icon_params2
jsr open_directory jsr open_directory
lda icon_params2 lda icon_params2
jsr icon_entry_lookup jsr icon_entry_lookup
stax icon_ptr stax icon_ptr
ldy #IconEntry::win_type ldy #IconEntry::win_type
lda (icon_ptr),y lda (icon_ptr),y
@ -6499,7 +6437,6 @@ common:
jsr create_file_icon_ep1 jsr create_file_icon_ep1
rts rts
L7620: .byte $00
.endproc .endproc
;;; ============================================================ ;;; ============================================================
@ -6544,6 +6481,7 @@ ep2: pha ; entry point #2 ???
ldx cached_window_id ldx cached_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
;; TODO: Guaranteed to exist?
sta icon_params2 sta icon_params2
lda #$80 lda #$80
@ -7453,6 +7391,7 @@ index := $805
start: ldx cached_window_id start: ldx cached_window_id
dex dex
lda window_to_dir_icon_table,x lda window_to_dir_icon_table,x
;; BUG: What if dir icon is freed? ($FF)
ldx #0 ldx #0
: cmp LE1F1+1,x : cmp LE1F1+1,x
@ -9206,6 +9145,20 @@ remove: lda cached_window_icon_list+1,x
rts rts
.endproc .endproc
;;; ============================================================
;;; Search the window->dir_icon mapping table.
;;; Inputs: A = icon number
;;; Outputs: Z=1 && N=0 if found, X = index (0-7), A unchanged
.proc find_window_for_dir_icon
ldx #7
: cmp window_to_dir_icon_table,x
beq done
dex
bpl :-
done: rts
.endproc
;;; ============================================================ ;;; ============================================================
.proc mark_icons_not_opened .proc mark_icons_not_opened
@ -9224,16 +9177,12 @@ L8B1F: lda icon_params2
;; Find open window for the icon ;; Find open window for the icon
start: lda icon_params2 start: lda icon_params2
ldx #8 - 1 jsr find_window_for_dir_icon
: cmp window_to_dir_icon_table,x bne skip ; not found
beq :+
dex
bpl :-
jmp skip
;; If found, remove from the table ;; If found, remove from the table
: lda #0 ;; TODO: should this be $FF instead?
sta window_to_dir_icon_table,x copy #0, window_to_dir_icon_table,x
;; Update the icon and redraw ;; Update the icon and redraw
skip: lda icon_params2 skip: lda icon_params2
@ -9242,7 +9191,7 @@ skip: lda icon_params2
ldy #IconEntry::win_type ldy #IconEntry::win_type
lda (ptr),y lda (ptr),y
and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag and #AS_BYTE(~icon_entry_open_mask) ; clear open_flag
sta ($06),y sta (ptr),y
jsr redraw_selected_icons jsr redraw_selected_icons
jsr pop_pointers jsr pop_pointers
rts rts

View File

@ -987,6 +987,7 @@ device_to_icon_map:
;;; Path buffer for open_directory logic ;;; Path buffer for open_directory logic
open_dir_path_buf: open_dir_path_buf:
.res 65, 0 .res 65, 0
LE1F1: .res 15, 0 ; length-prefixed string LE1F1: .res 15, 0 ; length-prefixed string
LE200: .word 0 LE200: .word 0
LE202: .res 24, 0 ; addr table LE202: .res 24, 0 ; addr table
@ -1365,6 +1366,9 @@ window_icon_list_table:
active_window_id: active_window_id:
.byte $00 .byte $00
;;; $00 = window not in use
;;; $FF = window in use, but dir (vol/folder) icon deleted
;;; Otherwise, dir (vol/folder) icon associated with window.
window_to_dir_icon_table: window_to_dir_icon_table:
.res 8, 0 .res 8, 0