home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaMiscModsCD3.iso / _PROGRAMME / PLAYER / GUI / EasyPlayer.lha / EYP / Source / easyplayer.e < prev    next >
Encoding:
Text File  |  1999-09-28  |  48.8 KB  |  1,948 lines

  1. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  2. -- EasyPlayer, EYP, Ralph Debusmann 1997-9
  3. */
  4.  
  5. OPT LARGE
  6. OPT OSVERSION=37
  7.  
  8. MODULE 'tools/EasyGUI',
  9. 'devices/inputevent',
  10. 'dos/dos','dos/dostags',
  11. 'exec/memory','exec/tasks',
  12. 'gadtools','libraries/gadtools',
  13. 'intuition/intuition','intuition/intuitionbase',
  14. 'utility/tagitem',
  15. 'workbench/startup',
  16. 'afc/Reqtooller',
  17. '*modules/plugins/multitext','*modules/plugins/dclistview',
  18. '*modules/plugins/vanilla','*modules/plugins/rawkey',
  19. '*modules/listv','*modules/randomlist','*modules/reqs',
  20. '*modules/strings','*modules/time','*modules/vbsig',
  21. '*easyconst','*easyfile','*easyimages',
  22. '*easyinterface','*easyplaylist',
  23. '*easyrecognize','*easystructs'
  24.  
  25. CONST FILEHEADER=5,VERSION=1,
  26. INVGUI=0,RECOGGUI=1,
  27. TAB=9,CR=13,ESCAPE=27,SPACEBAR=32,DEL=127,
  28. ATOZ=FALSE,ZTOA=TRUE,
  29. RTOPENLIB=$A0002
  30.  
  31. DEF ver,
  32. rt:PTR TO reqtooller,ti:PTR TO time,vb:PTR TO vbsig,
  33. plst:PTR TO playlist,
  34. plstgad:PTR TO dclistview,
  35. images:PTR TO mainimages,
  36. menu,mh=NIL,ghmain:PTR TO guihandle,
  37. prevmodgad,playgad,nextmodgad,songnumgad,stopgad,ejectgad,
  38. mainx=-1,mainy=-1,mainxs=-1,mainys=-1,
  39. debug=FALSE,
  40. int:PTR TO interface,
  41. maintitle[42]:STRING,hours,mins,secs,ticker=FALSE, -> 42 > INTERFACE (20) + 5 + approx 5 + x
  42. modnum,nummods, -> modnum = module playing at the very moment
  43. modfilename[FULL]:STRING,plstfilename[FULL]:STRING,
  44. -> prefs
  45. ghprefs:PTR TO guihandle,prefschange,
  46. prefsmulti:PTR TO multitext_plugin,
  47. prefsfilereqimage1:PTR TO filereqimage,prefsfilereqimage2:PTR TO filereqimage,
  48. prefsvan:PTR TO vanilla,
  49. modpathgad,plstpathgad,
  50. modpath[FULL]:STRING,modpath2[FULL]:STRING,
  51. plstpath[FULL]:STRING,plstpath2[FULL]:STRING,
  52. prefsfilename[FULL]:STRING,
  53. -> ints
  54. ghints:PTR TO guihandle,intlist:PTR TO listv,
  55. intsmulti:PTR TO multitext_plugin,intsgad:PTR TO dclistview,
  56. intsvan:PTR TO vanilla,intsraw:PTR TO rawkey,
  57. upintsgad,firstintgad,downintsgad,lastintgad,sortintsgadatoz,sortintsgadztoa,
  58. editintgad,copyintgad,toggleintgad,delintgad,clearintsgad,
  59. intinfo:PTR TO interfaceinfo,intinfo2:PTR TO interfaceinfo,
  60. numints=0,numintst=0,
  61. intschange,
  62. intsfilename[FULL]:STRING,
  63. -> int
  64. ghint:PTR TO LONG,intgui:PTR TO LONG,intindex:PTR TO LONG,
  65. intnamegad:PTR TO LONG,prognamegad:PTR TO LONG,
  66. songarggad:PTR TO LONG,helparggad:PTR TO LONG,progargsgad:PTR TO LONG,consolegad:PTR TO LONG,
  67. headergad:PTR TO LONG,headeroffgad:PTR TO LONG,patterngad:PTR TO LONG,numoffgad:PTR TO LONG,
  68. numlengad:PTR TO LONG,numaddgad:PTR TO LONG,songsoffgad:PTR TO LONG,songslengad:PTR TO LONG,
  69. songsaddgad:PTR TO LONG,
  70. intvan:PTR TO LONG,intfilereqimage:PTR TO LONG,
  71. intinfo3:PTR TO interfaceinfo,intchangelist:PTR TO LONG,
  72. intname:PTR TO LONG,progname:PTR TO LONG,progargs:PTR TO LONG,console:PTR TO LONG,
  73. songarg:PTR TO LONG,helparg:PTR TO LONG,pattern:PTR TO LONG,header:PTR TO LONG
  74.  
  75. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  76. -- main
  77. */
  78.  
  79. PROC main() HANDLE
  80. DEF multi=NIL:PTR TO multitext_plugin,
  81. van=NIL:PTR TO vanilla,raw=NIL:PTR TO rawkey
  82.  
  83.     ver:='$VER: EasyPlayer 0.91 (28.9.1999)'
  84.  
  85.     NEW rt.reqtooller(38) -> open reqtools.library v38
  86.     NEW ti.time() -> plugin for time stopping
  87.     NEW vb.vbsig(10,-10) -> plugin for vb interrupt
  88.  
  89.     StrCopy(prefsfilename,'PROGDIR:EYP.prefs')
  90.     loadprefs()
  91.     StrCopy(intsfilename,'PROGDIR:EYP.ints')
  92.     NEW intlist.stringnode()
  93.     loadints()
  94.     updateintlist(0)
  95.     newints(numints)
  96.     useints()
  97.  
  98.     NEW plst.playlist()
  99.  
  100.     NEW multi.multitext([PLA_MultiText_Text,['Playlist'],
  101.         PLA_MultiText_Justification,PLV_MultiText_JustifyCenter,
  102.         PLA_MultiText_DrawBar,TRUE,TAG_DONE])
  103.     NEW plstgad.dclistview([DCLV_RELX,10,DCLV_RELY,10,
  104.         DCLV_LIST,plst.addr(),TAG_DONE])
  105.     NEW images.mainimages()
  106.     NEW van.vanilla([ESCAPE,CR,SPACEBAR,TAB,"a","+",DEL,"-","f","p","d","l","s","r","t"])
  107.     NEW raw.rawkey([CURSORUP,CURSORDOWN,CURSORRIGHT,CURSORLEFT])
  108.  
  109.     menu:=[NM_TITLE,0,'Project',NIL,0,0,0,
  110.                     NM_ITEM,0,'Open ...','O',0,0,{main_open},
  111.                     NM_ITEM,0,'Append ...','A',0,0,{main_append},
  112.                     NM_ITEM,0,'Save As ...','S',0,0,{main_saveas},
  113.                     NM_ITEM,0,NM_BARLABEL,NIL,0,0,0,
  114.                     NM_ITEM,0,'Snapshot','T',0,0,{main_snapshot},
  115.                     NM_ITEM,0,NM_BARLABEL,NIL,0,0,0,
  116.                     NM_ITEM,0,'Debug ...','D',0,0,{main_debug},
  117.                     NM_ITEM,0,NM_BARLABEL,NIL,0,0,0,
  118.                     NM_ITEM,0,'About ...','?',0,0,{main_about},
  119.                     NM_ITEM,0,NM_BARLABEL,NIL,0,0,0,
  120.                     NM_ITEM,0,'Quit','Q',0,0,0,
  121.                 NM_TITLE,0,'Preferences',NIL,0,0,0,
  122.                     NM_ITEM,0,'Change ...','P',0,0,{openprefs},
  123.                     NM_ITEM,0,'Open ...','0',0,0,{prefs_open},
  124.                     NM_ITEM,0,'Save As ...','1',0,0,{prefs_saveas},
  125.                 NM_TITLE,0,'Interfaces',NIL,0,0,0,
  126.                     NM_ITEM,0,'Change ...','I',0,0,{openints},
  127.                     NM_ITEM,0,'Open ...','9',0,0,{ints_open},
  128.                     NM_ITEM,0,'Append ...','7',0,0,{ints_append},
  129.                     NM_ITEM,0,'Save as ...','6',0,0,{ints_saveas},
  130.                 NM_END,0,NIL,NIL,0,0,0]:newmenu
  131.  
  132.     mh:=multiinit()
  133.  
  134.     ghmain:=addmultiA(mh,'EYP (0:00)',
  135.         [ROWS,
  136.             [PLUGIN,1,multi],
  137.             [PLUGIN,{main_plst},plstgad,TRUE],
  138.             [COLS,
  139.                 [PLUGIN,{main_add},images.nib[ADDNIB]],
  140.                 [SPACEH],
  141.                 [PLUGIN,{main_del},images.nib[DELNIB]],
  142.                 [SPACEH],
  143.                 [PLUGIN,{main_first},images.nib[FIRSTNIB]],
  144.                 [SPACEH],
  145.                 [PLUGIN,{main_up},images.nib[UPNIB]],
  146.                 [SPACEH],
  147.                 [PLUGIN,{main_down},images.nib[DOWNNIB]],
  148.                 [SPACEH],
  149.                 [PLUGIN,{main_last},images.nib[LASTNIB]],
  150.                 [SPACEH],
  151.                 [PLUGIN,{main_shuffle},images.nib[SHUFFLENIB]]],
  152.             [BAR],
  153.             [BEVEL,
  154.                 [COLS,
  155.                     prevmodgad:=[PLUGIN,{main_prevmod},images.nib[PREVMODNIB]],
  156.                     [SPACEH],
  157.                     playgad:=[PLUGIN,{main_play},images.nib[PLAYNIB]],
  158.                     [SPACEH],
  159.                     songnumgad:=[PLUGIN,{main_songnum},images.nib[SONGNUMNIB]],
  160.                     [SPACEH],
  161.                     nextmodgad:=[PLUGIN,{main_nextmod},images.nib[NEXTMODNIB]],
  162.                     [SPACEH],
  163.                     stopgad:=[PLUGIN,{main_stop},images.nib[STOPNIB]],
  164.                     [SPACEH],
  165.                     ejectgad:=[PLUGIN,{main_eject},images.nib[EJECTNIB]]]],
  166.             [PLUGIN,{main_vanilla},van],
  167.             [PLUGIN,{main_rawkey},raw]],
  168.             [EG_MENU,menu,EG_TOP,mainy,EG_LEFT,mainx,TAG_DONE])
  169.  
  170.     resizewin(ghmain,mainx,mainy,mainxs,mainys)
  171.  
  172.     plstitem(-1)
  173.  
  174.     startupargs()
  175.  
  176.     multiloop2(mh)
  177.  
  178. EXCEPT DO
  179.     END int
  180.  
  181.     cleanmulti(mh)
  182.  
  183.     END raw,van,images,plstgad,multi
  184.  
  185.     END plst
  186.  
  187.     endints(numints)
  188.  
  189.     END intlist
  190.  
  191.     END vb,ti
  192.  
  193.     IF reqtoolsbase THEN END rt
  194.  
  195.     SELECT exception
  196.         CASE RTOPENLIB
  197.             errorreq('Couldn''t open ''reqtools.library'' v38.','main')
  198.         CASE "MEM"
  199.             errorreq('EasyGUI-exception: "MEM".','main')
  200.         CASE "GUI"
  201.             errorreq('EasyGUI-exception: "GUI".','main')
  202.         CASE "GT"
  203.             errorreq('EasyGUI-exception: "GT".','main')
  204.         CASE "bigg"
  205.             errorreq('EasyGUI-exception: "bigg".','main')
  206.         CASE "Egui"
  207.             errorreq('EasyGUI-exception: "Egui".','main')
  208.     ENDSELECT
  209. ENDPROC
  210.  
  211. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  212. -- main menu items
  213. */
  214.  
  215. PROC main_open() HANDLE
  216.     IF plstfilereq('Open playlist file')
  217.         loadplst()
  218.         stopmain()
  219.         refreshplst()
  220.         plstitem(0)
  221.         play()
  222.     ENDIF
  223. EXCEPT
  224. ENDPROC
  225.  
  226. PROC main_append() HANDLE
  227. DEF oldpos
  228.     IF plstfilereq('Append playlist file')
  229.         oldpos:=plst.pos()
  230.         IF oldpos=-1 THEN oldpos:=0
  231.         loadplst(TRUE)
  232.         refreshplst()
  233.         plstitem(oldpos)
  234.     ENDIF
  235. EXCEPT
  236. ENDPROC
  237.  
  238. PROC main_saveas() HANDLE
  239.     IF nummods=0 THEN Raise(ERR_NOMOD)
  240.     IF plstfilereq('Save playlist file')
  241.         saveplst(TRUE)
  242.     ENDIF
  243. EXCEPT
  244.     SELECT exception
  245.         CASE ERR_NOMOD
  246.             errorreq('No module in list to save.','main_saveas')
  247.     ENDSELECT
  248. ENDPROC
  249.  
  250. PROC main_snapshot()
  251.     saveprefs(FALSE,TRUE)
  252. ENDPROC
  253.  
  254. PROC main_debug()
  255.     IF debug
  256.         debug:=FALSE
  257.         easyreq('Debug mode off.')
  258.     ELSE
  259.         debug:=TRUE
  260.         easyreq('Debug mode on.')
  261.     ENDIF    
  262. ENDPROC
  263.  
  264. PROC main_about()
  265.     easyreq('%s\n\nModule Player Interface Program\n\n1997-1999 Ralph Debusmann',[ver+6],'EYP about','Ok')
  266. ENDPROC
  267.  
  268. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  269. -- main shortcuts
  270. */
  271.  
  272. PROC main_vanilla(info,plugin:PTR TO vanilla)
  273. DEF qual
  274.     qual:=plugin.qual
  275.     SELECT 128 OF plugin.hit
  276.         CASE ESCAPE
  277.             Raise(0)
  278.         CASE "a","+"
  279.             main_add()
  280.         CASE DEL
  281.             IF images.enabled(DELNIB) THEN main_del()
  282.         CASE "-"
  283.             IF images.enabled(DELNIB) THEN main_del()
  284.         CASE "f"
  285.             IF images.enabled(FIRSTNIB) THEN main_first()
  286.         CASE "p"
  287.             IF images.enabled(UPNIB) THEN main_up()
  288.         CASE "d"
  289.             IF images.enabled(DOWNNIB) THEN main_down()
  290.         CASE "l"
  291.             IF images.enabled(LASTNIB) THEN main_last()
  292.         CASE "s","r"
  293.             IF images.enabled(SHUFFLENIB) THEN main_shuffle()
  294.         CASE "t"
  295.             BCHG #1,$BFE001
  296.         CASE CR
  297.             IF qual AND (IEQUALIFIER_LSHIFT OR IEQUALIFIER_RSHIFT)
  298.                 main_play()
  299.             ELSE
  300.                 IF nummods>0 THEN play()
  301.             ENDIF
  302.         CASE SPACEBAR
  303.             IF images.enabled(STOPNIB) THEN main_stop()
  304.         CASE TAB
  305.             IF images.enabled(EJECTNIB) THEN main_eject()
  306.     ENDSELECT
  307. ENDPROC
  308.  
  309. PROC main_rawkey(info,plugin:PTR TO rawkey)
  310. DEF qual,pos
  311.     qual:=plugin.qual
  312.     pos:=plst.pos()
  313.     SELECT 128 OF plugin.hit
  314.         CASE CURSORUP
  315.             IF qual AND (IEQUALIFIER_LALT OR IEQUALIFIER_RALT)
  316.                 plstitem(0)
  317.             ELSE
  318.                 IF pos>0 THEN plstitem(pos-1)
  319.             ENDIF
  320.         CASE CURSORDOWN
  321.             IF qual AND (IEQUALIFIER_LALT OR IEQUALIFIER_RALT)
  322.                 plstitem(nummods-1)
  323.             ELSE
  324.                 IF (nummods>0) AND pos<(nummods-1) THEN plstitem(pos+1)
  325.             ENDIF
  326.         CASE CURSORRIGHT
  327.             IF qual AND (IEQUALIFIER_LSHIFT OR IEQUALIFIER_RSHIFT)
  328.                 IF images.enabled(NEXTMODNIB) THEN main_nextmod()
  329.             ELSE
  330.                 IF images.enabled(SONGNUMNIB) THEN main_songnum2(1)
  331.             ENDIF
  332.         CASE CURSORLEFT
  333.             IF qual AND (IEQUALIFIER_LSHIFT OR IEQUALIFIER_RSHIFT)
  334.                 IF images.enabled(PREVMODNIB) THEN main_prevmod()
  335.             ELSE
  336.                 IF images.enabled(SONGNUMNIB) THEN main_songnum2(-1)
  337.             ENDIF
  338.     ENDSELECT
  339. ENDPROC
  340.  
  341. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  342. -- main playlist
  343. */
  344.  
  345. PROC main_add()
  346. DEF oldpos
  347.     oldpos:=plst.pos()
  348.     IF modfilereq()
  349.         refreshplst()
  350.         IF oldpos=-1 THEN oldpos:=0
  351.         plstitem(oldpos)
  352.     ENDIF
  353. ENDPROC
  354.  
  355. PROC main_del()
  356.     IF nummods>0
  357.         plst.del()
  358.         nummods--
  359.         refreshplst()
  360.         plstitem(plst.pos())
  361.     ENDIF
  362. ENDPROC
  363.  
  364. PROC main_first()
  365.     IF (nummods>0) AND (plst.pos()>0)
  366.         plst.moveitemfirst()
  367.         refreshplst()
  368.         plstitem(0)
  369.     ENDIF
  370. ENDPROC
  371.  
  372. PROC main_up()
  373. DEF pos
  374.     IF (nummods>0) AND (plst.pos()>0)
  375.         pos:=plst.moveitemup()
  376.         refreshplst()
  377.         plstitem(pos)
  378.     ENDIF
  379. ENDPROC
  380.  
  381. PROC main_down()
  382. DEF pos
  383.     IF (nummods>0) AND (plst.pos()<(nummods-1))
  384.         pos:=plst.moveitemdown()
  385.         refreshplst()
  386.         plstitem(pos)
  387.     ENDIF
  388. ENDPROC
  389.  
  390. PROC main_last()
  391. DEF pos
  392.     IF (nummods>0) AND (plst.pos()<(nummods-1))
  393.         pos:=plst.moveitemlast()
  394.         refreshplst()
  395.         plstitem(pos)
  396.     ENDIF
  397. ENDPROC
  398.  
  399. PROC main_shuffle()
  400. DEF p,i,plst2:PTR TO playlist,oldpos,newpos=-1
  401.     IF nummods>0
  402.         oldpos:=plst.pos()
  403.         p:=randomlist(nummods)
  404.         NEW plst2.playlist()
  405.         FOR i:=0 TO nummods-1
  406.             plst.item(p[i])
  407.             plst2.add(plst.dirlist.obj(),plst.filelist.obj())
  408.             IF ((newpos=-1) AND (p[i]=oldpos)) THEN newpos:=i
  409.         ENDFOR
  410.         END plst
  411.         plst:=plst2
  412.         refreshplst()
  413.         plstitem(newpos)
  414.     ENDIF
  415. ENDPROC
  416.  
  417. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  418. -- main tapedeck
  419. */
  420.  
  421. PROC main_plst(info,plugin)
  422. DEF n
  423.     n:=plstgad.get(DCLV_CURRENT)
  424.     IF plstgad.get(DCLV_CLICK) THEN play()
  425.     plstitem(n)
  426. ENDPROC
  427.  
  428. PROC main_prevmod()
  429.     IF modnum>0
  430.         plstitem(modnum-1)
  431.         play()
  432.     ENDIF
  433. ENDPROC
  434.  
  435. PROC main_play()
  436. DEF oldnummods
  437.     oldnummods:=nummods
  438.     IF modfilereq()
  439.         refreshplst()
  440.         plstitem(oldnummods)
  441.         play()
  442.     ENDIF
  443. ENDPROC
  444.  
  445. PROC main_songnum()
  446.     main_songnum2(0)
  447. ENDPROC
  448.  
  449. PROC main_songnum2(change)
  450. DEF n
  451.     IF int
  452.         IF int.numsongs
  453.             IF ((int.songnum+change)>0) AND ((int.songnum+change)<=int.numsongs)
  454.                 rt.setattrs([RT_TITLE,'Choose new song number',
  455.                     RT_MINVAL,1,RT_MAXVAL,int.numsongs,RT_DEFVAL,int.songnum+change,TAG_DONE])
  456.                 IF rt.req(RTREQ_NUMBER)
  457.                     n:=rt.get(RT_NUM)
  458.                     IF (n<>0) AND (n<>int.songnum) AND (n<=int.numsongs) THEN play(n)
  459.                 ENDIF
  460.             ENDIF
  461.         ENDIF
  462.     ENDIF
  463. ENDPROC
  464.  
  465. PROC main_nextmod()
  466.     IF modnum<(nummods-1)
  467.         plstitem(modnum+1)
  468.         play()
  469.     ENDIF
  470. ENDPROC
  471.  
  472. PROC main_stop()
  473.     stopmain()
  474.     plstitem(plst.pos())
  475. ENDPROC
  476.  
  477. PROC main_eject()
  478.     stopmain()
  479.     IF nummods
  480.         nummods:=0
  481.         plst.clear()
  482.         refreshplst()
  483.         plstitem(0)
  484.     ENDIF
  485. ENDPROC
  486.  
  487. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  488. -- main support
  489. */
  490.  
  491. PROC modfilereq()
  492. DEF dir,file,success
  493.     rt.setattrs([RT_TITLE,'Add one or more module(s)',RT_PATH,modpath,
  494.     RT_FILENAME,FilePart(modfilename),RT_FULLNAME,FALSE,TAG_DONE])
  495.     IF (success:=rt.req(RTREQ_MULTI))
  496.         dir:=rt.get(RT_PATH)
  497.         WHILE (file:=rt.get(RT_MULTINEXT))
  498.             plst.add(dir,file)
  499.         ENDWHILE
  500.         nummods:=plst.numitems()
  501.  
  502.         StrCopy(modpath,dir)
  503.         IF ghprefs
  504.             setstr(ghprefs,modpathgad,modpath)
  505.             prefschange:=TRUE
  506.         ENDIF
  507.     ENDIF
  508. ENDPROC success
  509.  
  510. PROC plstfilereq(title)
  511. DEF success
  512.     rt.setattrs([RT_TITLE,title,RT_PATH,plstpath,RT_FILENAME,FilePart(plstfilename),RT_FULLNAME,TRUE,TAG_DONE])
  513.     IF (success:=rt.req(RTREQ_FILE))
  514.         strcopy(plstfilename,rt.get(RT_FILENAME))
  515.  
  516.         StrCopy(plstpath,rt.get(RT_PATH))
  517.         IF ghprefs
  518.             setstr(ghprefs,plstpathgad,plstpath)
  519.             prefschange:=TRUE
  520.         ENDIF
  521.     ENDIF
  522. ENDPROC success
  523.  
  524. PROC play(songnum=0) HANDLE
  525. DEF modid,oldwin,ib:PTR TO intuitionbase
  526.     IF intinfo=NIL THEN Raise(ERR_NOINT)
  527.     blockwin(ghmain)
  528.     stopmain() -> ticker:=FALSE, END int, changetitle
  529.     StrCopy(modfilename,plst.dirlist.obj())
  530.     AddPart(modfilename,plst.filelist.obj(),FULL)
  531.     modid:=recognize(modfilename,intinfo,numints)
  532.     NEW int.interface(intinfo[modid-1],modfilename,debug)
  533.     IF songnum THEN int.songnum:=songnum
  534.     ib:=intuitionbase
  535.     oldwin:=ib.activewindow
  536.     int.start(debug)
  537.     ActivateWindow(oldwin)
  538.     ti.start()
  539.     ticker:=TRUE
  540.     modnum:=plst.pos()
  541.     plstitem(modnum)
  542. EXCEPT DO
  543.     unblockwin(ghmain)
  544.     SELECT exception
  545.         CASE ERR_NOINT
  546.             errorreq('No interface enabled.','play')
  547.         CASE ERR_LAUNCH
  548.             errorreq('Couldn''t launch "%s"-player program.','play',[int.intinfo.intname])
  549.     ENDSELECT
  550. ENDPROC
  551.  
  552. PROC plstitem(newpos)
  553. DEF numsongs=0
  554.     plst.item(newpos)
  555.     plstgad.set(DCLV_CURRENT,newpos)
  556.  
  557.     IF int THEN numsongs:=int.numsongs
  558.     enablenibgads([images.nib[PREVMODNIB],modnum>0,
  559.         images.nib[PLAYNIB],TRUE,
  560.         images.nib[SONGNUMNIB],numsongs>1,
  561.         images.nib[NEXTMODNIB],modnum<(nummods-1),
  562.         images.nib[STOPNIB],ticker,
  563.         images.nib[EJECTNIB],nummods>0,
  564.         images.nib[ADDNIB],TRUE,
  565.         images.nib[DELNIB],nummods>0,
  566.         images.nib[FIRSTNIB],(nummods>0) AND (newpos>0),
  567.         images.nib[UPNIB],(nummods>0) AND (newpos>0),
  568.         images.nib[DOWNNIB],(nummods>0) AND (newpos<(nummods-1)),
  569.         images.nib[LASTNIB],(nummods>0) AND (newpos<(nummods-1)),
  570.         images.nib[SHUFFLENIB],(nummods>1),TAG_DONE])
  571. ENDPROC
  572.  
  573. PROC refreshplst()
  574.     plstgad.set(DCLV_LIST,-1)
  575.     plstgad.set(DCLV_LIST,plst.addr())
  576. ENDPROC
  577.  
  578. PROC stopmain()
  579. DEF figure[4]:STRING
  580.     ticker:=FALSE
  581.  
  582.     END int
  583.  
  584.     StrCopy(maintitle,'EYP (')
  585.     IF hours>0
  586.         StringF(figure,'\d:',hours)
  587.         StrAdd(maintitle,figure)
  588.     ENDIF
  589.     IF mins>=10
  590.         StringF(figure,'\z\d[2]:',mins)
  591.         StrAdd(maintitle,figure)
  592.     ELSE
  593.         StringF(figure,'\z\d[1]:',mins)
  594.         StrAdd(maintitle,figure)
  595.     ENDIF
  596.     StringF(figure,'\z\d[2])',secs)
  597.     StrAdd(maintitle,figure)
  598.     changetitle(ghmain,maintitle)
  599. ENDPROC
  600.  
  601. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  602. -- prefs
  603. */
  604.  
  605. PROC openprefs()
  606.     IF ghprefs=NIL
  607.         NEW prefsmulti.multitext([PLA_MultiText_Text,['Preferences'],
  608.             PLA_MultiText_Justification,PLV_MultiText_JustifyCenter,
  609.             PLA_MultiText_DrawBar,TRUE,TAG_DONE])
  610.         NEW prefsfilereqimage1.filereqimage()
  611.         NEW prefsfilereqimage2.filereqimage()
  612.         NEW prefsvan.vanilla([ESCAPE,"1","2"])
  613.         ghprefs:=addmultiA(mh,'EYP prefs',
  614.             [EQROWS,
  615.                 [PLUGIN,1,prefsmulti],
  616.                 [COLS,
  617.                     modpathgad:=[STR,{prefs_modpath},'_Module path',modpath,100,10,FALSE,NIL,"m"],
  618.                     [PLUGIN,{prefs_modpathreq},prefsfilereqimage1.nib]],
  619.                 [COLS,
  620.                     plstpathgad:=[STR,{prefs_plstpath},'_Playlist path',plstpath,100,10,FALSE,NIL,"p"],
  621.                     [PLUGIN,{prefs_plstpathreq},prefsfilereqimage2.nib]],
  622.                 [BAR],
  623.                 [COLS,
  624.                     [BUTTON,{prefs_save},'_Save',NIL,"s",NIL,FALSE],
  625.                     [SPACEH],
  626.                     [BUTTON,{prefs_use},'_Use',NIL,"u",NIL,FALSE],
  627.                     [SPACEH],
  628.                     [BUTTON,{prefs_cancel},'_Cancel',NIL,"c",NIL,FALSE]],
  629.                 [PLUGIN,{prefs_vanilla},prefsvan]],
  630.             [EG_MENU,menu,EG_CLOSE,{prefs_use},TAG_DONE])
  631.         prefschange:=FALSE
  632.         StrCopy(modpath2,modpath)
  633.         StrCopy(plstpath2,plstpath)
  634.     ELSE
  635.         WindowToFront(ghprefs.wnd)
  636.         ActivateWindow(ghprefs.wnd)
  637.     ENDIF
  638. ENDPROC
  639.  
  640. PROC closeprefs()
  641.     cleangui(ghprefs)
  642.     ghprefs:=NIL
  643.     END prefsvan,prefsfilereqimage2,prefsfilereqimage1,prefsmulti
  644. ENDPROC
  645.  
  646. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  647. -- prefs menu items
  648. */
  649.  
  650. PROC prefs_open()
  651.     IF filereq('Open preferences file',prefsfilename)
  652.         IF loadprefs()
  653.             resizewin(ghmain,mainx,mainy,mainxs,mainys)
  654.             IF ghprefs
  655.                 closewin(ghprefs)
  656.                 setstr(ghprefs,modpathgad,modpath)
  657.                 setstr(ghprefs,plstpathgad,plstpath)
  658.                 openwin(ghprefs)
  659.             ENDIF
  660.         ENDIF
  661.     ENDIF
  662. ENDPROC
  663.  
  664. PROC prefs_saveas()
  665.     IF filereq('Save preferences file',prefsfilename)
  666.         useprefs()
  667.         saveprefs(TRUE)
  668.     ENDIF
  669. ENDPROC
  670.  
  671. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  672. -- prefs shortcuts
  673. */
  674.  
  675. PROC prefs_vanilla(info,plugin:PTR TO vanilla)
  676.     SELECT 128 OF plugin.hit
  677.         CASE ESCAPE
  678.             prefs_use()
  679.         CASE "1"
  680.             prefs_modpathreq()
  681.         CASE "2"
  682.             prefs_plstpathreq()
  683.     ENDSELECT
  684. ENDPROC
  685.  
  686. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  687. -- prefs gui
  688. */
  689.  
  690. PROC prefs_modpath()
  691.     IF StrCmp(modpath,modpath2)=FALSE
  692.         prefschange:=TRUE
  693.     ENDIF
  694. ENDPROC
  695.  
  696. PROC prefs_modpathreq()
  697.     IF pathreq('Choose module path',modpath)
  698.         setstr(ghprefs,modpathgad,modpath)
  699.         prefschange:=TRUE
  700.     ENDIF
  701. ENDPROC
  702.  
  703. PROC prefs_plstpath()
  704.     IF StrCmp(plstpath,plstpath2)=FALSE
  705.         prefschange:=TRUE
  706.     ENDIF
  707. ENDPROC
  708.  
  709. PROC prefs_plstpathreq()
  710.     IF pathreq('Choose playlist path',plstpath)
  711.         setstr(ghprefs,plstpathgad,plstpath)
  712.         prefschange:=TRUE
  713.     ENDIF
  714. ENDPROC
  715.  
  716. PROC prefs_save()
  717.     useprefs()
  718.     IF saveprefs(FALSE) THEN closeprefs()
  719. ENDPROC
  720.  
  721. PROC prefs_use()
  722.     useprefs()
  723.     closeprefs()
  724. ENDPROC
  725.  
  726. PROC prefs_cancel()
  727.     IF prefschange
  728.         StrCopy(modpath,modpath2)
  729.         StrCopy(plstpath,plstpath2)
  730.     ENDIF
  731.     closeprefs()
  732. ENDPROC
  733.  
  734. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  735. -- prefs support
  736. */
  737.  
  738. PROC useprefs()
  739.     IF ghprefs
  740.         StrCopy(modpath,getstr(ghprefs,modpathgad))
  741.         StrCopy(plstpath,getstr(ghprefs,plstpathgad))
  742.     ENDIF
  743. ENDPROC
  744.  
  745. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  746. -- interfaces
  747. */
  748.  
  749. PROC openints()
  750.     IF ghints=NIL
  751.         NEW intsmulti.multitext([PLA_MultiText_Text,['Interfaces'],
  752.             PLA_MultiText_Justification,PLV_MultiText_JustifyCenter,
  753.             PLA_MultiText_DrawBar,TRUE,TAG_DONE])
  754.         NEW intsgad.dclistview([DCLV_RELX,12,DCLV_RELY,12,
  755.             DCLV_LIST,intlist.addr(),DCLV_CURRENT,intlist.pos(),TAG_DONE])
  756.         NEW intsvan.vanilla([ESCAPE,CR,DEL,INTDISABLED])
  757.         NEW intsraw.rawkey([CURSORUP,CURSORDOWN])
  758.         ghints:=addmultiA(mh,'EYP ints',
  759.             [ROWS,
  760.                 [PLUGIN,1,intsmulti],
  761.                 [COLS,
  762.                     [PLUGIN,{ints_intlist},intsgad,TRUE],
  763.                     [EQROWS,
  764.                         firstintgad:=[BUTTON,{ints_first},'_First',NIL,"f",NIL,Not(((numints>0) AND (intlist.pos()>0)))],
  765.                         upintsgad:=[BUTTON,{ints_up},'U_p',NIL,"p",NIL,Not(((numints>0) AND (intlist.pos()>0)))],
  766.                         downintsgad:=[BUTTON,{ints_down},'_Down',NIL,"d",NIL,Not(((numints>0) AND (intlist.pos()<(numints-1))))],
  767.                         lastintgad:=[BUTTON,{ints_last},'_Last',NIL,"l",NIL,Not(((numints>0) AND (intlist.pos()<(numints-1))))],
  768.                         sortintsgadatoz:=[BUTTON,{ints_sort},'_a-z',ATOZ,"a",NIL,Not(numints>1)],
  769.                         sortintsgadztoa:=[BUTTON,{ints_sort},'_z-a',ZTOA,"z",NIL,Not(numints>1)]]],
  770.                 [ROWS,
  771.                     [COLS,
  772.                         [SBUTTON,{ints_add},'_New',NIL,"n",NIL,FALSE],
  773.                         [SPACEH],
  774.                         editintgad:=[SBUTTON,{ints_edit},'_Edit',NIL,"e",NIL,FALSE],
  775.                         [SPACEH],
  776.                         copyintgad:=[SBUTTON,{ints_copy},'Cop_y',NIL,"y",NIL,Not(numints>0)],
  777.                         [SPACEH],
  778.                         toggleintgad:=[SBUTTON,{ints_toggle},'_*',NIL,"*",NIL,Not(numints>0)],
  779.                         [SPACEH],
  780.                         delintgad:=[SBUTTON,{ints_del},'Del',NIL,"m",NIL,Not(numints>0)],
  781.                         [SPACEH],
  782.                         clearintsgad:=[SBUTTON,{ints_clear},'Clea_r',NIL,"r",NIL,Not(numints>0)]],
  783.                     [BAR],
  784.                     [COLS,
  785.                         [BUTTON,{ints_save},'_Save',NIL,"s",NIL,FALSE],
  786.                         [SPACEH],
  787.                         [BUTTON,{ints_use},'_Use',NIL,"u",NIL,FALSE],
  788.                         [SPACEH],
  789.                         [BUTTON,{ints_cancel},'_Cancel',NIL,"c",NIL,FALSE]]],
  790.                 [PLUGIN,{ints_vanilla},intsvan],
  791.                 [PLUGIN,{ints_rawkey},intsraw]],
  792.             [EG_MENU,menu,EG_CLOSE,{ints_use},EG_INFO,intlist.pos(),TAG_DONE])
  793.     ELSE
  794.         WindowToFront(ghints.wnd)
  795.         ActivateWindow(ghints.wnd)
  796.     ENDIF
  797. ENDPROC
  798.  
  799. PROC closeints()
  800. DEF i,win:PTR TO window
  801.     FOR i:=0 TO numints-1
  802.         IF ghint[i]
  803.             int_use(i)
  804.         ENDIF
  805.     ENDFOR
  806.     win:=ghints.wnd
  807.     cleangui(ghints)
  808.     ghints:=NIL
  809.     END intsvan,intsraw,intsmulti,intsgad
  810. ENDPROC
  811.  
  812. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  813. -- interfaces shortcuts
  814. */
  815.  
  816. PROC ints_vanilla(num,plugin:PTR TO vanilla)
  817.     SELECT 128 OF plugin.hit
  818.         CASE ESCAPE
  819.             ints_use()
  820.         CASE CR
  821.             IF numints THEN ints_edit(num)
  822.         CASE DEL
  823.             IF numints THEN ints_del()
  824.         CASE INTDISABLED
  825.             IF numints THEN ints_toggle(num)
  826.     ENDSELECT
  827. ENDPROC
  828.  
  829. PROC ints_rawkey(info,plugin:PTR TO rawkey)
  830. DEF qual
  831.     qual:=plugin.qual
  832.     SELECT 128 OF plugin.hit
  833.         CASE CURSORUP
  834.             IF intlist.empty()=FALSE
  835.                 IF qual AND (IEQUALIFIER_LALT OR IEQUALIFIER_RALT)
  836.                     IF intlist.first() THEN moveinintlist(0)
  837.                 ELSE
  838.                     IF intlist.prev() THEN moveinintlist(intlist.pos())
  839.                 ENDIF
  840.             ENDIF
  841.         CASE CURSORDOWN
  842.             IF intlist.empty()=FALSE
  843.                 IF qual AND (IEQUALIFIER_LALT OR IEQUALIFIER_RALT)
  844.                     IF intlist.last() THEN moveinintlist(intlist.numitems()-1)
  845.                 ELSE
  846.                     IF intlist.succ() THEN moveinintlist(intlist.pos())
  847.                 ENDIF
  848.             ENDIF
  849.     ENDSELECT
  850. ENDPROC
  851.  
  852. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  853. -- interfaces menu items
  854. */
  855.  
  856. PROC ints_open()
  857. DEF oldnumints
  858.     IF filereq('Open interfaces file',intsfilename)
  859.         oldnumints:=numints
  860.         IF loadints()
  861.             IF ghints THEN closewin(ghints)
  862.             updateints(oldnumints,numints,0)
  863.             updateintlist(0)
  864.             IF ghints
  865.                 openwin(ghints)
  866.                 refreshintlist()
  867.             ENDIF
  868.         ENDIF
  869.     ENDIF
  870. ENDPROC
  871.  
  872. PROC ints_append()
  873. DEF oldnumints,oldpos
  874.     IF filereq('Append interfaces file',intsfilename)
  875.         oldnumints:=numints
  876.         oldpos:=intlist.pos()
  877.         IF oldpos=-1 THEN oldpos:=0
  878.         IF loadints(TRUE)
  879.             IF ghints THEN closewin(ghints)
  880.             updateints(oldnumints,numints,oldpos)
  881.             updateintlist(oldpos)
  882.             IF ghints
  883.                 openwin(ghints)
  884.                 refreshintlist()
  885.             ENDIF
  886.         ENDIF
  887.     ENDIF
  888. ENDPROC
  889.  
  890. PROC ints_saveas() HANDLE
  891.     IF numints=0 THEN Raise(ERR_NOINT)
  892.     IF filereq('Save interfaces file',intsfilename)
  893.         saveints(TRUE)
  894.     ENDIF
  895. EXCEPT
  896.     SELECT exception
  897.         CASE ERR_NOINT
  898.             errorreq('No interface available to save.','ints_saveas')
  899.     ENDSELECT
  900. ENDPROC
  901.  
  902. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  903. -- interfaces gui
  904. */
  905.  
  906. PROC ints_intlist(info,plugin)
  907. DEF num,double
  908.     num:=intsgad.get(DCLV_CURRENT)
  909.     double:=intsgad.get(DCLV_CLICK)
  910.     intlist.item(num)
  911.     moveinintlist(num)
  912.     IF double THEN ints_edit(num)
  913. ENDPROC
  914.  
  915. PROC ints_first()
  916.     IF (numints>0) AND (intlist.pos()>0)
  917.         intlist.moveitemfirst()
  918.         intlisttointinfo()
  919.         updateints(numints,numints,0)
  920.         refreshintlist()
  921.     ENDIF
  922. ENDPROC
  923.  
  924. PROC ints_up()
  925. DEF newpos
  926.     IF (numints>0) AND (intlist.pos()>0)
  927.         newpos:=intlist.moveitemup()
  928.         intlisttointinfo()
  929.         updateints(numints,numints,newpos)
  930.         refreshintlist()
  931.     ENDIF
  932. ENDPROC
  933.  
  934. PROC ints_down()
  935. DEF newpos
  936.     IF (numints>0) AND (intlist.pos()<(numints-1))
  937.         newpos:=intlist.moveitemdown()
  938.         intlisttointinfo()
  939.         updateints(numints,numints,newpos)
  940.         refreshintlist()
  941.     ENDIF
  942. ENDPROC
  943.  
  944. PROC ints_last()
  945.     IF (numints>0) AND (intlist.pos()<(numints-1))
  946.         intlist.moveitemlast()
  947.         intlisttointinfo()
  948.         updateints(numints,numints,numints-1)
  949.         refreshintlist()
  950.     ENDIF
  951. ENDPROC
  952.  
  953. PROC ints_sort(inverted,info)
  954.     IF numints
  955.         intlist.sort(FALSE,inverted)
  956.         intlisttointinfo()
  957.         updateints(numints,numints,0)
  958.         refreshintlist()
  959.     ENDIF
  960. ENDPROC
  961.  
  962. PROC ints_add()
  963. DEF newpos
  964.     newpos:=intlist.insert('<new>')    
  965.     intlisttointinfo()
  966.     updateints(numints-1,numints,newpos)
  967.     refreshintlist()
  968.     openint(newpos)
  969. ENDPROC
  970.  
  971. PROC ints_edit(num)
  972.     openint(num)
  973. ENDPROC
  974.  
  975. PROC ints_copy(num)
  976. DEF newpos
  977.     newpos:=intlist.insert(intinfo[num].intname)
  978.     intlisttointinfo()
  979.     CopyMem(intinfo[num],intinfo[num+1],SIZEOF interfaceinfo)
  980.     updateints(numints-1,numints,newpos)
  981.     refreshintlist()
  982. ENDPROC
  983.  
  984. PROC ints_toggle(num)
  985. DEF toggle,newintname[INTERFACE]:STRING
  986.     toggle:=intinfo[num].intname[]=INTDISABLED
  987.     IF toggle
  988.         StrCopy(newintname,intinfo[num].intname+1)
  989.     ELSE
  990.         StrCopy(newintname,' ')
  991.         newintname[]:=INTDISABLED
  992.         StrAdd(newintname,intinfo[num].intname)
  993.     ENDIF
  994.     strcopy(intinfo[num].intname,newintname)
  995.     StrCopy(intname[num],newintname)
  996.     changeintlist(num,newintname)
  997.     IF ghint[num]
  998.         setstr(ghint[num],intnamegad[num],intname[num])
  999.         changetitle(ghint[num],intinfo[num].intname)
  1000.         intchangelist[num]:=TRUE
  1001.     ENDIF
  1002. ENDPROC
  1003.  
  1004. PROC ints_del()
  1005. DEF newpos
  1006.     IF numints
  1007.         intlist.del()
  1008.         newpos:=intlist.pos()
  1009.         intlisttointinfo()
  1010.         updateints(numints+1,numints,newpos)
  1011.         refreshintlist()
  1012.     ENDIF
  1013. ENDPROC
  1014.  
  1015. PROC ints_clear()
  1016. DEF oldnumints
  1017.     IF numints
  1018.         oldnumints:=numints
  1019.         intlist.clear()
  1020.         intlisttointinfo()
  1021.         updateints(oldnumints,0,-1)
  1022.         refreshintlist()
  1023.     ENDIF
  1024. ENDPROC
  1025.  
  1026. PROC ints_save() HANDLE
  1027.     IF numints=0 THEN Raise(ERR_NOINT)
  1028.     saveints(FALSE)
  1029.     closeints()
  1030.     useints()
  1031. EXCEPT
  1032.     SELECT exception
  1033.         CASE ERR_NOINT
  1034.             errorreq('No interface available to save.','ints_save')
  1035.     ENDSELECT
  1036. ENDPROC
  1037.  
  1038. PROC ints_use()
  1039.     closeints()
  1040.     useints()
  1041. ENDPROC
  1042.  
  1043. PROC ints_cancel()
  1044. DEF oldnumints
  1045.     closeints()
  1046.     IF intschange
  1047.         oldnumints:=numints
  1048.         cancelints()
  1049.         updateintlist(0)
  1050.         updateints(oldnumints,numints,0)
  1051.     ENDIF
  1052. ENDPROC
  1053.  
  1054. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1055. -- interfaces support
  1056. */
  1057.  
  1058. PROC cancelints()
  1059. DEF i
  1060.     END intinfo[numints]
  1061.     NEW intinfo[numintst]
  1062.     FOR i:=0 TO numintst-1
  1063.         CopyMem(intinfo2[i],intinfo[i],SIZEOF interfaceinfo)
  1064.     ENDFOR
  1065.     numints:=numintst
  1066.     intschange:=FALSE
  1067. ENDPROC
  1068.  
  1069. PROC changeintlist(num,news)
  1070.     intlist.change2(num,news)
  1071.     IF ghints
  1072.         refreshintlist()
  1073.     ENDIF
  1074.     intschange:=TRUE
  1075. ENDPROC
  1076.  
  1077. PROC endints(endnumints)
  1078. DEF i
  1079.     IF endnumints
  1080.         FOR i:=0 TO endnumints-1
  1081.             IF ghint[i]
  1082.                 closeint(i)
  1083.             ENDIF
  1084.  
  1085.             DisposeLink(header[i]); DisposeLink(pattern[i]); DisposeLink(helparg[i])
  1086.             DisposeLink(songarg[i]); DisposeLink(console[i]); DisposeLink(progargs[i])
  1087.             DisposeLink(progname[i]); DisposeLink(intname[i])
  1088.         ENDFOR 
  1089.  
  1090.         END header[endnumints],pattern[endnumints],helparg[endnumints],songarg[endnumints],
  1091.             console[endnumints],progargs[endnumints],progname[endnumints],intname[endnumints]
  1092.  
  1093.         END intinfo3[endnumints],intchangelist[endnumints]
  1094.  
  1095.         END intvan[endnumints],intfilereqimage[endnumints]
  1096.  
  1097.         END intnamegad[endnumints],prognamegad[endnumints],
  1098.             songarggad[endnumints],helparggad[endnumints],progargsgad[endnumints],consolegad[endnumints],
  1099.             headergad[endnumints],headeroffgad[endnumints],patterngad[endnumints],numoffgad[endnumints],
  1100.             numlengad[endnumints],numaddgad[endnumints],songsoffgad[endnumints],songslengad[endnumints],
  1101.             songsaddgad[endnumints]
  1102.  
  1103.         END intindex[endnumints]
  1104.  
  1105.         END intgui[endnumints]
  1106.  
  1107.         END ghint[endnumints]
  1108.     ENDIF
  1109. ENDPROC
  1110.  
  1111. PROC intlisttointinfo()
  1112. DEF oldpos,intinfol=NIL:PTR TO interfaceinfo,i,j,found
  1113.     IF intlist.numitems()
  1114.         oldpos:=intlist.pos()
  1115.         NEW intinfol[intlist.numitems()]
  1116.         FOR i:=0 TO intlist.numitems()-1
  1117.             intlist.item(i)
  1118.             j:=0
  1119.             found:=FALSE
  1120.             IF intinfo
  1121.                 REPEAT
  1122.                     IF intinfo[j].intname[]
  1123.                         IF StrCmp(intlist.obj(),intinfo[j].intname)
  1124.                             CopyMem(intinfo[j],intinfol[i],SIZEOF interfaceinfo)
  1125.                             intinfo[j].intname[]:=0
  1126.                             found:=TRUE
  1127.                         ENDIF
  1128.                     ENDIF
  1129.                     j++
  1130.                 UNTIL (j=numints) OR found
  1131.             ENDIF    
  1132.             IF found=FALSE
  1133.                 nullintinfo(intinfol[i])
  1134.                 strcopy(intinfol[i].intname,intlist.obj())
  1135.             ENDIF
  1136.         ENDFOR
  1137.         END intinfo[numints]
  1138.         intinfo:=intinfol
  1139.         intlist.item(oldpos)
  1140.     ELSE
  1141.         END intinfo[numints]
  1142.     ENDIF
  1143.     numints:=intlist.numitems()
  1144. ENDPROC
  1145.  
  1146. PROC moveinintlist(newpos)
  1147.     IF ghints
  1148.         IF newpos<>-1
  1149.             intsgad.set(DCLV_CURRENT,newpos)
  1150.         ENDIF
  1151.         changeinfo(ghints,newpos)
  1152.         enablegads(ghints,[
  1153.             firstintgad,((numints>0) AND (newpos>0)),
  1154.             upintsgad,((numints>0) AND (newpos>0)),
  1155.             downintsgad,((numints>0) AND (newpos<(numints-1))),
  1156.             lastintgad,((numints>0) AND (newpos<(numints-1))),
  1157.             sortintsgadatoz,numints>1,sortintsgadztoa,numints>1,
  1158.             copyintgad,numints>0,editintgad,numints>0,toggleintgad,numints>0,
  1159.             delintgad,numints>0,clearintsgad,numints>0,TAG_DONE])
  1160.     ENDIF
  1161. ENDPROC
  1162.  
  1163. PROC newints(newnumints)
  1164. DEF i
  1165.     IF newnumints
  1166.         NEW ghint[newnumints] -> list of interface windows
  1167.  
  1168.         NEW intgui[newnumints]
  1169.  
  1170.         NEW intindex[newnumints]
  1171.  
  1172.         NEW intnamegad[newnumints],prognamegad[newnumints],
  1173.             songarggad[newnumints],helparggad[newnumints],progargsgad[newnumints],consolegad[newnumints],
  1174.             headergad[newnumints],headeroffgad[newnumints],patterngad[newnumints],numoffgad[newnumints],
  1175.             numlengad[newnumints],numaddgad[newnumints],songsoffgad[newnumints],songslengad[newnumints],
  1176.             songsaddgad[newnumints]
  1177.  
  1178.         NEW intvan[newnumints],intfilereqimage[newnumints]
  1179.  
  1180.         NEW intinfo3[newnumints],intchangelist[newnumints]
  1181.  
  1182.         NEW intname[newnumints] -> partial intinfo (need to have estrings for gui)
  1183.         NEW progname[newnumints]
  1184.         NEW progargs[newnumints]
  1185.         NEW console[newnumints]
  1186.         NEW songarg[newnumints]
  1187.         NEW helparg[newnumints]
  1188.         NEW pattern[newnumints]
  1189.         NEW header[newnumints]
  1190.  
  1191.         FOR i:=0 TO newnumints-1
  1192.             ghint[i]:=NIL
  1193.  
  1194.             intindex[i]:=0
  1195.  
  1196.             intname[i]:=String(INTERFACE)
  1197.             StrCopy(intname[i],intinfo[i].intname)
  1198.             progname[i]:=String(FULL)
  1199.             StrCopy(progname[i],intinfo[i].progname)
  1200.             progargs[i]:=String(FULL)
  1201.             StrCopy(progargs[i],intinfo[i].progargs)
  1202.             console[i]:=String(FULL)
  1203.             StrCopy(console[i],intinfo[i].console)
  1204.             songarg[i]:=String(SONGARG)
  1205.             StrCopy(songarg[i],intinfo[i].songarg)
  1206.             helparg[i]:=String(FULL)
  1207.             StrCopy(helparg[i],intinfo[i].helparg)
  1208.             pattern[i]:=String(PATTERN)
  1209.             StrCopy(pattern[i],intinfo[i].pattern)
  1210.             header[i]:=String(HEADER)
  1211.             StrCopy(header[i],intinfo[i].header)
  1212.         ENDFOR
  1213.     ENDIF
  1214. ENDPROC
  1215.  
  1216. PROC refreshintlist()
  1217.     intsgad.set(DCLV_LIST,-1)
  1218.     intsgad.set(DCLV_LIST,intlist.addr())
  1219. ENDPROC
  1220.  
  1221. PROC updateintlist(newpos)
  1222. DEF i
  1223.     intlist.clear()
  1224.     FOR i:=0 TO numints-1 DO intlist.add(intinfo[i].intname)
  1225.     intlist.item(newpos)
  1226. ENDPROC
  1227.  
  1228. PROC updateints(oldnumints,newnumints,newpos)
  1229.     endints(oldnumints)
  1230.     newints(newnumints)
  1231.     moveinintlist(newpos)
  1232.     intschange:=TRUE
  1233. ENDPROC
  1234.  
  1235. PROC useints()
  1236. DEF i
  1237.     END intinfo2[numintst]
  1238.     NEW intinfo2[numints]
  1239.     FOR i:=0 TO numints-1
  1240.         CopyMem(intinfo[i],intinfo2[i],SIZEOF interfaceinfo)
  1241.     ENDFOR
  1242.     numintst:=numints
  1243.     intschange:=FALSE
  1244. ENDPROC
  1245.  
  1246. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1247. -- interface definition
  1248. */
  1249.  
  1250. PROC openint(num)
  1251. DEF van:PTR TO vanilla,image:PTR TO filereqimage,intgui2:PTR TO LONG,ghint2:PTR TO guihandle,
  1252. intnamegad2,prognamegad2,songarggad2,helparggad2,progargsgad2,consolegad2,
  1253. headergad2,headeroffgad2,patterngad2,numoffgad2,numlengad2,numaddgad2,
  1254. songsoffgad2,songslengad2,songsaddgad2,
  1255. songnumlen,numsongslen
  1256.  
  1257.     IF ghint[num]=NIL
  1258.         NEW van.vanilla([ESCAPE,"1","?"])
  1259.         intvan[num]:=van
  1260.         NEW image.filereqimage()
  1261.         intfilereqimage[num]:=image
  1262.  
  1263.         IF intinfo[num].songnumlen=4 THEN songnumlen:=3 ELSE songnumlen:=intinfo[num].songnumlen
  1264.         IF intinfo[num].numsongslen=4 THEN numsongslen:=3 ELSE numsongslen:=intinfo[num].numsongslen
  1265.  
  1266.         intgui[num]:=
  1267.             NEW [
  1268.                 NEW [ROWS,
  1269.                     NEW [EQCOLS,
  1270.                         NEW [SBUTTON,{int_changegui},'_Invocation',INVGUI,"i",NIL,TRUE],
  1271.                         NEW [SBUTTON,{int_changegui},'_Recognition',RECOGGUI,"r",NIL,FALSE]],
  1272.                     NEW [BAR],
  1273.                     NEW [ROWS,
  1274.                         intnamegad2:=NEW [STR,{int_intname},'_Name',intname[num],100,8,FALSE,NIL,"n"]],
  1275.                     NEW [BAR],
  1276.                     NEW [EQROWS,
  1277.                         NEW [COLS,
  1278.                             prognamegad2:=NEW [STR,{int_progname},'     _Path',progname[num],100,8,FALSE,NIL,"p"],
  1279.                             NEW [PLUGIN,{int_prognamereq},image.nib]],
  1280.                         progargsgad2:=NEW [STR,{int_progargs},'_Misc args',progargs[num],100,8,FALSE,NIL,"m"],
  1281.                         songarggad2:=NEW [STR,{int_songarg},'_Song arg',songarg[num],100,8,FALSE,NIL,"s"],
  1282.                         NEW [COLS,
  1283.                             helparggad2:=NEW [STR,{int_helparg},' _Help arg',helparg[num],100,4,FALSE,NIL,"h"],
  1284.                             NEW [BUTTON,{int_help},'_?',NIL,"?",NIL,FALSE]],
  1285.                         consolegad2:=NEW [STR,{int_console},'Conso_le',console[num],100,8,FALSE,NIL,"l"],
  1286.                         NEW [CHECK,{int_quotes},'Put _quotes around modname',intinfo[num].quotes,FALSE,NIL,"q"],
  1287.                         NEW [CHECK,{int_filter},'_Force filter off',intinfo[num].filter,FALSE,NIL,"f"]],
  1288.                     NEW [ROWS,
  1289.                         NEW [BAR],
  1290.                         NEW [COLS,
  1291.                             NEW [BUTTON,{int_use},'_Use',NIL,"u",NIL,FALSE],
  1292.                             NEW [SPACEH],
  1293.                             NEW [BUTTON,{int_cancel},'_Cancel',NIL,"c",NIL,FALSE]],
  1294.                             NEW [PLUGIN,{int_vanilla},intvan[num]]]],
  1295.  
  1296.                 NEW [ROWS,
  1297.                     NEW [EQCOLS,
  1298.                         NEW [SBUTTON,{int_changegui},'_Invocation',INVGUI,"i",NIL,FALSE],
  1299.                         NEW [SBUTTON,{int_changegui},'_Recognition',RECOGGUI,"r",NIL,TRUE]],
  1300.                     NEW [BAR],
  1301.                     NEW [ROWS,
  1302.                         NEW [COLS,
  1303.                             headergad2:=NEW [STR,{int_header},' _Header',header[num],100,5,FALSE,NIL,"h"],
  1304.                             headeroffgad2:=NEW [INTEGER,{int_headeroff},'_Offset',intinfo[num].headeroffset,5,FALSE,"o"]],
  1305.                         patterngad2:=NEW [STR,{int_pattern},'_Pattern',pattern[num],100,5,FALSE,NIL,"p"]],
  1306.                     NEW [BAR],
  1307.                     NEW [ROWS,
  1308.                         NEW [CHECK,{int_songs},'_Subsong support',intinfo[num].songs,TRUE,NIL,"s"],
  1309.                         numoffgad2:=NEW [INTEGER,{int_numoff},' _Default song offset',intinfo[num].songnumoffset,6,0,"d",Not(intinfo[num].songs)],
  1310.                         NEW [COLS,
  1311.                             numlengad2:=NEW [CYCLE,{int_numlen},'_Length',['0','1','2','4',NIL],songnumlen,0,"l",Not(intinfo[num].songs)],
  1312.                             numaddgad2:=NEW [INTEGER,{int_numadd},'_Add to value',intinfo[num].songnumadd,6,0,"a",Not(intinfo[num].songs)]],
  1313.                         songsoffgad2:=NEW [INTEGER,{int_songsoff},'_Num songs offset',intinfo[num].numsongsoffset,6,0,"n",Not(intinfo[num].songs)],
  1314.                         NEW [COLS,
  1315.                             songslengad2:=NEW [CYCLE,{int_songslen},'L_ength',['0','1','2','4',NIL],numsongslen,0,"e",Not(intinfo[num].songs)],
  1316.                             songsaddgad2:=NEW [INTEGER,{int_songsadd},'Add to _value',intinfo[num].numsongsadd,6,0,"v",Not(intinfo[num].songs)]]],
  1317.                     NEW [ROWS,
  1318.                         NEW [BAR],
  1319.                         NEW [COLS,
  1320.                             NEW [BUTTON,{int_use},'_Use',NIL,"u",NIL,FALSE],
  1321.                             NEW [SPACEH],
  1322.                             NEW [BUTTON,{int_cancel},'_Cancel',NIL,"c",NIL,FALSE]],
  1323.                             NEW [PLUGIN,{int_vanilla},intvan[num]]]]
  1324.             ]
  1325.  
  1326.             intnamegad[num]:=intnamegad2 ; prognamegad[num]:=prognamegad2
  1327.             songarggad[num]:=songarggad2 ; helparggad[num]:=helparggad2
  1328.             progargsgad[num]:=progargsgad2 ; consolegad[num]:=consolegad2 ; headergad[num]:=headergad2
  1329.             headeroffgad[num]:=headeroffgad2 ; patterngad[num]:=patterngad2 ; numoffgad[num]:=numoffgad2
  1330.             numlengad[num]:=numlengad2 ; numaddgad[num]:=numaddgad2; songsoffgad[num]:=songsoffgad2
  1331.             songslengad[num]:=songslengad2 ; songsaddgad[num]:=songsaddgad2
  1332.  
  1333.             intgui2:=intgui[num]
  1334.             ghint[num]:=addmultiA(mh,intinfo[num].intname,intgui2[intindex[num]],
  1335.                 [EG_MENU,menu,EG_CLOSE,{int_use},EG_INFO,num,TAG_DONE])
  1336.             CopyMem(intinfo[num],intinfo3[num],SIZEOF interfaceinfo)
  1337.             intchangelist[num]:=FALSE
  1338.     ELSE
  1339.         ghint2:=ghint[num]
  1340.         WindowToFront(ghint2.wnd)
  1341.         ActivateWindow(ghint2.wnd)
  1342.     ENDIF
  1343. ENDPROC
  1344.  
  1345. PROC closeint(num)
  1346. DEF van:PTR TO vanilla,i,intgui2:PTR TO LONG
  1347.     cleangui(ghint[num])
  1348.     ghint[num]:=NIL
  1349.     intgui2:=intgui[num]
  1350.     FOR i:=INVGUI TO RECOGGUI DO disposegui(intgui2[i])
  1351.     van:=intvan[num]
  1352.     END van
  1353. ENDPROC
  1354.  
  1355. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1356. -- interface shortcuts
  1357. */
  1358.  
  1359. PROC int_vanilla(num,plugin:PTR TO vanilla)
  1360.     SELECT 128 OF plugin.hit
  1361.         CASE ESCAPE
  1362.             int_use(num)
  1363.         CASE "1"
  1364.             int_prognamereq(num,0)
  1365.         CASE "?"
  1366.             int_help(num)
  1367.     ENDSELECT
  1368. ENDPROC
  1369.  
  1370. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1371. -- interface gui
  1372. */
  1373.  
  1374. PROC int_changegui(index,num)
  1375. DEF intgui2:PTR TO LONG
  1376.     intgui2:=intgui[num]
  1377.     changegui(ghint[num],intgui2[index])
  1378.     intindex[num]:=index
  1379. ENDPROC
  1380.  
  1381. PROC int_intname(num,news)
  1382.     IF StrCmp(intinfo[num].intname,news)=FALSE
  1383.         strcopy(intinfo[num].intname,news)
  1384.         changetitle(ghint[num],intinfo[num].intname)
  1385.         changeintlist(num,news)
  1386.         intchangelist[num]:=TRUE
  1387.     ENDIF
  1388. ENDPROC
  1389.  
  1390. PROC int_progname(num,news)
  1391.     IF StrCmp(intinfo[num].progname,news)=FALSE
  1392.         strcopy(intinfo[num].progname,news)
  1393.         intchangelist[num]:=TRUE
  1394.     ENDIF
  1395. ENDPROC
  1396.  
  1397. PROC int_prognamereq(num,plugin)
  1398.     IF filereq('Choose program file',intinfo[num].progname)
  1399.         setstr(ghint[num],prognamegad[num],intinfo[num].progname)
  1400.         intchangelist[num]:=TRUE
  1401.     ENDIF
  1402. ENDPROC
  1403.  
  1404. PROC int_songarg(num,news)
  1405.     IF StrCmp(intinfo[num].songarg,news)=FALSE
  1406.         strcopy(intinfo[num].songarg,news)
  1407.         intchangelist[num]:=TRUE
  1408.     ENDIF
  1409. ENDPROC
  1410.  
  1411. PROC int_helparg(num,news)
  1412.     IF StrCmp(intinfo[num].helparg,news)=FALSE
  1413.         strcopy(intinfo[num].helparg,news)
  1414.         intchangelist[num]:=TRUE
  1415.     ENDIF
  1416. ENDPROC
  1417.  
  1418. PROC int_help(num)
  1419. DEF command[256]:STRING
  1420.     StrAdd(command,intinfo[num].progname)
  1421.     IF intinfo[num].helparg
  1422.         StrAdd(command,' ',1)
  1423.         StrAdd(command,intinfo[num].helparg)
  1424.     ENDIF
  1425.     IF debug THEN PrintF('command: \s\n',command)
  1426.     SystemTagList(command,[SYS_ASYNCH,TRUE,SYS_INPUT,NIL,SYS_OUTPUT,NIL,TAG_DONE])
  1427. ENDPROC
  1428.  
  1429. PROC int_progargs(num,news)
  1430.     IF StrCmp(intinfo[num].progargs,news)=FALSE
  1431.         strcopy(intinfo[num].progargs,news)
  1432.         intchangelist[num]:=TRUE
  1433.     ENDIF
  1434. ENDPROC
  1435.  
  1436. PROC int_console(num,news)
  1437.     IF StrCmp(intinfo[num].console,news)=FALSE
  1438.         strcopy(intinfo[num].console,news)
  1439.         intchangelist[num]:=TRUE
  1440.     ENDIF
  1441. ENDPROC
  1442.  
  1443. PROC int_quotes(num,quotes)
  1444.     intinfo[num].quotes:=quotes
  1445.     intchangelist[num]:=TRUE
  1446. ENDPROC
  1447.  
  1448. PROC int_filter(num,filter)
  1449.     intinfo[num].filter:=filter
  1450.     intchangelist[num]:=TRUE
  1451. ENDPROC
  1452.  
  1453. PROC int_header(num,news)
  1454.     IF StrCmp(intinfo[num].header,news)=FALSE
  1455.         strcopy(intinfo[num].header,news)
  1456.         intchangelist[num]:=TRUE
  1457.     ENDIF
  1458. ENDPROC
  1459.  
  1460. PROC int_headeroff(num,headeroffset)
  1461.     IF (intinfo[num].headeroffset)<>headeroffset
  1462.         intinfo[num].headeroffset:=headeroffset
  1463.         intchangelist[num]:=TRUE
  1464.     ENDIF
  1465. ENDPROC
  1466.  
  1467. PROC int_pattern(num,news)
  1468.     IF StrCmp(intinfo[num].pattern,news)=FALSE
  1469.         strcopy(intinfo[num].pattern,news)
  1470.         intchangelist[num]:=TRUE
  1471.     ENDIF
  1472. ENDPROC
  1473.  
  1474. PROC int_songs(num,songs)
  1475.     intinfo[num].songs:=songs
  1476.     enablegads(ghint[num],[numoffgad[num],songs,numlengad[num],songs,
  1477.         numaddgad[num],songs,songsoffgad[num],songs,songslengad[num],songs,
  1478.         songsaddgad[num],songs,TAG_DONE])
  1479.     intchangelist[num]:=TRUE
  1480. ENDPROC
  1481.  
  1482. PROC int_numoff(num,songnumoffset)
  1483.     IF (intinfo[num].songnumoffset)<>songnumoffset
  1484.         intinfo[num].songnumoffset:=songnumoffset
  1485.         intchangelist[num]:=TRUE
  1486.     ENDIF
  1487. ENDPROC
  1488.  
  1489. PROC int_numlen(num,songnumlen)
  1490.     IF songnumlen=3
  1491.         intinfo[num].songnumlen:=4
  1492.     ELSE
  1493.         intinfo[num].songnumlen:=songnumlen
  1494.     ENDIF
  1495.     intchangelist[num]:=TRUE
  1496. ENDPROC
  1497.  
  1498. PROC int_numadd(num,songnumadd)
  1499.     IF (intinfo[num].songnumadd)<>songnumadd
  1500.         intinfo[num].songnumadd:=songnumadd
  1501.         intchangelist[num]:=TRUE
  1502.     ENDIF
  1503. ENDPROC
  1504.  
  1505. PROC int_songsoff(num,numsongsoffset)
  1506.     IF (intinfo[num].numsongsoffset)<>numsongsoffset
  1507.         intinfo[num].numsongsoffset:=numsongsoffset
  1508.         intchangelist[num]:=TRUE
  1509.     ENDIF
  1510. ENDPROC
  1511.  
  1512. PROC int_songslen(num,numsongslen)
  1513.     IF numsongslen=3
  1514.         intinfo[num].numsongslen:=4
  1515.     ELSE
  1516.         intinfo[num].numsongslen:=numsongslen
  1517.     ENDIF
  1518.     intchangelist[num]:=TRUE
  1519. ENDPROC
  1520.  
  1521. PROC int_songsadd(num,numsongsadd)
  1522.     IF (intinfo[num].numsongsadd)<>numsongsadd
  1523.         intinfo[num].numsongsadd:=numsongsadd
  1524.         intchangelist[num]:=TRUE
  1525.     ENDIF
  1526. ENDPROC
  1527.  
  1528. PROC int_use(num) HANDLE
  1529. DEF index
  1530.     index:=intindex[num]
  1531.     SELECT index
  1532.         CASE INVGUI
  1533.             strcopy(intinfo[num].intname,getstr(ghint[num],intnamegad[num]))
  1534.             strcopy(intinfo[num].progname,getstr(ghint[num],prognamegad[num]))
  1535.             strcopy(intinfo[num].songarg,getstr(ghint[num],songarggad[num]))
  1536.             strcopy(intinfo[num].helparg,getstr(ghint[num],helparggad[num]))
  1537.             strcopy(intinfo[num].progargs,getstr(ghint[num],progargsgad[num]))
  1538.             strcopy(intinfo[num].console,getstr(ghint[num],consolegad[num]))
  1539.         CASE RECOGGUI
  1540.             intinfo[num].songnumoffset:=getinteger(ghint[num],numoffgad[num])
  1541.             intinfo[num].numsongsoffset:=getinteger(ghint[num],songsoffgad[num])
  1542.             intinfo[num].songnumadd:=getinteger(ghint[num],numaddgad[num])
  1543.             intinfo[num].numsongsadd:=getinteger(ghint[num],songsaddgad[num])
  1544.             strcopy(intinfo[num].header,getstr(ghint[num],headergad[num]))
  1545.             intinfo[num].headeroffset:=getinteger(ghint[num],headeroffgad[num])
  1546.             strcopy(intinfo[num].pattern,getstr(ghint[num],patterngad[num]))
  1547.     ENDSELECT
  1548.     IF ghints
  1549.         intlist.change2(num,intinfo[num].intname)
  1550.         refreshintlist()
  1551.     ENDIF
  1552.     closeint(num)
  1553.     intschange:=TRUE
  1554. EXCEPT
  1555. ENDPROC
  1556.  
  1557. PROC int_cancel(num)
  1558.     IF intchangelist[num]
  1559.         CopyMem(intinfo3[num],intinfo[num],SIZEOF interfaceinfo)
  1560.         StrCopy(intname[num],intinfo[num].intname)
  1561.         StrCopy(progname[num],intinfo[num].progname)
  1562.         StrCopy(progargs[num],intinfo[num].progargs)
  1563.         StrCopy(console[num],intinfo[num].console)
  1564.         StrCopy(songarg[num],intinfo[num].songarg)
  1565.         StrCopy(helparg[num],intinfo[num].helparg)
  1566.         StrCopy(pattern[num],intinfo[num].pattern)
  1567.         StrCopy(header[num],intinfo[num].header)
  1568.     ENDIF
  1569.     closeint(num)
  1570. ENDPROC
  1571.  
  1572. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1573. -- message and interrupt control
  1574. */
  1575.  
  1576. PROC multiloop2(mh:PTR TO multihandle)
  1577. DEF res=-1,wakeupsigs
  1578.     WHILE res<0
  1579.         EXIT mh.opencount=0
  1580.       wakeupsigs:=Wait(vb.mainsig OR mh.sig)
  1581.         IF wakeupsigs AND vb.mainsig THEN ticker_()
  1582.         res:=multimessage(mh)
  1583.     ENDWHILE
  1584. ENDPROC res
  1585.  
  1586. PROC ticker_()
  1587.     IF ticker AND int
  1588.         IF int.running()
  1589.             titletimer__()
  1590.         ELSE
  1591.             IF modnum<(nummods-1)
  1592.                 main_nextmod()
  1593.             ELSE
  1594.                 stopmain()
  1595.             ENDIF
  1596.         ENDIF
  1597.     ENDIF
  1598. ENDPROC
  1599.  
  1600. PROC titletimer__()
  1601. DEF hours2=0,mins2=0,secs2=0,figure[4]:STRING,intname[INTERFACE]:STRING
  1602.     IF ti.started THEN hours2,mins2,secs2:=ti.stop()
  1603.     IF (hours<>hours2) OR (mins<>mins2) OR (secs<>secs2)
  1604.         hours:=hours2
  1605.         mins:=mins2
  1606.         secs:=secs2
  1607.         StrCopy(maintitle,'EYP, ')
  1608.         IF int
  1609.             StringF(intname,'\s, ',int.intinfo.intname)
  1610.             StrAdd(maintitle,intname)
  1611.         ENDIF
  1612.         IF hours>0
  1613.             StringF(figure,'\d:',hours)
  1614.             StrAdd(maintitle,figure)
  1615.         ENDIF
  1616.         IF mins>=10
  1617.             StringF(figure,'\z\d[2]:',mins)
  1618.             StrAdd(maintitle,figure)
  1619.         ELSE
  1620.             StringF(figure,'\z\d[1]:',mins)
  1621.             StrAdd(maintitle,figure)
  1622.         ENDIF
  1623.         StringF(figure,'\z\d[2]',secs)
  1624.         StrAdd(maintitle,figure)
  1625.         changetitle(ghmain,maintitle)
  1626.     ENDIF
  1627. ENDPROC
  1628.  
  1629. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1630. -- EasyGUI support
  1631. */
  1632.  
  1633. PROC enablegads(gh,enablelist:PTR TO LONG)
  1634. DEF item=0
  1635.     REPEAT
  1636.         setdisabled(gh,enablelist[item],Not(enablelist[item+1]))
  1637.         item:=item+2
  1638.     UNTIL enablelist[item]=0
  1639. ENDPROC
  1640.  
  1641. PROC resizewin(gh:PTR TO guihandle,x,y,xs,ys)
  1642. DEF win:PTR TO window
  1643.     win:=gh.wnd
  1644.     IF ((x<>-1) AND (y<>-1)) AND ((x<>win.leftedge) OR (y<>win.topedge))
  1645.         movewin(gh,x,y)
  1646.     ENDIF
  1647.     IF ((xs<>-1) AND (ys<>-1)) AND ((xs<>win.width) OR (ys<>win.height))
  1648.         sizewin(gh,xs,ys)
  1649.     ENDIF
  1650. ENDPROC
  1651.  
  1652. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1653. -- reqtooller support
  1654. */
  1655.  
  1656. PROC filereq(title,fullfilename)
  1657. DEF pathname[FULL]:STRING,success
  1658.     StrCopy(pathname,fullfilename,PathPart(fullfilename)-fullfilename)
  1659.     rt.setattrs([RT_TITLE,title,RT_PATH,pathname,RT_FILENAME,FilePart(fullfilename),
  1660.   RT_FULLNAME,TRUE,TAG_DONE])
  1661.     IF (success:=rt.req(RTREQ_FILE)) THEN strcopy(fullfilename,rt.get(RT_FILENAME))
  1662. ENDPROC success
  1663.  
  1664. PROC pathreq(title,pathname)
  1665. DEF success
  1666.     rt.setattrs([RT_TITLE,title,RT_PATH,pathname,TAG_DONE])
  1667.     IF (success:=rt.req(RTREQ_PATH)) THEN    strcopy(pathname,rt.get(RT_PATH))
  1668. ENDPROC success
  1669.  
  1670. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1671. -- shell and Workbench args
  1672. */
  1673.  
  1674. PROC startupargs() HANDLE
  1675. DEF args[2]:ARRAY OF LONG,rdargs,wb:PTR TO wbstartup,p=FALSE
  1676.     IF (wb:=wbmessage)=NIL
  1677.         args[0]:=NIL
  1678.         args[1]:=NIL
  1679.         IF (rdargs:=ReadArgs('MOD=MODULE/M,PLST=PLAYLIST',args,NIL))=NIL
  1680.             Raise(ERR_READARGS)
  1681.         ELSE
  1682.             IF args[0]
  1683.                 shelladdmods(args[0])
  1684.                 p:=TRUE
  1685.             ENDIF
  1686.             IF args[1]
  1687.                 StrCopy(plstfilename,args[1])
  1688.                 loadplst(TRUE)
  1689.                 p:=TRUE
  1690.             ENDIF
  1691.             FreeArgs(rdargs)
  1692.         ENDIF
  1693.     ELSE
  1694.         IF wb.numargs>1
  1695.             wbaddmods(wb)
  1696.             p:=TRUE
  1697.         ENDIF
  1698.     ENDIF
  1699.     IF p
  1700.         refreshplst()
  1701.         plstitem(0)
  1702.         play()
  1703.     ENDIF
  1704. EXCEPT
  1705.     SELECT exception
  1706.         CASE ERR_READARGS
  1707.             errorreq('Couldn''t parse shell arguments.','shellargs')
  1708.     ENDSELECT
  1709. ENDPROC
  1710.  
  1711. PROC shelladdmods(shellarg:PTR TO LONG)
  1712. DEF i=0,dir,file,filepart
  1713.     WHILE ((file:=shellarg[i])<>NIL) AND ((dir:=String(FULL))<>NIL)
  1714.         filepart:=FilePart(file)
  1715.         IF filepart>file THEN StrCopy(dir,file,filepart-file)
  1716.         plst.add(dir,filepart)
  1717.         i++
  1718.     ENDWHILE
  1719.     nummods:=plst.numitems()
  1720. ENDPROC
  1721.  
  1722. PROC wbaddmods(wb:PTR TO wbstartup)
  1723. DEF i,args:PTR TO wbarg,lockname[FULL]:STRING
  1724.     args:=wb.arglist
  1725.     FOR i:=1 TO (wb.numargs-1)
  1726.         IF NameFromLock(args[i].lock,lockname,FULL)
  1727.             plst.add(lockname,args[i].name)
  1728.         ENDIF
  1729.     ENDFOR
  1730.     nummods:=plst.numitems()
  1731. ENDPROC
  1732.  
  1733. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1734. -- load and save playlist
  1735. */
  1736.  
  1737. PROC loadplst(append=FALSE) HANDLE
  1738. DEF buffer=NIL,bufferlen=0,nummods2,success=FALSE,i,j=2, -> skip 2 bytes (1 int) = nummods2
  1739. dirname2[FULL]:ARRAY,filename2[FULL]:ARRAY
  1740.     buffer,bufferlen:=readfile(plstfilename,0,'EYPL',FILEHEADER,VERSION)
  1741.     IF (nummods2:=Int(buffer))=0 THEN Raise(ERR_NOMOD)
  1742.     IF append
  1743.         nummods:=nummods+nummods2
  1744.     ELSE
  1745.         nummods:=nummods2
  1746.         plst.clear()
  1747.     ENDIF
  1748.     FOR i:=0 TO nummods2-1
  1749.         strget(dirname2,buffer,{j})
  1750.         strget(filename2,buffer,{j})
  1751.         plst.add(dirname2,filename2)
  1752.     ENDFOR
  1753.     success:=TRUE
  1754.     IF debug THEN PrintF('loaded: \s, modules: \d\n',plstfilename,nummods)
  1755. EXCEPT DO
  1756.     END buffer[bufferlen]
  1757.     ReThrow()
  1758. ENDPROC success
  1759.  
  1760. PROC saveplst(askoverwrite) HANDLE
  1761. DEF buffer=NIL,bufferlen=0,success=FALSE,i,j,oldpos
  1762.     IF nummods
  1763.         bufferlen:=FILEHEADER+2+(2*FULL*nummods)
  1764.         NEW buffer[bufferlen]
  1765.         strcopy(buffer,'EYPL')
  1766.         PutChar(buffer+FILEHEADER-1,VERSION)
  1767.         PutInt(buffer+FILEHEADER,nummods)
  1768.         j:=FILEHEADER+2
  1769.         oldpos:=plst.pos()
  1770.         FOR i:=0 TO nummods-1
  1771.             plst.item(i)
  1772.             strput(buffer,plst.dirlist.obj(),{j})
  1773.             strput(buffer,plst.filelist.obj(),{j})
  1774.         ENDFOR
  1775.         plst.item(oldpos)
  1776.         writefile(plstfilename,buffer,j,askoverwrite)
  1777.         success:=TRUE
  1778.         IF debug THEN PrintF('saved: \s, modules: \d\n',plstfilename,nummods)
  1779.     ENDIF
  1780. EXCEPT DO
  1781.     END buffer[bufferlen]
  1782. ENDPROC success
  1783.  
  1784. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1785. -- load and save prefs
  1786. */
  1787.  
  1788. PROC loadprefs() HANDLE
  1789. DEF buffer=NIL,bufferlen=0,success=FALSE,i=0
  1790.     buffer,bufferlen:=readfile(prefsfilename,0,'EYPP',FILEHEADER,VERSION)
  1791.  
  1792.     strget(modpath,buffer,{i})
  1793.     strget(plstpath,buffer,{i})
  1794.     mainx:=longget(buffer,{i})
  1795.     mainy:=longget(buffer,{i})
  1796.     mainxs:=longget(buffer,{i})
  1797.     mainys:=longget(buffer,{i})
  1798.  
  1799.     success:=TRUE
  1800.     IF debug THEN PrintF('loaded: \s\n',prefsfilename)
  1801. EXCEPT DO
  1802.     END buffer[bufferlen]
  1803. ENDPROC success
  1804.  
  1805. PROC saveprefs(askoverwrite,snapshot=FALSE) HANDLE
  1806. DEF buffer=NIL,bufferlen=0,i,success=FALSE,win:PTR TO window
  1807.     bufferlen:=FILEHEADER+StrLen(modpath)+1+StrLen(plstpath)+1+(4*4)
  1808. -> 4*4=main window snapshot + 4*4=ints window snapshot
  1809.     NEW buffer[bufferlen]
  1810.     strcopy(buffer,'EYPP')
  1811.     PutChar(buffer+FILEHEADER-1,VERSION)
  1812.     i:=FILEHEADER
  1813.  
  1814.     strput(buffer,modpath,{i})
  1815.     strput(buffer,plstpath,{i})
  1816.  
  1817.     IF snapshot
  1818.         win:=ghmain.wnd
  1819.         mainx:=win.leftedge
  1820.         mainy:=win.topedge
  1821.         mainxs:=win.width
  1822.         mainys:=win.height
  1823.     ENDIF
  1824.     longput(buffer,mainx,{i})
  1825.     longput(buffer,mainy,{i})
  1826.     longput(buffer,mainxs,{i})
  1827.     longput(buffer,mainys,{i})
  1828.  
  1829.     writefile(prefsfilename,buffer,i,askoverwrite)
  1830.     success:=TRUE
  1831.     IF debug THEN PrintF('saved: \s\n',prefsfilename)
  1832. EXCEPT DO
  1833.     END buffer[bufferlen]
  1834. ENDPROC success
  1835.  
  1836. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1837. -- load and save interfaces
  1838. */
  1839.  
  1840. PROC loadints(append=FALSE) HANDLE
  1841. DEF buffer=NIL,bufferlen=0,numints2,intinfol:PTR TO interfaceinfo,i,appendpos=0,j=1, -> skip 1 byte = numints2
  1842. success=FALSE
  1843.     buffer,bufferlen:=readfile(intsfilename,0,'EYPI',FILEHEADER,VERSION)
  1844.     IF (numints2:=Char(buffer))=0 THEN Raise(ERR_NOINT)
  1845.     IF append
  1846.         numints2:=numints+numints2
  1847.         NEW intinfol[numints2]
  1848.         FOR i:=0 TO numints-1
  1849.             CopyMem(intinfo[i],intinfol[i],SIZEOF interfaceinfo)
  1850.         ENDFOR
  1851.         appendpos:=numints
  1852.     ELSE
  1853.         NEW intinfol[numints2]
  1854.     ENDIF
  1855.     END intinfo[numints]
  1856.     numints:=numints2
  1857.     intinfo:=intinfol
  1858.     FOR i:=appendpos TO numints2-1
  1859.         strget(intinfo[i].intname,buffer,{j})
  1860.         strget(intinfo[i].progname,buffer,{j})
  1861.         strget(intinfo[i].progargs,buffer,{j})
  1862.         strget(intinfo[i].console,buffer,{j})
  1863.         strget(intinfo[i].songarg,buffer,{j})
  1864.         strget(intinfo[i].helparg,buffer,{j})
  1865.         strget(intinfo[i].pattern,buffer,{j})
  1866.         strget(intinfo[i].header,buffer,{j})
  1867.  
  1868.         intinfo[i].quotes:=longget(buffer,{j})
  1869.         intinfo[i].filter:=longget(buffer,{j})
  1870.         intinfo[i].songs:=longget(buffer,{j})
  1871.         intinfo[i].songnumoffset:=longget(buffer,{j})
  1872.         intinfo[i].songnumlen:=longget(buffer,{j})
  1873.         intinfo[i].songnumadd:=longget(buffer,{j})
  1874.         intinfo[i].numsongsoffset:=longget(buffer,{j})
  1875.         intinfo[i].numsongslen:=longget(buffer,{j})
  1876.         intinfo[i].numsongsadd:=longget(buffer,{j})
  1877.         intinfo[i].headeroffset:=longget(buffer,{j})
  1878.     ENDFOR
  1879.     success:=TRUE
  1880.     IF debug THEN PrintF('loaded: \s, interfaces: \d\n',intsfilename,numints)
  1881. EXCEPT DO
  1882.     END buffer[bufferlen]
  1883. ENDPROC success
  1884.  
  1885. PROC saveints(askoverwrite) HANDLE
  1886. DEF buffer=NIL,bufferlen=0,i,j,success=FALSE
  1887.     IF numints
  1888.         bufferlen:=FILEHEADER+1+((SIZEOF interfaceinfo)*numints)
  1889.         NEW buffer[bufferlen]
  1890.         strcopy(buffer,'EYPI')
  1891.         PutChar(buffer+FILEHEADER-1,VERSION)
  1892.         PutChar(buffer+FILEHEADER,numints)
  1893.         j:=FILEHEADER+1
  1894.         FOR i:=0 TO numints-1
  1895.             strput(buffer,intinfo[i].intname,{j})
  1896.             strput(buffer,intinfo[i].progname,{j})
  1897.             strput(buffer,intinfo[i].progargs,{j})
  1898.             strput(buffer,intinfo[i].console,{j})
  1899.             strput(buffer,intinfo[i].songarg,{j})
  1900.             strput(buffer,intinfo[i].helparg,{j})
  1901.             strput(buffer,intinfo[i].pattern,{j})
  1902.             strput(buffer,intinfo[i].header,{j})
  1903.  
  1904.             longput(buffer,intinfo[i].quotes,{j})
  1905.             longput(buffer,intinfo[i].filter,{j})
  1906.             longput(buffer,intinfo[i].songs,{j})
  1907.             longput(buffer,intinfo[i].songnumoffset,{j})
  1908.             longput(buffer,intinfo[i].songnumlen,{j})
  1909.             longput(buffer,intinfo[i].songnumadd,{j})
  1910.             longput(buffer,intinfo[i].numsongsoffset,{j})
  1911.             longput(buffer,intinfo[i].numsongslen,{j})
  1912.             longput(buffer,intinfo[i].numsongsadd,{j})
  1913.             longput(buffer,intinfo[i].headeroffset,{j})
  1914.         ENDFOR
  1915.  
  1916.         writefile(intsfilename,buffer,j,askoverwrite)
  1917.         success:=TRUE
  1918.         IF debug THEN PrintF('saved: \s, interfaces: \d\n',intsfilename,numints)
  1919.     ENDIF
  1920. EXCEPT DO
  1921.     END buffer[bufferlen]
  1922. ENDPROC success
  1923.  
  1924. /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1925. -- load and save support
  1926. */
  1927.  
  1928. PROC strget(dest,buffer,i)
  1929.     strcopy(dest,buffer+^i)
  1930.     ^i:=^i+StrLen(dest)+1
  1931. ENDPROC
  1932.  
  1933. PROC longget(buffer,i)
  1934. DEF i2
  1935.     i2:=^i
  1936.     ^i:=^i+4
  1937. ENDPROC Long(buffer+i2)
  1938.  
  1939. PROC strput(buffer,source,i)
  1940.     strcopy(buffer+^i,source)
  1941.     ^i:=^i+StrLen(source)+1
  1942. ENDPROC
  1943.  
  1944. PROC longput(buffer,source,i)
  1945.     PutLong(buffer+^i,source)
  1946.     ^i:=^i+4
  1947. ENDPROC
  1948.