home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / sharewar / mikm202 / source / loaders / ultload.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-18  |  4.8 KB  |  300 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. #define ULTS_16BITS     4
  9. #define ULTS_LOOP               8
  10. #define ULTS_REVERSE    16
  11.  
  12.  
  13.  
  14. // Raw ULT header struct:
  15.  
  16. typedef struct ULTHEADER{
  17.     char  id[15];
  18.     char  songtitle[32];
  19.     char  reserved;
  20. } ULTHEADER;
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27. // Raw ULT sampleinfo struct:
  28.  
  29. typedef struct ULTSAMPLE{
  30.     char  samplename[32];
  31.     char  dosname[12];
  32.     LONG  loopstart;
  33.     LONG  loopend;
  34.     LONG  sizestart;
  35.     LONG  sizeend;
  36.     UBYTE volume;
  37.     UBYTE flags;
  38.     WORD  finetune;
  39. } ULTSAMPLE;
  40.  
  41.  
  42. typedef struct ULTEVENT{
  43.     UBYTE note,sample,eff,dat1,dat2;
  44. } ULTEVENT;
  45.  
  46.  
  47. char *ULT_Version[]={
  48.     "Ultra Tracker V1.3",
  49.     "Ultra Tracker V1.4",
  50.     "Ultra Tracker V1.5",
  51.     "Ultra Tracker V1.6"
  52. };
  53.  
  54.  
  55.  
  56.  
  57. BOOL ULT_Test(void)
  58. {
  59.     char id[15];
  60.  
  61.     rewind(modfp);
  62.     if(!fread(&id,15,1,modfp)) return 0;
  63.  
  64.     return(!strncmp(id,"MAS_UTrack_V00",14));
  65. }
  66.  
  67.  
  68. BOOL ULT_Init(void)
  69. {
  70.     return 1;
  71. }
  72.  
  73.  
  74. void ULT_Cleanup(void)
  75. {
  76. }
  77.  
  78. ULTEVENT ev;
  79.  
  80.  
  81.  
  82. BOOL ReadUltEvent(ULTEVENT *event)
  83. {
  84.     UBYTE flag,rep;
  85.  
  86.  
  87.     if(!fread(&flag,1,1,modfp)) return 0;
  88.  
  89.     if(flag==0xfc){
  90.         fread(&rep,1,1,modfp);
  91.         if(fread(event,sizeof(ULTEVENT),1,modfp)) return rep;
  92.     }
  93.     else{
  94.         event->note=flag;
  95.         if(fread(&event->sample,sizeof(ULTEVENT)-1,1,modfp)) return 1;
  96.     }
  97.     return 0;
  98. }
  99.  
  100.  
  101.  
  102.  
  103. BOOL ULT_Load(void)
  104. {
  105.     int t,u,tracks=0;
  106.     UWORD dummy;
  107.     INSTRUMENT *d;
  108.     SAMPLE *q;
  109.     ULTSAMPLE s;
  110.     ULTHEADER mh;
  111.     UBYTE nos,noc,nop;
  112.  
  113.     rewind(modfp);
  114.  
  115.     // try to read module header
  116.  
  117.     if(!fread(&mh,sizeof(ULTHEADER),1,modfp)){
  118.         myerr=ERROR_LOADING_HEADER;
  119.         return 0;
  120.     }
  121.  
  122.     if(mh.id[14]<'1' || mh.id[14]>'4'){
  123.         printf("This version is not yet supported\n");
  124.         return 0;
  125.     }
  126.  
  127.     of.modtype=strdup(ULT_Version[mh.id[14]-'1']);
  128.     of.initspeed=6;
  129.     of.inittempo=125;
  130.  
  131.     // read songtext
  132.  
  133.     if(!ReadComment((UWORD)mh.reserved*32)) return 0;
  134.  
  135.     if(!fread(&nos,1,1,modfp)){
  136.         myerr=ERROR_LOADING_HEADER;
  137.         return 0;
  138.     }
  139.  
  140.     of.songname=DupStr(mh.songtitle,32);
  141.     of.numins=nos;
  142.  
  143.     if(!AllocInstruments()) return 0;
  144.  
  145.     d=of.instruments;
  146.  
  147.     for(t=0;t<nos;t++){
  148.  
  149.         d->numsmp=1;
  150.         if(!AllocSamples(d)) return 0;
  151.         q=d->samples;
  152.  
  153.         // try to read sample info
  154.  
  155.         if(!fread(&s,sizeof(ULTSAMPLE),1,modfp)){
  156.             myerr=ERROR_LOADING_SAMPLEINFO;
  157.             return 0;
  158.         }
  159.  
  160.         d->insname=DupStr(s.samplename,32);
  161.  
  162. /*              printf("%s ss %ld se %ld ls %ld le %ld\n",
  163.             d->samplename,
  164.             s.sizestart,
  165.             s.sizeend,
  166.             s.loopstart,
  167.             s.loopend);
  168. */
  169.         q->seekpos=0;
  170.  
  171.         q->c2spd=8363;
  172.  
  173.         if(mh.id[14]>='4'){
  174.             fread(&dummy,sizeof(UWORD),1,modfp);        // read 1.6 extra info(??) word
  175.             q->c2spd=s.finetune;
  176.         }
  177.  
  178.         q->length=s.sizeend-s.sizestart;
  179.         q->volume=s.volume>>2;
  180.         q->loopstart=s.loopstart;
  181.         q->loopend=s.loopend;
  182.  
  183.         q->flags=SF_SIGNED;
  184.  
  185.         if(s.flags&ULTS_LOOP){
  186.             q->flags|=SF_LOOP;
  187.         }
  188.  
  189.         if(s.flags&ULTS_16BITS){
  190.             q->flags|=SF_16BITS;
  191.             q->loopstart>>=1;
  192.             q->loopend>>=1;
  193.         }
  194.  
  195. //              printf("Sample %d %s length %ld\n",t,d->samplename,d->length);
  196.         d++;
  197.     }
  198.  
  199.     fread(of.positions,256,1,modfp);
  200.  
  201.     for(t=0;t<256;t++){
  202.         if(of.positions[t]==255) break;
  203.     }
  204.     of.numpos=t;
  205.  
  206.     fread(&noc,1,1,modfp);
  207.     fread(&nop,1,1,modfp);
  208.  
  209.     of.numchn=noc+1;
  210.     of.numpat=nop+1;
  211.     of.numtrk=of.numchn*of.numpat;
  212.  
  213.     if(!AllocTracks()) return 0;
  214.     if(!AllocPatterns()) return 0;
  215.  
  216.     for(u=0;u<of.numchn;u++){
  217.         for(t=0;t<of.numpat;t++){
  218.             of.patterns[(t*of.numchn)+u]=tracks++;
  219.         }
  220.     }
  221.  
  222.     // read pan position table for v1.5 and higher
  223.  
  224.     if(mh.id[14]>='3'){
  225.         for(t=0;t<of.numchn;t++) of.panning[t]=fgetc(modfp)<<4;
  226.     }
  227.  
  228.  
  229.     for(t=0;t<of.numtrk;t++){
  230.         int rep,s,done;
  231.  
  232.         UniReset();
  233.         done=0;
  234.  
  235.         while(done<64){
  236.  
  237.             if(!(rep=ReadUltEvent(&ev))){
  238.                 myerr=ERROR_LOADING_TRACK;
  239.                 return 0;
  240.             }
  241.  
  242. //                      printf("rep %d: n %d i %d e %x d1 %d d2 %d \n",rep,ev.note,ev.sample,ev.eff,ev.dat1,ev.dat2);
  243.  
  244.  
  245.             for(s=0;s<rep;s++){
  246.                 UBYTE eff;
  247.  
  248.  
  249.                 if(ev.sample){
  250.                     UniInstrument(ev.sample-1);
  251.                 }
  252.  
  253.                 if(ev.note){
  254.                     UniNote(ev.note+23);
  255.                 }
  256.  
  257.                 eff=ev.eff>>4;
  258.  
  259.  
  260.                 /*
  261.                     ULT panning effect fixed by Alexander Kerkhove :
  262.                 */
  263.  
  264.  
  265.                 if(eff==0xc) UniPTEffect(eff,ev.dat2>>2);
  266.                 else if(eff==0xb) UniPTEffect(8,ev.dat2*0xf);
  267.                 else UniPTEffect(eff,ev.dat2);
  268.  
  269.                 eff=ev.eff&0xf;
  270.  
  271.                 if(eff==0xc) UniPTEffect(eff,ev.dat1>>2);
  272.                 else if(eff==0xb) UniPTEffect(8,ev.dat1*0xf);
  273.                 else UniPTEffect(eff,ev.dat1);
  274.  
  275.                 UniNewline();
  276.                 done++;
  277.             }
  278.         }
  279. //              printf("----------------");
  280.  
  281.         if(!(of.tracks[t]=UniDup())) return 0;
  282.     }
  283.  
  284. //      printf("%d channels %d patterns\n",of.numchn,of.numpat);
  285. //      printf("Song %32.32s: There's %d samples\n",mh.songtitle,nos);
  286.     return 1;
  287. }
  288.  
  289.  
  290.  
  291. LOADER ultload={
  292.     NULL,
  293.     "ULT",
  294.     "ULT loader v0.1",
  295.     ULT_Init,
  296.     ULT_Test,
  297.     ULT_Load,
  298.     ULT_Cleanup
  299. };
  300.