home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / sharewar / mikm202 / source / loaders / dsmload.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-18  |  5.3 KB  |  331 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include "mloader.h"
  6. #include "munitrk.h"
  7.  
  8.  
  9.  
  10. typedef struct DSMNOTE{
  11.     UBYTE note,ins,vol,cmd,inf;
  12. } DSMNOTE;
  13.  
  14. typedef struct DSMINST{
  15.     UBYTE filename[13];
  16.     UWORD flags;
  17.     UBYTE volume;
  18.     ULONG length;
  19.     ULONG loopstart;
  20.     ULONG loopend;
  21.     ULONG reserved1;
  22.     UWORD c2spd;
  23.     UWORD reserved2;
  24.     UBYTE samplename[28];
  25. } DSMINST;
  26.  
  27.  
  28.  
  29. typedef struct DSMSONG{
  30.     char  songname[28];
  31.     UWORD reserved1;
  32.     UWORD flags;
  33.     ULONG reserved2;
  34.     UWORD numord;
  35.     UWORD numsmp;
  36.     UWORD numpat;
  37.     UWORD numtrk;
  38.     UBYTE globalvol;
  39.     UBYTE mastervol;
  40.     UBYTE speed;
  41.     UBYTE bpm;
  42.     UBYTE panpos[16];
  43.     UBYTE orders[128];
  44. } DSMSONG;
  45.  
  46.  
  47.  
  48. #define MOTLONG(a,b,c,d) (((ULONG)d<<24)|((ULONG)c<<16)|((ULONG)b<<8)|a)
  49. #define SONGID MOTLONG('S','O','N','G')
  50. #define INSTID MOTLONG('I','N','S','T')
  51. #define PATTID MOTLONG('P','A','T','T')
  52.  
  53.  
  54. ULONG blockid;
  55. ULONG blockln;
  56. ULONG blocklp;
  57.  
  58. static DSMSONG *mh;
  59. DSMNOTE *dsmbuf;
  60.  
  61. char DSM_Version[]="DSIK DSM-format";
  62.  
  63.  
  64.  
  65. BOOL DSM_Test(void)
  66. {
  67.     char id[12];
  68.     rewind(modfp);
  69.  
  70.     if(!fread(id,12,1,modfp)) return 0;
  71.  
  72.     if(!memcmp(id,"RIFF",4) &&
  73.        !memcmp(&id[8],"DSMF",4)) return 1;
  74.     return 0;
  75. }
  76.  
  77.  
  78.  
  79. BOOL DSM_Init(void)
  80. {
  81.     dsmbuf=NULL;
  82.     mh=NULL;
  83.  
  84.     if(!(dsmbuf=(DSMNOTE *)MyMalloc(16*64*sizeof(DSMNOTE)))) return 0;
  85.     if(!(mh=(DSMSONG *)MyCalloc(1,sizeof(DSMSONG)))) return 0;
  86.     return 1;
  87. }
  88.  
  89.  
  90.  
  91. void DSM_Cleanup(void)
  92. {
  93.     if(dsmbuf!=NULL) free(dsmbuf);
  94.     if(mh!=NULL) free(mh);
  95. }
  96.  
  97.  
  98.  
  99. BOOL GetBlockHeader(void)
  100. {
  101.     /* make sure we're at the right position for reading the
  102.        next riff block, no matter how many bytes read */
  103.  
  104.     fseek(modfp,blocklp+blockln,SEEK_SET);
  105.  
  106.     while(1){
  107.  
  108.         if(!fread(&blockid,sizeof(ULONG),1,modfp) ||
  109.            !fread(&blockln,sizeof(ULONG),1,modfp)){
  110.             myerr=ERROR_LOADING_HEADER;
  111.             return 0;
  112.         }
  113.  
  114.         if(blockid!=SONGID &&
  115.            blockid!=INSTID &&
  116.            blockid!=PATTID ){
  117.  
  118.             printf("Skipping unknown block type %4.4s\n",&blockid);
  119.  
  120.             fseek(modfp,blockln,SEEK_CUR);
  121.         }
  122.         else break;
  123.     }
  124.  
  125.     blocklp=ftell(modfp);
  126.     return 1;
  127. }
  128.  
  129.  
  130.  
  131. BOOL DSM_ReadPattern(void)
  132. {
  133.     int row=0,flag;
  134.     DSMNOTE *n;
  135.  
  136.     // clear pattern data
  137.  
  138.     memset(dsmbuf,255,16*64*sizeof(DSMNOTE));
  139.  
  140.     fgetc(modfp);
  141.     fgetc(modfp);
  142.  
  143.     while(row<64){
  144.  
  145.         flag=fgetc(modfp);
  146.  
  147.         if(flag==EOF){
  148.             myerr=ERROR_LOADING_PATTERN;
  149.             return 0;
  150.         }
  151.  
  152.         if(flag){
  153.  
  154.             n=&dsmbuf[((flag&0xf)*64)+row];
  155.             if(flag&0x80) n->note=fgetc(modfp);
  156.             if(flag&0x40) n->ins=fgetc(modfp);
  157.             if(flag&0x20) n->vol=fgetc(modfp);
  158.             if(flag&0x10){
  159.                 n->cmd=fgetc(modfp);
  160.                 n->inf=fgetc(modfp);
  161.             }
  162.         }
  163.         else row++;
  164.     }
  165.     return 1;
  166. }
  167.  
  168.  
  169.  
  170. UBYTE *DSM_ConvertTrack(DSMNOTE *tr)
  171. {
  172.     int t;
  173.  
  174.     UBYTE note,ins,vol,cmd,inf;
  175.  
  176.     UniReset();
  177.     for(t=0;t<64;t++){
  178.  
  179.         note=tr[t].note;
  180.         ins=tr[t].ins;
  181.         vol=tr[t].vol;
  182.         cmd=tr[t].cmd;
  183.         inf=tr[t].inf;
  184.  
  185.         if(ins!=0 && ins!=255){
  186.             UniInstrument(ins-1);
  187.         }
  188.  
  189.         if(note!=255){
  190.             UniNote(note-1);                // <- normal note
  191.         }
  192.  
  193.  
  194.         if(vol<65){
  195.             UniPTEffect(0xc,vol);
  196.         }
  197.  
  198.         if(cmd!=255){
  199.  
  200.             if(cmd==0x8){
  201.                 if(inf<=0x80){
  202.                     inf=(inf<0x80) ? inf<<1 : 255;
  203.                     UniPTEffect(cmd,inf);
  204.                 }
  205.             }
  206.             else if(cmd==0xb){
  207.                 if(inf<=0x7f) UniPTEffect(cmd,inf);
  208.             }
  209.             else UniPTEffect(cmd,inf);
  210.  
  211.         }
  212.  
  213.         UniNewline();
  214.     }
  215.     return UniDup();
  216. }
  217.  
  218.  
  219.  
  220. BOOL DSM_Load(void)
  221. {
  222.     int t;
  223.     DSMINST s;
  224.     INSTRUMENT *d;
  225.     SAMPLE *q;
  226.  
  227.     int cursmp=0,curpat=0,track=0;
  228.  
  229.     blocklp=0;
  230.     blockln=12;
  231.  
  232.     if(!GetBlockHeader()) return 0;
  233.  
  234.     if(blockid!=SONGID){
  235.         myerr=ERROR_LOADING_HEADER;
  236.         return 0;
  237.     }
  238.  
  239.     if(!fread(mh,sizeof(DSMSONG),1,modfp)){
  240.         myerr=ERROR_LOADING_HEADER;
  241.         return 0;
  242.     }
  243.  
  244.     /* set module variables */
  245.  
  246.     of.initspeed=mh->speed;
  247.     of.inittempo=mh->bpm;
  248.     of.modtype=strdup(DSM_Version);
  249.     of.numchn=mh->numtrk;
  250.     of.numpat=mh->numpat;
  251.     of.numtrk=of.numchn*of.numpat;
  252.  
  253.     of.songname=DupStr(mh->songname,28);    // make a cstr of songname
  254.  
  255.     for(t=0;t<16;t++){
  256.         of.panning[t]=mh->panpos[t]<0x80 ? (mh->panpos[t]<<1) : 255;
  257.     }
  258.  
  259.     of.numpos=0;
  260.     for(t=0;t<mh->numord;t++){
  261.         of.positions[of.numpos]=mh->orders[t];
  262.         if(mh->orders[t]<254) of.numpos++;
  263.     }
  264.  
  265.     of.numins=mh->numsmp;
  266.  
  267.     if(!AllocInstruments()) return 0;
  268.     if(!AllocTracks()) return 0;
  269.     if(!AllocPatterns()) return 0;
  270.  
  271.     while(cursmp<of.numins || curpat<of.numpat){
  272.  
  273.         if(!GetBlockHeader()) return 0;
  274.  
  275.         if(blockid==INSTID && cursmp<of.numins){
  276.  
  277.             d=&of.instruments[cursmp];
  278.  
  279.             d->numsmp=1;
  280.             if(!AllocSamples(d)) return 0;
  281.             q=d->samples;
  282.  
  283.             // try to read sample info
  284.  
  285.             if(!fread(&s,sizeof(DSMINST),1,modfp)){
  286.                 myerr=ERROR_LOADING_SAMPLEINFO;
  287.                 return 0;
  288.             }
  289.  
  290.             d->insname=DupStr(s.samplename,28);
  291.             q->seekpos=ftell(modfp);
  292.             q->c2spd=s.c2spd;
  293.             q->length=s.length;
  294.             q->loopstart=s.loopstart;
  295.             q->loopend=s.loopend;
  296.             q->volume=s.volume;
  297.             q->flags=0;
  298.  
  299.             if(s.flags&1) q->flags|=SF_LOOP;
  300.             if(s.flags&2) q->flags|=SF_SIGNED;
  301.  
  302.             cursmp++;
  303.         }
  304.         else if(blockid==PATTID && curpat<of.numpat){
  305.  
  306.             DSM_ReadPattern();
  307.  
  308.             for(t=0;t<of.numchn;t++){
  309.                 if(!(of.tracks[track++]=DSM_ConvertTrack(&dsmbuf[t*64]))) return 0;
  310.             }
  311.  
  312.             curpat++;
  313.         }
  314.     }
  315.  
  316.     return 1;
  317. }
  318.  
  319.  
  320.  
  321.  
  322. LOADER dsmload={
  323.     NULL,
  324.     "DSM",
  325.     "DSM loader v0.1",
  326.     DSM_Init,
  327.     DSM_Test,
  328.     DSM_Load,
  329.     DSM_Cleanup
  330. };
  331.