home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / amiga / midi / med210.lhw / in.adf / Source / med210src.lzh / med-objsav.c < prev    next >
C/C++ Source or Header  |  1990-06-17  |  6KB  |  182 lines

  1. /* MED - music editor ⌐ 1989, 1990 by Teijo Kinnunen */
  2. /* med-objsav.c: Object file saving routine */
  3.  
  4. #include "med.h"
  5. #include "medproto.h"
  6.  
  7. #define    ERR return(DISKERR)
  8. extern struct Kappale far song;
  9. extern struct Soitin *sample[];
  10. extern struct Lohko *lohko[];
  11. extern UBYTE blocks;
  12. extern BPTR fh;
  13.  
  14. static BOOL __regargs FWrite(char *,long);
  15. static BOOL __regargs WriteLong(ULONG);
  16. static ULONG __regargs NofLWs(ULONG);
  17. static BOOL __regargs WriteName(char *);
  18. static BOOL __regargs pad(ULONG);
  19.  
  20. static BOOL __regargs FWrite(char *ptr,long len)
  21. {
  22.     return((BOOL)(Write(fh,ptr,len) != len));
  23. }
  24.  
  25. static BOOL __regargs WriteLong(ULONG lw)
  26. {
  27.     return(FWrite((char *)(&lw),4));
  28. }
  29.  
  30. static ULONG __regargs NofLWs(ULONG num)
  31. {
  32.     while(num % 4) num++;
  33.     num /= 4;
  34.     return(num);
  35. }
  36.  
  37. static BOOL __regargs WriteName(char *name)
  38. {
  39.     ULONG    namelen = NofLWs(strlen(name));
  40.     UBYTE    padn = ((UBYTE)namelen * 4) - strlen(name),padcnt,zero = 0;
  41.     if(WriteLong(namelen)) return(TRUE);
  42.     if(FWrite(name,strlen(name))) return(TRUE);
  43.     for(padcnt = 0; padcnt < padn; padcnt++) {
  44.         if(FWrite(&zero,1)) return(TRUE);
  45.     }
  46.     return(FALSE);
  47. }
  48.  
  49. static BOOL __regargs pad(ULONG size)
  50. {
  51.     ULONG paddedsize = NofLWs(size) * 4;
  52.     UBYTE zero = 0;
  53.     while(size++ < paddedsize) if(FWrite(&zero,1)) return(TRUE);
  54.     return(FALSE);
  55. }
  56.  
  57. char *WriteObj(char *name,UWORD objtype)
  58. {
  59.     char fname2[52];
  60.     struct MMD0 mod;
  61.     ULONG instrsiz = 0,blksiz = 0,bpsiz,ioffstbl[63],blkoffstbl[100] = {0};
  62.     ULONG reloffs = 0,size3rd;
  63.     UBYTE scnt,nofinstrs = 0,oldexists = 0,maxinstr = 0;
  64.     struct MMD0song *sng;
  65.     if(*name == '\0') return(AskName());
  66.     strcpy(fname2,name);
  67.     scnt = strlen(fname2);
  68.     if(scnt > 2 && fname2[scnt - 1] == 'o' && fname2[scnt - 2] == '.');
  69.     else strcat(fname2,".o");
  70.     if(IsHere(fname2)) {
  71.         Ilmoita(fileex);
  72.         oldexists = 1;
  73.         if(!Continue()) return(notsaved);
  74.     }
  75.     if(!(fh = Open2(fname2,MODE_NEWFILE))) ERR;
  76.     Ilmoita("Saving object file...");
  77. /* -------- First: write hunk_unit, which contains the name of this unit */
  78.     if(WriteLong(0x000003E7)) ERR; /* hunk_unit */
  79.     if(WriteName(fname2)) ERR;
  80. /* ----------- Write the first hunk, which contains the instruments */
  81.     if(objtype == 0 && WriteLong(0x400003EA)) ERR; /* hunk_data (chip) */
  82.     else if(objtype == 1 && WriteLong(0x000003EA)) ERR;
  83.     for(scnt = 0; scnt < 63; scnt++) {
  84.         if(sample[scnt]) {
  85.             ioffstbl[scnt] = instrsiz;
  86.             instrsiz += sizeof(struct Soitin);
  87.             instrsiz += (sample[scnt]->length & 0xfffffffe);
  88.             nofinstrs++;
  89.             maxinstr = scnt + 1;
  90.         } else ioffstbl[scnt] = 0L;
  91.     }
  92.     for(scnt = 0; scnt < blocks; scnt++) {
  93.         blkoffstbl[scnt] = blksiz;
  94.         blksiz += MMDBLKHDRSZ + 3 * lohko[scnt]->numtracks *
  95.             (lohko[scnt]->lines + 1);
  96.     }
  97.     bpsiz = 4 * blocks; /* size of block pointers */
  98.     if(WriteLong(NofLWs(instrsiz) | (objtype ? 0x40000000 : 0))) ERR;
  99.     for(scnt = 0; scnt < 63; scnt++) {
  100.         if(sample[scnt]) {
  101.             if(FWrite((char *)sample[scnt],sizeof(struct Soitin)
  102.                 + (sample[scnt]->length & 0xfffffffe))) ERR;
  103.         }
  104.     }
  105.     if(pad(instrsiz)) ERR;
  106.     if(WriteLong(0x000003F2)) ERR; /* hunk_end */
  107. /* ---------- Then write the second hunk, music */
  108.     if(WriteLong(0x000003EA)) ERR; /* hunk_data */
  109.     if(WriteLong(NofLWs(blksiz))) ERR;
  110.     for(scnt = 0; scnt < blocks; scnt++) {
  111.         if(FWrite((char *)(lohko[scnt]),MMDBLKHDRSZ)) ERR;
  112.         if(FWrite(lohko[scnt]->music,3 * lohko[scnt]->numtracks *
  113.             (lohko[scnt]->lines + 1))) ERR;
  114.     }
  115.     if(pad(blksiz)) ERR;
  116.     if(WriteLong(0x000003F2)) ERR; /* hunk_end */
  117. /* --------- And finally the third hunk, which contains everything else */
  118.     size3rd = 4 * maxinstr + bpsiz + sizeof(struct MMD0song) +
  119.         sizeof(struct MMD0);
  120.     if(WriteLong(0x000003EA)) ERR; /* hunk_data */
  121.     if(WriteLong(NofLWs(size3rd))) ERR;
  122. /* - write block pointers */
  123.     if(FWrite((char *)blkoffstbl,bpsiz)) ERR;
  124. /* - write sample ptrs */
  125.     if(maxinstr && FWrite((char *)ioffstbl,maxinstr * 4)) ERR;
  126. /* - create & write MMD0song */
  127.     if(!(sng = MakeMMD0song())) return(nomem);
  128.     sng->numsamples = maxinstr;
  129.     if(FWrite((char *)sng,sizeof(struct MMD0song))) {
  130.         FreeMem(sng,sizeof(struct MMD0song));
  131.         ERR;
  132.     }
  133.     FreeMem(sng,sizeof(struct MMD0song));
  134. /* - then build the module structure */
  135.     memset((void *)&mod,0,sizeof(mod));
  136.     mod.id = ((long)'M'<<24|(long)'M'<<16|(long)'D'<<8|(long)'0');
  137.     mod.actplayline = -1;
  138.     /* block ptr table offset = 0, no need to initialize */
  139.     mod.smplarr = (struct Soitin **)bpsiz;
  140.     mod.song = (struct MMD0song *)(bpsiz + maxinstr * 4);
  141. /* - and write it */
  142.     if(FWrite((char *)&mod,sizeof(struct MMD0))) ERR;
  143.     if(pad(size3rd)) ERR;
  144. /* --------- We need to relocate something */
  145.     if(WriteLong(0x000003EC)) ERR; /* hunk_reloc32 */
  146. /* reloc block ptrs */
  147.     if(WriteLong((ULONG)blocks)) ERR;
  148.     if(WriteLong(0x00000001)) ERR; /* Music in hunk #1 */
  149.     for(scnt = 0; scnt < blocks; scnt++, reloffs += 4) {
  150.         if(WriteLong(reloffs)) ERR;
  151.     }
  152.     if(nofinstrs) {
  153.         if(WriteLong((ULONG)nofinstrs)) ERR;
  154.         if(WriteLong(0x00000000)) ERR; /* Instruments in hunk #0 */
  155.         for(scnt = 0; scnt < maxinstr; scnt++, reloffs += 4)
  156.             if(sample[scnt]) {
  157.                 if(WriteLong(reloffs)) ERR;
  158.             }
  159.     }
  160.     reloffs += sizeof(struct MMD0song); /* skip the song */
  161.     if(WriteLong(3)) ERR; /* relocate block ptrs, sample ptrs & song */
  162.     if(WriteLong(0x00000002)) ERR; /* they're in hunk #2 */
  163.     if(WriteLong(reloffs + 8)) ERR; /* offset 8 = song ptr */
  164.     if(WriteLong(reloffs + 16)) ERR; /* 16 = block table ptr */
  165.     if(WriteLong(reloffs + 24)) ERR; /* 24 = sample table ptr */
  166.     if(WriteLong(0x00000000)) ERR; /* end */
  167. /* -------- And dump the external symbols defined in this file */
  168.     if(WriteLong(0x000003EF)) ERR; /* hunk_ext */
  169.     size3rd = NofLWs(strlen(name)+1);
  170.     if(WriteLong(0x01000000|size3rd)) ERR;
  171.     if(FWrite("_",1)) ERR; /* leading _ for C.. */
  172.     if(FWrite(name,strlen(name))) ERR;
  173.     if(pad(strlen(name)+1)) ERR;
  174.     if(WriteLong(reloffs)) ERR; /* remember? reloffs = offset of MMD0 */
  175.     if(WriteLong(0x00000000)) ERR;
  176.     if(WriteLong(0x000003F2)) ERR; /* hunk_end */
  177.     Close(fh); fh = 0L; /* huh, huh !! */
  178.     if(!oldexists) InsertSavedFile(fname2);
  179.     Ilmoita("Saved.");
  180.     return(NOERR);
  181. }
  182.