?login_element?

Subversion Repositories NedoOS

Rev

Rev 2015 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.         DEVICE ZXSPECTRUM128
  2.         include "../_sdk/sys_h.asm"
  3.         include "playerdefs.asm"
  4.  
  5. NUM_PLAYERS = 5
  6. SFN_SIZE = 13
  7. FILE_DATA_SIZE = 52 ;keep in sync with getfiledataoffset
  8. FILE_DISPLAY_INFO_OFFSET = 0
  9. FILE_DISPLAY_INFO_SIZE = 38
  10. FILE_NAME_OFFSET = FILE_DISPLAY_INFO_OFFSET+FILE_DISPLAY_INFO_SIZE
  11. FILE_NAME_SIZE = SFN_SIZE
  12. FILE_ATTRIB_OFFSET = FILE_NAME_OFFSET+FILE_NAME_SIZE
  13. FILE_ATTRIB_SIZE = 1
  14. BROWSER_FILE_COUNT=162
  15. PLAYLIST_FILE_COUNT=40
  16. PANELCOLOR = 0x4f
  17. CURSORCOLOR = 0x28
  18. PANELFILECOLOR = 0x0f
  19. PANELDIRCOLOR = 0x4f
  20. PANELDRIVECOLOR = 0x4b
  21. FILE_LINE_COUNT = 22
  22. FILES_WINDOW_X = 0
  23. FILE_ATTRIB_MUSIC = 255
  24. FILE_ATTRIB_PARENT_DIR = 0
  25. FILE_ATTRIB_DRIVE = 1
  26. FILE_ATTRIB_FOLDER = 2
  27. PLAYLIST_VERSION = 1
  28.  
  29.         org PROGSTART
  30.  
  31. mainbegin
  32.         ld sp,0x4000
  33.         OS_HIDEFROMPARENT
  34.         ld e,6 ;textmode
  35.         OS_SETGFX
  36.         ld e,7
  37.         OS_CLS
  38.  
  39.         OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
  40.         ld (gpsettings.sharedpages),hl
  41.         ld a,e
  42.         ld (gpsettings.sharedpages+2),a
  43.         ld d,b
  44.         call closeexistingplayer
  45.  
  46.         ld de,currentfolder
  47.         OS_GETPATH
  48.         ld hl,(currentfolder+2)
  49.         ld a,l
  50.         xor '/'
  51.         or h
  52.         jr nz,$+5
  53.         ld (currentfolder+2),a
  54.  
  55.         OS_SETSYSDRV
  56.         call loadsettings
  57.         call detectmoonsound
  58.         call detecttfm
  59.         call loadplayers
  60.         jp nz,printerrorandexit
  61.  
  62.         ld ix,browserpanel
  63.         call clearpanel
  64.         ld ix,playlistpanel
  65.         call clearpanel
  66.         or 255 ;set zf=0
  67.         call setcurrentpanel
  68.  
  69.         ld de,defaultplaylistfilename
  70.         call loadplaylist
  71.         xor a
  72.         ld (playlistchanged),a
  73.  
  74.         ld hl,COMMANDLINE
  75.         call skipword_hl
  76.         call skipspaces_hl
  77.         ld a,(hl)
  78.         or a
  79.         call nz,setcurrentfolder
  80.         push hl
  81.         call changetocurrentfolder
  82.         pop de
  83.         ld hl,chdirfailedstr
  84.         jp nz,printerrorandexit
  85.         push de
  86.         call createfileslist
  87.         pop de
  88.         ld a,(de)
  89.         or a
  90.         call nz,findfile
  91.         ld (browserpanel.currentfileindex),a
  92.         push af
  93.         call drawui
  94.         pop af
  95.         call c,startplaying
  96.  
  97. playloop
  98. isplaying=$+1
  99.         ld a,0
  100.         or a
  101.         jr z,checkmsgs
  102.         call musicplay
  103.         call z,playnextfile
  104.         call updateprogressbar
  105.  
  106. checkmsgs
  107.         ld a,(COMMANDLINE)
  108.         or a
  109.         ld a,key_esc
  110.         jr z,closeplayer
  111.         OS_GETKEY
  112.         call tolower
  113. closeplayer
  114.         ld hl,playloop
  115.         push hl
  116. currentmsgtable=$+1
  117.         ld hl,mainmsgtable
  118.         ld de,3
  119.         ld b,(hl)
  120.         inc hl
  121. checkmsgloop
  122.         cp (hl)
  123.         jr z,processmsg
  124.         add hl,de
  125.         djnz checkmsgloop
  126.         ret
  127.  
  128. processmsg
  129.         inc hl
  130.         ld e,(hl)
  131.         inc hl
  132.         ld d,(hl)
  133.         ex de,hl
  134.         jp (hl)
  135.  
  136. printerrorandexit
  137.         call print_hl
  138.         ld hl,pressanykeystr
  139.         call print_hl
  140.         YIELDGETKEYLOOP
  141.         QUIT
  142.  
  143. mainmsgtable
  144.         db (mainmsghandlers_end-mainmsghandlers_start)/3
  145. mainmsghandlers_start
  146.         db 0             : dw nokey
  147.         db key_redraw    : dw redraw
  148.         db key_up        : dw goprevfile
  149.         db key_down      : dw gonextfile
  150.         db key_enter     : dw startplaying
  151.         db key_esc       : dw exitplayer
  152.         db ' '           : dw addtoplaylist
  153.         db key_tab       : dw switchpanels
  154.         db key_backspace : dw clearplaylist
  155.         db key_home      : dw gotop
  156.         db key_end       : dw golastfile
  157.         db key_left      : dw gopageup
  158.         db key_right     : dw gopagedown
  159.         db key_pgup      : dw gopageup
  160.         db key_pgdown    : dw gopagedown
  161.         db 's'           : dw onhotkeyS
  162. mainmsghandlers_end
  163.  
  164. playmsgtable
  165.         db (playmsghandlers_end-playmsghandlers_start)/3
  166. playmsghandlers_start
  167.         db key_redraw    : dw redraw
  168.         db ' '           : dw playnextfile
  169.         db key_esc       : dw stopplaying
  170. playmsghandlers_end
  171.  
  172. nokey
  173.         YIELD
  174.         ret
  175.  
  176. gotop
  177.         ld ix,(currentpaneladdr)
  178.         xor a
  179.         ld (ix+PANEL.currentfileindex),a
  180.         ld (ix+PANEL.firstfiletoshow),a
  181.         jp drawcurrentpanelfilelist
  182.  
  183. markplaylistdirty
  184.         ld a,255
  185.         ld (playlistchanged),a
  186.         ret
  187.  
  188. clearplaylist
  189.         call markplaylistdirty
  190.         ld ix,playlistpanel
  191.         call clearpanel
  192.         jp drawplaylistwindow
  193.  
  194. playnextfile
  195.         ld ix,(currentpaneladdr)
  196.         call setnextfileindex
  197.         jp c,startplaying
  198.         xor a
  199.         ld (ix+PANEL.currentfileindex),a
  200.         ld (ix+PANEL.firstfiletoshow),a
  201.         ld hl,(currentpaneladdr)
  202.         ld de,PANEL.fileslist+FILE_ATTRIB_OFFSET
  203.         add hl,de
  204.         ld e,FILE_DATA_SIZE
  205. .wraploop
  206.         ld a,(hl)
  207.         cp FILE_ATTRIB_MUSIC
  208.         jp z,startplaying
  209.         add hl,de
  210.         inc (ix+PANEL.currentfileindex)
  211.         jr .wraploop
  212.  
  213. switchpanels
  214.         ld a,(browserpanel.isinactive)
  215.         or a
  216. setcurrentpanel
  217.         ld a,255
  218.         ld (browserpanel.isinactive),a
  219.         ld (playlistpanel.isinactive),a
  220.         call nz,getbrowserpanelparams
  221.         call z,getplaylistpanelparams
  222.         ld (currentpaneladdr),ix
  223.         ld (currentpanelpos),de
  224.         ld (ix+PANEL.isinactive),0
  225.         call drawbrowserfileslist
  226.         jp drawplaylistfileslist
  227.  
  228. addtoplaylist
  229.         call markplaylistdirty
  230.         ld a,(browserpanel.isinactive)
  231.         or a
  232.         jr nz,removefromplaylist
  233.         ld hl,currentfolder
  234.         ld de,fullpathbuffer
  235.         call strcopy_hltode
  236.         ld a,'/'
  237.         ld (de),a
  238.         inc de
  239.         push de
  240.         ld a,(browserpanel.currentfileindex)
  241.         call getfiledataoffset
  242.         ld de,browserpanel.fileslist+FILE_ATTRIB_OFFSET
  243.         add hl,de
  244.         ld a,(hl)
  245.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  246.         add hl,de
  247.         pop de
  248.         cp FILE_ATTRIB_MUSIC
  249.         ret nz
  250.         call strcopy_hltode
  251.         ld hl,fullpathbuffer+FILE_DATA_SIZE-2
  252.         sub hl,de
  253.         ret c
  254.         jr z,skippadding
  255.         ld bc,hl
  256.         ld hl,de
  257.         inc de
  258.         ldir
  259.         dec de
  260. skippadding
  261.         inc de
  262.         ld a,255
  263.         ld (de),a
  264.         ld hl,playlistpanel.filecount
  265.         ld a,(hl)
  266.         cp PLAYLIST_FILE_COUNT
  267.         ret nc
  268.         inc (hl)
  269.         call getfiledataoffset
  270.         ld de,playlistpanel.fileslist
  271.         add hl,de
  272.         ex de,hl
  273.         ld hl,fullpathbuffer
  274.         ld bc,FILE_DATA_SIZE
  275.         ldir
  276.         jp drawplaylistfileslist
  277.  
  278. removefromplaylist
  279.         ld a,(playlistpanel.filecount)
  280.         or a
  281.         ret z
  282.         dec a
  283.         jp z,clearplaylist
  284.         ld (playlistpanel.filecount),a
  285.         ld b,a
  286.         ld a,(playlistpanel.currentfileindex)
  287.         cp b
  288.         jr nz,.movetail
  289.         dec a
  290.         ld (playlistpanel.currentfileindex),a
  291.         jp drawplaylistwindow
  292. .movetail
  293.         call getfiledataoffset
  294.         ld de,playlistpanel.fileslist
  295.         add hl,de
  296.         ex de,hl
  297.         ld hl,playlistpanel.fileslist+FILE_DATA_SIZE*(PLAYLIST_FILE_COUNT-1)
  298.         sub hl,de
  299.         ld bc,hl
  300.         ld hl,FILE_DATA_SIZE
  301.         add hl,de
  302.         ldir
  303.         jp drawplaylistwindow
  304.  
  305. exitplayer
  306.         pop hl
  307.         call stopplaying
  308.         ld hl,playerpages
  309.         ld a,(playercount)
  310.         ld b,a
  311. playerdeinitloop
  312.         push bc
  313.         push hl
  314.         ld a,(hl)
  315.         SETPG4000
  316.         call playerdeinit
  317.         pop hl
  318.         pop bc
  319.         inc hl
  320.         djnz playerdeinitloop
  321. ;save playlist
  322.         ld a,255
  323.         ld (playlistpanel.isinactive),a
  324.         OS_SETSYSDRV
  325.         ld de,defaultplaylistfilename
  326.         ld a,(playlistchanged)
  327.         or a
  328.         call nz,saveplaylist
  329.         QUIT
  330.  
  331. saveplaylist
  332. ;de = filename
  333.         push de
  334.         call openstream_file
  335.         pop de
  336.         or a
  337.         jr z,.openedfile
  338.         OS_CREATEHANDLE
  339.         or a
  340.         ret nz
  341.         ld a,b
  342.         ld (filehandle),a
  343. .openedfile
  344.         ld a,(filehandle)
  345.         ld b,a
  346.         ld de,playlistdatastart
  347.         ld hl,playlistdatasize
  348.         OS_WRITEHANDLE
  349.         call closestream_file
  350.         xor a
  351.         ret
  352.  
  353. onhotkeyS
  354.         ld de,playlistfilename
  355.         call saveplaylist
  356.         ld de,playlistfilename
  357.         jp createfilelistandchangesel
  358.  
  359. startplaying
  360.         call stopplaying
  361.         ld ix,(currentpaneladdr)
  362.         ld a,(ix+PANEL.filecount)
  363.         or a
  364.         ret z
  365.         ld a,(ix+PANEL.currentfileindex)
  366.         call getfiledataoffset
  367.         ld a,ixl
  368.         add PANEL.fileslist+FILE_ATTRIB_OFFSET
  369.         ld e,a
  370.         adc a,ixh
  371.         sub e
  372.         ld d,a
  373.         add hl,de
  374.         ld a,(hl)
  375.         cp FILE_ATTRIB_PARENT_DIR
  376.         jp z,changetoparentdir
  377.         cp FILE_ATTRIB_FOLDER
  378.         jp z,changetofolder
  379.         cp FILE_ATTRIB_DRIVE
  380.         jr z,changedrive
  381.         cp FILE_ATTRIB_MUSIC
  382.         ret nz
  383.         ld a,(browserpanel.isinactive)
  384.         or a
  385.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  386.         jr z,$+5
  387.         ld de,FILE_DISPLAY_INFO_OFFSET-FILE_ATTRIB_OFFSET
  388.         add hl,de
  389.         ld (.filename),hl
  390.         call getfileextension
  391.         ld (.filext2),de
  392.         ld (.filext1),bc
  393.         call isfileplaylist
  394.         jp z,.loadplaylist
  395.         call findsupportedplayer
  396.         ret nz
  397.         call drawplayerwindow
  398. .filext1=$+1
  399.         ld bc,0
  400. .filext2=$+1
  401.         ld de,0
  402. .filename=$+1
  403.         ld hl,0
  404.         call musicload
  405.         jp nz,drawui
  406.         ld hl,playmsgtable
  407.         ld (currentmsgtable),hl
  408.         ld a,1
  409.         ld (isplaying),a
  410.         call drawsongtitle
  411.         jp drawprogress
  412. .loadplaylist
  413.         ld de,(.filename)
  414.         call loadplaylist
  415.         call drawplaylistwindow
  416.         xor a
  417.         call setcurrentpanel
  418.         jp startplaying
  419.  
  420. changedrive
  421.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  422.         add hl,de
  423.         push hl
  424.         ld de,(currentfolder)
  425.         push de
  426.         ld de,currentfolder
  427.         ldi
  428.         ldi
  429.         call changetocurrentfolder
  430.         pop hl
  431.         pop de
  432.         jp z,createfilelistandchangesel
  433.         ld (currentfolder),hl
  434.         ret
  435.  
  436. changetoparentdir
  437.         ld hl,currentfolder
  438.         ld c,'/'
  439.         call findlastchar ;out: de = after last slash or start
  440.         push de
  441.         dec de
  442.         xor a
  443.         ld (de),a
  444.         call changetocurrentfolder
  445.         pop de
  446.         jp createfilelistandchangesel
  447.  
  448. createfilelistandchangesel
  449. ;de = selection filename
  450.         push de
  451.         call createfileslist
  452.         pop de
  453.         call findfile
  454.         ld (browserpanel.currentfileindex),a
  455.         sub FILE_LINE_COUNT-1
  456.         jp c,drawbrowserwindow
  457.         ld hl,browserpanel.firstfiletoshow
  458.         cp (hl)
  459.         jp c,drawbrowserwindow
  460.         ld (hl),a
  461.         jp drawbrowserwindow
  462.  
  463. changetofolder
  464.         ld de,FILE_NAME_OFFSET-FILE_ATTRIB_OFFSET
  465.         add hl,de
  466.         ld de,currentfolder-1
  467. .findzeroloop
  468.         inc de
  469.         ld a,(de)
  470.         or a
  471.         jr nz,.findzeroloop
  472.         ld a,'/'
  473.         ld (de),a
  474.         inc de
  475.         call strcopy_hltode
  476.         call changetocurrentfolder
  477.         call createfileslist
  478.         xor a
  479.         ld (browserpanel.currentfileindex),a
  480.         jp drawbrowserwindow
  481.  
  482. stopplaying
  483.         ld a,(isplaying)
  484.         or a
  485.         ret z
  486.         call musicunload
  487.         ld hl,mainmsgtable
  488.         ld (currentmsgtable),hl
  489.         xor a
  490.         ld (isplaying),a
  491.         jp drawui
  492.  
  493. setnextfileindex
  494. ;ix = current panel
  495. ;out: cf=0 if at the end of file list, c1=1 otherwise
  496.         ld a,(ix+PANEL.currentfileindex)
  497.         inc a
  498.         cp (ix+PANEL.filecount)
  499.         ret nc
  500.         ld (ix+PANEL.currentfileindex),a
  501.         sub FILE_LINE_COUNT-1
  502.         ret c
  503.         cp (ix+PANEL.firstfiletoshow)
  504.         ret c
  505.         ld (ix+PANEL.firstfiletoshow),a
  506.         scf
  507.         ret
  508.  
  509. golastfile
  510.         ld ix,(currentpaneladdr)
  511.         call setnextfileindex
  512.         jr c,$-3
  513.         jp drawcurrentpanelfilelist
  514.  
  515. gopagedown     
  516.         ld ix,(currentpaneladdr)
  517.         ld b,FILE_LINE_COUNT
  518.         call setnextfileindex
  519.         djnz $-3
  520.         jp drawcurrentpanelfilelist
  521.  
  522. gonextfile
  523.         ld ix,(currentpaneladdr)
  524.         call setnextfileindex
  525.         ret nc
  526.         jp drawcurrentpanelfilelist
  527.  
  528. setprevfileindex
  529. ;ix = current panel
  530.         ld a,(ix+PANEL.currentfileindex)
  531.         or a
  532.         ret z
  533.         dec a
  534.         ld (ix+PANEL.currentfileindex),a
  535.         cp (ix+PANEL.firstfiletoshow)
  536.         ret nc
  537.         ld (ix+PANEL.firstfiletoshow),a
  538.         ret
  539.  
  540. goprevfile
  541.         ld ix,(currentpaneladdr)
  542.         call setprevfileindex
  543.         jp drawcurrentpanelfilelist
  544.  
  545. gopageup
  546.         ld ix,(currentpaneladdr)
  547.         ld b,FILE_LINE_COUNT
  548.         call setprevfileindex
  549.         djnz $-3
  550.         jp drawcurrentpanelfilelist
  551.  
  552. loadplaylist
  553. ;de = filename
  554.         call markplaylistdirty
  555.         call openstream_file
  556.         or a
  557.         jr nz,initemptyplaylist
  558.         ld de,playlistdatastart
  559.         ld hl,playlistdatasize
  560.         call readstream_file
  561.         call closestream_file
  562.         ld de,PLAYLIST_VERSION
  563.         ld hl,(playlistpanelversion)
  564.         sub hl,de
  565.         ret z
  566. initemptyplaylist
  567.         ld hl,PLAYLIST_VERSION
  568.         ld (playlistpanelversion),hl
  569.         ld ix,playlistpanel
  570.         jr clearpanel
  571.  
  572. clearpanel
  573. ;ix = panel
  574.         xor a
  575.         ld (ix+PANEL.filecount),a
  576.         ld (ix+PANEL.currentfileindex),a
  577.         ld (ix+PANEL.firstfiletoshow),a
  578.         ret
  579.  
  580. changetocurrentfolder
  581. ;out: zf=1 if succeeded, zf=0 otherwise
  582.         ld hl,(currentfolder+2)
  583.         push hl
  584.         ld a,l
  585.         or a
  586.         jr nz,$+8
  587.         ld hl,'/'
  588.         ld (currentfolder+2),hl
  589.         ld de,currentfolder
  590.         OS_CHDIR
  591.         pop hl
  592.         ld (currentfolder+2),hl
  593.         or a
  594.         ret
  595.  
  596. setcurrentfolder
  597. ;out: hl = file name only
  598.         push hl
  599.         ld c,'/'
  600.         call findlastchar ;out: de = after last slash or start
  601.         pop bc
  602.         ld hl,de
  603.         sub hl,bc
  604.         ex hl,de
  605.         ret z
  606. ;copy file path
  607.         ld hl,bc
  608.         ld bc,de
  609.         ld de,currentfolder
  610.         ldir
  611.         dec de
  612.         xor a
  613.         ld (de),a
  614.         ret
  615.  
  616. findfile
  617. ;de = file name
  618. ;out: a = file index, cf=1 if file was found
  619.         ld a,(browserpanel.filecount)
  620.         or a
  621.         ret z
  622.         ld b,a
  623.         ld c,0
  624.         ld hl,browserpanel.fileslist+FILE_NAME_OFFSET
  625. .searchloop
  626.         push bc
  627.         push de
  628.         push hl
  629.         call stricmp
  630.         pop hl
  631.         ld de,FILE_DATA_SIZE
  632.         add hl,de
  633.         pop de
  634.         pop bc
  635.         scf
  636.         ld a,c
  637.         ret z
  638.         inc c
  639.         djnz .searchloop
  640.         xor a
  641.         ret
  642.  
  643. stricmp
  644. ;hl = string1 addr
  645. ;de = string2 addr
  646. ;out: zf=1 if equal
  647.         ld a,(hl)
  648.         call tolower
  649.         ld c,a
  650.         ld a,(de)
  651.         call tolower
  652.         ld b,a
  653.         or c
  654.         ret z
  655.         ld a,b
  656.         cp c
  657.         ret nz
  658.         cp 1
  659.         ret c
  660.         inc hl
  661.         inc de
  662.         jr stricmp
  663.  
  664. getmusicprogress
  665. ;out: zf=0 and a=progress if progress is available, zf=1 and a=255 otherwise
  666.         ld hl,(MUSICPROGRESSADDR)
  667.         ld a,l
  668.         or h
  669.         ld a,255
  670.         ret z
  671.         ld a,(hl)
  672.         ret
  673.  
  674. drawplayerwindow
  675.         ld de,PANELCOLOR
  676.         OS_SETCOLOR
  677.         call getmusicprogress
  678.         push af
  679.         ld (musicprogress),a
  680.         ld de,8*256+6
  681.         ld bc,66*256+4
  682.         ld a,8
  683.         jr nz,$+10
  684.         ld de,8*256+12
  685.         ld bc,54*256+3
  686.         ld a,14
  687.         ld (playerwindowtitlepos),a
  688.         ld (songtitlepos),a
  689.         call drawwindow
  690.         ld de,CURSORCOLOR
  691.         OS_SETCOLOR
  692. playerwindowtitlepos=$+1
  693.         ld de,8*256+0
  694.         OS_SETXY
  695.         ld hl,playingstr
  696.         call print_hl
  697.         call drawsongtitle
  698.         pop af
  699.         ret z
  700.         ld a,(isplaying)
  701.         or a
  702.         jp nz,drawprogress
  703.         ld de,PANELDIRCOLOR
  704.         OS_SETCOLOR
  705.         ld de,11*256+36
  706.         OS_SETXY
  707.         ld hl,loadingstr
  708.         jp print_hl
  709.  
  710. drawsongtitle
  711.         ld de,PANELDIRCOLOR
  712.         OS_SETCOLOR
  713. songtitlepos=$+1
  714.         ld de,10*256+0
  715.         OS_SETXY
  716.         ld hl,(MUSICTITLEADDR)
  717.         ld a,l
  718.         or h
  719.         jp nz,print_hl
  720.         ld ix,(currentpaneladdr)
  721.         ld a,(ix+PANEL.currentfileindex)
  722.         call getfiledataoffset
  723.         ld a,ixl
  724.         add PANEL.fileslist+FILE_DISPLAY_INFO_OFFSET
  725.         ld e,a
  726.         adc a,ixh
  727.         sub e
  728.         ld d,a
  729.         add hl,de
  730.         jp print_hl
  731.  
  732. drawprogress
  733.         ld a,(musicprogress)
  734.         cp 255
  735.         ret z
  736.         ld de,11*256+8
  737.         OS_SETXY
  738.         ld a,(musicprogress)
  739.         ld c,a
  740.         or a
  741.         jr z,.drawremaining
  742.         ld b,a
  743. .drawdoneloop
  744.         push bc
  745.         ld a,178
  746.         PRCHAR
  747.         pop bc
  748.         djnz .drawdoneloop
  749. .drawremaining
  750.         ld a,64
  751.         sub c
  752.         ret z
  753.         ld b,a
  754. .drawremainingloop
  755.         push bc
  756.         ld a,176
  757.         PRCHAR
  758.         pop bc
  759.         djnz .drawremainingloop
  760.         ret
  761.  
  762. updateprogressbar
  763.         call getmusicprogress
  764.         ret z
  765.         ld d,a
  766.         ld hl,musicprogress
  767.         ld e,(hl)
  768.         sub e
  769.         ret z
  770.         ld (hl),d
  771.         push af
  772.         ld hl,11*256+8
  773.         ld d,0
  774.         add hl,de
  775.         ex de,hl
  776.         OS_SETXY
  777.         pop bc
  778. .drawloop
  779.         push bc
  780.         ld a,178
  781.         PRCHAR
  782.         pop bc
  783.         djnz .drawloop
  784.         ret
  785.  
  786. drawwindowline
  787. ;d = left char
  788. ;e = right char
  789. ;c = middle char
  790. ;b = middle char count
  791.         ld a,d
  792.         push de
  793.         push bc
  794.         PRCHAR
  795.         pop bc
  796. .drawloop
  797.         push bc
  798.         ld a,c
  799.         PRCHAR
  800.         pop bc
  801.         djnz .drawloop
  802.         pop de
  803.         ld a,e
  804.         PRCHAR
  805.         ret
  806.  
  807. drawwindow
  808. ;e = left coord
  809. ;d = top coord
  810. ;b = client area width
  811. ;c = client area height
  812. ;top line
  813.         push de
  814.         push bc
  815.         OS_SETXY
  816.         pop bc
  817.         push bc
  818.         ld de,0xc9bb
  819.         ld c,0xcd
  820.         call drawwindowline
  821.         pop bc
  822.         pop de
  823.         inc d
  824. ;client area
  825. .drawloop
  826.         push de
  827.         push bc
  828.         OS_SETXY
  829.         pop bc
  830.         push bc
  831.         ld de,0xbaba
  832.         ld c,0x20
  833.         call drawwindowline
  834.         pop bc
  835.         pop de
  836.         inc d
  837.         dec c
  838.         jr nz,.drawloop
  839. ;bottom line
  840.         push bc
  841.         OS_SETXY
  842.         pop bc
  843.         ld de,0xc8bc
  844.         ld c,0xcd
  845.         jp drawwindowline
  846.  
  847. getfiledataoffset
  848. ;a = index
  849. ;out: hl = index * FILE_DATA_SIZE
  850.         ld l,a
  851.         ld h,0
  852.         ld de,hl
  853.         add hl,hl
  854.         add hl,hl
  855.         ex de,hl
  856.         add hl,de
  857.         ex de,hl
  858.         add hl,hl
  859.         add hl,de
  860.         add hl,hl
  861.         add hl,hl
  862.         ret
  863.  
  864. getfileinfocolor
  865. ;c = file index
  866. ;hl = file data address
  867. currentfileindex=$+1
  868.         ld a,0
  869.         cp c
  870.         ld de,CURSORCOLOR
  871.         ret z
  872.         ld a,(ix+FILE_ATTRIB_OFFSET-FILE_DISPLAY_INFO_OFFSET)
  873.         cp FILE_ATTRIB_MUSIC
  874.         ld de,PANELFILECOLOR
  875.         ret z
  876.         cp FILE_ATTRIB_DRIVE
  877.         ld de,PANELDRIVECOLOR
  878.         ret z
  879. ;FILE_ATTRIB_PARENT_DIR or FILE_ATTRIB_FOLDER
  880.         ld de,PANELDIRCOLOR
  881.         ret
  882.  
  883. printfilesinfos
  884. ;ix = struct PANEL
  885. ;e = left coord
  886. ;d = top coord
  887. ;b = line count
  888. ;c = first file index
  889.         ld a,(ix+PANEL.currentfileindex)
  890.         or (ix+PANEL.isinactive)
  891.         ld (currentfileindex),a
  892.         ld a,(ix+PANEL.filecount)
  893.         ld (.currentfilecount),a
  894.         push de
  895.         ld a,c
  896.         call getfiledataoffset
  897.         ld de,ix
  898.         add hl,de
  899.         ld de,FILE_DISPLAY_INFO_OFFSET+PANEL.fileslist
  900.         add hl,de
  901.         pop de
  902. .filesloop
  903.         ld a,c
  904. .currentfilecount=$+1
  905.         cp 0
  906.         ret nc
  907.         push de
  908.         push hl
  909.         push bc
  910.         OS_SETXY
  911.         pop bc
  912.         pop ix
  913.         push bc
  914.         push ix
  915.         call getfileinfocolor
  916.         OS_SETCOLOR
  917.         pop hl
  918.         pop bc
  919.         push bc
  920.         ld b,FILE_DISPLAY_INFO_SIZE
  921. .printdisplaystringloop
  922.         push bc
  923.         push hl
  924.         ld a,(hl)
  925.         or a
  926.         jr nz,$+4
  927.         ld a,' '
  928.         PRCHAR
  929.         pop hl
  930.         pop bc
  931.         inc hl
  932.         djnz .printdisplaystringloop
  933.         ld de,FILE_DATA_SIZE-FILE_DISPLAY_INFO_SIZE
  934.         add hl,de
  935.         pop bc
  936.         pop de
  937.         inc c
  938.         inc d
  939.         djnz .filesloop
  940.         ret
  941.  
  942. getbrowserpanelparams
  943.         ld ix,browserpanel
  944.         ld de,256+1+FILES_WINDOW_X
  945.         ret
  946.  
  947. drawbrowserfileslist
  948.         call getbrowserpanelparams
  949.         ld b,FILE_LINE_COUNT
  950.         ld c,(ix+PANEL.firstfiletoshow)
  951.         jp printfilesinfos
  952.  
  953. getplaylistpanelparams
  954.         ld ix,playlistpanel
  955.         ld de,256+FILE_DISPLAY_INFO_SIZE+3+FILES_WINDOW_X
  956.         ret
  957.  
  958. drawplaylistfileslist
  959.         call getplaylistpanelparams
  960.         ld b,FILE_LINE_COUNT
  961.         ld c,(ix+PANEL.firstfiletoshow)
  962.         jp printfilesinfos
  963.  
  964. drawcurrentpanelfilelist
  965. currentpaneladdr=$+2
  966.         ld ix,0
  967. currentpanelpos=$+1
  968.         ld de,0
  969.         ld b,FILE_LINE_COUNT
  970.         ld c,(ix+PANEL.firstfiletoshow)
  971.         jp printfilesinfos
  972.  
  973. drawbrowserwindow
  974.         ld de,PANELCOLOR
  975.         OS_SETCOLOR
  976.         ld de,FILES_WINDOW_X
  977.         ld bc,FILE_DISPLAY_INFO_SIZE*256+FILE_LINE_COUNT
  978.         call drawwindow
  979.         ld de,CURSORCOLOR
  980.         OS_SETCOLOR
  981.         ld de,FILES_WINDOW_X+2
  982.         OS_SETXY
  983.         ld hl,currentfolder
  984.         call print_hl
  985.         jp drawbrowserfileslist
  986.  
  987. drawplaylistwindow
  988.         ld de,PANELCOLOR
  989.         OS_SETCOLOR
  990.         ld de,FILES_WINDOW_X+FILE_DISPLAY_INFO_SIZE+2
  991.         ld bc,FILE_DISPLAY_INFO_SIZE*256+FILE_LINE_COUNT
  992.         call drawwindow
  993.         ld de,CURSORCOLOR
  994.         OS_SETCOLOR
  995.         ld de,FILES_WINDOW_X+FILE_DISPLAY_INFO_SIZE+4
  996.         OS_SETXY
  997.         ld hl,playliststr
  998.         call print_hl
  999.         jr drawplaylistfileslist
  1000.  
  1001. redraw
  1002.         ld e,7
  1003.         OS_CLS
  1004. drawui
  1005.         call drawbrowserwindow
  1006.         call drawplaylistwindow
  1007.         ld de,0x7
  1008.         OS_SETCOLOR
  1009.         ld de,24*256+3
  1010.         OS_SETXY
  1011.         ld hl,hotkeystr
  1012.         call print_hl
  1013.         ld a,(isplaying)
  1014.         or a
  1015.         ret z
  1016.         jp drawplayerwindow
  1017.  
  1018. skipword_hl
  1019.         ld a,(hl)
  1020.         or a
  1021.         ret z
  1022.         cp ' '
  1023.         ret z
  1024.         inc hl
  1025.         jr skipword_hl
  1026.  
  1027. skipspaces_hl
  1028.         ld a,(hl)
  1029.         cp ' '
  1030.         ret nz
  1031.         inc hl
  1032.         jr skipspaces_hl
  1033.  
  1034. print_hl
  1035.         ld a,(hl)
  1036.         or a
  1037.         ret z
  1038.         push hl
  1039.         PRCHAR
  1040.         pop hl
  1041.         inc hl
  1042.         jp print_hl
  1043.  
  1044. strcopy_hltode
  1045.         ld a,(hl)
  1046.         ld (de),a
  1047.         or a
  1048.         ret z
  1049.         inc hl
  1050.         inc de
  1051.         jr strcopy_hltode
  1052.  
  1053. ;c = character
  1054. ;hl = poi to filename in string
  1055. ;out: de = after last char or start
  1056. findlastchar
  1057.         ld d,h
  1058.         ld e,l ;de = after last char
  1059. findlastchar0
  1060.         ld a,(hl)
  1061.         inc hl
  1062.         or a
  1063.         ret z
  1064.         cp c
  1065.         jr nz,findlastchar0
  1066.         jr findlastchar
  1067.  
  1068. tolower
  1069.         cp 'A'
  1070.         ret c
  1071.         cp 'Z'+1
  1072.         ret nc
  1073.         add 32
  1074.         ret
  1075.  
  1076. pressanykeystr
  1077.         db "\r\nPress any key to continue...\r\n",0
  1078. playersfilename
  1079.         db "gp/gp.plr",0
  1080. settingsfilename
  1081.         db "gp/gp.ini",0
  1082. defaultplaylistfilename
  1083.         db "gp/"
  1084. playlistfilename
  1085.         db "playlist.gpl",0
  1086. invalidplayerfilestr
  1087.         db "Corrupted gp/gp.plr file!",0
  1088. noplayersloadedstr
  1089.         db "Unable to load any players!",0
  1090. playersloaderrorstr
  1091.         db "Failed to load gp/gp.plr from OS folder!",0
  1092. chdirfailedstr
  1093.         db "Unable to change directory!",0
  1094. playliststr
  1095.         db "Playlist",0
  1096. playingstr
  1097.         db "Playing...",0
  1098. closingplayerstr
  1099.         db "Closing old player instance...\r\n",0
  1100. emptystr
  1101.         db 0
  1102. initializing1str
  1103.         db "Initializing ",0
  1104. initializing2str
  1105.         db "...",0
  1106. detectingmoonsoundstr
  1107.         db "Detecting MoonSound...",0
  1108. detectingtfmstr
  1109.         db "Detecting TurboSound FM...",0
  1110. notfoundstr
  1111.         db "no device!\r\n",0
  1112. foundstr
  1113.         db "found!\r\n",0
  1114. rom001200
  1115.         db "Copyright"
  1116. loadingstr
  1117.         db "LOADING...",0
  1118. firmwareerrorstr
  1119.         db "firmware problem!\r\nPlease update ZXM-MoonSound firmware to revision 1.01\r\n"
  1120.         db "https://www.dropbox.com/s/1e0b2197emrhzos/zxm_moonsound01_frm0101.zip",0
  1121. hotkeystr
  1122.         db "Arrows=Navigate  Enter=Play  Tab=Panel  Space=Add/Remove  S=Save Playlist",0
  1123. drivedata
  1124.         db "E: - IDE Master p.1                   E:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1125.         db "F: - IDE Master p.2                   F:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1126.         db "M: - SD Z-controller                  M:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1127.         db "O: - USB ZX-NetUsb                    O:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1128. drivedataend
  1129.  
  1130. loadplayer
  1131. ;de = code size
  1132. ;hl = settings variable addr
  1133.         ld (.codesize),de
  1134.         ld a,h
  1135.         or l
  1136.         ld a,'1' ;default for Use<Player> variable is 1
  1137.         jr z,$+3
  1138.         ld a,(hl)
  1139.         ld (.settingsvalue),a
  1140.         OS_NEWPAGE
  1141.         or a
  1142.         ret nz
  1143.         ld a,e
  1144.         ld (.playerpage),a
  1145.         SETPG4000
  1146.         ld de,0x4000
  1147. .codesize=$+1
  1148.         ld hl,0
  1149.         call readstream_file
  1150. .settingsvalue=$+1
  1151.         ld a,0
  1152.         cp '0'
  1153.         jr z,.cleanup
  1154.         ld hl,initializing1str
  1155.         call print_hl
  1156.         ld hl,(PLAYERNAMESTRADDR)
  1157.         call print_hl
  1158.         ld hl,initializing2str
  1159.         call print_hl
  1160.         ld hl,gpsettings
  1161.         ld ix,gpsettings
  1162.         ld a,(.playerpage)
  1163.         call playerinit
  1164.         push af
  1165.         call print_hl
  1166.         pop af
  1167.         jr nz,.cleanup
  1168.         ld hl,playercount
  1169.         ld e,(hl)
  1170.         inc (hl)
  1171.         ld d,0
  1172.         ld hl,playerpages
  1173.         add hl,de
  1174. .playerpage=$+1
  1175.         ld (hl),0
  1176.         ret
  1177. .cleanup
  1178.         ld a,(.playerpage)
  1179.         ld e,a
  1180.         OS_DELPAGE
  1181.         ret
  1182.  
  1183. loadplayers
  1184. ;output: zf=1 if success, zf=0 and hl=error message if failed
  1185.         ld de,playersfilename
  1186.         call openstream_file
  1187.         or a
  1188.         ld hl,playersloaderrorstr
  1189.         ret nz
  1190. ;check if the file matches this build
  1191.         ld a,(filehandle)
  1192.         ld b,a
  1193.         OS_GETFILESIZE
  1194.         ld de,plrend-plrbegin
  1195.         sub hl,de
  1196.         ld hl,invalidplayerfilestr
  1197.         ret nz
  1198. ;load players from file
  1199.         xor a
  1200.         ld (playercount),a
  1201.         ld de,modend-modstart : ld hl,(gpsettings.usemoonmod) : call loadplayer
  1202.         ld de,mwmend-mwmstart : ld hl,(gpsettings.usemwm) : call loadplayer
  1203.         ld de,mp3end-mp3start : ld hl,(gpsettings.usemp3) : call loadplayer
  1204.         ld de,pt3end-pt3start : ld hl,(gpsettings.usept3) : call loadplayer
  1205.         ld de,vgmend-vgmstart : ld hl,(gpsettings.usevgm) : call loadplayer
  1206.         call closestream_file
  1207.         ld a,(playercount)
  1208.         dec a
  1209.         ld hl,noplayersloadedstr
  1210.         ret m
  1211.         xor a
  1212.         ret
  1213.  
  1214. detectmoonsound
  1215.         ld hl,detectingmoonsoundstr
  1216.         call print_hl
  1217.         call ismoonsoundpresent
  1218.         ld hl,notfoundstr
  1219.         jp nz,print_hl
  1220.         call opl4init
  1221.         ld bc,9
  1222.         ld d,0
  1223.         ld hl,0x1200
  1224.         ld ix,browserpanel
  1225.         call opl4readmemory
  1226.         ld b,9
  1227.         ld de,rom001200
  1228.         ld hl,gpsettings.moonsoundstatus
  1229. .cmploop
  1230.         ld a,(de)
  1231.         cp (ix)
  1232.         jr nz,.waveportsfailed
  1233.         inc de
  1234.         inc ix
  1235.         djnz .cmploop
  1236.         ld (hl),2
  1237.         ld hl,foundstr
  1238.         jp print_hl
  1239. .waveportsfailed
  1240.         ld (hl),1
  1241.         ld hl,firmwareerrorstr
  1242.         call print_hl
  1243.         ld hl,pressanykeystr
  1244.         call print_hl
  1245.         YIELDGETKEYLOOP
  1246.         ret
  1247.  
  1248. detecttfm
  1249.         ld hl,detectingtfmstr
  1250.         call print_hl
  1251.         call istfmpresent
  1252.         ld hl,notfoundstr
  1253.         jp nz,print_hl
  1254.         ld a,1
  1255.         ld (gpsettings.tfmstatus),a
  1256.         ld hl,foundstr
  1257.         jp print_hl
  1258.  
  1259. loadsettings
  1260.         ld de,settingsfilename
  1261.         call openstream_file
  1262.         or a
  1263.         ret nz
  1264.         ld de,browserpanel
  1265.         ld hl,0x4000
  1266.         call readstream_file
  1267.         ld de,browserpanel
  1268.         add hl,de
  1269.         ld (hl),0
  1270.         call closestream_file
  1271.         ld de,browserpanel
  1272. .parseloop
  1273.         ld bc,'='*256
  1274.         call findnextchar
  1275.         or a
  1276.         ret z
  1277.         cp b
  1278.         jr nz,.parseloop
  1279.         ld b,settingsvarcount
  1280.         ld hl,settingsvars
  1281. .varsearchloop
  1282.         ld a,(hl)
  1283.         inc hl
  1284.         cp c
  1285.         jr z,.foundvar
  1286.         inc hl
  1287.         inc hl
  1288.         djnz .varsearchloop
  1289.         jr .nextvar
  1290. .foundvar
  1291.         ld a,(hl)
  1292.         inc hl
  1293.         ld h,(hl)
  1294.         ld l,a
  1295.         ld (hl),e
  1296.         inc hl
  1297.         ld (hl),d
  1298. .nextvar
  1299.         ld b,0
  1300.         call findnextchar
  1301.         or a
  1302.         jr nz,.parseloop
  1303.         ret
  1304.  
  1305. findnextchar
  1306. ;de = ptr
  1307. ;b = character to search
  1308. ;c = LRC
  1309. ;output: de = ptr past character, c = updated LRC
  1310.         ld a,(de)
  1311.         inc de
  1312.         or a
  1313.         ret z
  1314.         cp "\n"
  1315.         ret z
  1316.         cp b
  1317.         ret z
  1318.         xor c
  1319.         ld c,a
  1320.         jr findnextchar
  1321.  
  1322. gpsettings GPSETTINGS
  1323.  
  1324. settingsvars
  1325.         db 0x19 : dw gpsettings.usemp3
  1326.         db 0x14 : dw gpsettings.usemwm
  1327.         db 0x74 : dw gpsettings.usept3
  1328.         db 0x1F : dw gpsettings.usevgm
  1329.         db 0x26 : dw gpsettings.usemoonmod
  1330.         db 0x7F : dw gpsettings.moonmoddefaultpanning
  1331.         db 0x7A : dw gpsettings.midiuartdelayoverride
  1332. settingsvarcount=($-settingsvars)/3
  1333.  
  1334. getfileextension
  1335. ;hl = file name
  1336. ;out: cde = file extension
  1337.         ld c,'.'
  1338.         call findlastchar ;out: de = after last dot or start
  1339.         ex de,hl
  1340.         ld a,(hl)
  1341.         call tolower
  1342.         ld c,a
  1343.         inc hl
  1344.         ld a,(hl)
  1345.         call tolower
  1346.         ld d,a
  1347.         inc hl
  1348.         ld a,(hl)
  1349.         call tolower
  1350.         ld e,a
  1351.         ret
  1352.  
  1353. isfileplaylist
  1354. ;cde = file extension
  1355. ;out: zf=1 if playlist, zf=0 otherwise
  1356.         ld a,c
  1357.         cp 'g'
  1358.         ret nz
  1359.         ld a,d
  1360.         cp 'p'
  1361.         ret nz
  1362.         ld a,e
  1363.         cp 'l'
  1364.         ret
  1365.  
  1366. findsupportedplayer
  1367. ;cde = file extension
  1368.         ld hl,playerpages
  1369.         ld a,(playercount)
  1370.         ld b,a
  1371. .findplayerloop
  1372.         push hl
  1373.         push bc
  1374.         ld a,(hl)
  1375.         SETPG4000
  1376.         pop bc
  1377.         call isfilesupported
  1378.         pop hl
  1379.         ret z
  1380.         inc hl
  1381.         djnz .findplayerloop
  1382.         dec b ;set zf=0
  1383.         ret
  1384.  
  1385. createfileslist
  1386.         ld de,emptystr
  1387.         OS_OPENDIR
  1388.  
  1389.         ld a,(gpsettings.sharedpages)
  1390.         SETPG8000
  1391.         ld a,(gpsettings.sharedpages+1)
  1392.         SETPGC000
  1393.  
  1394.         xor a
  1395.         ld (browserpanel.currentfileindex),a
  1396.         ld (browserpanel.firstfiletoshow),a
  1397.  
  1398.         ld hl,currentfolder+2
  1399.         cp (hl)
  1400.         ld hl,0x8000
  1401.         jr nz,.startloop
  1402.         ex de,hl
  1403.         ld hl,drivedata
  1404.         ld bc,drivedataend-drivedata
  1405.         ldir
  1406.         ex de,hl
  1407.         ld a,(drivedataend-drivedata)/FILE_DATA_SIZE
  1408. .startloop
  1409.         ld (browserpanel.filecount),a
  1410. .fileenumloop
  1411.         ld (.filedataaddr),hl
  1412. .skiptonextfile
  1413.         ld de,filinfo
  1414.         OS_READDIR
  1415.         or a
  1416.         jp nz,.sortfiles
  1417. ;skip '.' folder
  1418.         ld hl,(filinfo+FILINFO_FNAME)
  1419.         ld a,l
  1420.         xor '.'
  1421.         or h
  1422.         jr z,.skiptonextfile
  1423. ;skip findsupportedplayer for folders
  1424.         ld a,(filinfo+FILINFO_FATTRIB)
  1425.         and FATTRIB_DIR
  1426.         jr nz,.foundfileordir
  1427.         ld hl,filinfo+FILINFO_FNAME
  1428.         call getfileextension
  1429.         call isfileplaylist
  1430.         jr z,.foundfileordir
  1431.         call findsupportedplayer
  1432.         jr nz,.skiptonextfile
  1433. ;we've got either a playable file or a folder
  1434. .foundfileordir
  1435. .filedataaddr=$+1
  1436.         ld de,0
  1437.         ld hl,FILE_NAME_OFFSET
  1438.         add hl,de
  1439.         ex de,hl
  1440.         ld hl,filinfo+FILINFO_FNAME
  1441.         ld bc,9*256+SFN_SIZE
  1442. .copysfnloop
  1443.         ld a,(hl)
  1444.         cp '.'
  1445.         jr z,.foundsfnext
  1446.         or a
  1447.         jr z,.sfntailloop
  1448.         call tolower
  1449.         ld (de),a
  1450.         inc hl
  1451.         inc de
  1452.         dec c
  1453.         dec b
  1454.         jr .copysfnloop
  1455. ;this is a folder, pad it to SFN_SIZE with zeros
  1456. .sfntailloop
  1457.         ld (de),a
  1458.         inc de
  1459.         dec c
  1460.         jr nz,.sfntailloop
  1461.         jr .donesfncopy
  1462. ;format SFN as 8.3 fixed-position array padding with '*' if necessary
  1463. ;this is needed for sorting
  1464. .foundsfnext
  1465.         ld a,'*'
  1466. .sfntailloop1
  1467.         ld (de),a
  1468.         inc de
  1469.         djnz .sfntailloop1
  1470.         dec de
  1471. ;copy dot, extension, zero terminator
  1472.         ld b,5
  1473. .sfntailloop2
  1474.         ld a,(hl)
  1475.         call tolower
  1476.         ld (de),a
  1477.         inc hl
  1478.         inc de
  1479.         djnz .sfntailloop2
  1480. .donesfncopy
  1481. ;fill display name
  1482.         ld hl,FILE_DISPLAY_INFO_OFFSET-FILE_NAME_OFFSET-SFN_SIZE
  1483.         add hl,de
  1484.         ex de,hl
  1485.         ld hl,filinfo+FILINFO_LNAME
  1486.         ld a,(hl)
  1487.         or a
  1488.         jr nz,$+5
  1489.         ld hl,filinfo+FILINFO_FNAME
  1490.         ld bc,(FILE_DISPLAY_INFO_SIZE-1)*256+255
  1491. .copylfnloop
  1492.         ldi
  1493.         dec b
  1494.         jr z,.lfncopydone
  1495.         ld a,(hl)
  1496.         or a
  1497.         jr nz,.copylfnloop
  1498. .filltailloop
  1499.         ld (de),a
  1500.         inc de
  1501.         djnz .filltailloop
  1502. .lfncopydone
  1503.         xor a
  1504.         ld (de),a
  1505. ;set atrribute data
  1506.         call getfileattrib
  1507.         ld hl,FILE_ATTRIB_OFFSET-FILE_DISPLAY_INFO_OFFSET-FILE_DISPLAY_INFO_SIZE+1
  1508.         add hl,de
  1509.         ld (hl),a
  1510.         ld de,FILE_DATA_SIZE-FILE_ATTRIB_OFFSET
  1511.         add hl,de
  1512. ;check if we have space for more files
  1513.         ld a,(browserpanel.filecount)
  1514.         inc a
  1515.         ld (browserpanel.filecount),a
  1516.         cp BROWSER_FILE_COUNT
  1517.         jp c,.fileenumloop
  1518. .sortfiles
  1519.         ld a,(browserpanel.filecount)
  1520.         or a
  1521.         ret z
  1522.         ld c,a
  1523.         ld b,0
  1524.         ld a,12
  1525.         ld ix,fileextsortkeyoffsets
  1526.         ld hl,0x8000
  1527.         ld de,FILE_DATA_SIZE
  1528.         ld iy,browserpanel.fileslist
  1529.         call radixsort
  1530. ;remove '*' padding restoring SFN to original null-terminated string form
  1531.         ld a,(browserpanel.filecount)
  1532.         ld b,a
  1533.         ld hl,browserpanel.fileslist+FILE_NAME_OFFSET
  1534. .removepaddingnextfile
  1535.         ld de,hl
  1536.         push hl
  1537. .removepaddingloop
  1538.         ld a,(hl)
  1539.         inc hl
  1540.         cp '*'
  1541.         jr z,.removepaddingloop
  1542.         ld (de),a
  1543.         inc de
  1544.         or a
  1545.         jr nz,.removepaddingloop
  1546.         pop hl
  1547.         ld de,FILE_DATA_SIZE
  1548.         add hl,de
  1549.         djnz .removepaddingnextfile
  1550.         ret
  1551.  
  1552. getfileattrib
  1553. ;out: a = attribute value
  1554.         ld a,(filinfo+FILINFO_FATTRIB)
  1555.         and FATTRIB_DIR
  1556.         ld a,FILE_ATTRIB_MUSIC
  1557.         ret z
  1558.         ld hl,(filinfo+FILINFO_FNAME)
  1559.         ld bc,'..'
  1560.         sub hl,bc
  1561.         ld a,FILE_ATTRIB_PARENT_DIR
  1562.         ret z
  1563.         ld a,FILE_ATTRIB_FOLDER
  1564.         ret
  1565.  
  1566. fileextsortkeyoffsets
  1567.         dw FILE_NAME_OFFSET+7, FILE_NAME_OFFSET+6, FILE_NAME_OFFSET+5
  1568.         dw FILE_NAME_OFFSET+4, FILE_NAME_OFFSET+3, FILE_NAME_OFFSET+2
  1569.         dw FILE_NAME_OFFSET+1, FILE_NAME_OFFSET+0
  1570.         dw FILE_NAME_OFFSET+11, FILE_NAME_OFFSET+10, FILE_NAME_OFFSET+9
  1571.         dw FILE_ATTRIB_OFFSET
  1572.  
  1573.         macro jumpindirect addr
  1574.         push hl
  1575.         ld hl,(addr)
  1576.         ex (sp),hl
  1577.         ret
  1578.         endm
  1579.  
  1580. playerinit      jumpindirect PLAYERINITPROCADDR
  1581. playerdeinit    jumpindirect PLAYERDEINITPROCADDR
  1582. musicload       jumpindirect MUSICLOADPROCADDR
  1583. musicunload     jumpindirect MUSICUNLOADPROCADDR
  1584. musicplay       jumpindirect MUSICPLAYPROCADDR
  1585. isfilesupported jumpindirect ISFILESUPPORTEDPROCADDR
  1586.  
  1587.         include "../_sdk/file.asm"
  1588.         include "common/radixsort.asm"
  1589.         include "common/opl4.asm"
  1590.         include "common/opn.asm"
  1591.  
  1592. trywritingmoonsoundfm1
  1593.         djnz $
  1594.         ld a,e
  1595.         out (MOON_REG1),a
  1596.         djnz $
  1597.         ld a,d
  1598.         out (MOON_DAT1),a
  1599.         ret
  1600.  
  1601. ismoonsoundpresent
  1602. ;out: zf=1 if Moonsound is present, zf=0 if not
  1603.         switch_to_pcm_ports_c2_c3
  1604. ;check for 255 as an early exit condition
  1605.         in a,(MOON_STAT)
  1606.         add a,1
  1607.         sbc a,a
  1608.         ret nz
  1609. ;read the status second time, now expect all bits clear
  1610.         in a,(MOON_STAT)
  1611.         or a
  1612.         ret nz
  1613. ;start timer
  1614.         ld de,0xff03
  1615.         call trywritingmoonsoundfm1
  1616.         ld de,0x4204
  1617.         call trywritingmoonsoundfm1
  1618.         ld d,0x80
  1619.         call trywritingmoonsoundfm1
  1620. ;wait for the timer to finish
  1621.         YIELD
  1622.         YIELD
  1623. ;check the timer flags
  1624.         in a,(MOON_STAT)
  1625.         cp 0xa0
  1626.         ret nz
  1627. ;there must be MoonSound in this system
  1628.         call opl4mute
  1629.         xor a
  1630.         ret
  1631.  
  1632. trywritingtfm1
  1633.         dec a
  1634.         jr nz,$-1
  1635.         ld bc,OPN_REG
  1636.         out (c),e
  1637.         dec a
  1638.         jr nz,$-1
  1639.         ld bc,OPN_DAT
  1640.         out (c),d
  1641.         ret
  1642.  
  1643. istfmpresent
  1644. ;check for non-zero as an early exit condition
  1645.         ld bc,OPN_REG
  1646.         ld a,%11111100
  1647.         out (c),a
  1648.         in a,(c)
  1649.         or a
  1650.         ret nz
  1651. ;start timer
  1652.         ld de,0xff26
  1653.         call trywritingtfm1
  1654.         ld de,0x2a27
  1655.         call trywritingtfm1
  1656. ;wait for the timer to finish
  1657.         YIELD
  1658.         YIELD
  1659. ;check the timer flags
  1660.         ld bc,OPN_REG
  1661.         in a,(c)
  1662.         cp 2
  1663.         ret nz
  1664. ;there must be TFM in this system
  1665.         call opnmute
  1666.         xor a
  1667.         ret
  1668.  
  1669. closeexistingplayer
  1670. ;d = current pid
  1671.         ld e,1
  1672. .searchloop
  1673.         ld a,e
  1674.         cp d
  1675.         jr z,.nextprocess
  1676.         push de
  1677.         OS_GETAPPMAINPAGES ;d,e,h,l=pages in 0000,4000,8000,c000
  1678.         or a
  1679.         ld a,d
  1680.         pop de
  1681.         jr nz,.nextprocess
  1682.         push de
  1683.         SETPGC000
  1684.         ld hl,0xc000+COMMANDLINE
  1685.         ld de,0x8000
  1686.         ld bc,COMMANDLINE_sz
  1687.         ldir
  1688.         ld hl,0x8000
  1689.         call skipword_hl
  1690.         ld (hl),0
  1691.         ld hl,0x8000
  1692.         ld c,'/'
  1693.         call findlastchar ;out: de = after last slash or start
  1694.         call isplayer
  1695.         pop de
  1696.         jr z,.foundplayer
  1697. .nextprocess
  1698.         inc e
  1699.         ld a,e
  1700.         inc a
  1701.         jr nz,.searchloop
  1702.         ret
  1703. .foundplayer
  1704.         xor a
  1705.         ld (0xc000+COMMANDLINE),a
  1706.         push de
  1707.         ld hl,closingplayerstr
  1708.         call print_hl
  1709.         pop de
  1710. .waitloop
  1711.         push de
  1712.         YIELD
  1713.         YIELD
  1714.         YIELD
  1715.         YIELD
  1716.         OS_GETAPPMAINPAGES
  1717.         pop de
  1718.         or a
  1719.         jr z,.waitloop
  1720.         ret
  1721.  
  1722. isplayer
  1723. ;de = command line file name
  1724. ;out: zf=1 if gp, zf=0 otherwise
  1725.         ld a,(de)
  1726.         call tolower
  1727.         cp 'g'
  1728.         ret nz
  1729.         inc de
  1730.         ld a,(de)
  1731.         call tolower
  1732.         cp 'p'
  1733.         ret nz
  1734.         inc de
  1735.         ld a,(de)
  1736.         or a
  1737.         ret z
  1738.         cp '.'
  1739.         ret
  1740. mainend
  1741.  
  1742. playerpages
  1743.         ds NUM_PLAYERS
  1744. filinfo
  1745.         ds FILINFO_sz
  1746. currentfolder
  1747.         ds MAXPATH_sz
  1748. fullpathbuffer
  1749.         ds MAXPATH_sz
  1750.  
  1751.         struct PANEL
  1752. filecount ds 1
  1753. currentfileindex ds 1
  1754. firstfiletoshow ds 1
  1755. isinactive ds 1
  1756. fileslist ds FILE_DATA_SIZE
  1757.         ends
  1758.  
  1759. browserpanel PANEL
  1760.         ds FILE_DATA_SIZE*(BROWSER_FILE_COUNT-1)
  1761.  
  1762. playlistdatastart=$
  1763. playlistpanelversion ds 2
  1764. playlistpanel PANEL
  1765.         ds FILE_DATA_SIZE*(PLAYLIST_FILE_COUNT-1)
  1766. playlistdatasize=$-playlistdatastart
  1767.  
  1768. musicprogress ds 1
  1769. playercount ds 1
  1770. playlistchanged ds 1
  1771.  
  1772.         assert $ <= 0x3e00 ;reserve 512 bytes for stack
  1773.  
  1774.         savebin "gp.com",mainbegin,mainend-mainbegin
  1775.  
  1776.         org 0x0000
  1777.  
  1778. plrbegin
  1779. modstart
  1780.         incbin "moonmod.bin"
  1781. modend
  1782. mwmstart
  1783.         incbin "mwm.bin"
  1784. mwmend
  1785. mp3start
  1786.         incbin "mp3.bin"
  1787. mp3end
  1788. pt3start
  1789.         incbin "pt3.bin"
  1790. pt3end
  1791. vgmstart
  1792.         incbin "vgm.bin"
  1793. vgmend
  1794. plrend
  1795.  
  1796.         savebin "gp.plr",plrbegin,plrend-plrbegin
  1797.