load_mtm.c
Upload User: wstnjxml
Upload Date: 2014-04-03
Package Size: 7248k
Code Size: 7k
Category:

Windows CE

Development Platform:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
  3. AUTHORS for complete list.
  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., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19. /*==============================================================================
  20.   $Id: load_mtm.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
  21.   MTM module loader
  22. ==============================================================================*/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #include <stdio.h>
  30. #ifdef HAVE_MEMORY_H
  31. #include <memory.h>
  32. #endif
  33. #include <string.h>
  34. #include "mikmod_internals.h"
  35. #ifdef SUNOS
  36. extern int fprintf(FILE *, const char *, ...);
  37. #endif
  38. /*========== Module structure */
  39. typedef struct MTMHEADER {
  40. UBYTE id[3]; /* MTM file marker */
  41. UBYTE version; /* upper major, lower nibble minor version number */
  42. CHAR  songname[20]; /* ASCIIZ songname */
  43. UWORD numtracks; /* number of tracks saved */
  44. UBYTE lastpattern; /* last pattern number saved */
  45. UBYTE lastorder; /* last order number to play (songlength-1) */
  46. UWORD commentsize; /* length of comment field */
  47. UBYTE numsamples; /* number of samples saved  */
  48. UBYTE attribute; /* attribute byte (unused) */
  49. UBYTE beatspertrack;
  50. UBYTE numchannels; /* number of channels used  */
  51. UBYTE panpos[32]; /* voice pan positions */
  52. } MTMHEADER;
  53. typedef struct MTMSAMPLE {
  54. CHAR  samplename[22];
  55. ULONG length;
  56. ULONG reppos;
  57. ULONG repend;
  58. UBYTE finetune;
  59. UBYTE volume;
  60. UBYTE attribute;
  61. } MTMSAMPLE;
  62. typedef struct MTMNOTE {
  63. UBYTE a,b,c;
  64. } MTMNOTE;
  65. /*========== Loader variables */
  66. static MTMHEADER *mh = NULL;
  67. static MTMNOTE *mtmtrk = NULL;
  68. static UWORD pat[32];
  69. static CHAR MTM_Version[] = "MTM";
  70. /*========== Loader code */
  71. BOOL MTM_Test(void)
  72. {
  73. UBYTE id[3];
  74. if(!_mm_read_UBYTES(id,3,modreader)) return 0;
  75. if(!memcmp(id,"MTM",3)) return 1;
  76. return 0;
  77. }
  78. BOOL MTM_Init(void)
  79. {
  80. if(!(mtmtrk=(MTMNOTE*)_mm_calloc(64,sizeof(MTMNOTE)))) return 0;
  81. if(!(mh=(MTMHEADER*)_mm_malloc(sizeof(MTMHEADER)))) return 0;
  82. return 1;
  83. }
  84. void MTM_Cleanup(void)
  85. {
  86. _mm_free(mtmtrk);
  87. _mm_free(mh);
  88. }
  89. static UBYTE* MTM_Convert(void)
  90. {
  91. int t;
  92. UBYTE a,b,inst,note,eff,dat;
  93. UniReset();
  94. for(t=0;t<64;t++) {
  95. a=mtmtrk[t].a;
  96. b=mtmtrk[t].b;
  97. inst=((a&0x3)<<4)|(b>>4);
  98. note=a>>2;
  99. eff=b&0xf;
  100. dat=mtmtrk[t].c;
  101. if(inst) UniInstrument(inst-1);
  102. if(note) UniNote(note+2*OCTAVE);
  103. /* MTM bug workaround : when the effect is volslide, slide-up *always*
  104.    overrides slide-down. */
  105. if(eff==0xa && (dat&0xf0)) dat&=0xf0;
  106. /* Convert pattern jump from Dec to Hex */
  107. if(eff==0xd)
  108. dat=(((dat&0xf0)>>4)*10)+(dat&0xf);
  109. UniPTEffect(eff,dat);
  110. UniNewline();
  111. }
  112. return UniDup();
  113. }
  114. BOOL MTM_Load(BOOL curious)
  115. {
  116. int t,u;
  117. MTMSAMPLE s;
  118. SAMPLE *q;
  119. /* try to read module header  */
  120. _mm_read_UBYTES(mh->id,3,modreader);
  121. mh->version     =_mm_read_UBYTE(modreader);
  122. _mm_read_string(mh->songname,20,modreader);
  123. mh->numtracks   =_mm_read_I_UWORD(modreader);
  124. mh->lastpattern =_mm_read_UBYTE(modreader);
  125. mh->lastorder   =_mm_read_UBYTE(modreader);
  126. mh->commentsize =_mm_read_I_UWORD(modreader);
  127. mh->numsamples  =_mm_read_UBYTE(modreader);
  128. mh->attribute   =_mm_read_UBYTE(modreader);
  129. mh->beatspertrack=_mm_read_UBYTE(modreader);
  130. mh->numchannels =_mm_read_UBYTE(modreader);
  131. _mm_read_UBYTES(mh->panpos,32,modreader);
  132. if(_mm_eof(modreader)) {
  133. _mm_errno = MMERR_LOADING_HEADER;
  134. return 0;
  135. }
  136. /* set module variables */
  137. of.initspeed = 6;
  138. of.inittempo = 125;
  139. of.modtype   = strdup(MTM_Version);
  140. of.numchn    = mh->numchannels;
  141. of.numtrk    = mh->numtracks+1;           /* get number of channels */
  142. of.songname  = DupStr(mh->songname,20,1); /* make a cstr of songname */
  143. of.numpos    = mh->lastorder+1;           /* copy the songlength */
  144. of.numpat    = mh->lastpattern+1;
  145. of.reppos    = 0;
  146. of.flags    |= UF_PANNING;
  147. for(t=0;t<32;t++) of.panning[t]=mh->panpos[t]<< 4;
  148. of.numins=of.numsmp=mh->numsamples;
  149. if(!AllocSamples()) return 0;
  150. q=of.samples;
  151. for(t=0;t<of.numins;t++) {
  152. /* try to read sample info */
  153. _mm_read_string(s.samplename,22,modreader);
  154. s.length    =_mm_read_I_ULONG(modreader);
  155. s.reppos    =_mm_read_I_ULONG(modreader);
  156. s.repend    =_mm_read_I_ULONG(modreader);
  157. s.finetune  =_mm_read_UBYTE(modreader);
  158. s.volume    =_mm_read_UBYTE(modreader);
  159. s.attribute =_mm_read_UBYTE(modreader);
  160. if(_mm_eof(modreader)) {
  161. _mm_errno = MMERR_LOADING_SAMPLEINFO; 
  162. return 0;
  163. }
  164. q->samplename = DupStr(s.samplename,22,1);
  165. q->seekpos   = 0;
  166. q->speed     = finetune[s.finetune];
  167. q->length    = s.length;
  168. q->loopstart = s.reppos;
  169. q->loopend   = s.repend;
  170. q->volume    = s.volume;
  171. if((s.repend-s.reppos)>2) q->flags |= SF_LOOP;
  172. if(s.attribute&1) {
  173. /* If the sample is 16-bits, convert the length and replen
  174.    byte-values into sample-values */
  175. q->flags|=SF_16BITS;
  176. q->length>>=1;
  177. q->loopstart>>=1;
  178. q->loopend>>=1;
  179. }
  180. q++;
  181. }
  182. if(!AllocPositions(of.numpos)) return 0;
  183. for(t=0;t<of.numpos;t++)
  184. of.positions[t]=_mm_read_UBYTE(modreader);
  185. for(;t<128;t++) _mm_read_UBYTE(modreader);
  186. if(_mm_eof(modreader)) {
  187. _mm_errno = MMERR_LOADING_HEADER;
  188. return 0;
  189. }
  190. if(!AllocTracks()) return 0;
  191. if(!AllocPatterns()) return 0;
  192. of.tracks[0]=MTM_Convert(); /* track 0 is empty */
  193. for(t=1;t<of.numtrk;t++) {
  194. int s;
  195. for(s=0;s<64;s++) {
  196. mtmtrk[s].a=_mm_read_UBYTE(modreader);
  197. mtmtrk[s].b=_mm_read_UBYTE(modreader);
  198. mtmtrk[s].c=_mm_read_UBYTE(modreader);
  199. }
  200. if(_mm_eof(modreader)) {
  201. _mm_errno = MMERR_LOADING_TRACK;
  202. return 0;
  203. }
  204. if(!(of.tracks[t]=MTM_Convert())) return 0;
  205. }
  206. for(t=0;t<of.numpat;t++) {
  207. _mm_read_I_UWORDS(pat,32,modreader);
  208. for(u=0;u<of.numchn;u++)
  209. of.patterns[((long)t*of.numchn)+u]=pat[u];
  210. }
  211. /* read comment field */
  212. if(mh->commentsize)
  213. if(!ReadLinedComment(mh->commentsize, 40)) return 0;
  214. return 1;
  215. }
  216. CHAR *MTM_LoadTitle(void)
  217. {
  218. CHAR s[20];
  219. _mm_fseek(modreader,4,SEEK_SET);
  220. if(!_mm_read_UBYTES(s,20,modreader)) return NULL;
  221. return(DupStr(s,20,1));
  222. }
  223. /*========== Loader information */
  224. MIKMODAPI MLOADER load_mtm={
  225. NULL,
  226. "MTM",
  227. "MTM (MultiTracker Module editor)",
  228. MTM_Init,
  229. MTM_Test,
  230. MTM_Load,
  231. MTM_Cleanup,
  232. MTM_LoadTitle
  233. };
  234. /* ex:set ts=4: */