home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 February / PCO_0299.ISO / filesbbs / linux / mikmod-3.000 / mikmod-3 / mikmod-3.1.2 / loaders / load_far.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-07  |  7.5 KB  |  328 lines

  1. /*    MikMod sound library
  2.     (c) 1998 Miodrag Vallat and others - see file AUTHORS for complete list
  3.  
  4.     This library is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU Library General Public License as
  6.     published by the Free Software Foundation; either version 2 of
  7.     the License, or (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU Library General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Library General Public
  15.     License along with this library; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. /*==============================================================================
  20.  
  21.   $Id: load_far.c,v 1.19 1998/12/07 06:00:13 miod Exp $
  22.  
  23.   Farandole (FAR) module loader
  24.  
  25. ==============================================================================*/
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include "config.h"
  29. #endif
  30.  
  31. #include <string.h>
  32.  
  33. #include <mikmod_internals.h>
  34.  
  35. /*========== Module structure */
  36.  
  37. typedef struct FARHEADER1 {
  38.     UBYTE id[4];            /* file magic */
  39.     CHAR  songname[40];        /* songname */
  40.     CHAR  blah[3];            /* 13,10,26 */
  41.     UWORD headerlen;        /* remaining length of header in bytes */
  42.     UBYTE version;
  43.     UBYTE onoff[16];
  44.     UBYTE edit1[9];
  45.     UBYTE speed;
  46.     UBYTE panning[16];
  47.     UBYTE edit2[4];
  48.     UWORD stlen;
  49. } FARHEADER1;
  50.  
  51. typedef struct FARHEADER2 {
  52.     UBYTE orders[256];
  53.     UBYTE numpat;
  54.     UBYTE snglen;
  55.     UBYTE loopto;
  56.     UWORD patsiz[256];
  57. } FARHEADER2;
  58.  
  59. typedef struct FARSAMPLE {
  60.     CHAR  samplename[32];
  61.     ULONG length;
  62.     UBYTE finetune;
  63.     UBYTE volume;
  64.     ULONG reppos;
  65.     ULONG repend;
  66.     UBYTE type;
  67.     UBYTE loop;
  68. } FARSAMPLE;
  69.  
  70. typedef struct FARNOTE {
  71.     UBYTE note,ins,vol,eff;
  72. } FARNOTE;
  73.  
  74. /*========== Loader variables */
  75.  
  76. static    CHAR FAR_Version[] = "Farandole";
  77. static    FARHEADER1 *mh1 = NULL;
  78. static    FARHEADER2 *mh2 = NULL;
  79. static    FARNOTE *pat = NULL;
  80.  
  81. static    unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
  82.  
  83. /*========== Loader code */
  84.  
  85. BOOL FAR_Test(void)
  86. {
  87.     UBYTE id[47];
  88.  
  89.     if(!_mm_read_UBYTES(id,47,modfp)) return 0;
  90.     if((memcmp(id,FARSIG,4))||(memcmp(id+44,FARSIG+4,3))) return 0;
  91.     return 1;
  92. }
  93.  
  94. BOOL FAR_Init(void)
  95. {
  96.     if(!(mh1 = (FARHEADER1*)_mm_malloc(sizeof(FARHEADER1)))) return 0;
  97.     if(!(mh2 = (FARHEADER2*)_mm_malloc(sizeof(FARHEADER2)))) return 0;
  98.     if(!(pat = (FARNOTE*)_mm_malloc(256*16*4*sizeof(FARNOTE)))) return 0;
  99.  
  100.     return 1;
  101. }
  102.  
  103. void FAR_Cleanup(void)
  104. {
  105.     if(mh1) free(mh1);
  106.     if(mh2) free(mh2);
  107.     if(pat) free(pat);
  108.  
  109.     mh1=NULL;
  110.     mh2=NULL;
  111.     pat=NULL;
  112. }
  113.  
  114. UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows)
  115. {
  116.     int t,vibdepth=1;
  117.  
  118.     UniReset();
  119.     for(t=0;t<rows;t++) {
  120.         if(n->note) {
  121.             UniInstrument(n->ins);
  122.             UniNote(n->note+3*OCTAVE-1);
  123.         }
  124.         if (n->vol&0xf) UniPTEffect(0xc,(n->vol&0xf)<<2);
  125.         if (n->eff)
  126.             switch(n->eff>>4) {
  127.                 case 0x3: /* porta to note */
  128.                     UniPTEffect(0x3,(n->eff&0xf)<<4);
  129.                     break;
  130.                 case 0x5: /* set vibrato depth */
  131.                     vibdepth=n->eff&0xf;
  132.                     break;
  133.                 case 0x6: /* vibrato */
  134.                     UniPTEffect(0x4,((n->eff&0xf)<<4)|vibdepth);
  135.                     break;
  136.                 case 0x7: /* volume slide up */
  137.                     UniPTEffect(0xa,(n->eff&0xf)<<4);
  138.                     break;
  139.                 case 0x8: /* volume slide down */
  140.                     UniPTEffect(0xa,n->eff&0xf);
  141.                     break;
  142.                 case 0xf: /* set speed */
  143.                     UniPTEffect(0xf,n->eff&0xf);
  144.                     break;
  145.  
  146.                 /* others not yet implemented */
  147.                 default:
  148. #ifdef MIKMOD_DEBUG
  149.                     fprintf(stderr,"\rFAR: unsupported effect %02X\n",n->eff);
  150. #endif
  151.                     break;
  152.             }
  153.  
  154.         UniNewline();
  155.         n+=16;
  156.     }
  157.     return UniDup();
  158. }
  159.  
  160. BOOL FAR_Load(BOOL curious)
  161. {
  162.     int t,u,tracks=0;
  163.     SAMPLE *q;
  164.     FARSAMPLE s;
  165.     FARNOTE *crow;
  166.     UBYTE smap[8];
  167.  
  168.     /* try to read module header (first part) */
  169.     _mm_read_UBYTES(mh1->id,4,modfp);
  170.     _mm_read_SBYTES(mh1->songname,40,modfp);
  171.     _mm_read_SBYTES(mh1->blah,3,modfp);
  172.     mh1->headerlen = _mm_read_I_UWORD (modfp);
  173.     mh1->version   = _mm_read_UBYTE (modfp);
  174.     _mm_read_UBYTES(mh1->onoff,16,modfp);
  175.     _mm_read_UBYTES(mh1->edit1,9,modfp);
  176.     mh1->speed     = _mm_read_UBYTE(modfp);
  177.     _mm_read_UBYTES(mh1->panning,16,modfp);
  178.     _mm_read_UBYTES(mh1->edit2,4,modfp);
  179.     mh1->stlen     = _mm_read_I_UWORD (modfp);
  180.  
  181.     /* init modfile data */
  182.     of.modtype   = strdup(FAR_Version);
  183.     of.songname  = DupStr(mh1->songname,40);
  184.     of.numchn    = 16;
  185.     of.initspeed = mh1->speed;
  186.     of.inittempo = 80;
  187.     of.reppos    = 0;
  188.     for(t=0;t<16;t++) of.panning[t]=mh1->panning[t]<<4;
  189.  
  190.     /* read songtext into comment field */
  191.     if(mh1->stlen)
  192.         if(!ReadComment(mh1->stlen)) return 0;
  193.  
  194.     /* try to read module header (second part) */
  195.     _mm_read_UBYTES(mh2->orders,256,modfp);
  196.     mh2->numpat        = _mm_read_UBYTE(modfp);
  197.     mh2->snglen        = _mm_read_UBYTE(modfp);
  198.     mh2->loopto        = _mm_read_UBYTE(modfp);
  199.     _mm_read_I_UWORDS(mh2->patsiz,256,modfp);
  200.  
  201.     of.numpos = mh2->snglen;
  202.     if(!AllocPositions(of.numpos)) return 0;
  203.     for(t=0;t<of.numpos;t++) {
  204.         if(mh2->orders[t]==0xff) break;
  205.         of.positions[t] = mh2->orders[t];
  206.     }
  207.  
  208.     /* count number of patterns stored in file */
  209.     of.numpat = 0;
  210.     for(t=0;t<256;t++)
  211.         if(mh2->patsiz[t])
  212.             if((t+1)>of.numpat) of.numpat=t+1;
  213.     of.numtrk = of.numpat*of.numchn;
  214.  
  215.     /* seek across eventual new data */
  216.     _mm_fseek(modfp,mh1->headerlen-(869+mh1->stlen),SEEK_CUR);
  217.  
  218.     /* alloc track and pattern structures */
  219.     if(!AllocTracks()) return 0;
  220.     if(!AllocPatterns()) return 0;
  221.  
  222.     for(t=0;t<of.numpat;t++) {
  223.         UBYTE rows=0,tempo;
  224.  
  225.         memset(pat,0,256*16*4*sizeof(FARNOTE));
  226.         if(mh2->patsiz[t]) {
  227.             rows  = _mm_read_UBYTE(modfp);
  228.             tempo = _mm_read_UBYTE(modfp);
  229.  
  230.             crow = pat;
  231.             /* file often allocates 64 rows even if there are less in pattern */
  232.             if (mh2->patsiz[t]<2+(rows*16*4)) {
  233.                 _mm_errno = MMERR_LOADING_PATTERN;
  234.                 return 0;
  235.             }
  236.             for(u=(mh2->patsiz[t]-2)/4;u;u--,crow++) {
  237.                 crow->note = _mm_read_UBYTE(modfp);
  238.                 crow->ins  = _mm_read_UBYTE(modfp);
  239.                 crow->vol  = _mm_read_UBYTE(modfp);
  240.                 crow->eff  = _mm_read_UBYTE(modfp);
  241.             }
  242.  
  243.             if(feof(modfp)) {
  244.                 _mm_errno = MMERR_LOADING_PATTERN;
  245.                 return 0;
  246.             }
  247.  
  248.             crow=pat;
  249.             of.pattrows[t] = rows;
  250.             for(u=16;u;u--,crow++)
  251.                 if(!(of.tracks[tracks++]=FAR_ConvertTrack(crow,rows))) {
  252.                     _mm_errno=MMERR_LOADING_PATTERN;
  253.                     return 0;
  254.                 }
  255.         } else
  256.             tracks+=16;
  257.     }
  258.  
  259.     /* read sample map */
  260.     if(!_mm_read_UBYTES(smap,8,modfp)) {
  261.         _mm_errno = MMERR_LOADING_HEADER;
  262.         return 0;
  263.     }
  264.  
  265.     /* count number of samples used */
  266.     of.numins = 0;
  267.     for(t=0;t<64;t++)
  268.         if(smap[t>>3]&(1<<(t&7))) of.numins=t+1;
  269.     of.numsmp = of.numins;             
  270.  
  271.     /* alloc sample structs */
  272.     if(!AllocSamples()) return 0;
  273.  
  274.     q = of.samples;
  275.     for(t=0;t<of.numsmp;t++) {
  276.         q->speed      = 8363;
  277.         q->flags      = SF_SIGNED;
  278.         if(smap[t>>3]&(1<<(t&7))) {
  279.             _mm_read_SBYTES(s.samplename,32,modfp);
  280.             s.length   = _mm_read_I_ULONG(modfp);
  281.             s.finetune = _mm_read_UBYTE(modfp);
  282.             s.volume   = _mm_read_UBYTE(modfp);
  283.             s.reppos   = _mm_read_I_ULONG(modfp);
  284.             s.repend   = _mm_read_I_ULONG(modfp);
  285.             s.type     = _mm_read_UBYTE(modfp);
  286.             s.loop     = _mm_read_UBYTE(modfp);
  287.  
  288.             q->samplename = DupStr(s.samplename,32);
  289.             q->length     = s.length;
  290.             q->loopstart  = s.reppos;
  291.             q->loopend    = s.repend;
  292.             q->volume     = s.volume<<2;
  293.  
  294.             if(s.type&1) q->flags|=SF_16BITS;
  295.             if(s.loop&8) q->flags|=SF_LOOP;
  296.  
  297.             q->seekpos    = _mm_ftell(modfp);
  298.             _mm_fseek(modfp,q->length,SEEK_CUR);
  299.         } else 
  300.             q->samplename = DupStr(NULL,0);
  301.         q++;
  302.     }
  303.     return 1;
  304. }
  305.  
  306. CHAR *FAR_LoadTitle(void)
  307. {
  308.     CHAR s[40];
  309.  
  310.     _mm_fseek(modfp,4,SEEK_SET);
  311.     if(!fread(s,40,1,modfp)) return NULL;
  312.    
  313.     return(DupStr(s,40));
  314. }
  315.  
  316. /*========== Loader information */
  317.  
  318. MLOADER load_far={
  319.     NULL,
  320.     "FAR",
  321.     "FAR loader v0.1",
  322.     FAR_Init,
  323.     FAR_Test,
  324.     FAR_Load,
  325.     FAR_Cleanup,
  326.     FAR_LoadTitle
  327. };
  328.