Subversion Repositories NedoOS

Rev

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

  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=169
  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.         ld (musicprogress),a
  666.         ld de,8*256+6
  667.         ld bc,66*256+4
  668.         ld a,8
  669.         jr nz,$+10
  670.         ld de,8*256+12
  671.         ld bc,54*256+3
  672.         ld a,14
  673.         ld (playerwindowtitlepos),a
  674.         ld (songtitlepos),a
  675.         call drawwindow
  676.         ld de,CURSORCOLOR
  677.         OS_SETCOLOR
  678. playerwindowtitlepos=$+1
  679.         ld de,8*256+0
  680.         OS_SETXY
  681.         ld hl,playingstr
  682.         call print_hl
  683.         call drawsongtitle
  684.         ld a,(isplaying)
  685.         or a
  686.         call nz,drawprogress
  687.         ret
  688.  
  689. drawsongtitle
  690.         ld de,PANELDIRCOLOR
  691.         OS_SETCOLOR
  692. songtitlepos=$+1
  693.         ld de,10*256+0
  694.         OS_SETXY
  695.         ld hl,(MUSICTITLEADDR)
  696.         ld a,l
  697.         or h
  698.         jp nz,print_hl
  699.         ld ix,(currentpaneladdr)
  700.         ld a,(ix+PANEL.currentfileindex)
  701.         call getfiledataoffset
  702.         ld a,ixl
  703.         add PANEL.fileslist+FILE_DISPLAY_INFO_OFFSET
  704.         ld e,a
  705.         adc a,ixh
  706.         sub e
  707.         ld d,a
  708.         add hl,de
  709.         jp print_hl
  710.  
  711. drawprogress
  712.         ld a,(musicprogress)
  713.         cp 255
  714.         ret z
  715.         ld de,11*256+8
  716.         OS_SETXY
  717.         ld a,(musicprogress)
  718.         ld c,a
  719.         or a
  720.         jr z,.drawremaining
  721.         ld b,a
  722. .drawdoneloop
  723.         push bc
  724.         ld a,178
  725.         PRCHAR
  726.         pop bc
  727.         djnz .drawdoneloop
  728. .drawremaining
  729.         ld a,64
  730.         sub c
  731.         ret z
  732.         ld b,a
  733. .drawremainingloop
  734.         push bc
  735.         ld a,176
  736.         PRCHAR
  737.         pop bc
  738.         djnz .drawremainingloop
  739.         ret
  740.  
  741. updateprogressbar
  742.         call getmusicprogress
  743.         ret z
  744.         ld d,a
  745.         ld hl,musicprogress
  746.         ld e,(hl)
  747.         sub e
  748.         ret z
  749.         ld (hl),d
  750.         push af
  751.         ld hl,11*256+8
  752.         ld d,0
  753.         add hl,de
  754.         ex de,hl
  755.         OS_SETXY
  756.         pop bc
  757. .drawloop
  758.         push bc
  759.         ld a,178
  760.         PRCHAR
  761.         pop bc
  762.         djnz .drawloop
  763.         ret
  764.  
  765. drawwindowline
  766. ;d = left char
  767. ;e = right char
  768. ;c = middle char
  769. ;b = middle char count
  770.         ld a,d
  771.         push de
  772.         push bc
  773.         PRCHAR
  774.         pop bc
  775. .drawloop
  776.         push bc
  777.         ld a,c
  778.         PRCHAR
  779.         pop bc
  780.         djnz .drawloop
  781.         pop de
  782.         ld a,e
  783.         PRCHAR
  784.         ret
  785.  
  786. drawwindow
  787. ;e = left coord
  788. ;d = top coord
  789. ;b = client area width
  790. ;c = client area height
  791. ;top line
  792.         push de
  793.         push bc
  794.         OS_SETXY
  795.         pop bc
  796.         push bc
  797.         ld de,0xc9bb
  798.         ld c,0xcd
  799.         call drawwindowline
  800.         pop bc
  801.         pop de
  802.         inc d
  803. ;client area
  804. .drawloop
  805.         push de
  806.         push bc
  807.         OS_SETXY
  808.         pop bc
  809.         push bc
  810.         ld de,0xbaba
  811.         ld c,0x20
  812.         call drawwindowline
  813.         pop bc
  814.         pop de
  815.         inc d
  816.         dec c
  817.         jr nz,.drawloop
  818. ;bottom line
  819.         push bc
  820.         OS_SETXY
  821.         pop bc
  822.         ld de,0xc8bc
  823.         ld c,0xcd
  824.         jp drawwindowline
  825.  
  826. getfiledataoffset
  827. ;a = index
  828. ;out: hl = index * FILE_DATA_SIZE
  829.         ld l,a
  830.         ld h,0
  831.         ld de,hl
  832.         add hl,hl
  833.         add hl,hl
  834.         ex de,hl
  835.         add hl,de
  836.         ex de,hl
  837.         add hl,hl
  838.         add hl,de
  839.         add hl,hl
  840.         add hl,hl
  841.         ret
  842.  
  843. getfileinfocolor
  844. ;c = file index
  845. ;hl = file data address
  846. currentfileindex=$+1
  847.         ld a,0
  848.         cp c
  849.         ld de,CURSORCOLOR
  850.         ret z
  851.         ld a,(ix+FILE_ATTRIB_OFFSET-FILE_DISPLAY_INFO_OFFSET)
  852.         cp FILE_ATTRIB_MUSIC
  853.         ld de,PANELFILECOLOR
  854.         ret z
  855.         cp FILE_ATTRIB_DRIVE
  856.         ld de,PANELDRIVECOLOR
  857.         ret z
  858. ;FILE_ATTRIB_PARENT_DIR or FILE_ATTRIB_FOLDER
  859.         ld de,PANELDIRCOLOR
  860.         ret
  861.  
  862. printfilesinfos
  863. ;ix = struct PANEL
  864. ;e = left coord
  865. ;d = top coord
  866. ;b = line count
  867. ;c = first file index
  868.         ld a,(ix+PANEL.currentfileindex)
  869.         or (ix+PANEL.isinactive)
  870.         ld (currentfileindex),a
  871.         ld a,(ix+PANEL.filecount)
  872.         ld (.currentfilecount),a
  873.         push de
  874.         ld a,c
  875.         call getfiledataoffset
  876.         ld de,ix
  877.         add hl,de
  878.         ld de,FILE_DISPLAY_INFO_OFFSET+PANEL.fileslist
  879.         add hl,de
  880.         pop de
  881. .filesloop
  882.         ld a,c
  883. .currentfilecount=$+1
  884.         cp 0
  885.         ret nc
  886.         push de
  887.         push hl
  888.         push bc
  889.         OS_SETXY
  890.         pop bc
  891.         pop ix
  892.         push bc
  893.         push ix
  894.         call getfileinfocolor
  895.         OS_SETCOLOR
  896.         pop hl
  897.         pop bc
  898.         push bc
  899.         ld b,FILE_DISPLAY_INFO_SIZE
  900. .printdisplaystringloop
  901.         push bc
  902.         push hl
  903.         ld a,(hl)
  904.         or a
  905.         jr nz,$+4
  906.         ld a,' '
  907.         PRCHAR
  908.         pop hl
  909.         pop bc
  910.         inc hl
  911.         djnz .printdisplaystringloop
  912.         ld de,FILE_DATA_SIZE-FILE_DISPLAY_INFO_SIZE
  913.         add hl,de
  914.         pop bc
  915.         pop de
  916.         inc c
  917.         inc d
  918.         djnz .filesloop
  919.         ret
  920.  
  921. getbrowserpanelparams
  922.         ld ix,browserpanel
  923.         ld de,256+1+FILES_WINDOW_X
  924.         ret
  925.  
  926. drawbrowserfileslist
  927.         call getbrowserpanelparams
  928.         ld b,FILE_LINE_COUNT
  929.         ld c,(ix+PANEL.firstfiletoshow)
  930.         jp printfilesinfos
  931.  
  932. getplaylistpanelparams
  933.         ld ix,playlistpanel
  934.         ld de,256+FILE_DISPLAY_INFO_SIZE+3+FILES_WINDOW_X
  935.         ret
  936.  
  937. drawplaylistfileslist
  938.         call getplaylistpanelparams
  939.         ld b,FILE_LINE_COUNT
  940.         ld c,(ix+PANEL.firstfiletoshow)
  941.         jp printfilesinfos
  942.  
  943. drawcurrentpanelfilelist
  944. currentpaneladdr=$+2
  945.         ld ix,0
  946. currentpanelpos=$+1
  947.         ld de,0
  948.         ld b,FILE_LINE_COUNT
  949.         ld c,(ix+PANEL.firstfiletoshow)
  950.         jp printfilesinfos
  951.  
  952. drawbrowserwindow
  953.         ld de,PANELCOLOR
  954.         OS_SETCOLOR
  955.         ld de,FILES_WINDOW_X
  956.         ld bc,FILE_DISPLAY_INFO_SIZE*256+FILE_LINE_COUNT
  957.         call drawwindow
  958.         ld de,CURSORCOLOR
  959.         OS_SETCOLOR
  960.         ld de,FILES_WINDOW_X+2
  961.         OS_SETXY
  962.         ld hl,currentfolder
  963.         call print_hl
  964.         jp drawbrowserfileslist
  965.  
  966. drawplaylistwindow
  967.         ld de,PANELCOLOR
  968.         OS_SETCOLOR
  969.         ld de,FILES_WINDOW_X+FILE_DISPLAY_INFO_SIZE+2
  970.         ld bc,FILE_DISPLAY_INFO_SIZE*256+FILE_LINE_COUNT
  971.         call drawwindow
  972.         ld de,CURSORCOLOR
  973.         OS_SETCOLOR
  974.         ld de,FILES_WINDOW_X+FILE_DISPLAY_INFO_SIZE+4
  975.         OS_SETXY
  976.         ld hl,playliststr
  977.         call print_hl
  978.         jr drawplaylistfileslist
  979.  
  980. redraw
  981.         ld e,7
  982.         OS_CLS
  983. drawui
  984.         call drawbrowserwindow
  985.         call drawplaylistwindow
  986.         ld de,0x7
  987.         OS_SETCOLOR
  988.         ld de,24*256+3
  989.         OS_SETXY
  990.         ld hl,hotkeystr
  991.         call print_hl
  992.         ld a,(isplaying)
  993.         or a
  994.         ret z
  995.         jp drawplayerwindow
  996.  
  997. skipword_hl
  998.         ld a,(hl)
  999.         or a
  1000.         ret z
  1001.         cp ' '
  1002.         ret z
  1003.         inc hl
  1004.         jr skipword_hl
  1005.  
  1006. skipspaces_hl
  1007.         ld a,(hl)
  1008.         cp ' '
  1009.         ret nz
  1010.         inc hl
  1011.         jr skipspaces_hl
  1012.  
  1013. print_hl
  1014.         ld a,(hl)
  1015.         or a
  1016.         ret z
  1017.         push hl
  1018.         PRCHAR
  1019.         pop hl
  1020.         inc hl
  1021.         jp print_hl
  1022.  
  1023. strcopy_hltode
  1024.         ld a,(hl)
  1025.         ld (de),a
  1026.         or a
  1027.         ret z
  1028.         inc hl
  1029.         inc de
  1030.         jr strcopy_hltode
  1031.  
  1032. ;c = character
  1033. ;hl = poi to filename in string
  1034. ;out: de = after last char or start
  1035. findlastchar
  1036.         ld d,h
  1037.         ld e,l ;de = after last char
  1038. findlastchar0
  1039.         ld a,(hl)
  1040.         inc hl
  1041.         or a
  1042.         ret z
  1043.         cp c
  1044.         jr nz,findlastchar0
  1045.         jr findlastchar
  1046.  
  1047. tolower
  1048.         cp 'A'
  1049.         ret c
  1050.         cp 'Z'+1
  1051.         ret nc
  1052.         add 32
  1053.         ret
  1054.  
  1055. pressanykeystr
  1056.         db "\r\nPress any key to continue...\r\n",0
  1057. playersfilename
  1058.         db "gp/gp.plr",0
  1059. settingsfilename
  1060.         db "gp/gp.ini",0
  1061. defaultplaylistfilename
  1062.         db "gp/"
  1063. playlistfilename
  1064.         db "playlist.gpl",0
  1065. invalidplayerfilestr
  1066.         db "Corrupted gp/gp.plr file!",0
  1067. noplayersloadedstr
  1068.         db "Unable to load any players!",0
  1069. playersloaderrorstr
  1070.         db "Failed to load gp/gp.plr from OS folder!",0
  1071. chdirfailedstr
  1072.         db "Unable to change directory!",0
  1073. playliststr
  1074.         db "Playlist",0
  1075. playingstr
  1076.         db "Playing...",0
  1077. closingplayerstr
  1078.         db "Closing old player instance...\r\n",0
  1079. emptystr
  1080.         db 0
  1081. initializing1str
  1082.         db "Initializing ",0
  1083. initializing2str
  1084.         db "...",0
  1085. detectingmoonsoundstr
  1086.         db "Detecting MoonSound...",0
  1087. notfoundstr
  1088.         db "no device!\r\n",0
  1089. foundstr
  1090.         db "OK\r\n",0
  1091. rom001200
  1092.         db "Copyright"
  1093. firmwareerrorstr
  1094.         db "firmware problem!\r\nPlease update ZXM-MoonSound firmware to revision 1.01\r\n"
  1095.         db "https://www.dropbox.com/s/1e0b2197emrhzos/zxm_moonsound01_frm0101.zip",0
  1096. hotkeystr
  1097.         db "Arrows=Navigate  Enter=Play  Tab=Panel  Space=Add/Remove  S=Save Playlist",0
  1098. drivedata
  1099.         db "E: - IDE Master p.1                   E:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1100.         db "F: - IDE Master p.2                   F:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1101.         db "M: - SD Z-controller                  M:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1102.         db "O: - USB ZX-NetUsb                    O:",0,0,0,0,0,0,0,0,0,0,0,FILE_ATTRIB_DRIVE
  1103. drivedataend
  1104.  
  1105. loadplayer
  1106. ;de = code size
  1107. ;hl = settings variable addr
  1108.         ld (.codesize),de
  1109.         ld a,h
  1110.         or l
  1111.         ld a,'1' ;default for Use<Player> variable is 1
  1112.         jr z,$+3
  1113.         ld a,(hl)
  1114.         ld (.settingsvalue),a
  1115.         OS_NEWPAGE
  1116.         or a
  1117.         ret nz
  1118.         ld a,e
  1119.         ld (.playerpage),a
  1120.         SETPG4000
  1121.         ld de,0x4000
  1122. .codesize=$+1
  1123.         ld hl,0
  1124.         call readstream_file
  1125. .settingsvalue=$+1
  1126.         ld a,0
  1127.         cp '0'
  1128.         jr z,.cleanup
  1129.         ld hl,initializing1str
  1130.         call print_hl
  1131.         ld hl,(PLAYERNAMESTRADDR)
  1132.         call print_hl
  1133.         ld hl,initializing2str
  1134.         call print_hl
  1135.         ld hl,gpsettings
  1136.         ld a,(.playerpage)
  1137.         call playerinit
  1138.         push af
  1139.         call print_hl
  1140.         pop af
  1141.         jr nz,.cleanup
  1142.         ld hl,playercount
  1143.         ld e,(hl)
  1144.         inc (hl)
  1145.         ld d,0
  1146.         ld hl,playerpages
  1147.         add hl,de
  1148. .playerpage=$+1
  1149.         ld (hl),0
  1150.         ret
  1151. .cleanup
  1152.         ld a,(.playerpage)
  1153.         ld e,a
  1154.         OS_DELPAGE
  1155.         ret
  1156.  
  1157. loadplayers
  1158. ;output: zf=1 if success, zf=0 and hl=error message if failed
  1159.         ld de,playersfilename
  1160.         call openstream_file
  1161.         or a
  1162.         ld hl,playersloaderrorstr
  1163.         ret nz
  1164. ;check if the file matches this build
  1165.         ld a,(filehandle)
  1166.         ld b,a
  1167.         OS_GETFILESIZE
  1168.         ld de,plrend-plrbegin
  1169.         sub hl,de
  1170.         ld hl,invalidplayerfilestr
  1171.         ret nz
  1172. ;load players from file
  1173.         xor a
  1174.         ld (playercount),a
  1175.         ld de,modend-modstart : ld hl,(gpsettings.usemoonmod) : call loadplayer
  1176.         ld de,mwmend-mwmstart : ld hl,(gpsettings.usemwm) : call loadplayer
  1177.         ld de,pt3end-pt3start : ld hl,(gpsettings.usept3) : call loadplayer
  1178.         ld de,mp3end-mp3start : ld hl,(gpsettings.usemp3) : call loadplayer
  1179.         ld de,vgmend-vgmstart : ld hl,(gpsettings.usevgm) : call loadplayer
  1180.         call closestream_file
  1181.         ld a,(playercount)
  1182.         dec a
  1183.         ld hl,noplayersloadedstr
  1184.         ret m
  1185.         xor a
  1186.         ret
  1187.  
  1188. detectmoonsound
  1189.         ld hl,detectingmoonsoundstr
  1190.         call print_hl
  1191.         call ismoonsoundpresent
  1192.         ld hl,notfoundstr
  1193.         jp nz,print_hl
  1194.         call opl4init
  1195.         ld bc,9
  1196.         ld d,0
  1197.         ld hl,0x1200
  1198.         ld ix,browserpanel
  1199.         call opl4readmemory
  1200.         ld b,9
  1201.         ld de,rom001200
  1202.         ld hl,gpsettings.moonsoundstatus
  1203. .cmploop
  1204.         ld a,(de)
  1205.         cp (ix)
  1206.         jr nz,.waveportsfailed
  1207.         inc de
  1208.         inc ix
  1209.         djnz .cmploop
  1210.         ld (hl),2
  1211.         ld hl,foundstr
  1212.         jp print_hl
  1213. .waveportsfailed
  1214.         ld (hl),1
  1215.         ld hl,firmwareerrorstr
  1216.         call print_hl
  1217.         ld hl,pressanykeystr
  1218.         call print_hl
  1219.         YIELDGETKEYLOOP
  1220.         ret
  1221.  
  1222. loadsettings
  1223.         ld de,settingsfilename
  1224.         call openstream_file
  1225.         or a
  1226.         ret nz
  1227.         ld de,browserpanel
  1228.         ld hl,0x4000
  1229.         call readstream_file
  1230.         ld de,browserpanel
  1231.         add hl,de
  1232.         ld (hl),0
  1233.         call closestream_file
  1234.         ld de,browserpanel
  1235. .parseloop
  1236.         ld bc,'='*256
  1237.         call findnextchar
  1238.         or a
  1239.         ret z
  1240.         cp b
  1241.         jr nz,.parseloop
  1242.         ld b,settingsvarcount
  1243.         ld hl,settingsvars
  1244. .varsearchloop
  1245.         ld a,(hl)
  1246.         inc hl
  1247.         cp c
  1248.         jr z,.foundvar
  1249.         inc hl
  1250.         inc hl
  1251.         djnz .varsearchloop
  1252.         jr .nextvar
  1253. .foundvar
  1254.         ld a,(hl)
  1255.         inc hl
  1256.         ld h,(hl)
  1257.         ld l,a
  1258.         ld (hl),e
  1259.         inc hl
  1260.         ld (hl),d
  1261. .nextvar
  1262.         ld b,0
  1263.         call findnextchar
  1264.         or a
  1265.         jr nz,.parseloop
  1266.         ret
  1267.  
  1268. findnextchar
  1269. ;de = ptr
  1270. ;b = character to search
  1271. ;c = LRC
  1272. ;output: de = ptr past character, c = updated LRC
  1273.         ld a,(de)
  1274.         inc de
  1275.         or a
  1276.         ret z
  1277.         cp "\n"
  1278.         ret z
  1279.         cp b
  1280.         ret z
  1281.         xor c
  1282.         ld c,a
  1283.         jr findnextchar
  1284.  
  1285. gpsettings GPSETTINGS
  1286.  
  1287. settingsvars
  1288.         db 0x19 : dw gpsettings.usemp3
  1289.         db 0x14 : dw gpsettings.usemwm
  1290.         db 0x74 : dw gpsettings.usept3
  1291.         db 0x1F : dw gpsettings.usevgm
  1292.         db 0x26 : dw gpsettings.usemoonmod
  1293.         db 0x7F : dw gpsettings.moonmoddefaultpanning
  1294. settingsvarcount=($-settingsvars)/3
  1295.  
  1296. getfileextension
  1297. ;hl = file name
  1298. ;out: cde = file extension
  1299.         ld c,'.'
  1300.         call findlastchar ;out: de = after last dot or start
  1301.         ex de,hl
  1302.         ld a,(hl)
  1303.         call tolower
  1304.         ld c,a
  1305.         inc hl
  1306.         ld a,(hl)
  1307.         call tolower
  1308.         ld d,a
  1309.         inc hl
  1310.         ld a,(hl)
  1311.         call tolower
  1312.         ld e,a
  1313.         ret
  1314.  
  1315. isfileplaylist
  1316. ;cde = file extension
  1317. ;out: zf=1 if playlist, zf=0 otherwise
  1318.         ld a,c
  1319.         cp 'g'
  1320.         ret nz
  1321.         ld a,d
  1322.         cp 'p'
  1323.         ret nz
  1324.         ld a,e
  1325.         cp 'l'
  1326.         ret
  1327.  
  1328. findsupportedplayer
  1329. ;cde = file extension
  1330.         ld hl,playerpages
  1331.         ld a,(playercount)
  1332.         ld b,a
  1333. .findplayerloop
  1334.         push hl
  1335.         push bc
  1336.         ld a,(hl)
  1337.         SETPG4000
  1338.         pop bc
  1339.         call isfilesupported
  1340.         pop hl
  1341.         ret z
  1342.         inc hl
  1343.         djnz .findplayerloop
  1344.         dec b ;set zf=0
  1345.         ret
  1346.  
  1347. createfileslist
  1348.         ld de,emptystr
  1349.         OS_OPENDIR
  1350.  
  1351.         ld a,(gpsettings.sharedpages)
  1352.         SETPG8000
  1353.         ld a,(gpsettings.sharedpages+1)
  1354.         SETPGC000
  1355.  
  1356.         xor a
  1357.         ld (browserpanel.currentfileindex),a
  1358.         ld (browserpanel.firstfiletoshow),a
  1359.  
  1360.         ld hl,currentfolder+2
  1361.         cp (hl)
  1362.         ld hl,0x8000
  1363.         jr nz,.startloop
  1364.         ex de,hl
  1365.         ld hl,drivedata
  1366.         ld bc,drivedataend-drivedata
  1367.         ldir
  1368.         ex de,hl
  1369.         ld a,(drivedataend-drivedata)/FILE_DATA_SIZE
  1370. .startloop
  1371.         ld (browserpanel.filecount),a
  1372. .fileenumloop
  1373.         ld (.filedataaddr),hl
  1374. .skiptonextfile
  1375.         ld de,filinfo
  1376.         OS_READDIR
  1377.         or a
  1378.         jp nz,.sortfiles
  1379. ;skip '.' folder
  1380.         ld hl,(filinfo+FILINFO_FNAME)
  1381.         ld a,l
  1382.         xor '.'
  1383.         or h
  1384.         jr z,.skiptonextfile
  1385. ;skip findsupportedplayer for folders
  1386.         ld a,(filinfo+FILINFO_FATTRIB)
  1387.         and FATTRIB_DIR
  1388.         jr nz,.foundfileordir
  1389.         ld hl,filinfo+FILINFO_FNAME
  1390.         call getfileextension
  1391.         call isfileplaylist
  1392.         jr z,.foundfileordir
  1393.         call findsupportedplayer
  1394.         jr nz,.skiptonextfile
  1395. ;we've got either a playable file or a folder
  1396. .foundfileordir
  1397. .filedataaddr=$+1
  1398.         ld de,0
  1399.         ld hl,FILE_NAME_OFFSET
  1400.         add hl,de
  1401.         ex de,hl
  1402.         ld hl,filinfo+FILINFO_FNAME
  1403.         ld bc,9*256+SFN_SIZE
  1404. .copysfnloop
  1405.         ld a,(hl)
  1406.         cp '.'
  1407.         jr z,.foundsfnext
  1408.         or a
  1409.         jr z,.sfntailloop
  1410.         call tolower
  1411.         ld (de),a
  1412.         inc hl
  1413.         inc de
  1414.         dec c
  1415.         dec b
  1416.         jr .copysfnloop
  1417. ;this is a folder, pad it to SFN_SIZE with zeros
  1418. .sfntailloop
  1419.         ld (de),a
  1420.         inc de
  1421.         dec c
  1422.         jr nz,.sfntailloop
  1423.         jr .donesfncopy
  1424. ;format SFN as 8.3 fixed-position array padding with '*' if necessary
  1425. ;this is needed for sorting
  1426. .foundsfnext
  1427.         ld a,'*'
  1428. .sfntailloop1
  1429.         ld (de),a
  1430.         inc de
  1431.         djnz .sfntailloop1
  1432.         dec de
  1433. ;copy dot, extension, zero terminator
  1434.         ld b,5
  1435. .sfntailloop2
  1436.         ld a,(hl)
  1437.         call tolower
  1438.         ld (de),a
  1439.         inc hl
  1440.         inc de
  1441.         djnz .sfntailloop2
  1442. .donesfncopy
  1443. ;fill display name
  1444.         ld hl,FILE_DISPLAY_INFO_OFFSET-FILE_NAME_OFFSET-SFN_SIZE
  1445.         add hl,de
  1446.         ex de,hl
  1447.         ld hl,filinfo+FILINFO_LNAME
  1448.         ld a,(hl)
  1449.         or a
  1450.         jr nz,$+5
  1451.         ld hl,filinfo+FILINFO_FNAME
  1452.         ld bc,(FILE_DISPLAY_INFO_SIZE-1)*256+255
  1453. .copylfnloop
  1454.         ldi
  1455.         dec b
  1456.         jr z,.lfncopydone
  1457.         ld a,(hl)
  1458.         or a
  1459.         jr nz,.copylfnloop
  1460. .filltailloop
  1461.         ld (de),a
  1462.         inc de
  1463.         djnz .filltailloop
  1464. .lfncopydone
  1465.         xor a
  1466.         ld (de),a
  1467. ;set atrribute data
  1468.         call getfileattrib
  1469.         ld hl,FILE_ATTRIB_OFFSET-FILE_DISPLAY_INFO_OFFSET-FILE_DISPLAY_INFO_SIZE+1
  1470.         add hl,de
  1471.         ld (hl),a
  1472.         ld de,FILE_DATA_SIZE-FILE_ATTRIB_OFFSET
  1473.         add hl,de
  1474. ;check if we have space for more files
  1475.         ld a,(browserpanel.filecount)
  1476.         inc a
  1477.         ld (browserpanel.filecount),a
  1478.         cp BROWSER_FILE_COUNT
  1479.         jp c,.fileenumloop
  1480. .sortfiles
  1481.         ld a,(browserpanel.filecount)
  1482.         or a
  1483.         ret z
  1484.         ld c,a
  1485.         ld b,0
  1486.         ld a,12
  1487.         ld ix,fileextsortkeyoffsets
  1488.         ld hl,0x8000
  1489.         ld de,FILE_DATA_SIZE
  1490.         ld iy,browserpanel.fileslist
  1491.         call radixsort
  1492. ;remove '*' padding restoring SFN to original null-terminated string form
  1493.         ld a,(browserpanel.filecount)
  1494.         ld b,a
  1495.         ld hl,browserpanel.fileslist+FILE_NAME_OFFSET
  1496. .removepaddingnextfile
  1497.         ld de,hl
  1498.         push hl
  1499. .removepaddingloop
  1500.         ld a,(hl)
  1501.         inc hl
  1502.         cp '*'
  1503.         jr z,.removepaddingloop
  1504.         ld (de),a
  1505.         inc de
  1506.         or a
  1507.         jr nz,.removepaddingloop
  1508.         pop hl
  1509.         ld de,FILE_DATA_SIZE
  1510.         add hl,de
  1511.         djnz .removepaddingnextfile
  1512.         ret
  1513.  
  1514. getfileattrib
  1515. ;out: a = attribute value
  1516.         ld a,(filinfo+FILINFO_FATTRIB)
  1517.         and FATTRIB_DIR
  1518.         ld a,FILE_ATTRIB_MUSIC
  1519.         ret z
  1520.         ld hl,(filinfo+FILINFO_FNAME)
  1521.         ld bc,'..'
  1522.         sub hl,bc
  1523.         ld a,FILE_ATTRIB_PARENT_DIR
  1524.         ret z
  1525.         ld a,FILE_ATTRIB_FOLDER
  1526.         ret
  1527.  
  1528. fileextsortkeyoffsets
  1529.         dw FILE_NAME_OFFSET+7, FILE_NAME_OFFSET+6, FILE_NAME_OFFSET+5
  1530.         dw FILE_NAME_OFFSET+4, FILE_NAME_OFFSET+3, FILE_NAME_OFFSET+2
  1531.         dw FILE_NAME_OFFSET+1, FILE_NAME_OFFSET+0
  1532.         dw FILE_NAME_OFFSET+11, FILE_NAME_OFFSET+10, FILE_NAME_OFFSET+9
  1533.         dw FILE_ATTRIB_OFFSET
  1534.  
  1535.         macro jumpindirect addr
  1536.         push hl
  1537.         ld hl,(addr)
  1538.         ex (sp),hl
  1539.         ret
  1540.         endm
  1541.  
  1542. playerinit      jumpindirect PLAYERINITPROCADDR
  1543. playerdeinit    jumpindirect PLAYERDEINITPROCADDR
  1544. musicload       jumpindirect MUSICLOADPROCADDR
  1545. musicunload     jumpindirect MUSICUNLOADPROCADDR
  1546. musicplay       jumpindirect MUSICPLAYPROCADDR
  1547. isfilesupported jumpindirect ISFILESUPPORTEDPROCADDR
  1548.  
  1549.         include "../_sdk/file.asm"
  1550.         include "common/radixsort.asm"
  1551.         include "common/opl4.asm"
  1552.  
  1553. trywritingfm1
  1554.         djnz $
  1555.         ld a,e
  1556.         out (MOON_REG1),a
  1557.         djnz $
  1558.         ld a,d
  1559.         out (MOON_DAT1),a
  1560.         ret
  1561.  
  1562. ismoonsoundpresent
  1563. ;out: zf=1 if Moonsound is present, zf=0 if not
  1564.         switch_to_pcm_ports_c2_c3
  1565. ;check for 255 as an early exit condition
  1566.         in a,(MOON_STAT)
  1567.         add a,1
  1568.         sbc a,a
  1569.         ret nz
  1570. ;read the status second time, now expect all bits clear
  1571.         in a,(MOON_STAT)
  1572.         or a
  1573.         ret nz
  1574. ;start timer
  1575.         ld de,0x8003
  1576.         call trywritingfm1
  1577.         ld de,0x4204
  1578.         call trywritingfm1
  1579.         ld d,0x80
  1580.         call trywritingfm1
  1581. ;wait for the timer to finish
  1582.         YIELD
  1583.         YIELD
  1584. ;check the timer flags
  1585.         in a,(MOON_STAT)
  1586.         cp 0xa0
  1587.         ret nz
  1588. ;no kidding, there must be MoonSound in this system
  1589.         call opl4mute
  1590.         xor a
  1591.         ret
  1592.  
  1593. closeexistingplayer
  1594. ;d = current pid
  1595.         ld e,1
  1596. .searchloop
  1597.         ld a,e
  1598.         cp d
  1599.         jr z,.nextprocess
  1600.         push de
  1601.         OS_GETAPPMAINPAGES ;d,e,h,l=pages in 0000,4000,8000,c000
  1602.         or a
  1603.         ld a,d
  1604.         pop de
  1605.         jr nz,.nextprocess
  1606.         push de
  1607.         SETPGC000
  1608.         ld hl,0xc000+COMMANDLINE
  1609.         ld de,0x8000
  1610.         ld bc,COMMANDLINE_sz
  1611.         ldir
  1612.         ld hl,0x8000
  1613.         call skipword_hl
  1614.         ld (hl),0
  1615.         ld hl,0x8000
  1616.         ld c,'/'
  1617.         call findlastchar ;out: de = after last slash or start
  1618.         call isplayer
  1619.         pop de
  1620.         jr z,.foundplayer
  1621. .nextprocess
  1622.         inc e
  1623.         ld a,e
  1624.         inc a
  1625.         jr nz,.searchloop
  1626.         ret
  1627. .foundplayer
  1628.         xor a
  1629.         ld (0xc000+COMMANDLINE),a
  1630.         push de
  1631.         ld hl,closingplayerstr
  1632.         call print_hl
  1633.         pop de
  1634. .waitloop
  1635.         push de
  1636.         YIELD
  1637.         YIELD
  1638.         YIELD
  1639.         YIELD
  1640.         OS_GETAPPMAINPAGES
  1641.         pop de
  1642.         or a
  1643.         jr z,.waitloop
  1644.         ret
  1645.  
  1646. isplayer
  1647. ;de = command line file name
  1648. ;out: zf=1 if gp, zf=0 otherwise
  1649.         ld a,(de)
  1650.         call tolower
  1651.         cp 'g'
  1652.         ret nz
  1653.         inc de
  1654.         ld a,(de)
  1655.         call tolower
  1656.         cp 'p'
  1657.         ret nz
  1658.         inc de
  1659.         ld a,(de)
  1660.         or a
  1661.         ret z
  1662.         cp '.'
  1663.         ret
  1664. mainend
  1665.  
  1666. playerpages
  1667.         ds NUM_PLAYERS
  1668. filinfo
  1669.         ds FILINFO_sz
  1670. currentfolder
  1671.         ds MAXPATH_sz
  1672. fullpathbuffer
  1673.         ds MAXPATH_sz
  1674.  
  1675.         struct PANEL
  1676. filecount ds 1
  1677. currentfileindex ds 1
  1678. firstfiletoshow ds 1
  1679. isinactive ds 1
  1680. fileslist ds FILE_DATA_SIZE
  1681.         ends
  1682.  
  1683. browserpanel PANEL
  1684.         ds FILE_DATA_SIZE*(BROWSER_FILE_COUNT-1)
  1685.  
  1686. playlistdatastart=$
  1687. playlistpanelversion ds 2
  1688. playlistpanel PANEL
  1689.         ds FILE_DATA_SIZE*(PLAYLIST_FILE_COUNT-1)
  1690. playlistdatasize=$-playlistdatastart
  1691.  
  1692. musicprogress ds 1
  1693. playercount ds 1
  1694.  
  1695. page0dataend = $
  1696.  
  1697.         assert page0dataend <= 0x3e00 ;reserve 512 bytes for stack
  1698.  
  1699.         savebin "gp.com",mainbegin,mainend-mainbegin
  1700.  
  1701.         org 0x0000
  1702.  
  1703. plrbegin
  1704. modstart
  1705.         incbin "moonmod.bin"
  1706. modend
  1707. mwmstart
  1708.         incbin "mwm.bin"
  1709. mwmend
  1710. pt3start
  1711.         incbin "pt3.bin"
  1712. pt3end
  1713. mp3start
  1714.         incbin "mp3.bin"
  1715. mp3end
  1716. vgmstart
  1717.         incbin "vgm.bin"
  1718. vgmend
  1719. plrend
  1720.  
  1721.         savebin "gp.plr",plrbegin,plrend-plrbegin
  1722.