Image Preview: Add Minipix/Print Shop clip art support. Fixes #24

This commit is contained in:
Joshua Bell 2019-02-25 20:16:45 -08:00
parent 07efa542fa
commit 088ee11777
4 changed files with 330 additions and 81 deletions

View File

@ -18,7 +18,7 @@ https://github.com/inexorabletash/a2d/issues
* Add Special > Check Drive command to refresh a single drive. (#97)
* Show Text File DA: Keyboard support. Escape quits, arrows scroll. (#4)
* Reorganized/renamed several menu items. (#13)
* New icons for graphics, AppleWorks, relocatable, command, IIgs-specific file types, and DAs. (#105)
* New file type icons: graphics, AppleWorks, relocatable, command, IIgs-specific, and DAs. (#105)
* Desktop icon shown for AppleTalk file shares. (#88)
* Improvements to several existing icon bitmaps. (#74)
* Desk accessory files with high bit in aux-type set are hidden in Apple menu. (#102)
@ -50,7 +50,8 @@ functionality (see below).
Text and Graphics files with the correct file types can be previewed
without leaving DeskTop; select the file icon then select File > Open,
or double-click the file icon. Text files must be type TXT ($04).
Graphics files must be type FOT ($08).
Graphics files must be type FOT ($08), or BIN ($06) with an aux type
of $2000 (hi-res/double hi-res) or $5800 (Minipix a.k.a. Print Shop).
To preview files of other types, you can copy the preview handlers
named `SHOW.TEXT.FILE` and `SHOW.IMAGE.FILE` from the `PREVIEW` folder

View File

@ -912,6 +912,9 @@ begin:
;; Check file type.
: lda get_file_info_params::file_type
ldxy get_file_info_params::aux_type
jsr check_file_type_overrides
cmp #FT_BASIC
bne :+
jsr check_basic_system ; Only launch if BASIC.SYSTEM is found
@ -6640,21 +6643,20 @@ L7767: .byte $14
cmp #FT_BAD ; T$01 is overloaded below for "apps", so
beq is_generic ; treat as generic
;; DA_FILE_TYPE also requires correct AUX type
cmp #DA_FILE_TYPE ; Apple Menu item?
bne :+
;; Handle several classes of overrides
pha ; Load auxtype into X,Y
ldy #FileRecord::aux_type
lda (file_entry),y ; Must have correct aux type, otherwise
cmp #<DA_AUX_TYPE ; treat as generic
bne is_generic
lda (file_entry),y ; lo
pha
iny
lda (file_entry),y
and #%01111111 ; ignore high bit (set = don't show in menu)
cmp #>DA_AUX_TYPE
bne is_generic
lda #DA_FILE_TYPE
lda (file_entry),y ; hi
tay ; hi
pla
tax ; lo
pla
jsr check_file_type_overrides
: cmp #FT_SYSTEM ; Other system?
cmp #FT_SYSTEM ; Other system?
bne got_type ; nope
;; Distinguish *.SYSTEM files as apps (use $01) from other
@ -6763,9 +6765,6 @@ L7870: lda cached_window_id
jsr icon_window_to_screen
add16 file_entry, #icon_y_spacing, file_entry
rts
.byte 0
.byte 0
.endproc
;;; ============================================================
@ -6817,6 +6816,60 @@ file_type:
create_file_icon_ep2 := create_file_icon::ep1::ep2
create_file_icon_ep1 := create_file_icon::ep1
;;; ============================================================
;;; Check file type for possible overrides
;;; TODO: Make this data driven
;;; Input: A is filetype, X,Y is auxtype
;;; Output: A is filetype to use
.proc check_file_type_overrides
stxy auxtype
;; Binary - treat certain auxtypes as Graphics
cmp #FT_BINARY
bne :+
ldxy #$5800 ; minipix
jsr check_aux
beq is_graphics
ldxy #$2000 ; hires
jsr check_aux
beq is_graphics
;; DA - treat as generic *unless* auxtypes are correct
: cmp #DA_FILE_TYPE
bne :+
ldxy #DA_AUX_TYPE
jsr check_aux
beq :+
ldxy #DA_AUX_TYPE | $8000
jsr check_aux
bne is_generic
: rts
is_generic:
lda #FT_TYPELESS
rts
is_graphics:
lda #FT_GRAPHICS
rts
auxtype:
.word 0
.proc check_aux
cpx auxtype
bne :+
cpy auxtype+1
: rts
.endproc
.endproc
;;; ============================================================
;;; Draw header (items/k in disk/k available/lines)

View File

@ -2,17 +2,24 @@
▲ = Solid Apple
# Undiscoverable Features
* When dragging a selection of files to a destination on the same volume, the files will be moved by default. Hold down **△** before letting go of the mouse button to force a copy instead. Files dragged to a different volume will always be copied.
* Hold down **△** when launching `DESKTOP.SYSTEM` to prevent DeskTop from being copied to a RAM card.
* Desk Accessory files with high bit set in the aux type field will not appear in the Apple menu.
* Desk Accessory files with high bit set in the aux type field ($8640) will not appear in the Apple menu.
* You can't run a Binary file by double-clicking, but you can run it with the **△O** shortcut or holding down **△** or **▲** while selecting **File > Open**.
* The Sort Directory desk accessory has two modes:
* If any files are selected, these are moved to the start of the directory listing, in selection order; other files appear after, order unchanged.
* If no files are selected, all files are sorted by type: DIR, then TXT, then SYS, then others in descending numeric order.
# File Types
* Binary files (type $06) with aux type $2000 are treated as Graphics files (HR/DHR)
* Binary files (type $06) with aux type $5800 are treated as Graphics files (Minipix/Print Shop)
* Desk Accessory files have type $F1, and auxtype $640 or $8640
# Secrets and Mysteries
* The Calculator desk accessory has a tiny monogram resembling "JB" drawn in the title bar - possibly "J. Bernard" thanked in the credits?

View File

@ -7,44 +7,95 @@
.include "../desktop.inc"
.include "../macros.inc"
;;; ============================================================
;;; Memory map
;;;
;;; Main Aux
;;; : : : :
;;; | | | |
;;; | DHR | | DHR |
;;; $2000 +-----------+ +-----------+
;;; | IO Buffer | |Win Tables |
;;; $1C00 +-----------+ | |
;;; $1B00 | | +-----------+
;;; | | | |
;;; | | | |
;;; | MP Dst | | MP Dst |
;;; $1580 +-----------+ +-----------+
;;; | | | |
;;; | MP Src | | Menu Save |
;;; $1100 +-----------+ +-----------+
;;; | | | |
;;; | DA | | DA (Copy) |
;;; $800 +-----------+ +-----------+
;;; : : : :
;;;
hires := $2000 ; HR/DHR images are loaded directly into screen buffer
hires_size = $2000
;; Menu bits saved/restored
menu_rows = 13
menu_cols = 40
menu_save_area := $1100 ; Past DA code (need $410 bytes)
menu_save_size = menu_cols * 2 * menu_rows ; 5 pages
;; Minipix/Print Shop images are loaded/converted
minipix_src_buf = $1200 ; Load address
minipix_src_size = 576
minipix_dst_buf = $1580 ; Convert address
minipix_dst_size = 26*52
.assert (minipix_src_buf + minipix_src_size) < minipix_dst_buf, error, "Not enough room for Minipix load buffer"
.assert (menu_save_area + menu_save_size) < minipix_dst_buf, error, "Not enough room for menu save area"
.assert (minipix_dst_buf + minipix_dst_size) < WINDOW_ICON_TABLES, error, "Not enough room for Minipix convert buffer"
;;; ============================================================
.org $800
start: jmp copy2aux
da_start:
jmp start
save_stack:.byte 0
;;; Copy $800 through $13FF (the DA) to aux
.proc copy2aux
.proc start
tsx
stx save_stack
;; Copy DA to AUX
copy16 #da_start, STARTLO
copy16 #da_start, DESTINATIONLO
copy16 #da_end, ENDLO
sec ; main>aux
jsr AUXMOVE
;; Transfer control to aux
sta RAMWRTON
ldy #0
src: lda start,y ; self-modified
dst: sta start,y ; self-modified
dey
bne src
sta RAMRDON
;; Copy "call_main_template" routine to zero page
COPY_BYTES sizeof_routine+1, routine, call_main_trampoline
;; run the DA
jsr init
;; tear down/exit
sta ALTZPON
lda LCBANK1
lda LCBANK1
sta RAMRDOFF
sta RAMWRTOFF
inc src+2
inc dst+2
sta RAMWRTON
lda dst+2
cmp #$14
bne src
ldx save_stack
txs
rts
.endproc
call_main_trampoline := $20 ; installed on ZP, turns off auxmem and calls...
call_main_addr := call_main_trampoline+7 ; address patched in here
;;; Copy the following "call_main_template" routine to $20
.scope
sta RAMWRTON
sta RAMRDON
COPY_BYTES sizeof_routine+1, routine, call_main_trampoline
jmp call_init
.endscope
.proc routine
sta RAMRDOFF
sta RAMWRTOFF
@ -56,21 +107,6 @@ call_main_addr := call_main_trampoline+7 ; address patched in here
sizeof_routine = * - routine ; can't .sizeof(proc) before declaration
;; https://github.com/cc65/cc
.proc call_init
;; run the DA
jsr init
;; tear down/exit
sta ALTZPON
lda LCBANK1
lda LCBANK1
sta RAMRDOFF
sta RAMWRTOFF
ldx save_stack
txs
rts
.endproc
;;; ============================================================
;;; ProDOS MLI calls
@ -101,6 +137,15 @@ call_main_addr := call_main_trampoline+7 ; address patched in here
rts
.endproc
.proc read_minipix_file
jsr copy_params_aux_to_main
sta ALTZPOFF
MLI_CALL READ, read_minipix_params
sta ALTZPON
jsr copy_params_main_to_aux
rts
.endproc
.proc close_file
jsr copy_params_aux_to_main
sta ALTZPOFF
@ -140,19 +185,17 @@ loop: lda params_start - 1,y
rts
.endproc
;;; ----------------------------------------
params_start:
;;; This block gets copied between main/aux
;;; ProDOS MLI param blocks
hires := $2000
hires_size = $2000
DEFINE_OPEN_PARAMS open_params, pathbuff, $C00
DEFINE_OPEN_PARAMS open_params, pathbuff, DA_IO_BUFFER
DEFINE_GET_EOF_PARAMS get_eof_params
DEFINE_READ_PARAMS read_params, hires, hires_size
DEFINE_READ_PARAMS read_minipix_params, minipix_src_buf, minipix_src_size
DEFINE_CLOSE_PARAMS close_params
.proc pathbuff ; 1st byte is length, rest is full path
@ -224,7 +267,7 @@ colormasks: .byte MGTK::colormask_and, MGTK::colormask_or
penloc: DEFINE_POINT 0, 0
penwidth: .byte 1
penheight: .byte 1
penmode: .byte 0
penmode: .byte MGTK::notpencopy
textback: .byte $7F
textfont: .addr DEFAULT_FONT
nextwinfo: .addr 0
@ -329,6 +372,7 @@ end: rts
lda open_params::ref_num
sta get_eof_params::ref_num
sta read_params::ref_num
sta read_minipix_params::ref_num
sta close_params::ref_num
MGTK_CALL MGTK::HideCursor
@ -390,15 +434,21 @@ exit:
sbc #>(hires_size+1)
lda get_eof_params::eof+2
sbc #^(hires_size+1)
bcs dhr
bcc :+
jmp show_dhr_file
jsr show_hr_file
jmp close
;; If bigger than 576, assume HR
dhr: jsr show_dhr_file
: lda get_eof_params::eof
cmp #<(minipix_src_size+1)
lda get_eof_params::eof+1
sbc #>(minipix_src_size+1)
bcc :+
jmp show_hr_file
close: jsr close_file
rts
;; Otherwise, assume Minipix
: jmp show_minipix_file
.endproc
.proc show_hr_file
@ -452,6 +502,48 @@ close: jsr close_file
rts
.endproc
.proc show_minipix_file
jsr set_bw_mode
;; Load file at minipix_src_buf (MAIN $1800)
jsr read_minipix_file
jsr close_file
;; Convert (in main)
sta RAMWRTOFF
sta RAMRDOFF
jsr convert_minipix_to_bitmap
sta RAMWRTON
sta RAMRDON
;; Copy main>aux
copy16 #minipix_dst_buf, STARTLO
copy16 #minipix_dst_buf, DESTINATIONLO
copy16 #(minipix_dst_buf+minipix_dst_size), ENDLO
sec ; main>aux
jsr AUXMOVE
;; Draw
MGTK_CALL MGTK::PaintBits, paintbits_params
rts
minipix_width = 88 * 2
minipix_height = 52
.proc paintbits_params
viewloc: DEFINE_POINT (screen_width - minipix_width)/2, (screen_height - minipix_height)/2
mapbits: .addr minipix_dst_buf
mapwidth: .byte 26
reserved: .byte 0
maprect: DEFINE_RECT 0,0,minipix_width-1,minipix_height-1
.endproc
.endproc
;;; ============================================================
;;; Convert single hires to double hires
@ -527,14 +619,10 @@ done: sta PAGE2OFF
;;; screen to a scratch buffer and restore after
;;; destroying the window.
stash := $1200 ; Past DA code
rows = 13
cols = 40
.proc stash_menu
src := $08
dst := $06
copy16 #stash, dst
copy16 #menu_save_area, dst
sta PAGE2ON
jsr inner
@ -547,17 +635,17 @@ rloop: pha
tax
copy hires_table_lo,x, src
copy hires_table_hi,x, src+1
ldy #cols-1
ldy #menu_cols-1
cloop: lda (src),y
sta (dst),y
dey
bpl cloop
add16 dst, #cols, dst
add16 dst, #menu_cols, dst
pla
inc
cmp #rows
cmp #menu_rows
bcc rloop
rts
.endproc
@ -565,7 +653,7 @@ cloop: lda (src),y
.proc unstash_menu
src := $08
dst := $06
copy16 #stash, src
copy16 #menu_save_area, src
sta PAGE2ON
jsr inner
@ -578,21 +666,113 @@ rloop: pha
tax
copy hires_table_lo,x, dst
copy hires_table_hi,x, dst+1
ldy #cols-1
ldy #menu_cols-1
cloop: lda (src),y
sta (dst),y
dey
bpl cloop
add16 src, #cols, src
add16 src, #menu_cols, src
pla
inc
cmp #rows
cmp #menu_rows
bcc rloop
rts
.endproc
;;; ============================================================
;;; Minipix images
.proc convert_minipix_to_bitmap
rows = 52
cols = 88 ; pixels
src := $06
dst := $08
copy16 #minipix_src_buf, src
copy16 #minipix_dst_buf, dst
;; c/o Kent Dickey on comp.sys.apple2.programmer
;; https://groups.google.com/d/msg/comp.sys.apple2.programmer/XB0jUEvrAhE/loRorS5fBwAJ
ldx #rows
stx row
ldy #0 ; Y remains unchanged throughout
;; For each row...
dorow: ldx #8
stx srcbit
ldx #7
stx dstbit
ldx #cols
;; Process each bit
: jsr getbit
jsr putbit2
dex
bne :-
;; We've written out 88*2 bits = 176 bits. This means 1 bit was shifted into
;; the last bit. We need to get it from the MSB to the LSB, so it needs
;; to be shifted down 7 bits
: clc
jsr putbit1
dex
cpx #AS_BYTE(-7) ; do 7 times == 7 bits
bne :-
dec row
bne dorow
rts
.proc getbit
lda (src),y
rol
sta (src),y
dec srcbit
bne done
inc src
bne :+
inc src+1
: lda #8
sta srcbit
done: rts
.endproc
.proc putbit2
php
jsr putbit1
plp
;; fall through
.endproc
.proc putbit1
lda (dst),y
ror
sta (dst),y
dec dstbit
bne done
ror ; shift once more to get bits in right place
sta (dst),y
inc dst
bne :+
inc dst+1
: lda #7
sta dstbit
done: rts
.endproc
srcbit: .byte 0
dstbit: .byte 0
row: .byte 0
.endproc
;;; ============================================================
;;; Color/B&W Toggle
@ -626,5 +806,13 @@ done: rts
done: rts
.endproc
;;; ============================================================
.include "inc/hires_table.inc"
.include "inc/hr_to_dhr.inc"
;;; ============================================================
da_end:
.assert * <= menu_save_area, error, "DA overlapping menu save area"