Subversion Repositories NedoOS

Rev

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