MODLOAD.C
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:6k
源码类别:

游戏

开发平台:

Visual C++

  1. /*  modload.c - Tiny MOD Player V2.11 for Watcom C/C++ and DOS/4GW
  2.     Module and Sample file loader routines.
  3.     Copyright 1993,94 Carlos Hasan
  4. */
  5. #include <stdio.h>
  6. #include <conio.h>
  7. #include <malloc.h>
  8. #include <io.h>
  9. #include <fcntl.h>
  10. #include "modplay.h"
  11. /* MOD FileFormat */
  12. #define ID_MK   0x2E4B2E4D
  13. #define ID_FLT4 0x34544C46
  14. #define ID_6CHN 0x4E484336
  15. #define ID_8CHN 0x4E484338
  16. typedef struct {
  17.     byte        SampleName[22];
  18.     word        Length;
  19.     byte        FineTune;
  20.     byte        Volume;
  21.     word        LoopStart;
  22.     word        LoopLength;
  23. } MODSample;
  24. typedef struct {
  25.     byte        SongName[20];
  26.     MODSample   Samples[31];
  27.     byte        OrderLength;
  28.     byte        ReStart;
  29.     byte        Orders[128];
  30.     dword       Sign;
  31. } MODHeader;
  32. /* MOD PeriodTable */
  33. static word PeriodTable[12*7] = {
  34.     3424,3232,3048,2880,2712,2560,2416,2280,2152,2032,1920,1812,
  35.     1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
  36.     856,808,762,720,678,640,604,570,538,508,480,453,
  37.     428,404,381,360,339,320,302,285,269,254,240,226,
  38.     214,202,190,180,170,160,151,143,135,127,120,113,
  39.     107,101,95,90,85,80,75,71,67,63,60,56,
  40.     53,50,47,45,42,40,37,35,33,31,30,28 };
  41. /* WAV fileformat */
  42. #define ID_RIFF 0x46464952
  43. #define ID_WAVE 0x45564157
  44. #define ID_FMT  0x20746D66
  45. #define ID_DATA 0x61746164
  46. typedef struct {
  47.     dword   RIFFMagic;
  48.     dword   FileLength;
  49.     dword   FileType;
  50.     dword   FormMagic;
  51.     dword   FormLength;
  52.     word    SampleFormat;
  53.     word    NumChannels;
  54.     dword   PlayRate;
  55.     dword   BytesPerSec;
  56.     word    Pad;
  57.     word    BitsPerSample;
  58.     dword   DataMagic;
  59.     dword   DataLength;
  60. } WAVHeader;
  61. /* MOD Loader Routine */
  62. #define Swap(w) (((dword)(w&0xff))<<8|((dword)(w>>8)))
  63. Module *MODLoadModule(char *Path)
  64. {
  65.     int handle,NumTracks,NumPatts,i,j;
  66.     word Note,Period,Inst,Effect;
  67.     dword Length,LoopStart,LoopLength;
  68.     MODHeader Header;
  69.     MODSample *Sample;
  70.     Module *Song;
  71.     byte *Patt;
  72.     if ((handle = open(Path,O_RDONLY | O_BINARY)) == -1)
  73.         return NULL;
  74.     if (read(handle,&Header,sizeof(Header)) != sizeof(Header)) {
  75.         close(handle);
  76.         return NULL;
  77.     }
  78.     if ((Header.Sign == ID_MK) || (Header.Sign == ID_FLT4))
  79.         NumTracks = 4;
  80.     else if (Header.Sign == ID_6CHN)
  81.         NumTracks = 6;
  82.     else if (Header.Sign == ID_8CHN)
  83.         NumTracks = 8;
  84.     else {
  85.         close(handle);
  86.         return NULL;
  87.     }
  88.     if ((Song = calloc(1,sizeof(Module))) == NULL) {
  89.         close(handle);
  90.         return NULL;
  91.     }
  92.     Song->NumTracks = NumTracks;
  93.     Song->OrderLength = Header.OrderLength;
  94.     for (NumPatts = i = 0; i < 128; i++) {
  95.         Song->Orders[i] = Header.Orders[i];
  96.         if (NumPatts < Header.Orders[i])
  97.             NumPatts = Header.Orders[i];
  98.     }
  99.     NumPatts++;
  100.     for (i = 0; i < NumPatts; i++) {
  101.         if ((Song->Patterns[i] = malloc(256*NumTracks)) == NULL) {
  102.             MODFreeModule(Song);
  103.             close(handle);
  104.             return NULL;
  105.         }
  106.         if (read(handle,Song->Patterns[i],256*NumTracks) != 256*NumTracks) {
  107.             MODFreeModule(Song);
  108.             close(handle);
  109.             return NULL;
  110.         }
  111.         for (Patt = Song->Patterns[i], j = 0; j < 64*NumTracks; Patt += 4, j++) {
  112.             Period = ((word)(Patt[0] & 0x0F) << 8) | (Patt[1]);
  113.             Inst = (Patt[0] & 0xF0) | (Patt[2] >> 4);
  114.             Effect = ((word)(Patt[2] & 0x0F) << 8) | (Patt[3]);
  115.             for (Note = 0; Note < 12*7; Note++)
  116.                 if (Period >= PeriodTable[Note]) break;
  117.             if (Note == 12*7) Note = 0; else Note++;
  118.             Patt[0] = Note;
  119.             Patt[1] = Inst;
  120.             Patt[2] = Effect & 0xFF;
  121.             Patt[3] = Effect >> 8;
  122.         }
  123.     }
  124.     for (i = 1; i <= 31; i++) {
  125.         Sample = &Header.Samples[i-1];
  126.         if (Sample->Length) {
  127.             Length = Swap(Sample->Length) << 1;
  128.             LoopStart = Swap(Sample->LoopStart) << 1;
  129.             LoopLength = Swap(Sample->LoopLength) << 1;
  130.             if ((Song->SampPtr[i] = malloc(Length)) == NULL) {
  131.                 MODFreeModule(Song);
  132.                 close(handle);
  133.                 return NULL;
  134.             }
  135.             if ((unsigned)read(handle,Song->SampPtr[i],Length) != Length) {
  136.                 MODFreeModule(Song);
  137.                 close(handle);
  138.                 return NULL;
  139.             }
  140.             if (LoopLength <= 2) {
  141.                 Song->SampLoop[i] = Song->SampPtr[i] + Length;
  142.                 Song->SampEnd[i] = Song->SampLoop[i];
  143.             }
  144.             else {
  145.                 Song->SampLoop[i] = Song->SampPtr[i] + LoopStart;
  146.                 Song->SampEnd[i] = Song->SampLoop[i] + LoopLength;
  147.             }
  148.             Song->SampVolume[i] = Sample->Volume;
  149.         }
  150.     }
  151.     close(handle);
  152.     return Song;
  153. }
  154. void MODFreeModule(Module *Song)
  155. {
  156.     int i;
  157.     if (Song) {
  158.         for (i = 0; i < 128; i++)
  159.             if (Song->Patterns[i]) free(Song->Patterns[i]);
  160.         for (i = 1; i <= 31; i++)
  161.             if (Song->SampPtr[i]) free(Song->SampPtr[i]);
  162.         free(Song);
  163.     }
  164. }
  165. /* RIFF/WAV Loader Routine */
  166. Sample *MODLoadSample(char *Path)
  167. {
  168.     int handle;
  169.     WAVHeader Header;
  170.     Sample *Instr;
  171.     byte *ptr;
  172.     dword len;
  173.     if ((handle = open(Path,O_RDONLY | O_BINARY)) == -1)
  174.         return NULL;
  175.     if (read(handle,&Header,sizeof(Header)) != sizeof(Header)) {
  176.         close(handle);
  177.         return NULL;
  178.     }
  179.     if (Header.RIFFMagic != ID_RIFF || Header.FileType != ID_WAVE ||
  180.         Header.FormMagic != ID_FMT || Header.DataMagic != ID_DATA ||
  181.         Header.SampleFormat != 1 || Header.NumChannels != 1 ||
  182.         Header.BitsPerSample != 8) {
  183.         close(handle);
  184.         return NULL;
  185.     }
  186.     if ((Instr = malloc(sizeof(Sample)+Header.DataLength)) == NULL) {
  187.         close(handle);
  188.         return NULL;
  189.     }
  190.     Instr->Period = (8363L*428L)/Header.PlayRate;
  191.     Instr->Volume = 64;
  192.     Instr->Length = Header.DataLength;
  193.     Instr->Data = (byte*)(Instr+1);
  194.     if ((unsigned)read(handle,Instr->Data,Instr->Length) != Instr->Length) {
  195.         free(Instr);
  196.         close(handle);
  197.         return NULL;
  198.     }
  199.     close(handle);
  200.     for (ptr = Instr->Data, len = Instr->Length; len; len--)
  201.         *ptr++ ^= 0x80;
  202.     return Instr;
  203. }
  204. void MODFreeSample(Sample *Instr)
  205. {
  206.     if (Instr) free(Instr);
  207. }