home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaMiscModsCD3.iso / _PROGRAMME / CONVERTER / pro2fast11.lha / Pro2Fast / Source / Pro2Fast.c next >
Encoding:
C/C++ Source or Header  |  1996-02-29  |  59.1 KB  |  1,905 lines

  1. /********************************************************************
  2. *                                                                   *
  3. * This program can convert Protracker modules to a Fast/Taketracker *
  4. * module.                                                           *
  5. *                                                                   *
  6. ********************************************************************/
  7.  
  8. #include <string.h>
  9.  
  10. #include <exec/libraries.h>
  11. #include <exec/memory.h>
  12. #include <dos/dos.h>
  13. #include <intuition/intuition.h>
  14. #include <intuition/gadgetclass.h>
  15. #include <libraries/gadtools.h>
  16. #include <libraries/reqtools.h>
  17. #include <libraries/xpk.h>
  18.  
  19. #include <proto/exec.h>
  20. #include <proto/dos.h>
  21. #include <proto/intuition.h>
  22. #include <proto/gadtools.h>
  23. #include <proto/utility.h>
  24. #include <proto/reqtools.h>
  25.  
  26. #include "Pro2Fast.h"
  27.  
  28. // Define global variables
  29.  
  30. char Version[] = "$VER: Pro2Fast version 1.1";
  31. char ProgramName[] = "Pro2Fast";
  32.  
  33. char CLIString[] = "C=CALCULATE/S,M1=MODULE1/K,C11/K,C12/K,C13/K,C14/K,L1=LOOP1/S,M2=MODULE2/K,C21/K,C22/K,C23/K,C24/K,L2=LOOP2/S,M3=MODULE3/K,C31/K,C32/K,C33/K,C34/K,L3=LOOP3/S,M4=MODULE4/K,C41/K,C42/K,C43/K,C44/K,L4=LOOP4/S,M5=MODULE5/K,C51/K,C52/K,C53/K,C54/K,L5=LOOP5/S,M6=MODULE6/K,C61/K,C62/K,C63/K,C64/K,L6=LOOP6/S,M7=MODULE7/K,C71/K,C72/K,C73/K,C74/K,L7=LOOP7/S,M8=MODULE8/K,C81/K,C82/K,C83/K,C84/K,L8=LOOP8/S,DM=DESTMODULE/K";
  34.  
  35. ULONG ArgList[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,
  36.                    0,0,0,0,0,0,0,0,0,0,0,0,
  37.                    0,0,0,0,0,0,0,0,0,0,0,0,
  38.                    0,0,0,0,0,0,0,0,0,0,0,0,0};
  39.  
  40. char outbuf[80];
  41.  
  42. struct Library *GadToolsBase;
  43. struct ReqToolsBase *ReqToolsBase;
  44. struct Library *XpkBase;
  45. struct Gadget *glist = NULL;
  46. struct Gadget *our_gadgets[MaxGadgets];
  47. void  *vi = NULL;
  48. struct TextAttr Topaz80 = {"topaz.font",8,0,0};
  49. struct Image DiskNorm = {0,0,DISKWIDTH,DISKHEIGHT,2,Disk_Norm,3,0,NULL};
  50. struct Image DiskPres = {0,0,DISKWIDTH,DISKHEIGHT,2,Disk_Pres,3,0,NULL};
  51. struct Image AboutPic = {5,3,195,149,2,AboutImage,3,0,NULL};
  52.  
  53. BYTE  Activated[8] = {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
  54. UBYTE Chan[4][8] = {0, 0, 0, 0, 0, 0, 0, 0,
  55.                    1, 1, 1, 1, 1, 1, 1, 1,
  56.                    1, 1, 1, 1, 1, 1, 1, 1,
  57.                    0, 0, 0, 0, 0, 0, 0, 0};
  58. UBYTE Loop[8]    = {0, 0, 0, 0, 0, 0, 0, 0};
  59.  
  60. UBYTE chantab[64];
  61.  
  62. char File1[216], File2[216], File3[216], File4[216];
  63. char File5[216], File6[216], File7[216], File8[216];
  64. char DestFile[216];
  65.  
  66. APTR filereq;
  67. int lpoi, rpoi;
  68.  
  69. // Cycle Labels
  70.  
  71. char LeftTxt[] = {"L"};
  72. char RightTxt[] = {"R"};
  73. char OffTxt[] = {"O"};
  74.  
  75. char EndTxt[] = {"End"};
  76. char LoopTxt[] = {"Loop"};
  77.  
  78. char *ChanLab[] = {(char *)&LeftTxt, (char *)&RightTxt, (char *)&OffTxt, NULL};
  79. char *LoopLab[] = {(char *)&EndTxt, (char *)&LoopTxt, NULL};
  80.  
  81. struct NewMenu ourmenu[] =
  82. {
  83.     { NM_TITLE, "Project", NULL, 0, 0, NULL},
  84.     { NM_ITEM,  "Calculate", "a", 0, 0, NULL},
  85.     { NM_ITEM,  "Convert", "c", 0, 0, NULL},
  86.     { NM_ITEM, NM_BARLABEL, 0, 0, 0, NULL},
  87.     { NM_ITEM, "About", "?", 0, 0, NULL},
  88.     { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL},
  89.     { NM_ITEM, "Quit", "q", 0, 0, NULL},
  90.     { NM_END, NULL, 0, 0, NULL}
  91. };
  92.  
  93.  
  94. // Define Structures
  95.  
  96. struct BorderSize
  97. {
  98.   WORD Top;
  99.   WORD Left;
  100.   WORD Bottom;
  101.   WORD Right;
  102. };
  103.  
  104. struct ModInfo
  105. {
  106.   LONG  Size;
  107.   LONG  CalcSize;
  108.   MODULE *Module;
  109.   UBYTE MaxPatt;
  110. };
  111.  
  112. struct CalcInfo
  113. {
  114.   LONG  Size;
  115.   UBYTE Channels;
  116.   UBYTE SongLen;
  117.   UBYTE MaxPatt;
  118. };
  119.  
  120.  
  121. // Prototypes
  122.  
  123. BOOL TestArgs(void);
  124. void WriteErr(char *errmsg);
  125. void FormatText(char *dest, char *text, ...);
  126. struct BorderSize GetOffsets(struct Screen *scr);
  127. int  CreateGadgets(struct Screen *scr);
  128. void FixDisk(struct Gadget *gad);
  129. void RemoveGadgets(void);
  130. void DrawBevelBoxes(struct Window *win, struct Screen *scr);
  131. void DoWindow(void);
  132. void HandleEvents(struct Window *win, struct Screen *scr, struct Menu *menu);
  133. void FixGadgets(UWORD num, struct Window *win);
  134. void GetFile(struct Gadget *strgad, struct Window *win);
  135. void ShowRequest(char *text, ...);
  136. void CreateMod(struct Window *win);
  137. int  CopySample(struct CalcInfo *cinfo, struct ModInfo *minfo, MODULE *dmod, UBYTE *UsedSamp, APTR *SampPoi);
  138. void FreeSamples(APTR *SampPoi, MODULE *dmod);
  139. void CopyChannels(int num, struct CalcInfo *cinfo, MODULE *smod, MODULE *dmod);
  140. struct CalcInfo CalculateIt(struct Window *win);
  141. int  OneActive(void);
  142. struct ModInfo LoadModule(int num, struct Window *win);
  143. BPTR OpenFile(char *name);
  144. void CloseFile(BPTR fh);
  145. void About(struct Screen *pubscr);
  146.  
  147. /********************************************************************
  148. *                                                                   *
  149. * Main program                                                      *
  150. *                                                                   *
  151. ********************************************************************/
  152.  
  153. void main(void)
  154. {
  155. int i;
  156.  
  157.   if (!(GadToolsBase = OpenLibrary("gadtools.library",37)))
  158.     WriteErr("Ehhhh, can't open gadtools.library.");
  159.   else
  160.   {
  161.     if (!(ReqToolsBase = (struct ReqToolsBase *)OpenLibrary("reqtools.library",37)))
  162.       WriteErr("You need reqtools.library version 37 or higher.");
  163.     else
  164.     {
  165.       if (!(filereq = rtAllocRequestA(RT_FILEREQ, TAG_END)))
  166.         WriteErr("Can't allocate file requester.");
  167.       else
  168.       {
  169.         // Clear filename Variables
  170.         for (i=0; i<216; i++)
  171.         {
  172.           File1[i] = 0;
  173.           File2[i] = 0;
  174.           File3[i] = 0;
  175.           File4[i] = 0;
  176.           File5[i] = 0;
  177.           File6[i] = 0;
  178.           File7[i] = 0;
  179.           File8[i] = 0;
  180.           DestFile[i] = 0;
  181.         }
  182.  
  183.         if (!(TestArgs()))
  184.           DoWindow();
  185.  
  186.         rtFreeReqBuffer(filereq);
  187.       }
  188.       CloseLibrary((struct Library *)ReqToolsBase);
  189.     }
  190.     CloseLibrary(GadToolsBase);
  191.   }
  192. }
  193.  
  194. /********************************************************************
  195. *                                                                   *
  196. * This function will test the CLI arguments and return true or      *
  197. * false to indicate if there was some.                              *
  198. *                                                                   *
  199. ********************************************************************/
  200.  
  201. BOOL TestArgs(void)
  202. {
  203. int i,j,k,c;
  204. UBYTE num;
  205.  
  206.   for (i=0; i<50; i++)
  207.     if (ArgList[i] != NULL)
  208.     {
  209.       for (j=0; j<8; j++)
  210.       {
  211.         k = j*6+1;
  212.         if (ArgList[k] == NULL)
  213.           Activated[j] = FALSE;
  214.         else
  215.         {
  216.           Activated[j] = TRUE;
  217.  
  218.           for (c=1; c<5; c++)
  219.           {
  220.             if (ArgList[k+c] != NULL)
  221.             {
  222.               switch (ToUpper(((char *)ArgList[k+c])[0]))
  223.               {
  224.                 case 'L': num = 0;
  225.                           break;
  226.                 case 'R': num = 1;
  227.                           break;
  228.                 case 'O': num = 2;
  229.                           break;
  230.                 default:  num = Chan[c-1][j];
  231.                           break;
  232.               }
  233.               Chan[c-1][j] = num;
  234.             }
  235.           }
  236.  
  237.           if (ArgList[k+5] == NULL)
  238.             num = 0;
  239.           else
  240.             num = 1;
  241.  
  242.           Loop[j] = num;
  243.         }
  244.       }
  245.  
  246.       if (ArgList[0])
  247.         CalculateIt(NULL);
  248.       else
  249.         CreateMod(NULL);
  250.  
  251.       Write(Output(),outbuf,strlen(outbuf));
  252.       Write(Output(),"\n",1);
  253.       return(TRUE);
  254.     }
  255.  
  256.   return(FALSE);
  257. }
  258.  
  259. /********************************************************************
  260. *                                                                   *
  261. * This function will show an error message in an auto requester.    *
  262. *                                                                   *
  263. ********************************************************************/
  264.  
  265. void WriteErr(char *errmsg)
  266. {
  267. struct IntuiText bodytxt;
  268. struct IntuiText negtxt;
  269.  
  270.   bodytxt.FrontPen  = 255;
  271.   bodytxt.BackPen   = 255;
  272.   bodytxt.DrawMode  = 0;
  273.   bodytxt.LeftEdge  = 14;
  274.   bodytxt.TopEdge   = 14;
  275.   bodytxt.ITextFont = NULL;
  276.   bodytxt.IText     = errmsg;
  277.   bodytxt.NextText  = NULL;
  278.  
  279.   negtxt.FrontPen  = 255;
  280.   negtxt.BackPen   = 255;
  281.   negtxt.DrawMode  = 0;
  282.   negtxt.LeftEdge  = 4;
  283.   negtxt.TopEdge   = 4;
  284.   negtxt.ITextFont = NULL;
  285.   negtxt.IText     = "ABORT";
  286.   negtxt.NextText  = NULL;
  287.  
  288.   AutoRequest(NULL,&bodytxt,NULL,&negtxt,0,0,320,60);
  289. }
  290.  
  291. /********************************************************************
  292. *                                                                   *
  293. * Format a text string via RawDoFmt()                               *
  294. *                                                                   *
  295. ********************************************************************/
  296.  
  297. void FormatText(char *dest, char *text, ...)
  298. {
  299. #define RAWDOFMT_COPY (void *)"\x16\xc0\x4e\x75"  // MOVE.B D0,(A3)+
  300.                                                    // RTS
  301.  
  302.   RawDoFmt(text, &text+1, RAWDOFMT_COPY, dest);
  303. }
  304.  
  305. /********************************************************************
  306. *                                                                   *
  307. * Return the window border sizes.                                   *
  308. *                                                                   *
  309. ********************************************************************/
  310.  
  311. struct BorderSize GetBorder(struct Screen *scr)
  312. {
  313. struct BorderSize borsiz;
  314.  
  315.   borsiz.Left   = scr->WBorLeft;
  316.   borsiz.Top    = scr->Font->ta_YSize+scr->WBorTop+1;
  317.   borsiz.Right  = scr->WBorRight;
  318.   borsiz.Bottom = scr->WBorBottom;
  319.   return(borsiz);
  320. }
  321.  
  322. /********************************************************************
  323. *                                                                   *
  324. * Create gadtools gadgets.                                          *
  325. *                                                                   *
  326. ********************************************************************/
  327.  
  328. int CreateGadgets(struct Screen *scr)
  329. {
  330. struct Gadget *gad;
  331. struct NewGadget ng;
  332. int    success = FALSE;
  333. struct BorderSize bs;
  334.  
  335.   if ((vi = GetVisualInfo(scr, TAG_END)))
  336.   {
  337.     if ((gad = CreateContext(&glist)))
  338.     {
  339.       ng.ng_TextAttr      = &Topaz80;
  340.       ng.ng_VisualInfo    = vi;
  341.  
  342.       bs = GetBorder(scr);
  343.  
  344.       // **** Create Info Gadget
  345.       ng.ng_LeftEdge      = 2+bs.Left;
  346.       ng.ng_TopEdge       = 1+bs.Top;
  347.       ng.ng_Width         = 535;
  348.       ng.ng_Height        = 12;
  349.       ng.ng_GadgetText    = NULL;
  350.       ng.ng_GadgetID      = InfoGad;
  351.       ng.ng_Flags         = PLACETEXT_IN;
  352.  
  353.       our_gadgets[InfoGad-1] = gad = CreateGadget(TEXT_KIND, gad, &ng,
  354.                                     GTTX_Border,TRUE,
  355.                                     GTTX_Text,"                      Welcome to Pro -> Fast",
  356.                                     TAG_END);
  357.  
  358.       // **** Create Module 1 CheckBox
  359.       ng.ng_LeftEdge     += 4;
  360.       ng.ng_TopEdge      += 16;
  361.       ng.ng_Width         = CHECKBOXWIDTH;
  362.       ng.ng_Height        = CHECKBOXHEIGHT;
  363.       ng.ng_GadgetID      = Check1Gad;
  364.  
  365.       our_gadgets[Check1Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  366.                                     GTCB_Checked,TRUE, TAG_END);
  367.  
  368.       // Create Module 2 CheckBox
  369.       ng.ng_TopEdge      += 16;
  370.       ng.ng_GadgetID      = Check2Gad;
  371.  
  372.       our_gadgets[Check2Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  373.                                     TAG_END);
  374.  
  375.       // Create Module 3 CheckBox
  376.       ng.ng_TopEdge      += 16;
  377.       ng.ng_GadgetID      = Check3Gad;
  378.  
  379.       our_gadgets[Check3Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  380.                                     TAG_END);
  381.  
  382.       // Create Module 4 CheckBox
  383.       ng.ng_TopEdge      += 16;
  384.       ng.ng_GadgetID      = Check4Gad;
  385.  
  386.       our_gadgets[Check4Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  387.                                     TAG_END);
  388.  
  389.       // Create Module 5 CheckBox
  390.       ng.ng_TopEdge      += 16;
  391.       ng.ng_GadgetID      = Check5Gad;
  392.  
  393.       our_gadgets[Check5Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  394.                                     TAG_END);
  395.  
  396.       // Create Module 6 CheckBox
  397.       ng.ng_TopEdge      += 16;
  398.       ng.ng_GadgetID      = Check6Gad;
  399.  
  400.       our_gadgets[Check6Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  401.                                     TAG_END);
  402.  
  403.       // Create Module 7 CheckBox
  404.       ng.ng_TopEdge      += 16;
  405.       ng.ng_GadgetID      = Check7Gad;
  406.  
  407.       our_gadgets[Check7Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  408.                                     TAG_END);
  409.  
  410.       // Create Module 8 CheckBox
  411.       ng.ng_TopEdge      += 16;
  412.       ng.ng_GadgetID      = Check8Gad;
  413.  
  414.       our_gadgets[Check8Gad-1] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,
  415.                                     TAG_END);
  416.  
  417.       // **** Create Module 1 File
  418.       ng.ng_LeftEdge     += CHECKBOXWIDTH+4;
  419.       ng.ng_TopEdge       = 16+bs.Top;
  420.       ng.ng_Width         = 236;
  421.       ng.ng_Height        = 14;
  422.       ng.ng_GadgetID      = File1Gad;
  423.  
  424.       our_gadgets[File1Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  425.                                     GA_TabCycle,TRUE, GTST_String,&File1,
  426.                                     GTST_MaxChars,215, TAG_END);
  427.  
  428.       // Create Module 2 File
  429.       ng.ng_TopEdge      += 16;
  430.       ng.ng_GadgetID      = File2Gad;
  431.  
  432.       our_gadgets[File2Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  433.                                     GA_TabCycle,TRUE, GTST_String,&File2,
  434.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  435.                                     TAG_END);
  436.  
  437.       // Create Module 3 File
  438.       ng.ng_TopEdge      += 16;
  439.       ng.ng_GadgetID      = File3Gad;
  440.  
  441.       our_gadgets[File3Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  442.                                     GA_TabCycle,TRUE, GTST_String,&File3,
  443.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  444.                                     TAG_END);
  445.  
  446.       // Create Module 4 File
  447.       ng.ng_TopEdge      += 16;
  448.       ng.ng_GadgetID      = File4Gad;
  449.  
  450.       our_gadgets[File4Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  451.                                     GA_TabCycle,TRUE, GTST_String,&File4,
  452.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  453.                                     TAG_END);
  454.  
  455.       // Create Module 5 File
  456.       ng.ng_TopEdge      += 16;
  457.       ng.ng_GadgetID      = File5Gad;
  458.  
  459.       our_gadgets[File5Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  460.                                     GA_TabCycle,TRUE, GTST_String,&File5,
  461.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  462.                                     TAG_END);
  463.  
  464.       // Create Module 6 File
  465.       ng.ng_TopEdge      += 16;
  466.       ng.ng_GadgetID      = File6Gad;
  467.  
  468.       our_gadgets[File6Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  469.                                     GA_TabCycle,TRUE, GTST_String,&File6,
  470.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  471.                                     TAG_END);
  472.  
  473.       // Create Module 7 File
  474.       ng.ng_TopEdge      += 16;
  475.       ng.ng_GadgetID      = File7Gad;
  476.  
  477.       our_gadgets[File7Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  478.                                     GA_TabCycle,TRUE, GTST_String,&File7,
  479.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  480.                                     TAG_END);
  481.  
  482.       // Create Module 8 File
  483.       ng.ng_TopEdge      += 16;
  484.       ng.ng_GadgetID      = File8Gad;
  485.  
  486.       our_gadgets[File8Gad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  487.                                     GA_TabCycle,TRUE, GTST_String,&File8,
  488.                                     GTST_MaxChars,215, GA_Disabled,TRUE,
  489.                                     TAG_END);
  490.  
  491.       // **** Create Module 1 Disk
  492.       ng.ng_LeftEdge     += 240;
  493.       ng.ng_TopEdge       = 16+bs.Top;
  494.       ng.ng_Width         = DISKWIDTH;
  495.       ng.ng_Height        = DISKHEIGHT;
  496.       ng.ng_GadgetID      = Disk1Gad;
  497.  
  498.       our_gadgets[Disk1Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  499.                                     TAG_END);
  500.       FixDisk(gad);
  501.       gad->Flags &= ~(GFLG_DISABLED);
  502.  
  503.       // Create Module 2 Disk
  504.       ng.ng_TopEdge      += 16;
  505.       ng.ng_GadgetID      = Disk2Gad;
  506.  
  507.       our_gadgets[Disk2Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  508.                                     TAG_END);
  509.       FixDisk(gad);
  510.  
  511.       // Create Module 3 Disk
  512.       ng.ng_TopEdge      += 16;
  513.       ng.ng_GadgetID      = Disk3Gad;
  514.  
  515.       our_gadgets[Disk3Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  516.                                     TAG_END);
  517.       FixDisk(gad);
  518.  
  519.       // Create Module 4 Disk
  520.       ng.ng_TopEdge      += 16;
  521.       ng.ng_GadgetID      = Disk4Gad;
  522.  
  523.       our_gadgets[Disk4Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  524.                                     TAG_END);
  525.       FixDisk(gad);
  526.  
  527.       // Create Module 5 Disk
  528.       ng.ng_TopEdge      += 16;
  529.       ng.ng_GadgetID      = Disk5Gad;
  530.  
  531.       our_gadgets[Disk5Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  532.                                     TAG_END);
  533.       FixDisk(gad);
  534.  
  535.       // Create Module 6 Disk
  536.       ng.ng_TopEdge      += 16;
  537.       ng.ng_GadgetID      = Disk6Gad;
  538.  
  539.       our_gadgets[Disk6Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  540.                                     TAG_END);
  541.       FixDisk(gad);
  542.  
  543.       // Create Module 7 Disk
  544.       ng.ng_TopEdge      += 16;
  545.       ng.ng_GadgetID      = Disk7Gad;
  546.  
  547.       our_gadgets[Disk7Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  548.                                     TAG_END);
  549.       FixDisk(gad);
  550.  
  551.       // Create Module 8 Disk
  552.       ng.ng_TopEdge      += 16;
  553.       ng.ng_GadgetID      = Disk8Gad;
  554.  
  555.       our_gadgets[Disk8Gad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  556.                                     TAG_END);
  557.       FixDisk(gad);
  558.  
  559.       // **** Create Module 1 Channel 1
  560.       ng.ng_LeftEdge     += DISKWIDTH+4;
  561.       ng.ng_TopEdge       = 16+bs.Top;
  562.       ng.ng_Width         = 38;
  563.       ng.ng_Height        = 13;
  564.       ng.ng_GadgetID      = Chan11Gad;
  565.  
  566.       our_gadgets[Chan11Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  567.                                     GTCY_Labels,&ChanLab, TAG_END);
  568.  
  569.       // Create Module 2 Channel 1
  570.       ng.ng_TopEdge      += 16;
  571.       ng.ng_GadgetID      = Chan12Gad;
  572.  
  573.       our_gadgets[Chan12Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  574.                                     GTCY_Labels,&ChanLab,
  575.                                     GA_Disabled,TRUE, TAG_END);
  576.  
  577.       // Create Module 3 Channel 1
  578.       ng.ng_TopEdge      += 16;
  579.       ng.ng_GadgetID      = Chan13Gad;
  580.  
  581.       our_gadgets[Chan13Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  582.                                     GTCY_Labels,&ChanLab,
  583.                                     GA_Disabled,TRUE, TAG_END);
  584.  
  585.       // Create Module 4 Channel 1
  586.       ng.ng_TopEdge      += 16;
  587.       ng.ng_GadgetID      = Chan14Gad;
  588.  
  589.       our_gadgets[Chan14Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  590.                                     GTCY_Labels,&ChanLab,
  591.                                     GA_Disabled,TRUE, TAG_END);
  592.  
  593.       // Create Module 5 Channel 1
  594.       ng.ng_TopEdge      += 16;
  595.       ng.ng_GadgetID      = Chan15Gad;
  596.  
  597.       our_gadgets[Chan15Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  598.                                     GTCY_Labels,&ChanLab,
  599.                                     GA_Disabled,TRUE, TAG_END);
  600.  
  601.       // Create Module 6 Channel 1
  602.       ng.ng_TopEdge      += 16;
  603.       ng.ng_GadgetID      = Chan16Gad;
  604.  
  605.       our_gadgets[Chan16Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  606.                                     GTCY_Labels,&ChanLab,
  607.                                     GA_Disabled,TRUE, TAG_END);
  608.  
  609.       // Create Module 7 Channel 1
  610.       ng.ng_TopEdge      += 16;
  611.       ng.ng_GadgetID      = Chan17Gad;
  612.  
  613.       our_gadgets[Chan17Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  614.                                     GTCY_Labels,&ChanLab,
  615.                                     GA_Disabled,TRUE, TAG_END);
  616.  
  617.       // Create Module 8 Channel 1
  618.       ng.ng_TopEdge      += 16;
  619.       ng.ng_GadgetID      = Chan18Gad;
  620.  
  621.       our_gadgets[Chan18Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  622.                                     GTCY_Labels,&ChanLab,
  623.                                     GA_Disabled,TRUE, TAG_END);
  624.  
  625.       // **** Create Module 1 Channel 2
  626.       ng.ng_LeftEdge     += 42;
  627.       ng.ng_TopEdge       = 16+bs.Top;
  628.       ng.ng_GadgetID      = Chan21Gad;
  629.  
  630.       our_gadgets[Chan21Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  631.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  632.                                     TAG_END);
  633.  
  634.       // Create Module 2 Channel 2
  635.       ng.ng_TopEdge      += 16;
  636.       ng.ng_GadgetID      = Chan22Gad;
  637.  
  638.       our_gadgets[Chan22Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  639.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  640.                                     GA_Disabled,TRUE, TAG_END);
  641.  
  642.       // Create Module 3 Channel 2
  643.       ng.ng_TopEdge      += 16;
  644.       ng.ng_GadgetID      = Chan23Gad;
  645.  
  646.       our_gadgets[Chan23Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  647.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  648.                                     GA_Disabled,TRUE, TAG_END);
  649.  
  650.       // Create Module 4 Channel 2
  651.       ng.ng_TopEdge      += 16;
  652.       ng.ng_GadgetID      = Chan24Gad;
  653.  
  654.       our_gadgets[Chan24Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  655.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  656.                                     GA_Disabled,TRUE, TAG_END);
  657.  
  658.       // Create Module 5 Channel 2
  659.       ng.ng_TopEdge      += 16;
  660.       ng.ng_GadgetID      = Chan25Gad;
  661.  
  662.       our_gadgets[Chan25Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  663.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  664.                                     GA_Disabled,TRUE, TAG_END);
  665.  
  666.       // Create Module 6 Channel 2
  667.       ng.ng_TopEdge      += 16;
  668.       ng.ng_GadgetID      = Chan26Gad;
  669.  
  670.       our_gadgets[Chan26Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  671.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  672.                                     GA_Disabled,TRUE, TAG_END);
  673.  
  674.       // Create Module 7 Channel 2
  675.       ng.ng_TopEdge      += 16;
  676.       ng.ng_GadgetID      = Chan27Gad;
  677.  
  678.       our_gadgets[Chan27Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  679.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  680.                                     GA_Disabled,TRUE, TAG_END);
  681.  
  682.       // Create Module 8 Channel 2
  683.       ng.ng_TopEdge      += 16;
  684.       ng.ng_GadgetID      = Chan28Gad;
  685.  
  686.       our_gadgets[Chan28Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  687.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  688.                                     GA_Disabled,TRUE, TAG_END);
  689.  
  690.       // **** Create Module 1 Channel 3
  691.       ng.ng_LeftEdge     += 42;
  692.       ng.ng_TopEdge       = 16+bs.Top;
  693.       ng.ng_GadgetID      = Chan31Gad;
  694.  
  695.       our_gadgets[Chan31Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  696.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  697.                                     TAG_END);
  698.  
  699.       // Create Module 2 Channel 3
  700.       ng.ng_TopEdge      += 16;
  701.       ng.ng_GadgetID      = Chan32Gad;
  702.  
  703.       our_gadgets[Chan32Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  704.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  705.                                     GA_Disabled,TRUE, TAG_END);
  706.  
  707.       // Create Module 3 Channel 3
  708.       ng.ng_TopEdge      += 16;
  709.       ng.ng_GadgetID      = Chan33Gad;
  710.  
  711.       our_gadgets[Chan33Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  712.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  713.                                     GA_Disabled,TRUE, TAG_END);
  714.  
  715.       // Create Module 4 Channel 3
  716.       ng.ng_TopEdge      += 16;
  717.       ng.ng_GadgetID      = Chan34Gad;
  718.  
  719.       our_gadgets[Chan34Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  720.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  721.                                     GA_Disabled,TRUE, TAG_END);
  722.  
  723.       // Create Module 5 Channel 3
  724.       ng.ng_TopEdge      += 16;
  725.       ng.ng_GadgetID      = Chan35Gad;
  726.  
  727.       our_gadgets[Chan35Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  728.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  729.                                     GA_Disabled,TRUE, TAG_END);
  730.  
  731.       // Create Module 6 Channel 3
  732.       ng.ng_TopEdge      += 16;
  733.       ng.ng_GadgetID      = Chan36Gad;
  734.  
  735.       our_gadgets[Chan36Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  736.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  737.                                     GA_Disabled,TRUE, TAG_END);
  738.  
  739.       // Create Module 7 Channel 3
  740.       ng.ng_TopEdge      += 16;
  741.       ng.ng_GadgetID      = Chan37Gad;
  742.  
  743.       our_gadgets[Chan37Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  744.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  745.                                     GA_Disabled,TRUE, TAG_END);
  746.  
  747.       // Create Module 8 Channel 3
  748.       ng.ng_TopEdge      += 16;
  749.       ng.ng_GadgetID      = Chan38Gad;
  750.  
  751.       our_gadgets[Chan38Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  752.                                     GTCY_Labels,&ChanLab, GTCY_Active, 1,
  753.                                     GA_Disabled,TRUE, TAG_END);
  754.  
  755.       // **** Create Module 1 Channel 4
  756.       ng.ng_LeftEdge     += 42;
  757.       ng.ng_TopEdge       = 16+bs.Top;
  758.       ng.ng_GadgetID      = Chan41Gad;
  759.  
  760.       our_gadgets[Chan41Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  761.                                     GTCY_Labels,&ChanLab, TAG_END);
  762.  
  763.       // Create Module 2 Channel 4
  764.       ng.ng_TopEdge      += 16;
  765.       ng.ng_GadgetID      = Chan42Gad;
  766.  
  767.       our_gadgets[Chan42Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  768.                                     GTCY_Labels,&ChanLab,
  769.                                     GA_Disabled,TRUE, TAG_END);
  770.  
  771.       // Create Module 3 Channel 4
  772.       ng.ng_TopEdge      += 16;
  773.       ng.ng_GadgetID      = Chan43Gad;
  774.  
  775.       our_gadgets[Chan43Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  776.                                     GTCY_Labels,&ChanLab,
  777.                                     GA_Disabled,TRUE, TAG_END);
  778.  
  779.       // Create Module 4 Channel 4
  780.       ng.ng_TopEdge      += 16;
  781.       ng.ng_GadgetID      = Chan44Gad;
  782.  
  783.       our_gadgets[Chan44Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  784.                                     GTCY_Labels,&ChanLab,
  785.                                     GA_Disabled,TRUE, TAG_END);
  786.  
  787.       // Create Module 5 Channel 4
  788.       ng.ng_TopEdge      += 16;
  789.       ng.ng_GadgetID      = Chan45Gad;
  790.  
  791.       our_gadgets[Chan45Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  792.                                     GTCY_Labels,&ChanLab,
  793.                                     GA_Disabled,TRUE, TAG_END);
  794.  
  795.       // Create Module 6 Channel 4
  796.       ng.ng_TopEdge      += 16;
  797.       ng.ng_GadgetID      = Chan46Gad;
  798.  
  799.       our_gadgets[Chan46Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  800.                                     GTCY_Labels,&ChanLab,
  801.                                     GA_Disabled,TRUE, TAG_END);
  802.  
  803.       // Create Module 7 Channel 4
  804.       ng.ng_TopEdge      += 16;
  805.       ng.ng_GadgetID      = Chan47Gad;
  806.  
  807.       our_gadgets[Chan47Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  808.                                     GTCY_Labels,&ChanLab,
  809.                                     GA_Disabled,TRUE, TAG_END);
  810.  
  811.       // Create Module 8 Channel 4
  812.       ng.ng_TopEdge      += 16;
  813.       ng.ng_GadgetID      = Chan48Gad;
  814.  
  815.       our_gadgets[Chan48Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  816.                                     GTCY_Labels,&ChanLab,
  817.                                     GA_Disabled,TRUE, TAG_END);
  818.  
  819.       // **** Create Module 1 Loop
  820.       ng.ng_LeftEdge     += 42;
  821.       ng.ng_TopEdge       = 16+bs.Top;
  822.       ng.ng_Width         = 62;
  823.       ng.ng_GadgetID      = Loop1Gad;
  824.  
  825.       our_gadgets[Loop1Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  826.                                     GTCY_Labels,&LoopLab, TAG_END);
  827.  
  828.       // Create Module 2 Loop
  829.       ng.ng_TopEdge      += 16;
  830.       ng.ng_GadgetID      = Loop2Gad;
  831.  
  832.       our_gadgets[Loop2Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  833.                                     GTCY_Labels,&LoopLab,
  834.                                     GA_Disabled,TRUE, TAG_END);
  835.  
  836.       // Create Module 3 Loop
  837.       ng.ng_TopEdge      += 16;
  838.       ng.ng_GadgetID      = Loop3Gad;
  839.  
  840.       our_gadgets[Loop3Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  841.                                     GTCY_Labels,&LoopLab,
  842.                                     GA_Disabled,TRUE, TAG_END);
  843.  
  844.       // Create Module 4 Loop
  845.       ng.ng_TopEdge      += 16;
  846.       ng.ng_GadgetID      = Loop4Gad;
  847.  
  848.       our_gadgets[Loop4Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  849.                                     GTCY_Labels,&LoopLab,
  850.                                     GA_Disabled,TRUE, TAG_END);
  851.  
  852.       // Create Module 5 Loop
  853.       ng.ng_TopEdge      += 16;
  854.       ng.ng_GadgetID      = Loop5Gad;
  855.  
  856.       our_gadgets[Loop5Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  857.                                     GTCY_Labels,&LoopLab,
  858.                                     GA_Disabled,TRUE, TAG_END);
  859.  
  860.       // Create Module 6 Loop
  861.       ng.ng_TopEdge      += 16;
  862.       ng.ng_GadgetID      = Loop6Gad;
  863.  
  864.       our_gadgets[Loop6Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  865.                                     GTCY_Labels,&LoopLab,
  866.                                     GA_Disabled,TRUE, TAG_END);
  867.  
  868.       // Create Module 7 Loop
  869.       ng.ng_TopEdge      += 16;
  870.       ng.ng_GadgetID      = Loop7Gad;
  871.  
  872.       our_gadgets[Loop7Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  873.                                     GTCY_Labels,&LoopLab,
  874.                                     GA_Disabled,TRUE, TAG_END);
  875.  
  876.       // Create Module 8 Loop
  877.       ng.ng_TopEdge      += 16;
  878.       ng.ng_GadgetID      = Loop8Gad;
  879.  
  880.       our_gadgets[Loop8Gad-1] = gad = CreateGadget(CYCLE_KIND, gad, &ng,
  881.                                     GTCY_Labels,&LoopLab,
  882.                                     GA_Disabled,TRUE, TAG_END);
  883.  
  884.       // **** Create Destination File
  885.       ng.ng_LeftEdge      = 114+bs.Left;
  886.       ng.ng_TopEdge      += 18;
  887.       ng.ng_Width         = 391;
  888.       ng.ng_Height        = 14;
  889.       ng.ng_GadgetText    = "Destination:";
  890.       ng.ng_GadgetID      = DestFileGad;
  891.       ng.ng_Flags         = PLACETEXT_LEFT;
  892.  
  893.       our_gadgets[DestFileGad-1] = gad = CreateGadget(STRING_KIND, gad, &ng,
  894.                                     GA_TabCycle,TRUE, GTST_String,&DestFile,
  895.                                     GTST_MaxChars,215, TAG_END);
  896.  
  897.       // Create Destination Disk
  898.       ng.ng_LeftEdge     += 395;
  899.       ng.ng_GadgetText    = NULL;
  900.       ng.ng_GadgetID      = DestDiskGad;
  901.  
  902.       our_gadgets[DestDiskGad-1] = gad = CreateGadget(GENERIC_KIND, gad, &ng,
  903.                                     TAG_END);
  904.       FixDisk(gad);
  905.       gad->Flags &= ~(GFLG_DISABLED);
  906.  
  907.       // **** Create Convert Button
  908.       ng.ng_LeftEdge      = 6+bs.Left;
  909.       ng.ng_TopEdge      += 19;
  910.       ng.ng_Width         = 261;
  911.       ng.ng_Height        = 12;
  912.       ng.ng_GadgetText    = "Convert";
  913.       ng.ng_GadgetID      = ConvertGad;
  914.       ng.ng_Flags         = PLACETEXT_IN;
  915.  
  916.       our_gadgets[ConvertGad-1] = gad = CreateGadget(BUTTON_KIND, gad, &ng,
  917.                                     TAG_END);
  918.  
  919.       // Create Calculate Button
  920.       ng.ng_LeftEdge     += 265;
  921.       ng.ng_GadgetText    = "Calculate";
  922.       ng.ng_GadgetID      = CalculateGad;
  923.  
  924.       our_gadgets[CalculateGad-1] = gad = CreateGadget(BUTTON_KIND, gad, &ng,
  925.                                     TAG_END);
  926.  
  927.       // Check For An Error
  928.       if (gad != NULL)
  929.         success = TRUE;
  930.     }
  931.   }
  932.   return(success);
  933. }
  934.  
  935. /********************************************************************
  936. *                                                                   *
  937. * Will fix the gadget to a disk gadget.                             *
  938. *                                                                   *
  939. ********************************************************************/
  940.  
  941. void FixDisk (struct Gadget *gad)
  942. {
  943.   if (gad != NULL)
  944.   {
  945.     gad->Flags        = GFLG_GADGIMAGE | GFLG_GADGHIMAGE | GFLG_DISABLED;
  946.     gad->Activation  |= GACT_RELVERIFY | GACT_IMMEDIATE;
  947.     gad->GadgetRender = &DiskNorm;
  948.     gad->SelectRender = &DiskPres;
  949.   }
  950. }
  951.  
  952. /********************************************************************
  953. *                                                                   *
  954. * Remove all our gadgets from memory.                               *
  955. *                                                                   *
  956. ********************************************************************/
  957.  
  958. void RemoveGadgets(void)
  959. {
  960.   FreeGadgets(glist);
  961.   FreeVisualInfo(vi);
  962. }
  963.  
  964. /********************************************************************
  965. *                                                                   *
  966. * Draw bevel boxes.                                                 *
  967. *                                                                   *
  968. ********************************************************************/
  969.  
  970. void DrawBevelBoxes(struct Window *win, struct Screen *scr)
  971. {
  972. struct RastPort *rp;
  973. struct BorderSize borsiz;
  974.  
  975.   rp=win->RPort;
  976.   borsiz = GetBorder(scr);
  977.  
  978.   DrawBevelBox(rp,2+borsiz.Left,14+borsiz.Top,535,148,
  979.               GT_VisualInfo,vi,GTBB_Recessed,TRUE,TAG_END);
  980.  
  981.   DrawBevelBox(rp,2+borsiz.Left,163+borsiz.Top,535,16,
  982.               GT_VisualInfo,vi,GTBB_Recessed,TRUE,TAG_END);
  983. }
  984.  
  985. /********************************************************************
  986. *                                                                   *
  987. * Open window and handle IDCMPs.                                    *
  988. *                                                                   *
  989. ********************************************************************/
  990.  
  991. void DoWindow(void)
  992. {
  993. #define width   539
  994. #define height  180
  995.  
  996. int left, top;
  997. struct BorderSize bs;
  998. struct Screen *pub_screen;
  999. struct Window *our_window;
  1000. struct Menu   *our_menu;
  1001.  
  1002.   // Get a lock on the default public screen
  1003.   if (!(pub_screen = LockPubScreen(NULL)))
  1004.     WriteErr("Can't lock a public screen.");
  1005.   else
  1006.   {
  1007.  
  1008.     // Create Our gadgets
  1009.     if (!CreateGadgets(pub_screen))
  1010.       WriteErr("Can't create gadgets.");
  1011.     else
  1012.     {
  1013.       // Open our window
  1014.       bs = GetBorder(pub_screen);
  1015.  
  1016.       left = (pub_screen->Width - (bs.Left + bs.Right + width)) / 2;
  1017.       top  = (pub_screen->Height - (bs.Top + bs.Bottom + height)) / 2;
  1018.  
  1019.       if (!(our_window = OpenWindowTags(NULL,WA_Left,left,WA_Top,top,
  1020.                          WA_InnerWidth,width,WA_InnerHeight,height,
  1021.                          WA_IDCMP,our_idcmp,WA_AutoAdjust,TRUE,
  1022.                          WA_Title,"Protracker -> Fast/Taketracker Version 1.1",
  1023.                          WA_PubScreen,pub_screen,WA_PubScreenFallBack,TRUE,
  1024.                          WA_Gadgets,glist,
  1025.                          WA_CloseGadget,TRUE,WA_DragBar,TRUE,WA_DepthGadget,TRUE,
  1026.                          WA_Activate,TRUE,WA_SmartRefresh,TRUE,
  1027.                          WA_NewLookMenus,TRUE,
  1028.                          TAG_END)))
  1029.         WriteErr("Can't open window.");
  1030.       else
  1031.       {
  1032.         DrawBevelBoxes(our_window,pub_screen);
  1033.         if (!(our_menu = CreateMenus(ourmenu, TAG_END)))
  1034.           WriteErr("Can't create menus.");
  1035.         else
  1036.         {
  1037.           if (!(LayoutMenus(our_menu, vi, GTMN_NewLookMenus,TRUE, TAG_END)))
  1038.             WriteErr("Can't layout menus.");
  1039.           else
  1040.           {
  1041.             if (!(SetMenuStrip(our_window, our_menu)))
  1042.               WriteErr("Can't attach menu to window.");
  1043.             else
  1044.             {
  1045.               GT_RefreshWindow(our_window,NULL);
  1046.  
  1047.               About(pub_screen);
  1048.  
  1049.               HandleEvents(our_window, pub_screen, our_menu);
  1050.               ClearMenuStrip(our_window);
  1051.             }
  1052.           }
  1053.           FreeMenus(our_menu);
  1054.         }
  1055.         CloseWindow(our_window);
  1056.       }
  1057.     }
  1058.     RemoveGadgets();
  1059.     UnlockPubScreen(NULL,pub_screen);
  1060.   }
  1061. }
  1062.  
  1063. /********************************************************************
  1064. *                                                                   *
  1065. * Handle window IDCMPs.                                             *
  1066. *                                                                   *
  1067. ********************************************************************/
  1068.  
  1069. void HandleEvents(struct Window *win, struct Screen *scr, struct Menu *menu)
  1070. {
  1071. struct IntuiMessage *msg;
  1072. struct MenuItem *item;
  1073. LONG sigrcvd;
  1074. BOOL done = FALSE;
  1075. UWORD gadid, menunumber;
  1076. UWORD menunum, itemnum; //, subnum;
  1077.  
  1078.   while (!done)
  1079.   {
  1080.     sigrcvd = Wait((1L << win->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C);
  1081.  
  1082.     while ((!done) && (msg = GT_GetIMsg(win->UserPort)))
  1083.     {
  1084.       switch (msg->Class)
  1085.       {
  1086.         case IDCMP_REFRESHWINDOW:
  1087.           GT_BeginRefresh(win);
  1088.           GT_EndRefresh(win,TRUE);
  1089.           break;
  1090.  
  1091.         case IDCMP_CLOSEWINDOW:
  1092.           done = TRUE;
  1093.           break;
  1094.  
  1095.         case IDCMP_MENUPICK:
  1096.           menunumber = msg->Code;
  1097.           while ((menunumber != MENUNULL) && (!done))
  1098.           {
  1099.             item = ItemAddress(menu, menunumber);
  1100.  
  1101.             // Process the item here
  1102.             menunum = MENUNUM(menunumber);
  1103.             itemnum = ITEMNUM(menunumber);
  1104.             //subnum  = SUBNUM(menunumber);
  1105.  
  1106.             // stop if quit is selected
  1107.             switch (menunum)
  1108.             {
  1109.               case 0:
  1110.                 switch (itemnum)
  1111.                 {
  1112.                   case 0: CalculateIt(win);
  1113.                           break;
  1114.  
  1115.                   case 1: CreateMod(win);
  1116.                           break;
  1117.  
  1118.                   case 3: About(scr);
  1119.                           break;
  1120.  
  1121.                   case 5: done = TRUE;
  1122.                           break;
  1123.                 }
  1124.                 break;
  1125.             }
  1126.  
  1127.             menunumber = item->NextSelect;
  1128.           }
  1129.           break;
  1130.  
  1131.         case IDCMP_GADGETUP:
  1132.           if ((gadid = ((struct Gadget *)msg->IAddress)->GadgetID))
  1133.           {
  1134.             switch (gadid)
  1135.             {
  1136.               case Check1Gad:
  1137.               case Check2Gad:
  1138.               case Check3Gad:
  1139.               case Check4Gad:
  1140.               case Check5Gad:
  1141.               case Check6Gad:
  1142.               case Check7Gad:
  1143.               case Check8Gad:
  1144.                 Activated[gadid-Check1Gad] = msg->Code;
  1145.                 FixGadgets(gadid-Check1Gad, win);
  1146.                 break;
  1147.  
  1148.               case Chan11Gad:
  1149.               case Chan12Gad:
  1150.               case Chan13Gad:
  1151.               case Chan14Gad:
  1152.               case Chan15Gad:
  1153.               case Chan16Gad:
  1154.               case Chan17Gad:
  1155.               case Chan18Gad:
  1156.                 Chan[0][gadid-Chan11Gad] = msg->Code;
  1157.                 break;
  1158.  
  1159.               case Chan21Gad:
  1160.               case Chan22Gad:
  1161.               case Chan23Gad:
  1162.               case Chan24Gad:
  1163.               case Chan25Gad:
  1164.               case Chan26Gad:
  1165.               case Chan27Gad:
  1166.               case Chan28Gad:
  1167.                 Chan[1][gadid-Chan21Gad] = msg->Code;
  1168.                 break;
  1169.  
  1170.               case Chan31Gad:
  1171.               case Chan32Gad:
  1172.               case Chan33Gad:
  1173.               case Chan34Gad:
  1174.               case Chan35Gad:
  1175.               case Chan36Gad:
  1176.               case Chan37Gad:
  1177.               case Chan38Gad:
  1178.                 Chan[2][gadid-Chan31Gad] = msg->Code;
  1179.                 break;
  1180.  
  1181.               case Chan41Gad:
  1182.               case Chan42Gad:
  1183.               case Chan43Gad:
  1184.               case Chan44Gad:
  1185.               case Chan45Gad:
  1186.               case Chan46Gad:
  1187.               case Chan47Gad:
  1188.               case Chan48Gad:
  1189.                 Chan[3][gadid-Chan41Gad] = msg->Code;
  1190.                 break;
  1191.  
  1192.               case Loop1Gad:
  1193.               case Loop2Gad:
  1194.               case Loop3Gad:
  1195.               case Loop4Gad:
  1196.               case Loop5Gad:
  1197.               case Loop6Gad:
  1198.               case Loop7Gad:
  1199.               case Loop8Gad:
  1200.                 Loop[gadid-Loop1Gad] = msg->Code;
  1201.                 break;
  1202.  
  1203.               case Disk1Gad:
  1204.               case Disk2Gad:
  1205.               case Disk3Gad:
  1206.               case Disk4Gad:
  1207.               case Disk5Gad:
  1208.               case Disk6Gad:
  1209.               case Disk7Gad:
  1210.               case Disk8Gad:
  1211.                 GetFile(our_gadgets[gadid-8-1], win);
  1212.                 break;
  1213.  
  1214.               case DestDiskGad:
  1215.                 GetFile(our_gadgets[DestFileGad-1], win);
  1216.                 break;
  1217.  
  1218.               case ConvertGad:
  1219.                 CreateMod(win);
  1220.                 break;
  1221.  
  1222.               case CalculateGad:
  1223.                 CalculateIt(win);
  1224.                 break;
  1225.             }
  1226.           }
  1227.           break;
  1228.       }
  1229.  
  1230.       GT_ReplyIMsg(msg);
  1231.     }
  1232.  
  1233.     // Test to see if we got a CTRL-C signal
  1234.     if (sigrcvd & SIGBREAKF_CTRL_C)
  1235.       done = TRUE;
  1236.   }
  1237. }
  1238.  
  1239. /********************************************************************
  1240. *                                                                   *
  1241. * Ghost or unghost one line of gadgets.                             *
  1242. *                                                                   *
  1243. ********************************************************************/
  1244.  
  1245. void FixGadgets(UWORD num, struct Window *win)
  1246. {
  1247. int ghostflag  = TRUE;
  1248. UWORD ghostflag1 = GFLG_DISABLED;
  1249.  
  1250.   if (Activated[num])
  1251.   {
  1252.     ghostflag = FALSE;
  1253.     ghostflag1 = 0;
  1254.   }
  1255.  
  1256.   GT_SetGadgetAttrs(our_gadgets[File1Gad+num-1], win, NULL,
  1257.                       GA_Disabled,ghostflag, TAG_END);
  1258.  
  1259.   GT_SetGadgetAttrs(our_gadgets[Chan11Gad+num-1], win, NULL,
  1260.                       GA_Disabled,ghostflag, TAG_END);
  1261.  
  1262.   GT_SetGadgetAttrs(our_gadgets[Chan21Gad+num-1], win, NULL,
  1263.                       GA_Disabled,ghostflag, TAG_END);
  1264.  
  1265.   GT_SetGadgetAttrs(our_gadgets[Chan31Gad+num-1], win, NULL,
  1266.                       GA_Disabled,ghostflag, TAG_END);
  1267.  
  1268.   GT_SetGadgetAttrs(our_gadgets[Chan41Gad+num-1], win, NULL,
  1269.                       GA_Disabled,ghostflag, TAG_END);
  1270.  
  1271.   GT_SetGadgetAttrs(our_gadgets[Loop1Gad+num-1], win, NULL,
  1272.                       GA_Disabled,ghostflag, TAG_END);
  1273.  
  1274.   our_gadgets[Disk1Gad+num-1]->Flags = (our_gadgets[Disk1Gad+num-1]->Flags & ~(GFLG_DISABLED)) | ghostflag1;
  1275.   RefreshGList(our_gadgets[Disk1Gad+num-1],win,NULL,1);
  1276. }
  1277.  
  1278. /********************************************************************
  1279. *                                                                   *
  1280. * Popup a reqtools filerequester.                                   *
  1281. *                                                                   *
  1282. ********************************************************************/
  1283.  
  1284. void GetFile(struct Gadget *strgad, struct Window *win)
  1285. {
  1286. char file[108];
  1287. char dir[108];
  1288. char wholefile[216];
  1289. char *gstrpoi;
  1290. char *strpoi;
  1291.  
  1292.   // Copy old context of string gadget
  1293.   gstrpoi = ((struct StringInfo *)(strgad->SpecialInfo))->Buffer;
  1294.   if (gstrpoi[0] != '\0')
  1295.   {
  1296.     strpoi = FilePart(gstrpoi);
  1297.     stccpy((char *)&dir, gstrpoi, strpoi-gstrpoi+1);  // Copy Path
  1298.     strcpy((char *)&file, strpoi);                    // Copy File
  1299.  
  1300.     rtChangeReqAttr(filereq, RTFI_Dir,dir, TAG_END);
  1301.   }
  1302.   else
  1303.     file[0] = '\0';
  1304.  
  1305.   if ((rtFileRequest(filereq, (char *)&file, "Select a module/song",
  1306.                 RT_ReqPos,REQPOS_CENTERSCR, RT_LockWindow,TRUE,
  1307.                 RTFI_Flags,FREQF_PATGAD, TAG_END)))
  1308.   {
  1309.     strcpy((char *)&wholefile, ((struct rtFileRequester *)filereq)->Dir);
  1310.     AddPart((STRPTR)&wholefile, (STRPTR)&file, 216);
  1311.     GT_SetGadgetAttrs(strgad, win, NULL, GTST_String,wholefile, TAG_END);
  1312.   }
  1313. }
  1314.  
  1315. /********************************************************************
  1316. *                                                                   *
  1317. * Show a reqtools requester.                                        *
  1318. *                                                                   *
  1319. ********************************************************************/
  1320.  
  1321. void ShowRequest(char *text, ...)
  1322. {
  1323.   rtEZRequestTags(text, "Okay", NULL, &text+1,    // 1 Argument on the stack
  1324.               RT_LockWindow,TRUE, RTEZ_Flags,EZREQF_CENTERTEXT,
  1325.               TAG_END);
  1326. }
  1327.  
  1328. /********************************************************************
  1329. *                                                                   *
  1330. * Create final module and save it.                                  *
  1331. *                                                                   *
  1332. ********************************************************************/
  1333.  
  1334. void CreateMod (struct Window *win)
  1335. {
  1336. UBYTE UsedSamp[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1337.                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  1338. APTR SampPoi[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1339.                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  1340. char *destname;
  1341. MODULE *destmod;
  1342. UBYTE *destadr;
  1343. struct CalcInfo cinfo;
  1344. struct ModInfo minfo;
  1345. APTR sleep;
  1346. BPTR fh;
  1347. BOOL err;
  1348. int i;
  1349.  
  1350.   if (win != NULL)
  1351.     destname = ((struct StringInfo *)(our_gadgets[DestFileGad-1]->SpecialInfo))->Buffer;
  1352.   else
  1353.     destname = (char *)ArgList[49];
  1354.  
  1355.   err = TRUE;
  1356.   if (destname != NULL)
  1357.     if (destname[0] != '\0')
  1358.       err = FALSE;
  1359.  
  1360.   if (err)
  1361.     ShowRequest("You have to specify a destination filename");
  1362.   else
  1363.   {
  1364.     cinfo = CalculateIt(win);
  1365.     if (cinfo.Size != 0)
  1366.     {
  1367.       if (!(destmod = AllocMem(cinfo.Size, MEMF_PUBLIC|MEMF_CLEAR)))
  1368.         ShowRequest("Can't allocate %ld bytes of memory to the destination module",cinfo.Size);
  1369.       else
  1370.       {
  1371.         // Make songname out from destination filename
  1372.         if (win != NULL)
  1373.           sleep = rtLockWindow(win);
  1374.  
  1375.         stccpy(destmod->SongName, FilePart(destname), 20);
  1376.  
  1377.         // Create mark
  1378.         if (cinfo.Channels < 10)
  1379.           destmod->Mark = ((cinfo.Channels+48) << 24) | xchn;
  1380.         else
  1381.           destmod->Mark = ((((cinfo.Channels/10)+48) << 24) | (((cinfo.Channels%10)+48) << 16)) | xxch;
  1382.  
  1383.         // Create song positions
  1384.         for (i=0; i<cinfo.SongLen; i++)
  1385.           destmod->Positions[i] = i;
  1386.  
  1387.         // Fill other fields
  1388.         destmod->Pad = 127;
  1389.         destmod->SongLength = cinfo.SongLen;
  1390.  
  1391.         lpoi = 0;
  1392.         rpoi = 1;
  1393.  
  1394.         // Start to scan all the modules
  1395.         err = FALSE;
  1396.         for (i=0; i<8; i++)
  1397.         {
  1398.           if (Activated[i])
  1399.           {
  1400.             minfo = LoadModule(i, win);
  1401.             if (minfo.Module == NULL)
  1402.             {
  1403.               err = TRUE;
  1404.               break;
  1405.             }
  1406.             else
  1407.             {
  1408.               if (minfo.Size != minfo.CalcSize)
  1409.                 if ((CopySample(&cinfo, &minfo, destmod, UsedSamp, SampPoi)) == FALSE)
  1410.                 {
  1411.                   err = TRUE;
  1412.                   break;
  1413.                 }
  1414.  
  1415.               CopyChannels(i, &cinfo, minfo.Module, destmod);
  1416.               FreeMem(minfo.Module, minfo.Size);
  1417.             }
  1418.           }
  1419.         }
  1420.  
  1421.         if (!err)
  1422.         {
  1423.           // Copy the samples into the destination module
  1424.           destadr = ((UBYTE *)destmod) + sizeof(MODULE) + ((cinfo.SongLen)*(cinfo.Channels*sizeof(CHANNEL)*64));
  1425.           for (i=0; i<31; i++)
  1426.           {
  1427.             if (destmod->Samples[i].Length != 0)
  1428.             {
  1429.               CopyMem(SampPoi[i], destadr, destmod->Samples[i].Length*2);
  1430.               destadr += destmod->Samples[i].Length*2;
  1431.             }
  1432.           if (i >= 29)
  1433.             CopyMem("#Register APlayer now\0",destmod->Samples[i].Name,22);
  1434.           }
  1435.  
  1436.           if (!(fh = Open(destname, MODE_NEWFILE)))
  1437.             ShowRequest("Can't open destination file");
  1438.           else
  1439.           {
  1440.             if (Write(fh, destmod, cinfo.Size) == -1)
  1441.               ShowRequest("Write error while saving module");
  1442.             Close(fh);
  1443.           }
  1444.         }
  1445.  
  1446.         FreeSamples(SampPoi, destmod);
  1447.         FreeMem(destmod, cinfo.Size);
  1448.         if (win != NULL)
  1449.           rtUnlockWindow(win, sleep);
  1450.       }
  1451.     }
  1452.   }
  1453. }
  1454.  
  1455. /********************************************************************
  1456. *                                                                   *
  1457. * Copy sample names and data to destination module                  *
  1458. *                                                                   *
  1459. ********************************************************************/
  1460.  
  1461. int CopySample(struct CalcInfo *cinfo, struct ModInfo *minfo, MODULE *dmod, UBYTE *UsedSamp, APTR *SampPoi)
  1462. {
  1463. int i;
  1464. int ssamstr = 0;
  1465. SAMPLE *ssamp, *dsamp;
  1466. MODULE *smod = minfo->Module;
  1467.  
  1468.   // Copy sample data
  1469.   ssamp = smod->Samples;
  1470.   dsamp = dmod->Samples;
  1471.   for (i=0 ; i<31 ; i++)
  1472.   {
  1473.     if (UsedSamp[i] == 0)
  1474.       if (ssamp[i].Length != 0)
  1475.       {
  1476.         UsedSamp[i] = TRUE;
  1477.         CopyMem(((UBYTE *)(ssamp+i)), ((UBYTE *)(dsamp+i)), sizeof(SAMPLE));
  1478.  
  1479.         if ((SampPoi[i] = AllocMem(ssamp[i].Length*2, MEMF_PUBLIC)) == NULL)
  1480.         {
  1481.           ShowRequest("Can't allocate %ld bytes of memory for a sample",ssamp[i].Length*2);
  1482.           return(FALSE);
  1483.         }
  1484.  
  1485.         CopyMem((((UBYTE *)smod) + sizeof(MODULE) + ((minfo->MaxPatt)*1024) + ssamstr),
  1486.                 SampPoi[i], dsamp[i].Length*2);
  1487.       }
  1488.     ssamstr += ssamp[i].Length*2;
  1489.   }
  1490.   return(TRUE);
  1491. }
  1492.  
  1493. /********************************************************************
  1494. *                                                                   *
  1495. * Free all the samples again.                                       *
  1496. *                                                                   *
  1497. ********************************************************************/
  1498.  
  1499. void FreeSamples(APTR *SampPoi, MODULE *dmod)
  1500. {
  1501. int i;
  1502.  
  1503.   for (i=0; i<31; i++)
  1504.     if (SampPoi[i] != NULL)
  1505.       FreeMem(SampPoi[i], dmod->Samples[i].Length*2);
  1506. }
  1507.  
  1508. /********************************************************************
  1509. *                                                                   *
  1510. * Copy pattern data.                                                *
  1511. *                                                                   *
  1512. ********************************************************************/
  1513.  
  1514. void CopyChannels(int num, struct CalcInfo *cinfo, MODULE *smod, MODULE *dmod)
  1515. {
  1516. int cpoi;
  1517. int c,i,j,k;
  1518. CHANNEL *schan, *dchan;
  1519.  
  1520.   for (c=0; c<4; c++)
  1521.   {
  1522.     if (Chan[c][num] != 2)
  1523.     {
  1524.       if (Chan[c][num] == 0)
  1525.       {
  1526.         cpoi = lpoi;
  1527.         lpoi++;
  1528.         if ((lpoi%4) == 1)
  1529.           lpoi += 2;
  1530.       }
  1531.       else
  1532.       {
  1533.         cpoi = rpoi;
  1534.         rpoi++;
  1535.         if ((rpoi%4) == 3)
  1536.           rpoi += 2;
  1537.       }
  1538.  
  1539.       k = 0;
  1540.       do
  1541.         for (i=0; i<smod->SongLength; i++)
  1542.         {
  1543.           schan = ((CHANNEL *)(((UBYTE *)smod)+(((smod->Positions[i])*1024+sizeof(MODULE))))+c);
  1544.           dchan = ((CHANNEL *)(((UBYTE *)dmod)+((k*(cinfo->Channels*256)+sizeof(MODULE))))+cpoi);
  1545.  
  1546.           for (j=0; j<64; j++)
  1547.             dchan[j*cinfo->Channels] = schan[j*4];
  1548.  
  1549.           k++;
  1550.         }
  1551.       while ((k<cinfo->SongLen) && (Loop[num] == 1));
  1552.     }
  1553.   }
  1554. }
  1555.  
  1556. /********************************************************************
  1557. *                                                                   *
  1558. * Calculate size etc. of the final module.                          *
  1559. *                                                                   *
  1560. ********************************************************************/
  1561.  
  1562. struct CalcInfo CalculateIt(struct Window *win)
  1563. {
  1564. struct ModInfo minfo;
  1565. struct CalcInfo cinfo = {0,0,0,0};
  1566. UBYTE UsedSamp[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1567.                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  1568. int i,j,c;
  1569. BOOL song = FALSE, err = TRUE;
  1570. UBYTE maxsonglen = 0;
  1571. UBYTE maxpatt = 0;
  1572. UBYTE lchan = 0;
  1573. UBYTE rchan = 1;
  1574. BYTE maxchan;
  1575. int filesize = sizeof(MODULE);
  1576. SAMPLE *samp;
  1577. APTR sleep;
  1578. char trktype[] = "Take";
  1579. char infotxt[80];
  1580.  
  1581.   if (win != NULL)
  1582.   {
  1583.     sleep = rtLockWindow(win);
  1584.     GT_SetGadgetAttrs(our_gadgets[InfoGad-1], win, NULL, GTTX_Text,NULL, TAG_END);
  1585.   }
  1586.  
  1587.   for (i=0 ; i<64 ; i++)
  1588.     chantab[i] = 0;
  1589.  
  1590.   if (OneActive())
  1591.   {
  1592.     err = FALSE;
  1593.     i = 0;
  1594.     do
  1595.     {
  1596.       if (Activated[i])
  1597.       {
  1598.         minfo = LoadModule(i, win);
  1599.         if (minfo.Module == NULL)
  1600.         {
  1601.           err = TRUE;
  1602.           break;
  1603.         }
  1604.         else
  1605.         {
  1606.           if (minfo.Size != minfo.CalcSize)
  1607.           {
  1608.             // Add sample sizes to filesize
  1609.             song = TRUE;
  1610.             samp = minfo.Module->Samples;
  1611.             for (j=0; j<31; j++)
  1612.             {
  1613.               if (samp[j].Length != 0)
  1614.                 if (UsedSamp[j] == 0)
  1615.                 {
  1616.                   UsedSamp[j] = TRUE;
  1617.                   filesize += samp[j].Length*2;
  1618.                 }
  1619.             }
  1620.           }
  1621.  
  1622.           if ((minfo.Module->SongLength) > maxsonglen)
  1623.             maxsonglen = minfo.Module->SongLength;
  1624.  
  1625.           if (minfo.MaxPatt > maxpatt)
  1626.             maxpatt = minfo.MaxPatt;
  1627.  
  1628.           FreeMem(minfo.Module, minfo.Size);
  1629.  
  1630.           for (c=0; c<4; c++)
  1631.           {
  1632.             if (Chan[c][i] == 0)    // Left Channel
  1633.             {
  1634.               chantab[lchan] = 1;
  1635.               lchan++;
  1636.               if ((lchan%4) == 1)
  1637.                 lchan += 2;
  1638.             }
  1639.             else
  1640.               if (Chan[c][i] == 1)  // Right Channel
  1641.               {
  1642.                 chantab[rchan] = 1;
  1643.                 rchan++;
  1644.                 if ((rchan%4) == 3)
  1645.                   rchan += 2;
  1646.               }
  1647.           }
  1648.         }
  1649.       }
  1650.       i++;
  1651.     }
  1652.     while ((i<8) && (err == FALSE));
  1653.  
  1654.  
  1655.     for (maxchan=63; maxchan>=0; maxchan--)
  1656.       if (chantab[maxchan] == 1)
  1657.         break;
  1658.  
  1659.     maxchan++;
  1660.     filesize += (maxchan*sizeof(CHANNEL)*64)*maxsonglen;
  1661.  
  1662.     if (!(err))
  1663.     {
  1664.       if (!(song))
  1665.       {
  1666.         err = TRUE;
  1667.         ShowRequest("You have to select minimum one module");
  1668.       }
  1669.       else
  1670.         if (maxchan == 0)
  1671.         {
  1672.           err = TRUE;
  1673.           ShowRequest("You don't have any channels turned on");
  1674.         }
  1675.         else
  1676.           if (maxchan > 32)
  1677.           {
  1678.             err = TRUE;
  1679.             ShowRequest("You have selected %ld channels.\nYou can max use 32 channels",maxchan);
  1680.           }
  1681.         {
  1682.           if ((maxchan == 6) || (maxchan == 8))
  1683.             strcpy((char *)&trktype,"Fast");
  1684.  
  1685.           if (win != NULL)
  1686.           {
  1687.             FormatText((char *)&infotxt,"%2ld Channels %stracker  %6ld bytes  Patterns: %2ld  SongLen: %3ld",maxchan,trktype,filesize,maxpatt,maxsonglen);
  1688.             GT_SetGadgetAttrs(our_gadgets[InfoGad-1], win, NULL, GTTX_Text,infotxt, TAG_END);
  1689.           }
  1690.         }
  1691.     }
  1692.   }
  1693.  
  1694.   if (win != NULL)
  1695.     rtUnlockWindow(win,sleep);
  1696.  
  1697.   if (!err)
  1698.   {
  1699.     cinfo.Size      = filesize;
  1700.     cinfo.Channels  = maxchan;
  1701.     cinfo.SongLen   = maxsonglen;
  1702.     cinfo.MaxPatt   = maxpatt;
  1703.  
  1704.     FormatText(outbuf,"%ld %ld %ld %ld",maxchan,filesize,maxpatt,maxsonglen);
  1705.   }
  1706.  
  1707.   return(cinfo);
  1708. }
  1709.  
  1710. /********************************************************************
  1711. *                                                                   *
  1712. * Test to see if minimum one "file" is active.                      *
  1713. *                                                                   *
  1714. ********************************************************************/
  1715.  
  1716. int OneActive(void)
  1717. {
  1718. int num = 0;
  1719. int i;
  1720.  
  1721.   for (i=0; i<8; i++)
  1722.     if (Activated[i])
  1723.       num++;
  1724.  
  1725.   if (num == 0)
  1726.     ShowRequest("You have to activate at least one module");
  1727.  
  1728.   return(num);
  1729. }
  1730.  
  1731. /********************************************************************
  1732. *                                                                   *
  1733. * Load module into memory and calculate it's size.                  *
  1734. *                                                                   *
  1735. ********************************************************************/
  1736.  
  1737. struct ModInfo LoadModule(int num, struct Window *win)
  1738. {
  1739. struct ModInfo mi = {0, 0, NULL, 0};
  1740. char *fname;
  1741. BPTR  fh;
  1742. ULONG mark;
  1743. UBYTE maxpos = 0;
  1744. int i;
  1745.  
  1746.   if (win != NULL)
  1747.     fname = ((struct StringInfo *)(our_gadgets[File1Gad+num-1]->SpecialInfo))->Buffer;
  1748.   else
  1749.     fname = (char *)ArgList[num*6+1];
  1750.  
  1751.   if (fname[0] == '\0')
  1752.     ShowRequest("You have to specify a filename in row %ld\nor deactivate the row",num+1);
  1753.   else
  1754.   {
  1755.     if (!(fh = OpenFile(fname)))
  1756.       ShowRequest("Can't open file\n%s",fname);
  1757.     else
  1758.     {
  1759.       Seek(fh, 0, OFFSET_END);
  1760.       mi.Size = Seek(fh, 0, OFFSET_BEGINNING);
  1761.  
  1762.       if (mi.Size < sizeof(MODULE)+1024)
  1763.         ShowRequest("File %s is too small to be a Protracker module",fname);
  1764.       else
  1765.       {
  1766.         if (!(mi.Module = AllocMem(mi.Size, MEMF_PUBLIC|MEMF_CLEAR)))
  1767.           ShowRequest("Can't allocate %ld bytes of memory to the module",mi.Size);
  1768.         else
  1769.         {
  1770.           if ((Read(fh, mi.Module, mi.Size) == -1))
  1771.           {
  1772.             FreeMem(mi.Module, mi.Size);
  1773.             mi.Module = NULL;
  1774.             ShowRequest("Read error while reading file\n%s",fname);
  1775.           }
  1776.           else
  1777.           {
  1778.             // Test Mark to see if it's a Protracker module
  1779.             mark = (mi.Module->Mark);
  1780.             if (mark != m_k_)
  1781.               if (mark != M_K_)
  1782.                 if (mark != m_K_)
  1783.                 {
  1784.                   FreeMem(mi.Module, mi.Size);
  1785.                   mi.Module = NULL;
  1786.                   ShowRequest("File %s isn't a Protracker module",fname);
  1787.                   CloseFile(fh);
  1788.                   return(mi);
  1789.                 }
  1790.  
  1791.             // Begin to calculate module size
  1792.             for (i=0; i<sizeof(mi.Module->Positions); i++)
  1793.               if (mi.Module->Positions[i] > maxpos)
  1794.                 maxpos = mi.Module->Positions[i];
  1795.  
  1796.             mi.MaxPatt   = maxpos+1;
  1797.             mi.CalcSize  = sizeof(MODULE)+mi.MaxPatt*1024;
  1798.           }
  1799.         }
  1800.       }
  1801.       CloseFile(fh);
  1802.     }
  1803.   }
  1804.  
  1805.   return(mi);
  1806. }
  1807.  
  1808. /********************************************************************
  1809. *                                                                   *
  1810. * Open a file for reading and depack it if nessary.                 *
  1811. *                                                                   *
  1812. ********************************************************************/
  1813.  
  1814. BPTR OpenFile(char *name)
  1815. {
  1816. LONG  err;
  1817.  
  1818.   if ((XpkBase = OpenLibrary("xpkmaster.library",0)))
  1819.   {
  1820.     err = XpkUnpackTags(XPK_InName,name, XPK_OutName,"T:Pro2Fast.depack",
  1821.                         TAG_END);
  1822.  
  1823.     CloseLibrary(XpkBase);
  1824.  
  1825.     if (err != XPKERR_NOTPACKED)
  1826.       if (err)
  1827.         return(0);
  1828.       else
  1829.         return(Open("T:Pro2Fast.depack",MODE_OLDFILE));
  1830.   }
  1831.   return(Open(name,MODE_OLDFILE));
  1832. }
  1833.  
  1834. /********************************************************************
  1835. *                                                                   *
  1836. * Close the file again and clean up.                                *
  1837. *                                                                   *
  1838. ********************************************************************/
  1839.  
  1840. void CloseFile(BPTR fh)
  1841. {
  1842.   Close(fh);
  1843.   DeleteFile("T:Pro2Fast.depack");
  1844. }
  1845.  
  1846. /********************************************************************
  1847. *                                                                   *
  1848. * Show about information.                                           *
  1849. *                                                                   *
  1850. ********************************************************************/
  1851.  
  1852. void About(struct Screen *pubscr)
  1853. {
  1854. #define awidth  205
  1855. #define aheight 155
  1856.  
  1857. int left, top;
  1858. struct BorderSize bs;
  1859. struct Window *aboutwin;
  1860. struct IntuiMessage *msg;
  1861. BOOL done = FALSE;
  1862.  
  1863.   // Open the window
  1864.   bs = GetBorder(pubscr);
  1865.  
  1866.   left = (pubscr->Width - (bs.Left + bs.Right + awidth)) / 2;
  1867.   top  = (pubscr->Height - (bs.Top + bs.Bottom + aheight)) / 2;
  1868.  
  1869.   if ((aboutwin = OpenWindowTags(NULL,WA_Left,left,WA_Top,top,
  1870.                      WA_InnerWidth,awidth,WA_InnerHeight,aheight,
  1871.                      WA_IDCMP,abo_idcmp,WA_AutoAdjust,TRUE,
  1872.                      WA_Title,"About...",
  1873.                      WA_PubScreen,pubscr,WA_PubScreenFallBack,TRUE,
  1874.                      WA_DragBar,TRUE,WA_DepthGadget,TRUE,
  1875.                      WA_RMBTrap,TRUE,
  1876.                      WA_Activate,TRUE,WA_SmartRefresh,TRUE,
  1877.                      TAG_END)))
  1878.  
  1879.   {
  1880.     DrawImage(aboutwin->RPort,&AboutPic,bs.Left,bs.Top);
  1881.  
  1882.     while (!done)
  1883.     {
  1884.       WaitPort(aboutwin->UserPort);
  1885.  
  1886.       while ((!done) && (msg = (struct IntuiMessage *)GetMsg(aboutwin->UserPort)))
  1887.       {
  1888.         switch (msg->Class)
  1889.         {
  1890.           case IDCMP_MOUSEBUTTONS:
  1891.             if (msg->Code == SELECTDOWN)
  1892.               done = TRUE;
  1893.             break;
  1894.  
  1895.           case IDCMP_VANILLAKEY:
  1896.             if (msg->Code == 13)
  1897.               done = TRUE;
  1898.             break;
  1899.         }
  1900.       }
  1901.     }
  1902.     CloseWindow(aboutwin);
  1903.   }
  1904. }
  1905.