?login_element?

Subversion Repositories NedoOS

Rev

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