home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "mloader.h"
- #include "munitrk.h"
-
-
- typedef struct FARSAMPLE{
- char samplename[32];
- ULONG length;
- UBYTE finetune;
- UBYTE volume;
- ULONG reppos;
- ULONG repend;
- UBYTE type;
- UBYTE loop;
- } FARSAMPLE;
-
-
-
- typedef struct FARHEADER1{
- UBYTE id[4]; // file magic
- char songname[40]; // songname
- char blah[3]; // 13,10,26
- UWORD headerlen; // remaining length of header in bytes
- UBYTE version;
- UBYTE onoff[16];
- UBYTE edit1[9];
- UBYTE speed;
- UBYTE panning[16];
- UBYTE edit2[4];
- UWORD stlen;
- } FARHEADER1;
-
-
- typedef struct FARHEADER2{
- UBYTE orders[256];
- UBYTE numpat;
- UBYTE snglen;
- UBYTE loopto;
- UWORD patsiz[256];
- } FARHEADER2;
-
-
-
- typedef struct FARNOTE{
- UBYTE note,ins,vol,eff;
- } FARNOTE;
-
-
-
- char FAR_Version[]="Farandole";
- static FARHEADER1 *mh1;
- static FARHEADER2 *mh2;
- static FARNOTE *pat;
-
-
- BOOL FAR_Test(void)
- {
- char id[4];
-
- rewind(modfp);
- if(!fread(&id,4,1,modfp)) return 0;
-
- return(!strncmp(id,"FARâ– ",4));
- }
-
-
- BOOL FAR_Init(void)
- {
- mh1=NULL;
- mh2=NULL;
- pat=NULL;
-
- if(!(mh1=(FARHEADER1 *)MyMalloc(sizeof(FARHEADER1)))) return 0;
- if(!(mh2=(FARHEADER2 *)MyMalloc(sizeof(FARHEADER2)))) return 0;
- if(!(pat=(FARNOTE *)MyMalloc(16*256*sizeof(FARNOTE)))) return 0;
-
- return 1;
- }
-
-
- void FAR_Cleanup(void)
- {
- if(mh1!=NULL) free(mh1);
- if(mh2!=NULL) free(mh2);
- if(pat!=NULL) free(pat);
- }
-
-
- UBYTE *FAR_ConvertTrack(FARNOTE *n,int rows)
- {
- int t;
-
- UniReset();
-
- for(t=0;t<rows;t++){
-
- if(n->note){
- UniInstrument(n->ins);
- UniNote(n->note+23+12);
- }
-
- if(n->vol&0xf){
- UniPTEffect(0xc,(n->vol&0xf)<<2);
- }
-
- switch(n->eff>>4){
-
- case 0xf:
- UniPTEffect(0xf,n->eff&0xf);
- break;
-
- // others not yet implemented
- }
-
- UniNewline();
- n+=16;
-
- }
-
- return UniDup();
- }
-
-
-
- BOOL FAR_Load(void)
- {
- int t,u,tracks=0;
- INSTRUMENT *d;
- SAMPLE *q;
- FARSAMPLE s;
- UBYTE smap[8];
-
- rewind(modfp);
-
- // try to read module header (first part)
-
- if(!fread(mh1,sizeof(FARHEADER1),1,modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- // printf("Farandole version %d.%d\n",mh1->version>>4,mh1->version&0xf);
-
- // init modfile data
-
- of.modtype=strdup(FAR_Version);
- of.songname=DupStr(mh1->songname,40);
- of.numchn=16;
- of.initspeed=mh1->speed;
- of.inittempo=88;
-
- for(t=0;t<16;t++) of.panning[t]=mh1->panning[t]<<4;
-
- // read songtext into comment field
-
- if(!ReadComment(mh1->stlen)) return 0;
-
- // try to read module header (second part)
-
- if(!fread(mh2,sizeof(FARHEADER2),1,modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- // of.numpat=mh2->numpat;
- of.numpos=mh2->snglen;
- memcpy(of.positions,mh2->orders,256);
-
- // count number of patterns stored in file
-
- of.numpat=0;
- for(t=0;t<256;t++){
- if(mh2->patsiz[t]) if((t+1)>of.numpat) of.numpat=t+1;
- }
-
- of.numtrk=of.numpat*of.numchn;
-
- // seek across eventual new data
-
- fseek(modfp,mh1->headerlen-(869+mh1->stlen),SEEK_CUR);
-
- // printf("%s\n%d patterns\n%d pos\n",of.songname,of.numpat,of.songlength);
-
- // alloc track and pattern structures
-
- if(!AllocTracks()) return 0;
- if(!AllocPatterns()) return 0;
-
- for(t=0;t<of.numpat;t++){
- UBYTE rows=0,tempo;
-
- memset(pat,0,16*256*sizeof(FARNOTE));
-
- if(mh2->patsiz[t]){
-
- fread(&rows,1,1,modfp);
- fread(&tempo,1,1,modfp);
-
- if(!fread(pat,mh2->patsiz[t]-2,1,modfp)){
- myerr=ERROR_LOADING_PATTERN;
- return 0;
- };
- }
-
- of.pattrows[t]=rows+2;
-
- for(u=0;u<16;u++){
- if(!(of.tracks[tracks++]=FAR_ConvertTrack(&pat[u],rows+2))) return 0;
- }
- }
-
-
- // read sample map
-
- if(!fread(smap,8,1,modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- // count number of samples used
-
- of.numins=0;
- for(t=0;t<64;t++){
- if(smap[t>>3] & (1 << (t&7))) of.numins++;
- }
-
- // alloc sample structs
-
- if(!AllocInstruments()) return 0;
-
-
- d=of.instruments;
- for(t=0;t<64;t++){
-
- if(smap[t>>3] & (1 << (t&7))){
-
- d->numsmp=1;
- if(!AllocSamples(d)) return 0;
- q=d->samples;
-
- // and load sample info
-
- if(fread(&s,sizeof(FARSAMPLE),1,modfp)!=1){
- myerr=ERROR_LOADING_SAMPLEINFO;
- return 0;
- }
-
- d->insname=DupStr(s.samplename,32);
- q->length=s.length;
- q->loopstart=s.reppos;
- q->loopend=s.repend;
- q->volume=64;
- q->c2spd=8363;
-
- q->flags=SF_SIGNED;
- if(s.type&1) q->flags|=SF_16BITS;
- if(s.loop) q->flags|=SF_LOOP;
-
- q->seekpos=ftell(modfp);
-
- // printf("Sample %d : name %s %ld %ld %ld %ld\n",t,d->samplename,d->length,d->loopstart,d->loopend,d->seekpos);
-
- fseek(modfp,q->length,SEEK_CUR);
- }
- d++;
- }
- return 1;
- }
-
-
-
- LOADER farload={
- NULL,
- "FAR",
- "FAR loader v0.1",
- FAR_Init,
- FAR_Test,
- FAR_Load,
- FAR_Cleanup
- };
-