Subversion Repositories NedoOS

Rev

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