load_mod.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:12k
源码类别:

Windows CE

开发平台:

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_mod.c,v 1.2 2004/01/21 13:33:11 raph Exp $
  21.   Generic MOD loader (Protracker, StarTracker, FastTracker, etc)
  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 <ctype.h>
  30. #include <stdio.h>
  31. #ifdef HAVE_MEMORY_H
  32. #include <memory.h>
  33. #endif
  34. #include <string.h>
  35. #include "mikmod_internals.h"
  36. #ifdef SUNOS
  37. extern int fprintf(FILE *, const char *, ...);
  38. #endif
  39. /*========== Module structure */
  40. typedef struct MSAMPINFO {
  41. CHAR samplename[23]; /* 22 in module, 23 in memory */
  42. UWORD length;
  43. UBYTE finetune;
  44. UBYTE volume;
  45. UWORD reppos;
  46. UWORD replen;
  47. } MSAMPINFO;
  48. typedef struct MODULEHEADER {
  49. CHAR songname[21]; /* the songname.. 20 in module, 21 in memory */
  50. MSAMPINFO samples[31]; /* all sampleinfo */
  51. UBYTE songlength; /* number of patterns used */
  52. UBYTE magic1; /* should be 127 */
  53. UBYTE positions[128]; /* which pattern to play at pos */
  54. UBYTE magic2[4]; /* string "M.K." or "FLT4" or "FLT8" */
  55. } MODULEHEADER;
  56. typedef struct MODTYPE {
  57. CHAR id[5];
  58. UBYTE channels;
  59. CHAR *name;
  60. } MODTYPE;
  61. typedef struct MODNOTE {
  62. UBYTE a, b, c, d;
  63. } MODNOTE;
  64. /*========== Loader variables */
  65. #define MODULEHEADERSIZE 0x438
  66. static CHAR protracker[] = "Protracker";
  67. static CHAR startrekker[] = "Startrekker";
  68. static CHAR fasttracker[] = "Fasttracker";
  69. static CHAR oktalyser[] = "Oktalyser";
  70. static CHAR oktalyzer[] = "Oktalyzer";
  71. static CHAR taketracker[] = "TakeTracker";
  72. static CHAR orpheus[] = "Imago Orpheus (MOD format)";
  73. static MODULEHEADER *mh = NULL;
  74. static MODNOTE *patbuf = NULL;
  75. static int modtype, trekker;
  76. /*========== Loader code */
  77. /* given the module ID, determine the number of channels and the tracker
  78.    description ; also alters modtype */
  79. static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
  80. {
  81. modtype = trekker = 0;
  82. /* Protracker and variants */
  83. if ((!memcmp(id, "M.K.", 4)) || (!memcmp(id, "M!K!", 4))) {
  84. *descr = protracker;
  85. modtype = 0;
  86. *numchn = 4;
  87. return 1;
  88. }
  89. /* Star Tracker */
  90. if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
  91. (isdigit(id[3]))) {
  92. *descr = startrekker;
  93. modtype = trekker = 1;
  94. *numchn = id[3] - '0';
  95. if (*numchn == 4 || *numchn == 8)
  96. return 1;
  97. #ifdef MIKMOD_DEBUG
  98. else
  99. fprintf(stderr, "rUnknown FLT%d module typen", *numchn);
  100. #endif
  101. return 0;
  102. }
  103. /* Oktalyzer (Amiga) */
  104. if (!memcmp(id, "OKTA", 4)) {
  105. *descr = oktalyzer;
  106. modtype = 1;
  107. *numchn = 8;
  108. return 1;
  109. }
  110. /* Oktalyser (Atari) */
  111. if (!memcmp(id, "CD81", 4)) {
  112. *descr = oktalyser;
  113. modtype = 1;
  114. *numchn = 8;
  115. return 1;
  116. }
  117. /* Fasttracker */
  118. if ((!memcmp(id + 1, "CHN", 3)) && (isdigit(id[0]))) {
  119. *descr = fasttracker;
  120. modtype = 1;
  121. *numchn = id[0] - '0';
  122. return 1;
  123. }
  124. /* Fasttracker or Taketracker */
  125. if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2)))
  126. && (isdigit(id[0])) && (isdigit(id[1]))) {
  127. if (id[3] == 'H') {
  128. *descr = fasttracker;
  129. modtype = 2; /* this can also be Imago Orpheus */
  130. } else {
  131. *descr = taketracker;
  132. modtype = 1;
  133. }
  134. *numchn = (id[0] - '0') * 10 + (id[1] - '0');
  135. return 1;
  136. }
  137. return 0;
  138. }
  139. static BOOL MOD_Test(void)
  140. {
  141. UBYTE id[4], numchn;
  142. CHAR *descr;
  143. _mm_fseek(modreader, MODULEHEADERSIZE, SEEK_SET);
  144. if (!_mm_read_UBYTES(id, 4, modreader))
  145. return 0;
  146. if (MOD_CheckType(id, &numchn, &descr))
  147. return 1;
  148. return 0;
  149. }
  150. static BOOL MOD_Init(void)
  151. {
  152. if (!(mh = (MODULEHEADER *)_mm_malloc(sizeof(MODULEHEADER))))
  153. return 0;
  154. return 1;
  155. }
  156. static void MOD_Cleanup(void)
  157. {
  158. _mm_free(mh);
  159. _mm_free(patbuf);
  160. }
  161. /*
  162. Old (amiga) noteinfo:
  163. _____byte 1_____   byte2_    _____byte 3_____   byte4_
  164. /                 /        /                 /      
  165. 0000          0000-00000000  0000          0000-00000000
  166. Upper four    12 bits for    Lower four    Effect command.
  167. bits of sam-  note period.   bits of sam-
  168. ple number.                  ple number.
  169. */
  170. static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
  171. {
  172. UBYTE instrument, effect, effdat, note;
  173. UWORD period;
  174. UBYTE lastnote = 0;
  175. /* extract the various information from the 4 bytes that make up a note */
  176. instrument = (n->a & 0x10) | (n->c >> 4);
  177. period = (((UWORD)n->a & 0xf) << 8) + n->b;
  178. effect = n->c & 0xf;
  179. effdat = n->d;
  180. /* Convert the period to a note number */
  181. note = 0;
  182. if (period) {
  183. for (note = 0; note < 7 * OCTAVE; note++)
  184. if (period >= npertab[note])
  185. break;
  186. if (note == 7 * OCTAVE)
  187. note = 0;
  188. else
  189. note++;
  190. }
  191. if (instrument) {
  192. /* if instrument does not exist, note cut */
  193. if ((instrument > 31) || (!mh->samples[instrument - 1].length)) {
  194. UniPTEffect(0xc, 0);
  195. if (effect == 0xc)
  196. effect = effdat = 0;
  197. } else {
  198. /* Protracker handling */
  199. if (!modtype) {
  200. /* if we had a note, then change instrument... */
  201. if (note)
  202. UniInstrument(instrument - 1);
  203. /* ...otherwise, only adjust volume... */
  204. else {
  205. /* ...unless an effect was specified, which forces a new
  206.    note to be played */
  207. if (effect || effdat) {
  208. UniInstrument(instrument - 1);
  209. note = lastnote;
  210. } else
  211. UniPTEffect(0xc,
  212. mh->samples[instrument -
  213. 1].volume & 0x7f);
  214. }
  215. } else {
  216. /* Fasttracker handling */
  217. UniInstrument(instrument - 1);
  218. if (!note)
  219. note = lastnote;
  220. }
  221. }
  222. }
  223. if (note) {
  224. UniNote(note + 2 * OCTAVE - 1);
  225. lastnote = note;
  226. }
  227. /* Convert pattern jump from Dec to Hex */
  228. if (effect == 0xd)
  229. effdat = (((effdat & 0xf0) >> 4) * 10) + (effdat & 0xf);
  230. /* Volume slide, up has priority */
  231. if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0))
  232. effdat &= 0xf0;
  233. /* Handle ``heavy'' volumes correctly */
  234. if ((effect == 0xc) && (effdat > 0x40))
  235. effdat = 0x40;
  236. /* An isolated 100, 200 or 300 effect should be ignored (no
  237.    "standalone" porta memory in mod files). However, a sequence such
  238.    as 1XX, 100, 100, 100 is fine. */
  239. if ((!effdat) && ((effect == 1)||(effect == 2)||(effect ==3)) &&
  240. (lasteffect < 0x10) && (effect != lasteffect))
  241. effect = 0;
  242. UniPTEffect(effect, effdat);
  243. if (effect == 8)
  244. of.flags |= UF_PANNING;
  245. return effect;
  246. }
  247. static UBYTE *ConvertTrack(MODNOTE *n, int numchn)
  248. {
  249. int t;
  250. UBYTE lasteffect = 0x10; /* non existant effect */
  251. UniReset();
  252. for (t = 0; t < 64; t++) {
  253. lasteffect = ConvertNote(n,lasteffect);
  254. UniNewline();
  255. n += numchn;
  256. }
  257. return UniDup();
  258. }
  259. /* Loads all patterns of a modfile and converts them into the 3 byte format. */
  260. static BOOL ML_LoadPatterns(void)
  261. {
  262. int t, s, tracks = 0;
  263. if (!AllocPatterns())
  264. return 0;
  265. if (!AllocTracks())
  266. return 0;
  267. /* Allocate temporary buffer for loading and converting the patterns */
  268. if (!(patbuf = (MODNOTE *)_mm_calloc(64U * of.numchn, sizeof(MODNOTE))))
  269. return 0;
  270. if (trekker && of.numchn == 8) {
  271. /* Startrekker module dual pattern */
  272. for (t = 0; t < of.numpat; t++) {
  273. for (s = 0; s < (64U * 4); s++) {
  274. patbuf[s].a = _mm_read_UBYTE(modreader);
  275. patbuf[s].b = _mm_read_UBYTE(modreader);
  276. patbuf[s].c = _mm_read_UBYTE(modreader);
  277. patbuf[s].d = _mm_read_UBYTE(modreader);
  278. }
  279. for (s = 0; s < 4; s++)
  280. if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
  281. return 0;
  282. for (s = 0; s < (64U * 4); s++) {
  283. patbuf[s].a = _mm_read_UBYTE(modreader);
  284. patbuf[s].b = _mm_read_UBYTE(modreader);
  285. patbuf[s].c = _mm_read_UBYTE(modreader);
  286. patbuf[s].d = _mm_read_UBYTE(modreader);
  287. }
  288. for (s = 0; s < 4; s++)
  289. if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
  290. return 0;
  291. }
  292. } else {
  293. /* Generic module pattern */
  294. for (t = 0; t < of.numpat; t++) {
  295. /* Load the pattern into the temp buffer and convert it */
  296. for (s = 0; s < (64U * of.numchn); s++) {
  297. patbuf[s].a = _mm_read_UBYTE(modreader);
  298. patbuf[s].b = _mm_read_UBYTE(modreader);
  299. patbuf[s].c = _mm_read_UBYTE(modreader);
  300. patbuf[s].d = _mm_read_UBYTE(modreader);
  301. }
  302. for (s = 0; s < of.numchn; s++)
  303. if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, of.numchn)))
  304. return 0;
  305. }
  306. }
  307. return 1;
  308. }
  309. static BOOL MOD_Load(BOOL curious)
  310. {
  311. int t, scan;
  312. SAMPLE *q;
  313. MSAMPINFO *s;
  314. CHAR *descr;
  315. /* try to read module header */
  316. _mm_read_string((CHAR *)mh->songname, 20, modreader);
  317. mh->songname[20] = 0; /* just in case */
  318. for (t = 0; t < 31; t++) {
  319. s = &mh->samples[t];
  320. _mm_read_string(s->samplename, 22, modreader);
  321. s->samplename[22] = 0; /* just in case */
  322. s->length = _mm_read_M_UWORD(modreader);
  323. s->finetune = _mm_read_UBYTE(modreader);
  324. s->volume = _mm_read_UBYTE(modreader);
  325. s->reppos = _mm_read_M_UWORD(modreader);
  326. s->replen = _mm_read_M_UWORD(modreader);
  327. }
  328. mh->songlength = _mm_read_UBYTE(modreader);
  329. /* this fixes mods which declare more than 128 positions. 
  330.  * eg: beatwave.mod */
  331. if (mh->songlength > 128) { mh->songlength = 128; }
  332. mh->magic1 = _mm_read_UBYTE(modreader);
  333. _mm_read_UBYTES(mh->positions, 128, modreader);
  334. _mm_read_UBYTES(mh->magic2, 4, modreader);
  335. if (_mm_eof(modreader)) {
  336. _mm_errno = MMERR_LOADING_HEADER;
  337. return 0;
  338. }
  339. /* set module variables */
  340. of.initspeed = 6;
  341. of.inittempo = 125;
  342. if (!(MOD_CheckType(mh->magic2, &of.numchn, &descr))) {
  343. _mm_errno = MMERR_NOT_A_MODULE;
  344. return 0;
  345. }
  346. if (trekker && of.numchn == 8)
  347. for (t = 0; t < 128; t++)
  348. /* if module pretends to be FLT8, yet the order table
  349.    contains odd numbers, chances are it's a lying FLT4... */
  350. if (mh->positions[t] & 1) {
  351. of.numchn = 4;
  352. break;
  353. }
  354. if (trekker && of.numchn == 8)
  355. for (t = 0; t < 128; t++)
  356. mh->positions[t] >>= 1;
  357. of.songname = DupStr(mh->songname, 21, 1);
  358. of.numpos = mh->songlength;
  359. of.reppos = 0;
  360. /* Count the number of patterns */
  361. of.numpat = 0;
  362. for (t = 0; t < of.numpos; t++)
  363. if (mh->positions[t] > of.numpat)
  364. of.numpat = mh->positions[t];
  365. /* since some old modules embed extra patterns, we have to check the
  366.    whole list to get the samples' file offsets right - however we can find
  367.    garbage here, so check carefully */
  368. scan = 1;
  369. for (t = of.numpos; t < 128; t++)
  370. if (mh->positions[t] >= 0x80)
  371. scan = 0;
  372. if (scan)
  373. for (t = of.numpos; t < 128; t++) {
  374. if (mh->positions[t] > of.numpat)
  375. of.numpat = mh->positions[t];
  376. if ((curious) && (mh->positions[t]))
  377. of.numpos = t + 1;
  378. }
  379. of.numpat++;
  380. of.numtrk = of.numpat * of.numchn;
  381. if (!AllocPositions(of.numpos))
  382. return 0;
  383. for (t = 0; t < of.numpos; t++)
  384. of.positions[t] = mh->positions[t];
  385. /* Finally, init the sampleinfo structures  */
  386. of.numins = of.numsmp = 31;
  387. if (!AllocSamples())
  388. return 0;
  389. s = mh->samples;
  390. q = of.samples;
  391. for (t = 0; t < of.numins; t++) {
  392. /* convert the samplename */
  393. q->samplename = DupStr(s->samplename, 23, 1);
  394. /* init the sampleinfo variables and convert the size pointers */
  395. q->speed = finetune[s->finetune & 0xf];
  396. q->volume = s->volume & 0x7f;
  397. q->loopstart = (ULONG)s->reppos << 1;
  398. q->loopend = q->loopstart + ((ULONG)s->replen << 1);
  399. q->length = (ULONG)s->length << 1;
  400. q->flags = SF_SIGNED;
  401. /* Imago Orpheus creates MODs with 16 bit samples, check */
  402. if ((modtype == 2) && (s->volume & 0x80)) {
  403. q->flags |= SF_16BITS;
  404. descr = orpheus;
  405. }
  406. if (s->replen > 2)
  407. q->flags |= SF_LOOP;
  408. s++;
  409. q++;
  410. }
  411. of.modtype = strdup(descr);
  412. if (!ML_LoadPatterns())
  413. return 0;
  414. return 1;
  415. }
  416. static CHAR *MOD_LoadTitle(void)
  417. {
  418. CHAR s[21];
  419. _mm_fseek(modreader, 0, SEEK_SET);
  420. if (!_mm_read_UBYTES(s, 20, modreader))
  421. return NULL;
  422. s[20] = 0; /* just in case */
  423. return (DupStr(s, 21, 1));
  424. }
  425. /*========== Loader information */
  426. MIKMODAPI MLOADER load_mod = {
  427. NULL,
  428. "Standard module",
  429. "MOD (31 instruments)",
  430. MOD_Init,
  431. MOD_Test,
  432. MOD_Load,
  433. MOD_Cleanup,
  434. MOD_LoadTitle
  435. };
  436. /* ex:set ts=4: */