home *** CD-ROM | disk | FTP | other *** search
/ TopWare 18: Liquid / Image.iso / liquid / top1120 / build.c < prev    next >
C/C++ Source or Header  |  1994-04-10  |  20KB  |  706 lines

  1.  
  2. ;   /*\
  3. ;---|*|----====< build.c >====----
  4. ;---|*|
  5. ;---|*| This program displays the contents of the selected bank patches,
  6. ;---|*| then dumps it to disk
  7. ;---|*|
  8. ;---|*| Copyright (c) 1993,1994  V.E.S.A, Inc. All Rights Reserved.
  9. ;---|*|
  10. ;---|*| VBE/AI 1.0 Specification
  11. ;---|*|    February 2, 1994. 1.00 release
  12. ;---|*|
  13. ;   \*/
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19.  
  20. #include "bank.h"
  21. #include "..\..\..\vbeai.h"
  22.  
  23. ;   /*\
  24. ;---|*|----====< global constants >====----
  25. ;   \*/
  26.  
  27. #define TRUE    -1
  28. #define FALSE   0
  29.  
  30.         FILE *fn;                       // pointer to the stream
  31.         FILE *ouf;                      // output file
  32.  
  33.         BANKHEADER  Header;
  34.         TIMBRE      Instr;
  35.  
  36.         INSHEADER   InstrList[1000];    // array of 1000 instrument headers
  37.         int         InstrIndex;         // current index to the instrument array
  38.         int         InstrChanged;       // changes have occured flag
  39.         int         NewFreq = 60;       // percussive patch frequencies
  40.  
  41. #define INSTMAX 256
  42.         int     instidx    = 0;
  43.         long    instruments[256] = {0};
  44.  
  45.         long    vaipoffset = 0;     // offset to the patch chunk header
  46.  
  47. ;   /*\
  48. ;---|*|---====< VBE/AI OPL2 Patch Structure >====----
  49. ;   \*/
  50.  
  51.         typedef struct {
  52.             char    opl2ksl;       // ksl
  53.             char    opl2freqMult;  // freqMult
  54.             char    opl2feedBack;  // feedBack  // used by operator 0 only
  55.             char    opl2attack;    // attack
  56.             char    opl2sustLevel ;// sustLevel
  57.             char    opl2sustain;   // sustain
  58.             char    opl2decay;     // decay
  59.             char    opl2release;   // release
  60.             char    opl2output;    // output
  61.             char    opl2am;        // am
  62.             char    opl2vib;       // vib
  63.             char    opl2ksr;       // ksr
  64.             char    opl2fm;        // fm        // used by operator 0 only
  65.         } opl2opr;
  66.  
  67.         typedef struct {
  68.             int     opl2type;      // patch type
  69.             char    opl2mode;      // mode:  0 = melodic, 1 = percussive
  70.             char    opl2percVoice; // percVoice: if mode == 1, voice number to be used
  71.             opl2opr opl2op0;       // operator 0 parameters;
  72.             opl2opr opl2op1;       // operator 1 parameters;
  73.             char    opl2wave0;     // waveform for operator 0
  74.             char    opl2wave1;     // waveform for operator 1
  75.         } opl2patch;
  76.  
  77.         opl2patch opl2inst =
  78.             {
  79.               0,0,
  80.               0,0,0,0,0,0,0,0,0,0,0,0,0,
  81.               0,0,0,0,0,0,0,0,0,0,0,0,0,
  82.               0,0
  83.             };
  84.  
  85.     // the following structures are listed with indentation
  86.     // to indicate nesting levels of the VBE/AI patch library
  87.  
  88.         RIFFhdr riffhdr = { "RIFF", 0L };
  89.             VAILhdr vailhdr = { "vail", 0L };
  90.                 ZSTRhdr zstrhdr = { "ZSTR", 0L };
  91.                 VAIPhdr vaiphdr = { "vaip", 0L };
  92.                     VAIIhdr vaiihdr = { "vaii", 8L, 0L, 0L };
  93.                     VAIDhdr vaidhdr = { "vaid", 0L };
  94.  
  95.  
  96. ;   /*\
  97. ;---|*|----====< prototypes >====----
  98. ;   \*/
  99.  
  100.         void    DisplayInstrument   ( FILE *,int, int );
  101.         void    DoExit              ( int );
  102.         int     GetEntry            ( );
  103.         void    OpenBankFile        ( int, char * );
  104.         int     CopyToNew           ( opl2patch *, TIMBRE *, int );
  105.         void    DumpInstrument      ( int );
  106.  
  107.         void    LoadTextStrings     ( );
  108.                 WriteRIFFHeader     ( FILE *, long );
  109.                 WriteInstrument     ( opl2patch *);
  110.  
  111.  
  112. ;   /*\
  113. ;---|*|------------------------==============================---------------------
  114. ;---|*|---------------------====< Start of Execution >====---------------------
  115. ;---|*|---------------------==============================---------------------
  116. ;   \*/
  117.  
  118. main(argc,argv)
  119.     int argc;
  120.     char *argv[];
  121. {
  122. int index;
  123. fpos_t len;
  124.  
  125.     // get the bank file name
  126.  
  127.         OpenBankFile(argc,argv[1]);     // will not return if bad file read
  128.  
  129.     // open the target bank file
  130.  
  131.         ouf = fopen ("output.bnk","wb+");
  132.  
  133.     // process the list till done
  134.  
  135.         WriteRIFFHeader (ouf,0);
  136.  
  137.         while (1) {
  138.  
  139.             if ((index = GetEntry()) <= -1)
  140.                 break;
  141.  
  142.             DumpInstrument(index);
  143.  
  144.         }
  145.  
  146.         fgetpos (ouf,&len);
  147.         WriteRIFFHeader (ouf,(long)len);    // len = total file length
  148.         DoExit(0);
  149. }
  150.  
  151.  
  152. ;   /*\
  153. ;---|*|------------------------=======================------------------------
  154. ;---|*|------------------------====< Subroutines >====------------------------
  155. ;---|*|------------------------=======================------------------------
  156. ;   \*/
  157.  
  158.  
  159. ;   /*\
  160. ;---|*|----====< DisplayInstrument ( int, int ) >====----
  161. ;---|*|
  162. ;---|*| This displays the instrument contents, thats all...
  163. ;---|*|
  164. ;---|*| Entry Conditions:
  165. ;---|*|    None
  166. ;---|*|
  167. ;---|*| Exit Conditions:
  168. ;---|*|    None
  169. ;---|*|
  170.     \*/
  171. void DisplayInstrument(f,index,cls)
  172.     FILE *f;
  173.     int index;
  174.     int cls;
  175. {
  176. TIMBRE *i;
  177.  
  178.     // print each element
  179.  
  180.         i = &Instr;
  181.  
  182. ////    fprintf (f,"Index=%-3d Instrument Name \"%s\" Offset=%-3d\n",index+1,InstrList[index].name,InstrList[index].index);
  183. ////    fprintf (f,"============================================\n");
  184. ////    fprintf (f,"              1)mode  : %2u\n",i->mode );
  185. ////    fprintf (f,"              2)Voice : %2u\n",i->percVoice );
  186. ////    fprintf (f,"==== OPERATOR 0 ====    ==== OPERATOR 1 ====\n");
  187. ////    fprintf (f,"  3) ksl      = %4u    17) ksl      = %4u  \n",i->op0.ksl      , i->op1.ksl      );
  188. ////    fprintf (f,"  4) freqMult = %4u    18) freqMult = %4u  \n",i->op0.freqMult , i->op1.freqMult );
  189. ////    fprintf (f,"  5) feedBack = %4u    19) N/U (PAN)  %4u  \n",i->op0.feedBack , i->op1.feedBack );
  190. ////    fprintf (f,"  6) attack   = %4u    20) attack   = %4u  \n",i->op0.attack   , i->op1.attack   );
  191. ////    fprintf (f,"  7) sustLevel= %4u    21) sustLevel= %4u  \n",i->op0.sustLevel, i->op1.sustLevel);
  192. ////    fprintf (f,"  8) sustain  = %4u    22) sustain  = %4u  \n",i->op0.sustain  , i->op1.sustain  );
  193. ////    fprintf (f," 10) decay    = %4u    23) decay    = %4u  \n",i->op0.decay    , i->op1.decay    );
  194. ////    fprintf (f," 11) release  = %4u    24) release  = %4u  \n",i->op0.release  , i->op1.release  );
  195. ////    fprintf (f," 12) output   = %4u    25) output   = %4u  \n",i->op0.output   , i->op1.output   );
  196. ////    fprintf (f," 13) am       = %4u    26) am       = %4u  \n",i->op0.am       , i->op1.am       );
  197. ////    fprintf (f," 14) vib      = %4u    27) vib      = %4u  \n",i->op0.vib      , i->op1.vib      );
  198. ////    fprintf (f," 15) ksr      = %4u    28) ksr      = %4u  \n",i->op0.ksr      , i->op1.ksr      );
  199. ////    fprintf (f," 16) fm       = %4u    29) N/U        %4u  \n",i->op0.fm       , i->op1.fm       );
  200. ////    fprintf (f,"             30)op0 wave : %2u\n", i->wave0 );
  201. ////    fprintf (f,"             31)op1 wave : %2u\n", i->wave1 );
  202. ////
  203.  
  204. }
  205.  
  206. ;   /*\
  207. ;---|*|----====< DisplayNewInstrument ( int, int ) >====----
  208. ;---|*|
  209. ;---|*| This displays the instrument contents, thats all...
  210. ;---|*|
  211. ;---|*| Entry Conditions:
  212. ;---|*|    None
  213. ;---|*|
  214. ;---|*| Exit Conditions:
  215. ;---|*|    None
  216. ;---|*|
  217.     \*/
  218. void DisplayNewInstrument(f,index,d)
  219.     FILE *f;
  220.     int index;
  221.     opl2patch *d;
  222. {
  223.  
  224.     // print each element
  225.  
  226. ////    fprintf (f,"============================================\n");
  227. ////    fprintf (f,"              1)mode  : %2u\n",d->opl2mode );
  228. ////    fprintf (f,"              2)Voice : %2u\n",d->opl2percVoice );
  229. ////    fprintf (f,"==== OPERATOR 0 ====    ==== OPERATOR 1 ====\n");
  230. ////    fprintf (f,"  3) ksl      = %4u    17) ksl      = %4u  \n",d->opl2op0.opl2ksl      , d->opl2op1.opl2ksl      );
  231. ////    fprintf (f,"  4) freqMult = %4u    18) freqMult = %4u  \n",d->opl2op0.opl2freqMult , d->opl2op1.opl2freqMult );
  232. ////    fprintf (f,"  5) feedBack = %4u    19) N/U (PAN)  %4u  \n",d->opl2op0.opl2feedBack , d->opl2op1.opl2feedBack );
  233. ////    fprintf (f,"  6) attack   = %4u    20) attack   = %4u  \n",d->opl2op0.opl2attack   , d->opl2op1.opl2attack   );
  234. ////    fprintf (f,"  7) sustLevel= %4u    21) sustLevel= %4u  \n",d->opl2op0.opl2sustLevel, d->opl2op1.opl2sustLevel);
  235. ////    fprintf (f,"  8) sustain  = %4u    22) sustain  = %4u  \n",d->opl2op0.opl2sustain  , d->opl2op1.opl2sustain  );
  236. ////    fprintf (f," 10) decay    = %4u    23) decay    = %4u  \n",d->opl2op0.opl2decay    , d->opl2op1.opl2decay    );
  237. ////    fprintf (f," 11) release  = %4u    24) release  = %4u  \n",d->opl2op0.opl2release  , d->opl2op1.opl2release  );
  238. ////    fprintf (f," 12) output   = %4u    25) output   = %4u  \n",d->opl2op0.opl2output   , d->opl2op1.opl2output   );
  239. ////    fprintf (f," 13) am       = %4u    26) am       = %4u  \n",d->opl2op0.opl2am       , d->opl2op1.opl2am       );
  240. ////    fprintf (f," 14) vib      = %4u    27) vib      = %4u  \n",d->opl2op0.opl2vib      , d->opl2op1.opl2vib      );
  241. ////    fprintf (f," 15) ksr      = %4u    28) ksr      = %4u  \n",d->opl2op0.opl2ksr      , d->opl2op1.opl2ksr      );
  242. ////    fprintf (f," 16) fm       = %4u    29) N/U        %4u  \n",d->opl2op0.opl2fm       , d->opl2op1.opl2fm       );
  243. ////    fprintf (f,"             30)op0 wave : %2u\n", d->opl2wave0 );
  244. ////    fprintf (f,"             31)op1 wave : %2u\n", d->opl2wave1 );
  245. ////
  246.  
  247. }
  248.  
  249.  
  250. ;   /*\
  251. ;---|*|----====< CopyToNew >====----
  252. ;---|*|
  253. ;---|*| Copy the instrument to the VBE/AI format
  254. ;---|*|
  255. ;---|*| Entry Conditions:
  256. ;---|*|    None
  257. ;---|*|
  258. ;---|*| Exit Conditions:
  259. ;---|*|    None
  260. ;---|*|
  261.     \*/
  262.  
  263. CopyToNew (d,s,p)
  264.     opl2patch *d;
  265.     TIMBRE *s;
  266.     int p;  // patch #
  267. {
  268.  
  269.     // place the specified frequency in the old percussive field
  270.  
  271.         d->opl2percVoice        = NewFreq | 0x80;
  272.  
  273.         if (s->mode)
  274.             printf ("\aThere is a non-melodic mode specified in patch #%d!\n",p);
  275.  
  276.         d->opl2type             = MIDI_PATCH_OPL2;
  277.         d->opl2mode             = s->mode;
  278.  
  279.         d->opl2op0.opl2ksl      = s->op0.ksl;
  280.         d->opl2op0.opl2freqMult = s->op0.freqMult;
  281.         d->opl2op0.opl2feedBack = s->op0.feedBack;
  282.         d->opl2op0.opl2attack   = s->op0.attack;
  283.         d->opl2op0.opl2sustLevel= s->op0.sustLevel;
  284.         d->opl2op0.opl2sustain  = s->op0.sustain;
  285.         d->opl2op0.opl2decay    = s->op0.decay;
  286.         d->opl2op0.opl2release  = s->op0.release;
  287.         d->opl2op0.opl2output   = s->op0.output;
  288.         d->opl2op0.opl2am       = s->op0.am;
  289.         d->opl2op0.opl2vib      = s->op0.vib;
  290.         d->opl2op0.opl2ksr      = s->op0.ksr;
  291.         d->opl2op0.opl2fm       = s->op0.fm;
  292.  
  293.         d->opl2op1.opl2ksl      = s->op1.ksl;
  294.         d->opl2op1.opl2freqMult = s->op1.freqMult;
  295.         d->opl2op1.opl2feedBack = s->op1.feedBack;
  296.         d->opl2op1.opl2attack   = s->op1.attack;
  297.         d->opl2op1.opl2sustLevel= s->op1.sustLevel;
  298.         d->opl2op1.opl2sustain  = s->op1.sustain;
  299.         d->opl2op1.opl2decay    = s->op1.decay;
  300.         d->opl2op1.opl2release  = s->op1.release;
  301.         d->opl2op1.opl2output   = s->op1.output;
  302.         d->opl2op1.opl2am       = s->op1.am;
  303.         d->opl2op1.opl2vib      = s->op1.vib;
  304.         d->opl2op1.opl2ksr      = s->op1.ksr;
  305.         d->opl2op1.opl2fm       = s->op1.fm;
  306.  
  307.         d->opl2wave0            = s->wave0;
  308.         d->opl2wave1            = s->wave1;
  309. }
  310.  
  311.  
  312. ;   /*\
  313. ;---|*|----====< DoExit(int) >====----
  314. ;---|*|
  315. ;---|*| Shutdown and exit to DOS
  316. ;---|*|
  317. ;---|*| Entry Conditions:
  318. ;---|*|    int = completion code
  319. ;---|*|
  320. ;---|*| Exit Conditions:
  321. ;---|*|    None
  322. ;---|*|
  323. ;   \*/
  324. void DoExit(cc)
  325.    int cc;
  326. {
  327.  
  328.     // if the instrument bank is opened, close to save all...
  329.  
  330.         if (fn)
  331.             fclose (fn);
  332.  
  333.         if (ouf)
  334.             fclose (ouf);
  335.  
  336.     // bye...
  337.  
  338.         exit(cc);
  339. }
  340.  
  341.  
  342. ;   /*\
  343. ;---|*|----====< DumpInstrument() >====----
  344. ;---|*|
  345. ;---|*| This displays the instrument contents, then Dumps the
  346. ;---|*| operator to the output file.
  347. ;---|*|
  348. ;---|*| Entry Conditions:
  349. ;---|*|     int = the index of the instrument
  350. ;---|*|
  351. ;---|*| Exit Conditions:
  352. ;---|*|    None
  353. ;---|*|
  354. ;   \*/
  355. void DumpInstrument(index)
  356.     int index;
  357. {
  358. long pos;
  359. char buff[11];
  360.  
  361.     // position the file pointer to that record
  362.  
  363.         pos = (InstrList[index].index * sizeof(TIMBRE)) + Header.offsetTimbre;
  364.         fseek ( fn, pos, SEEK_SET );
  365.  
  366.     // read in the instrument record
  367.  
  368.         if (fread(&Instr,sizeof(TIMBRE),1,fn) != 1) {
  369.             printf ("Cannot read that instrument!\n");
  370.             return;
  371.         }
  372.  
  373.         if (Instr.mode)
  374.             printf ("===============Percussive mode patch!=================\n");
  375.  
  376.  
  377.  
  378.     // display and edit, display and edit, display and edit...
  379.  
  380.         DisplayInstrument(stdout,index,1);
  381.  
  382.         CopyToNew (&opl2inst,&Instr,index);
  383.  
  384.         DisplayNewInstrument(stdout,index,&opl2inst);
  385.  
  386.         WriteInstrument(&opl2inst);
  387.  
  388. }
  389.  
  390. ;   /*\
  391. ;---|*|----====< GetEntry >====----
  392. ;---|*|
  393. ;---|*| Get the next bank index #
  394. ;---|*|
  395. ;---|*| Entry Conditions:
  396. ;---|*|    none
  397. ;---|*|
  398. ;---|*| Exit Conditions:
  399. ;---|*|    -1 if done, else 0+ for the index
  400. ;---|*|
  401. ;   \*/
  402.  
  403. int GetEntry()
  404. {
  405. char buff[100];
  406. int result;
  407.  
  408.     while (1) {
  409.  
  410.         if (feof(stdin)) {
  411.             printf ("end of input\n");
  412.             return(-1);
  413.         }
  414.  
  415.         printf ("\nEnter an Index, (0 to exit, [ENTER] for next page) :");
  416.  
  417.         fgets(buff,99,stdin);
  418.         printf ("%s\n",buff);
  419.  
  420.         if (isdigit(buff[0]))
  421.             if (sscanf(buff,"%d %d",&result,&NewFreq) == 2)
  422.                 return (--result);
  423.     }
  424. }
  425.  
  426.  
  427. ;   /*\
  428. ;---|*|----====< OpenBankFile >====----
  429. ;---|*|
  430. ;---|*| Open the bank file, and read in the header block.
  431. ;---|*|
  432. ;---|*| Entry Conditions:
  433. ;---|*|
  434. ;---|*|    char *f is the possible file name
  435. ;---|*|
  436. ;---|*| Exit Conditions:
  437. ;---|*|    if in error, the routine returns directly to DOS.
  438. ;---|*|
  439. ;   \*/
  440.  
  441. void OpenBankFile (argc,f)
  442.     int argc;
  443.     char *f;
  444. {
  445. INSHEADER Iname; // current instrment header
  446.  
  447.     // if no arguments, just give helps
  448.  
  449.         if (argc < 2) {
  450.             printf ("\nBANK -- By Media Vision, Inc.\n\n");
  451.             printf ("To Use: DOS>BANK [FILENAME.BNK] [CREDITS]\n\n",f);
  452.             exit(0);
  453.         }
  454.  
  455.     // attemp the open
  456.  
  457.         if ((fn = fopen (f,"r+b")) == 0) {
  458.  
  459.             printf ("Cannot open the bank file: \"%s\"\n",f);
  460.             DoExit (-1);
  461.         }
  462.  
  463.     // read in the header
  464.  
  465.         if (fread(&Header,sizeof(BANKHEADER),1,fn) != 1) {
  466.  
  467.             printf ("Cannot read the bank's header record!");
  468.             DoExit (-1);
  469.         }
  470.  
  471.     // exit if no index entries are used
  472.  
  473.         if (Header.nrDefined == 0) {
  474.  
  475.             printf ("There are no valid entries in this bank!");
  476.             DoExit (-1);
  477.         }
  478.  
  479.     // load the instrument index into memory starting with the first record
  480.  
  481.         InstrIndex = 0;
  482.  
  483.     // read each header till done...
  484.  
  485.             do {
  486.  
  487.                 if (fread(&Iname,sizeof(INSHEADER),1,fn) != 1) {
  488.                     printf ("Unexpected end of file read the index!\n");
  489.                     DoExit(-1);
  490.                 }
  491.  
  492.             // save only if the data is valid
  493.  
  494.                 if (Iname.used) {
  495.  
  496.                     // save the instrument index data
  497.  
  498.                         memcpy
  499.                         (
  500.                             (void *)&InstrList[InstrIndex++],
  501.                             (void *)&Iname,
  502.                             sizeof (INSHEADER)
  503.                         );
  504.                 }
  505.  
  506.         } while (InstrIndex != Header.nrDefined);
  507.  
  508.     // InstrIndex will point to the last good entry
  509.  
  510.         InstrIndex--;
  511.  
  512. }
  513.  
  514.  
  515. ;   /*\
  516. ;---|*|----====< WriteInstrument >====----
  517. ;---|*|
  518. ;---|*| Write the instrument out to disk
  519. ;---|*|
  520. ;---|*| Entry Conditions:
  521. ;---|*|    none
  522. ;---|*|
  523. ;---|*| Exit Conditions:
  524. ;---|*|    none
  525. ;---|*|
  526. ;   \*/
  527.  
  528. WriteInstrument(d)
  529.     opl2patch *d;
  530. {
  531. int n;
  532. fpos_t p;
  533. char *s = (char *) &vaidhdr;
  534.  
  535.     // build the header
  536.  
  537.         vaidhdr.vaidlen = sizeof(opl2patch);
  538.  
  539.     // if we get the file position, save it in the table
  540.  
  541.         if (!fgetpos (ouf,&p))
  542.             instruments[instidx++] = (long)p - vaipoffset;
  543.  
  544.     // write the patch header to disk
  545.  
  546.         for (n=sizeof(VAIDhdr);n;n--)
  547.             fputc (*s++,ouf);
  548.  
  549.     // write the patch to disk
  550.  
  551.         s = (char *)d;
  552.         for (n=sizeof(opl2patch);n;n--)
  553.             fputc (*s++,ouf);
  554.  
  555. }
  556.  
  557.  
  558. ;   /*\
  559. ;---|*|----====< WriteRIFFHeader >====----
  560. ;---|*|
  561. ;---|*| Write the instrument out to disk
  562. ;---|*|
  563. ;---|*| Entry Conditions:
  564. ;---|*|    none
  565. ;---|*|
  566. ;---|*| Exit Conditions:
  567. ;---|*|    none
  568. ;---|*|
  569. ;   \*/
  570.  
  571. WriteRIFFHeader (ouf,len)
  572.     FILE *ouf;
  573.     long len;
  574. {
  575. char *s;
  576. int n,x;
  577. fpos_t p;
  578. long l;
  579.  
  580.     // start at the beginning
  581.  
  582.         fsetpos (ouf,0);
  583.  
  584.     // write the "RIFF" header
  585.  
  586.         len -= sizeof (RIFFhdr);    // remove this length
  587.  
  588.         s = (char *) &riffhdr;
  589.         riffhdr.rcount = len;
  590.  
  591.         for (n=sizeof(RIFFhdr);n;n--)
  592.             fputc (*s++,ouf);
  593.  
  594.     // write the "vail" header
  595.  
  596.         len -= sizeof (VAILhdr);    // remove this length
  597.  
  598.         s = (char *) &vailhdr;
  599.         vailhdr.pcount = len;
  600.  
  601.         for (n=sizeof(VAILhdr);n;n--)
  602.             fputc (*s++,ouf);
  603.  
  604.     // write the "ZSTR" headers
  605.  
  606.         LoadTextStrings();
  607.  
  608.     // write the "vaip" header
  609.  
  610.         if (!fgetpos (ouf,&p))
  611.             vaipoffset = (long)p;
  612.  
  613.         vaiphdr.vaiplen =   (instidx * sizeof(VAIIhdr))
  614.                           + (instidx * sizeof(VAIDhdr))
  615.                           + (instidx * sizeof(opl2patch));
  616.  
  617.         s = (char *) &vaiphdr;
  618.         for (n=sizeof(VAIPhdr);n;n--)
  619.             fputc (*s++,ouf);
  620.  
  621.     // write the "vaii" headers
  622.  
  623.         for (x=0;x<INSTMAX;x++) {
  624.  
  625.             // move the patch offset into the array
  626.  
  627.             vaiihdr.poffset = instruments[x];
  628.  
  629.             // move the patch length into the structure
  630.  
  631.             vaiihdr.vaidln = sizeof (opl2patch);
  632.  
  633.             // write out the array
  634.  
  635.             s = (char *) &vaiihdr;
  636.             for (n=sizeof(VAIIhdr);n;n--)
  637.                 fputc (*s++,ouf);
  638.         }
  639.  
  640. }
  641.  
  642.  
  643. ;   /*\
  644. ;---|*|----====< LoadTextSTrings >====----
  645. ;---|*|
  646. ;---|*| Give credit for the bank file
  647. ;---|*|
  648. ;---|*| Entry Conditions:
  649. ;---|*|    none
  650. ;---|*|
  651. ;---|*| Exit Conditions:
  652. ;---|*|    none
  653. ;---|*|
  654. ;   \*/
  655.  
  656. void LoadTextStrings()
  657. {
  658. FILE *tfil;
  659. char str[100],*s;
  660. int n;
  661.  
  662. ZSTRhdr thd;
  663.  
  664.         thd.type[0] = 'Z';
  665.         thd.type[1] = 'S';
  666.         thd.type[2] = 'T';
  667.         thd.type[3] = 'R';
  668.  
  669.         if ((tfil = fopen ("credits","r")) ==0)
  670.             return;
  671.  
  672.         while (fgets(str,99,tfil)) {
  673.  
  674.             s = str;
  675.             for (n=0;n<99;n++) {
  676.                 if (*s == 0x0A)
  677.                     *s == 0;
  678.                 if (*s == 0x0D)
  679.                     *s == 0;
  680.                 if (!*s++)
  681.                     break;
  682.             }
  683.  
  684.             if ((thd.tlen = n) == 0)
  685.                 break;
  686.  
  687.             s = (char *)&thd;
  688.             for (n=8;n;n--)
  689.                 fputc (*s++,ouf);
  690.  
  691.             s = str;
  692.             for (n=thd.tlen;n;n--)
  693.                 fputc (*s++,ouf);
  694.  
  695.         }
  696.  
  697.         fclose (tfil);
  698. }
  699.  
  700. ;   /*\
  701. ;---|*| end of build.c
  702. ;   \*/
  703.  
  704.  
  705.  
  706.