Subversion Repositories NedoOS

Rev

Rev 1637 | Rev 1712 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1.         DEVICE ZXSPECTRUM128
  2.         include "../_sdk/sys_h.asm"
  3.  
  4. NUM_PLAYERS = 4
  5. SFN_SIZE = 13
  6. FILE_DATA_SIZE = 52 ;keep in sync with getfiledataoffset
  7. FILE_DISPLAY_INFO_OFFSET = 0
  8. FILE_DISPLAY_INFO_SIZE = 38
  9. FILE_NAME_OFFSET = FILE_DISPLAY_INFO_OFFSET+FILE_DISPLAY_INFO_SIZE
  10. FILE_NAME_SIZE = SFN_SIZE
  11. FILE_ATTRIB_OFFSET = FILE_NAME_OFFSET+FILE_NAME_SIZE
  12. FILE_ATTRIB_SIZE = 1
  13. PANEL_FILE_COUNT = 80
  14. PANELCOLOR = 0x4f
  15. CURSORCOLOR = 0x28
  16. PANELFILECOLOR = 0x0f
  17. PANELDIRCOLOR = 0x4f
  18. FILE_LINE_COUNT = 22
  19. FILES_WINDOW_X = 0
  20. FILE_ATTRIB_MUSIC = 255
  21. FILE_ATTRIB_PARENT_DIR = 0
  22. FILE_ATTRIB_FOLDER = 1
  23. PANELVERSION = 1
  24.  
  25.         org PROGSTART
  26.  
  27. mainbegin
  28.         ld sp,0x4000
  29.         OS_HIDEFROMPARENT
  30.         ld e,6 ;textmode
  31.         OS_SETGFX
  32.         ld e,7
  33.         OS_CLS
  34.  
  35.         ld de,currentfolder
  36.         OS_GETPATH
  37.         ld hl,(currentfolder+2)
  38.         ld a,l
  39.         xor '/'
  40.         or h
  41.         jr nz,$+5
  42.         ld (currentfolder+2),a
  43.  
  44.         OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
  45.         ld (sharedpages),hl
  46.         ld a,e
  47.         ld (sharedpages+2),a
  48.  
  49.         OS_SETSYSDRV
  50.         call loadplayers
  51.         ld hl,playersloaderrorstr
  52.         jp nz,printerrorandexit
  53.  
  54.         call initplaylist
  55.         or 1
  56.         call setcurrentpanel
  57.  
  58.         ld hl,COMMANDLINE
  59.         call skipword_hl
  60.         call skipspaces_hl
  61.         ld a,(hl)
  62.         or a
  63.         call nz,setcurrentfolder
  64.         push hl
  65.         call changetocurrentfolder
  66.         pop de
  67.         ld hl,chdirfailedstr
  68.         jp nz,printerrorandexit
  69.         push de
  70.         call createfileslist
  71.         pop de
  72.         ld a,(de)
  73.         or a
  74.         call nz,findfile
  75.         ld (browserpanel.currentfileindex),a
  76.         push af
  77.         call drawui
  78.         pop af
  79.         call c,startplaying
  80.  
  81. playloop
  82. isplaying=$+1
  83.         ld a,0
  84.         or a
  85.         jr z,checkmsgs
  86.         call musicplay
  87.         call z,playnextfile
  88.  
  89. checkmsgs
  90.         OS_GETKEY
  91.         ld hl,playloop
  92.         push hl
  93. currentmsgtable=$+1
  94.         ld hl,mainmsgtable
  95.         ld de,3
  96.         ld b,(hl)
  97.         inc hl
  98. checkmsgloop
  99.         cp (hl)
  100.         jr z,processmsg
  101.         add hl,de
  102.         djnz checkmsgloop
  103.         ret
  104.  
  105. processmsg
  106.         inc hl
  107.         ld e,(hl)
  108.         inc hl
  109.         ld d,(hl)
  110.         ex de,hl
  111.         jp (hl)
  112.  
  113. printerrorandexit
  114.         call print_hl
  115.         ld hl,pressanykeystr
  116.         call print_hl
  117.         YIELDGETKEYLOOP
  118.         QUIT
  119.  
  120. mainmsgtable
  121.         db (mainmsghandlers_end-mainmsghandlers_start)/3
  122. mainmsghandlers_start
  123.         db key_redraw    : dw redraw
  124.         db key_up        : dw goprevfile
  125.         db key_down      : dw gonextfile
  126.         db key_enter     : dw startplaying
  127.         db key_esc       : dw exitplayer
  128.         db ' '           : dw addtoplaylist
  129.         db key_tab       : dw switchpanels
  130.         db key_backspace : dw clearplaylist
  131.         db key_home      : dw gotop
  132. mainmsghandlers_end
  133.  
  134. playmsgtable
  135.         db (playmsghandlers_end-playmsghandlers_start)/3
  136. playmsghandlers_start
  137.         db key_redraw    : dw redraw
  138.         db ' '           : dw playnextfile
  139.         db key_esc       : dw stopplaying
  140. playmsghandlers_end
  141.  
  142. gotop
  143.         ld ix,(currentpaneladdr)
  144.         xor a
  145.         ld (ix+PANEL.currentfileindex),a
  146.         ld (ix+PANEL.firstfiletoshow),a
  147.         jp drawcurrentpanelfilelist
  148.  
  149. clearplaylist
  150.         call initemptyplaylist
  151.         jp drawplaylistwindow
  152.  
  153. playnextfile
  154.         call gonextfile
  155.         jp startplaying
  156.  
  157. switchpanels
  158.         ld a,(browserpanel.isinactive)
  159.         or a
  160. setcurrentpanel
  161.         ld a,255
  162.         ld (browserpanel.isinactive),a
  163.         ld (playlistpanel.isinactive),a
  164.         call nz,getbrowserpanelparams
  165.         call z,getplaylistpanelparams
  166.         ld (currentpaneladdr),ix
  167.         ld (currentpanelpos),de
  168.         ld (ix+PANEL.isinactive),0
  169.         call drawbrowserfileslist
  170.         jp drawplaylistfileslist
  171.  
  172. addtoplaylist
  173.         ld a,(browserpanel.isinactive)
  174.         or a
  175.         jr nz,removefromplaylist
  176.         ld hl,currentfolder
  177.         ld de,fullpathbuffer
  178.         call strcopy_hltode
  179.         ld a,'/'
  180.         ld (de),a
  181.         inc de
  182.         push de
  183.         ld a,(browserpanel.currentfileindex)
  184.         call getfiledataoffset
  185.         ld de,browserpanel.fileslist+FILE_ATTRIB_OFFSET
  186.         add hl,de
  187.         ld a,(hl)
  188.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  189.         add hl,de
  190.         pop de
  191.         cp FILE_ATTRIB_MUSIC
  192.         ret nz
  193.         call strcopy_hltode
  194.         ld hl,fullpathbuffer+FILE_DATA_SIZE-2
  195.         sub hl,de
  196.         ret c
  197.         jr z,skippadding
  198.         ld bc,hl
  199.         ld hl,de
  200.         inc de
  201.         ldir
  202.         dec de
  203. skippadding
  204.         inc de
  205.         ld a,255
  206.         ld (de),a
  207.         ld hl,playlistpanel+PANEL.filecount
  208.         ld a,(hl)
  209.         cp PANEL_FILE_COUNT
  210.         ret nc
  211.         inc (hl)
  212.         call getfiledataoffset
  213.         ld de,playlistpanel.fileslist
  214.         add hl,de
  215.         ex de,hl
  216.         ld hl,fullpathbuffer
  217.         ld bc,FILE_DATA_SIZE
  218.         ldir
  219.         jp drawplaylistfileslist
  220.  
  221. removefromplaylist
  222.         ret
  223.  
  224. exitplayer
  225.         pop hl
  226.         call stopplaying
  227.         ld hl,playerpages
  228.         ld b,NUM_PLAYERS
  229. playerdeinitloop
  230.         push bc
  231.         push hl
  232.         ld a,(hl)
  233.         SETPG4000
  234.         call playerdeinit
  235.         pop hl
  236.         pop bc
  237.         inc hl
  238.         djnz playerdeinitloop
  239. ;save playlist
  240.         OS_SETSYSDRV
  241.         ld de,playlistfilename
  242.         call openstream_file
  243.         or a
  244.         jr z,.openedfile
  245.         ld de,playlistfilename
  246.         OS_CREATEHANDLE
  247.         or a
  248.         jr nz,.failedtoopenfile
  249.         ld a,b
  250.         ld (filehandle),a
  251. .openedfile
  252.         ld a,(filehandle)
  253.         ld b,a
  254.         ld de,playlistpanelversion
  255.         ld hl,PANEL+2
  256.         OS_WRITEHANDLE
  257.         call closestream_file
  258. .failedtoopenfile
  259.         QUIT
  260.  
  261. startplaying
  262.         call stopplaying
  263.         ld ix,(currentpaneladdr)
  264.         ld a,(ix+PANEL.currentfileindex)
  265.         call getfiledataoffset
  266.         ld a,ixl
  267.         add PANEL.fileslist+FILE_ATTRIB_OFFSET
  268.         ld e,a
  269.         adc a,ixh
  270.         sub e
  271.         ld d,a
  272.         add hl,de
  273.         ld a,(hl)
  274.         cp FILE_ATTRIB_PARENT_DIR
  275.         jr z,changetoparentdir
  276.         cp FILE_ATTRIB_FOLDER
  277.         jr z,changetofolder
  278.         cp FILE_ATTRIB_MUSIC
  279.         ret nz
  280.         ld a,(browserpanel.isinactive)
  281.         or a
  282.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  283.         jr z,$+5
  284.         ld de,FILE_DISPLAY_INFO_OFFSET-FILE_ATTRIB_OFFSET
  285.         add hl,de
  286.         ld (.filename),hl
  287.         call findsupportedplayer
  288.         ret nz
  289.         call drawplayerwindow
  290. .filename=$+1
  291.         ld de,0
  292.         call musicload
  293.         jp nz,drawui
  294.         ld hl,playmsgtable
  295.         ld (currentmsgtable),hl
  296.         ld a,1
  297.         ld (isplaying),a
  298.         ret
  299.  
  300. changetoparentdir
  301.         ld hl,currentfolder
  302.         ld c,'/'
  303.         call findlastchar ;out: de = after last slash or start
  304.         push de
  305.         dec de
  306.         xor a
  307.         ld (de),a
  308.         call changetocurrentfolder
  309.         call createfileslist
  310.         pop de
  311.         call findfile
  312.         ld (browserpanel.currentfileindex),a
  313.         sub FILE_LINE_COUNT-1
  314.         jp c,drawbrowserwindow
  315.         ld hl,browserpanel.firstfiletoshow
  316.         cp (hl)
  317.         jp c,drawbrowserwindow
  318.         ld (hl),a
  319.         jp drawbrowserwindow
  320.  
  321. changetofolder
  322.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  323.         add hl,de
  324.         ld de,currentfolder-1
  325. .findzeroloop
  326.         inc de
  327.         ld a,(de)
  328.         or a
  329.         jr nz,.findzeroloop
  330.         ld a,'/'
  331.         ld (de),a
  332.         inc de
  333.         call strcopy_hltode
  334.         call changetocurrentfolder
  335.         call createfileslist
  336.         xor a
  337.         ld (browserpanel.currentfileindex),a
  338.         jp drawbrowserwindow
  339.  
  340. stopplaying
  341.         ld a,(isplaying)
  342.         or a
  343.         ret z
  344.         call musicunload
  345.         ld hl,mainmsgtable
  346.         ld (currentmsgtable),hl
  347.         xor a
  348.         ld (isplaying),a
  349.         jp drawui
  350.  
  351. gonextfile
  352.         ld ix,(currentpaneladdr)
  353.         ld a,(ix+PANEL.currentfileindex)
  354.         inc a
  355.         cp (ix+PANEL.filecount)
  356.         ret nc
  357.         ld (ix+PANEL.currentfileindex),a
  358.         sub FILE_LINE_COUNT-1
  359.         jp c,drawcurrentpanelfilelist
  360.         cp (ix+PANEL.firstfiletoshow)
  361.         jp c,drawcurrentpanelfilelist
  362.         ld (ix+PANEL.firstfiletoshow),a
  363.         jp drawcurrentpanelfilelist
  364.  
  365. goprevfile
  366.         ld ix,(currentpaneladdr)
  367.         ld a,(ix+PANEL.currentfileindex)
  368.         or a
  369.         ret z
  370.         dec a
  371.         ld (ix+PANEL.currentfileindex),a
  372.         cp (ix+PANEL.firstfiletoshow)
  373.         jp nc,drawcurrentpanelfilelist
  374.         ld (ix+PANEL.firstfiletoshow),a
  375.         jp drawcurrentpanelfilelist
  376.  
  377. initplaylist
  378.         ld de,playlistfilename
  379.         call openstream_file
  380.         or a
  381.         jr nz,initemptyplaylist
  382.         ld de,playlistpanelversion
  383.         ld hl,PANEL+2
  384.         call readstream_file
  385.         call closestream_file
  386.         ld de,PANELVERSION
  387.         ld hl,(playlistpanelversion)
  388.         sub hl,de
  389.         ret z
  390. initemptyplaylist
  391.         ld ix,playlistpanel
  392.         xor a
  393.         ld (ix+PANEL.filecount),a
  394.         ld (ix+PANEL.currentfileindex),a
  395.         ld (ix+PANEL.firstfiletoshow),a
  396.         ld hl,PANELVERSION
  397.         ld (playlistpanelversion),hl
  398.         ret
  399.  
  400. changetocurrentfolder
  401. ;out: zf=1 if succeeded, zf=0 otherwise
  402.         ld hl,(currentfolder+2)
  403.         push hl
  404.         ld a,l
  405.         or a
  406.         jr nz,$+8
  407.         ld hl,'/'
  408.         ld (currentfolder+2),hl
  409.         ld de,currentfolder
  410.         OS_CHDIR
  411.         pop hl
  412.         ld (currentfolder+2),hl
  413.         or a
  414.         ret
  415.  
  416. setcurrentfolder
  417. ;out: hl = file name only
  418.         push hl
  419.         ld c,'/'
  420.         call findlastchar ;out: de = after last slash or start
  421.         pop bc
  422.         ld hl,de
  423.         sub hl,bc
  424.         ex hl,de
  425.         ret z
  426. ;copy file path
  427.         ld hl,bc
  428.         ld bc,de
  429.         ld de,currentfolder
  430.         ldir
  431.         dec de
  432.         xor a
  433.         ld (de),a
  434.         ret
  435.  
  436. findfile
  437. ;de = file name
  438. ;out: a = file index, cf=1 if file was found
  439.         ld a,(browserpanel.filecount)
  440.         or a
  441.         ret z
  442.         ld b,a
  443.         ld c,0
  444.         ld hl,browserpanel.fileslist+FILE_NAME_OFFSET
  445. .searchloop
  446.         push bc
  447.         push de
  448.         push hl
  449.         call stricmp
  450.         pop hl
  451.         ld de,FILE_DATA_SIZE
  452.         add hl,de
  453.         pop de
  454.         pop bc
  455.         scf
  456.         ld a,c
  457.         ret z
  458.         inc c
  459.         djnz .searchloop
  460.         xor a
  461.         ret
  462.  
  463. stricmp
  464. ;hl = string1 addr
  465. ;de = string2 addr
  466. ;out: zf=1 if equal
  467.         ld a,(hl)
  468.         call tolower
  469.         ld c,a
  470.         ld a,(de)
  471.         call tolower
  472.         ld b,a
  473.         or c
  474.         ret z
  475.         ld a,b
  476.         cp c
  477.         ret nz
  478.         cp 1
  479.         ret c
  480.         inc hl
  481.         inc de
  482.         jr stricmp
  483.  
  484. drawplayerwindow
  485.         ld de,PANELCOLOR
  486.         OS_SETCOLOR
  487.         ld de,8*256+12
  488.         ld bc,54*256+3
  489.         call drawwindow
  490.         ld de,CURSORCOLOR
  491.         OS_SETCOLOR
  492.         ld de,8*256+14
  493.         OS_SETXY
  494.         ld hl,playingstr
  495.         call print_hl
  496.         ld de,PANELDIRCOLOR
  497.         OS_SETCOLOR
  498.         ld de,10*256+14
  499.         OS_SETXY
  500.         ld ix,(currentpaneladdr)
  501.         ld a,(ix+PANEL.currentfileindex)
  502.         call getfiledataoffset
  503.         ld a,ixl
  504.         add PANEL.fileslist+FILE_DISPLAY_INFO_OFFSET
  505.         ld e,a
  506.         adc a,ixh
  507.         sub e
  508.         ld d,a
  509.         add hl,de
  510.         jp print_hl
  511.  
  512. drawwindowline
  513. ;d = left char
  514. ;e = right char
  515. ;c = middle char
  516. ;b = middle char count
  517.         ld a,d
  518.         push de
  519.         push bc
  520.         PRCHAR
  521.         pop bc
  522. .drawloop
  523.         push bc
  524.         ld a,c
  525.         PRCHAR
  526.         pop bc
  527.         djnz .drawloop
  528.         pop de
  529.         ld a,e
  530.         PRCHAR
  531.         ret
  532.  
  533. drawwindow
  534. ;e = left coord
  535. ;d = top coord
  536. ;b = client area width
  537. ;c = client area height
  538. ;top line
  539.         push de
  540.         push bc
  541.         OS_SETXY
  542.         pop bc
  543.         push bc
  544.         ld de,0xc9bb
  545.         ld c,0xcd
  546.         call drawwindowline
  547.         pop bc
  548.         pop de
  549.         inc d
  550. ;client area
  551. .drawloop
  552.         push de
  553.         push bc
  554.         OS_SETXY
  555.         pop bc
  556.         push bc
  557.         ld de,0xbaba
  558.         ld c,0x20
  559.         call drawwindowline
  560.         pop bc
  561.         pop de
  562.         inc d
  563.         dec c
  564.         jr nz,.drawloop
  565. ;bottom line
  566.         push bc
  567.         OS_SETXY
  568.         pop bc
  569.         ld de,0xc8bc
  570.         ld c,0xcd
  571.         jp drawwindowline
  572.  
  573. getfiledataoffset
  574. ;a = index
  575. ;out: hl = index * FILE_DATA_SIZE
  576.         ld l,a
  577.         ld h,0
  578.         ld de,hl
  579.         add hl,hl
  580.         add hl,hl
  581.         ex de,hl
  582.         add hl,de
  583.         ex de,hl
  584.         add hl,hl
  585.         add hl,de
  586.         add hl,hl
  587.         add hl,hl
  588.         ret
  589.  
  590. getfileinfocolor
  591. ;c = file index
  592. ;hl = file data address
  593. currentfileindex=$+1
  594.         ld a,0
  595.         cp c
  596.         ld de,CURSORCOLOR
  597.         ret z
  598.         ld a,(ix+FILE_ATTRIB_OFFSET-FILE_DISPLAY_INFO_OFFSET)
  599.         cp FILE_ATTRIB_MUSIC
  600.         ld de,PANELDIRCOLOR
  601.         ret nz
  602.         ld de,PANELFILECOLOR
  603.         ret
  604.  
  605. printfilesinfos
  606. ;ix = struct PANEL
  607. ;e = left coord
  608. ;d = top coord
  609. ;b = line count
  610. ;c = first file index
  611.         ld a,(ix+PANEL.currentfileindex)
  612.         or (ix+PANEL.isinactive)
  613.         ld (currentfileindex),a
  614.         ld a,(ix+PANEL.filecount)
  615.         ld (.currentfilecount),a
  616.         push de
  617.         ld a,c
  618.         call getfiledataoffset
  619.         ld de,ix
  620.         add hl,de
  621.         ld de,FILE_DISPLAY_INFO_OFFSET+PANEL.fileslist
  622.         add hl,de
  623.         pop de
  624. .filesloop
  625.         ld a,c
  626. .currentfilecount=$+1
  627.         cp 0
  628.         ret nc
  629.         push de
  630.         push hl
  631.         push bc
  632.         OS_SETXY
  633.         pop bc
  634.         pop ix
  635.         push bc
  636.         push ix
  637.         call getfileinfocolor
  638.         OS_SETCOLOR
  639.         pop hl
  640.         pop bc
  641.         push bc
  642.         ld b,FILE_DISPLAY_INFO_SIZE
  643. .printdisplaystringloop
  644.         push bc
  645.         push hl
  646.         ld a,(hl)
  647.         or a
  648.         jr nz,$+4
  649.         ld a,' '
  650.         PRCHAR
  651.         pop hl
  652.         pop bc
  653.         inc hl
  654.         djnz .printdisplaystringloop
  655.         ld de,FILE_DATA_SIZE-FILE_DISPLAY_INFO_SIZE
  656.         add hl,de
  657.         pop bc
  658.         pop de
  659.         inc c
  660.         inc d
  661.         djnz .filesloop
  662.         ret
  663.  
  664. getbrowserpanelparams
  665.         ld ix,browserpanel
  666.         ld de,256+1+FILES_WINDOW_X
  667.         ret
  668.  
  669. drawbrowserfileslist
  670.         call getbrowserpanelparams
  671.         ld b,FILE_LINE_COUNT
  672.         ld c,(ix+PANEL.firstfiletoshow)
  673.         jp printfilesinfos
  674.  
  675. getplaylistpanelparams
  676.         ld ix,playlistpanel
  677.         ld de,256+FILE_DISPLAY_INFO_SIZE+3+FILES_WINDOW_X
  678.         ret
  679.  
  680. drawplaylistfileslist
  681.         call getplaylistpanelparams
  682.         ld b,FILE_LINE_COUNT
  683.         ld c,(ix+PANEL.firstfiletoshow)
  684.         jp printfilesinfos
  685.  
  686. drawcurrentpanelfilelist
  687. currentpaneladdr=$+2
  688.         ld ix,0
  689. currentpanelpos=$+1
  690.         ld de,0
  691.         ld b,FILE_LINE_COUNT
  692.         ld c,(ix+PANEL.firstfiletoshow)
  693.         jp printfilesinfos
  694.  
  695. drawbrowserwindow
  696.         ld de,PANELCOLOR
  697.         OS_SETCOLOR
  698.         ld de,FILES_WINDOW_X
  699.         ld bc,FILE_DISPLAY_INFO_SIZE*256+FILE_LINE_COUNT
  700.         call drawwindow
  701.         ld de,CURSORCOLOR
  702.         OS_SETCOLOR
  703.         ld de,FILES_WINDOW_X+2
  704.         OS_SETXY
  705.         ld hl,currentfolder
  706.         call print_hl
  707.         jp drawbrowserfileslist
  708.  
  709. drawplaylistwindow
  710.         ld de,PANELCOLOR
  711.         OS_SETCOLOR
  712.         ld de,FILES_WINDOW_X+FILE_DISPLAY_INFO_SIZE+2
  713.         ld bc,FILE_DISPLAY_INFO_SIZE*256+FILE_LINE_COUNT
  714.         call drawwindow
  715.         ld de,CURSORCOLOR
  716.         OS_SETCOLOR
  717.         ld de,FILES_WINDOW_X+FILE_DISPLAY_INFO_SIZE+4
  718.         OS_SETXY
  719.         ld hl,playliststr
  720.         call print_hl
  721.         jr drawplaylistfileslist
  722.  
  723. redraw
  724.         ld e,7
  725.         OS_CLS
  726. drawui
  727.         call drawbrowserwindow
  728.         call drawplaylistwindow
  729.         ld a,(isplaying)
  730.         or a
  731.         ret z
  732.         jp drawplayerwindow
  733.  
  734. skipword_hl
  735.         ld a,(hl)
  736.         or a
  737.         ret z
  738.         cp ' '
  739.         ret z
  740.         inc hl
  741.         jr skipword_hl
  742.  
  743. skipspaces_hl
  744.         ld a,(hl)
  745.         cp ' '
  746.         ret nz
  747.         inc hl
  748.         jr skipspaces_hl
  749.  
  750. print_hl
  751.         ld a,(hl)
  752.         or a
  753.         ret z
  754.         push hl
  755.         PRCHAR
  756.         pop hl
  757.         inc hl
  758.         jp print_hl
  759.  
  760. strcopy_hltode
  761.         ld a,(hl)
  762.         ld (de),a
  763.         or a
  764.         ret z
  765.         inc hl
  766.         inc de
  767.         jr strcopy_hltode
  768.  
  769. ;c = character
  770. ;hl = poi to filename in string
  771. ;out: de = after last dot or start
  772. findlastchar
  773.         ld d,h
  774.         ld e,l ;de = after last char
  775. findlastchar0
  776.         ld a,(hl)
  777.         inc hl
  778.         or a
  779.         ret z
  780.         cp c
  781.         jr nz,findlastchar0
  782.         jr findlastchar
  783.  
  784. tolower
  785.         cp 'A'
  786.         ret c
  787.         cp 'Z'+1
  788.         ret nc
  789.         add 32
  790.         ret
  791.  
  792. pressanykeystr
  793.         db "!\r\nPress any key to exit...\r\n",0
  794. playersfilename
  795.         db "gp/gp.plr",0
  796. playlistfilename
  797.         db "gp/gp.dat",0
  798. playersloaderrorstr
  799.         db "Failed to load gp/gp.plr from OS folder",0
  800. chdirfailedstr
  801.         db "Unable to change directory",0
  802. playliststr
  803.         db "Playlist",0
  804. playingstr
  805.         db "Playing...",0
  806. emptystr
  807.         db 0
  808.  
  809.         macro loadplayer playerpage,playersize
  810.         OS_NEWPAGE
  811.         ld a,e
  812.         ld (playerpage),a
  813.         SETPG4000
  814.  
  815.         ld de,0x4000
  816.         ld hl,playersize
  817.         call readstream_file
  818.  
  819.         ld hl,sharedpages
  820.         ld a,(playerpage)
  821.         call playerinit
  822.         endm
  823.  
  824. loadplayers
  825.         ld de,playersfilename
  826.         call openstream_file
  827.         or a
  828.         ret nz
  829.  
  830.         loadplayer playerpages+0,mdrend-mdrstart
  831.         loadplayer playerpages+1,mwmend-mwmstart
  832.         loadplayer playerpages+2,pt3end-pt3start
  833.         loadplayer playerpages+3,mp3end-mp3start
  834.  
  835.         call closestream_file
  836.         xor a
  837.         ret
  838.  
  839. findsupportedplayer
  840. ;hl = file name
  841.         ld c,'.'
  842.         call findlastchar ;out: de = after last dot or start
  843.         ex de,hl
  844.         ld a,(hl)
  845.         call tolower
  846.         ld c,a
  847.         inc hl
  848.         ld a,(hl)
  849.         call tolower
  850.         ld d,a
  851.         inc hl
  852.         ld a,(hl)
  853.         call tolower
  854.         ld e,a
  855. ;cde = file extension
  856.         ld hl,playerpages
  857.         ld b,NUM_PLAYERS
  858. .findplayerloop
  859.         push hl
  860.         push bc
  861.         ld a,(hl)
  862.         SETPG4000
  863.         pop bc
  864.         call isfilesupported
  865.         pop hl
  866.         ret z
  867.         inc hl
  868.         djnz .findplayerloop
  869.         dec b ;set zf=0
  870.         ret
  871.  
  872. createfileslist
  873.         ld de,emptystr
  874.         OS_OPENDIR
  875.  
  876.         ld a,(sharedpages)
  877.         SETPG8000
  878.         ld a,(sharedpages+1)
  879.         SETPGC000
  880.  
  881.         xor a
  882.         ld (browserpanel.currentfileindex),a
  883.         ld (browserpanel.firstfiletoshow),a
  884.         ld (browserpanel.filecount),a
  885.  
  886.         ld hl,0x8000
  887. .fileenumloop
  888.         ld (.filedataaddr),hl
  889. .skiptonextfile
  890.         ld de,filinfo
  891.         OS_READDIR
  892.         or a
  893.         jp nz,.sortfiles
  894. ;skip '.' folder
  895.         ld hl,(filinfo+FILINFO_FNAME)
  896.         ld a,l
  897.         xor '.'
  898.         or h
  899.         jr z,.skiptonextfile
  900. ;skip findsupportedplayer for folders
  901.         ld a,(filinfo+FILINFO_FATTRIB)
  902.         and FATTRIB_DIR
  903.         jr nz,.founddir
  904.         ld hl,filinfo+FILINFO_FNAME
  905.         call findsupportedplayer
  906.         jr nz,.skiptonextfile
  907. ;we've got either a playable file or a folder
  908. .founddir
  909. .filedataaddr=$+1
  910.         ld de,0
  911.         ld hl,FILE_NAME_OFFSET
  912.         add hl,de
  913.         ex de,hl
  914.         ld hl,filinfo+FILINFO_FNAME
  915.         ld bc,9*256+SFN_SIZE
  916. .copysfnloop
  917.         ld a,(hl)
  918.         cp '.'
  919.         jr z,.foundsfnext
  920.         or a
  921.         jr z,.sfntailloop
  922.         call tolower
  923.         ld (de),a
  924.         inc hl
  925.         inc de
  926.         dec c
  927.         dec b
  928.         jr .copysfnloop
  929. ;this is a folder, pad it to SFN_SIZE with zeros
  930. .sfntailloop
  931.         ld (de),a
  932.         inc de
  933.         dec c
  934.         jr nz,.sfntailloop
  935.         jr .donesfncopy
  936. ;format SFN as 8.3 fixed-position array padding with '*' if necessary
  937. ;this is needed for sorting
  938. .foundsfnext
  939.         ld a,'*'
  940. .sfntailloop1
  941.         ld (de),a
  942.         inc de
  943.         djnz .sfntailloop1
  944.         dec de
  945. ;copy dot, extension, zero terminator
  946.         ld b,5
  947. .sfntailloop2
  948.         ld a,(hl)
  949.         call tolower
  950.         ld (de),a
  951.         inc hl
  952.         inc de
  953.         djnz .sfntailloop2
  954. .donesfncopy
  955. ;fill display name
  956.         ld hl,FILE_DISPLAY_INFO_OFFSET-FILE_NAME_OFFSET-SFN_SIZE
  957.         add hl,de
  958.         ex de,hl
  959.         ld hl,filinfo+FILINFO_LNAME
  960.         ld a,(hl)
  961.         or a
  962.         jr nz,$+5
  963.         ld hl,filinfo+FILINFO_FNAME
  964.         ld bc,(FILE_DISPLAY_INFO_SIZE-1)*256+255
  965. .copylfnloop
  966.         ldi
  967.         dec b
  968.         jr z,.lfncopydone
  969.         ld a,(hl)
  970.         or a
  971.         jr nz,.copylfnloop
  972. .filltailloop
  973.         ld (de),a
  974.         inc de
  975.         djnz .filltailloop
  976. .lfncopydone
  977.         xor a
  978.         ld (de),a
  979. ;set atrribute data
  980.         call getfileattrib
  981.         ld hl,FILE_ATTRIB_OFFSET-FILE_DISPLAY_INFO_OFFSET-FILE_DISPLAY_INFO_SIZE+1
  982.         add hl,de
  983.         ld (hl),a
  984.         ld de,FILE_DATA_SIZE-FILE_ATTRIB_OFFSET
  985.         add hl,de
  986. ;check if we have space for more files
  987.         ld a,(browserpanel.filecount)
  988.         inc a
  989.         ld (browserpanel.filecount),a
  990.         cp PANEL_FILE_COUNT
  991.         jp c,.fileenumloop
  992. .sortfiles
  993.         ld a,(browserpanel.filecount)
  994.         or a
  995.         ret z
  996.         ld c,a
  997.         ld b,0
  998.         ld a,12
  999.         ld ix,fileextsortkeyoffsets
  1000.         ld hl,0x8000
  1001.         ld de,FILE_DATA_SIZE
  1002.         ld iy,browserpanel.fileslist
  1003.         call radixsort
  1004. ;remove '*' padding restoring SFN to original null-terminated string form
  1005.         ld a,(browserpanel.filecount)
  1006.         ld b,a
  1007.         ld hl,browserpanel.fileslist+FILE_NAME_OFFSET
  1008. .removepaddingnextfile
  1009.         ld de,hl
  1010.         push hl
  1011. .removepaddingloop
  1012.         ld a,(hl)
  1013.         inc hl
  1014.         cp '*'
  1015.         jr z,.removepaddingloop
  1016.         ld (de),a
  1017.         inc de
  1018.         or a
  1019.         jr nz,.removepaddingloop
  1020.         pop hl
  1021.         ld de,FILE_DATA_SIZE
  1022.         add hl,de
  1023.         djnz .removepaddingnextfile
  1024.         ret
  1025.  
  1026. getfileattrib
  1027. ;out: a = attribute value
  1028.         ld a,(filinfo+FILINFO_FATTRIB)
  1029.         and FATTRIB_DIR
  1030.         ld a,FILE_ATTRIB_MUSIC
  1031.         ret z
  1032.         ld hl,(filinfo+FILINFO_FNAME)
  1033.         ld bc,'..'
  1034.         sub hl,bc
  1035.         ld a,FILE_ATTRIB_PARENT_DIR
  1036.         ret z
  1037.         ld a,FILE_ATTRIB_FOLDER
  1038.         ret
  1039.  
  1040. fileextsortkeyoffsets
  1041.         dw FILE_NAME_OFFSET+7, FILE_NAME_OFFSET+6, FILE_NAME_OFFSET+5
  1042.         dw FILE_NAME_OFFSET+4, FILE_NAME_OFFSET+3, FILE_NAME_OFFSET+2
  1043.         dw FILE_NAME_OFFSET+1, FILE_NAME_OFFSET+0
  1044.         dw FILE_NAME_OFFSET+11, FILE_NAME_OFFSET+10, FILE_NAME_OFFSET+9
  1045.         dw FILE_ATTRIB_OFFSET
  1046.  
  1047. PLAYERINITPROCADDR      = 0x4000
  1048. PLAYERDEINITPROCADDR    = 0x4002
  1049. MUSICLOADPROCADDR       = 0x4004
  1050. MUSICUNLOADPROCADDR     = 0x4006
  1051. MUSICPLAYPROCADDR       = 0x4008
  1052. ISFILESUPPORTEDPROCADDR = 0x400a
  1053.  
  1054.         macro jumpindirect addr
  1055.         push hl
  1056.         ld hl,(addr)
  1057.         ex (sp),hl
  1058.         ret
  1059.         endm
  1060.  
  1061. playerinit      jumpindirect PLAYERINITPROCADDR
  1062. playerdeinit    jumpindirect PLAYERDEINITPROCADDR
  1063. musicload       jumpindirect MUSICLOADPROCADDR
  1064. musicunload     jumpindirect MUSICUNLOADPROCADDR
  1065. musicplay       jumpindirect MUSICPLAYPROCADDR
  1066. isfilesupported jumpindirect ISFILESUPPORTEDPROCADDR
  1067.  
  1068.         include "../_sdk/file.asm"
  1069.         include "radixsort.asm"
  1070. mainend
  1071.  
  1072. sharedpages
  1073.         ds 3
  1074. playerpages
  1075.         ds NUM_PLAYERS
  1076. filinfo
  1077.         ds FILINFO_sz
  1078. currentfolder
  1079.         ds MAXPATH_sz
  1080. fullpathbuffer
  1081.         ds MAXPATH_sz
  1082.  
  1083.         struct PANEL
  1084. filecount ds 1
  1085. currentfileindex ds 1
  1086. firstfiletoshow ds 1
  1087. isinactive ds 1
  1088. fileslist ds FILE_DATA_SIZE*PANEL_FILE_COUNT
  1089.         ends
  1090.  
  1091. browserpanel PANEL
  1092. playlistpanelversion ds 2
  1093. playlistpanel PANEL
  1094.  
  1095. mdrstart
  1096.         incbin "mdr.bin"
  1097. mdrend
  1098.  
  1099. mwmstart
  1100.         incbin "mwm.bin"
  1101. mwmend
  1102.  
  1103. pt3start
  1104.         incbin "pt3.bin"
  1105. pt3end
  1106.  
  1107. mp3start
  1108.         incbin "mp3.bin"
  1109. mp3end
  1110.  
  1111.         savebin "gp.com",mainbegin,mainend-mainbegin
  1112.         savebin "gp.plr",mdrstart,mp3end-mdrstart
  1113.