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

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_med.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
  21.   Amiga MED 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 information */
  39. typedef struct MEDHEADER {
  40. ULONG id;
  41. ULONG modlen;
  42. ULONG MEDSONGP; /* struct MEDSONG *song; */
  43. UWORD psecnum; /* for the player routine, MMD2 only */
  44. UWORD pseq; /*  "   "   "   " */
  45. ULONG MEDBlockPP; /* struct MEDBlock **blockarr; */
  46. ULONG reserved1;
  47. ULONG MEDINSTHEADERPP; /* struct MEDINSTHEADER **smplarr; */
  48. ULONG reserved2;
  49. ULONG MEDEXPP; /* struct MEDEXP *expdata; */
  50. ULONG reserved3;
  51. UWORD pstate; /* some data for the player routine */
  52. UWORD pblock;
  53. UWORD pline;
  54. UWORD pseqnum;
  55. SWORD actplayline;
  56. UBYTE counter;
  57. UBYTE extra_songs; /* number of songs - 1 */
  58. } MEDHEADER;
  59. typedef struct MEDSAMPLE {
  60. UWORD rep, replen; /* offs: 0(s), 2(s) */
  61. UBYTE midich; /* offs: 4(s) */
  62. UBYTE midipreset; /* offs: 5(s) */
  63. UBYTE svol; /* offs: 6(s) */
  64. SBYTE strans; /* offs: 7(s) */
  65. } MEDSAMPLE;
  66. typedef struct MEDSONG {
  67. MEDSAMPLE sample[63]; /* 63 * 8 bytes = 504 bytes */
  68. UWORD numblocks; /* offs: 504 */
  69. UWORD songlen; /* offs: 506 */
  70. UBYTE playseq[256]; /* offs: 508 */
  71. UWORD deftempo; /* offs: 764 */
  72. SBYTE playtransp; /* offs: 766 */
  73. UBYTE flags; /* offs: 767 */
  74. UBYTE flags2; /* offs: 768 */
  75. UBYTE tempo2; /* offs: 769 */
  76. UBYTE trkvol[16]; /* offs: 770 */
  77. UBYTE mastervol; /* offs: 786 */
  78. UBYTE numsamples; /* offs: 787 */
  79. } MEDSONG;
  80. typedef struct MEDEXP {
  81. ULONG nextmod; /* pointer to next module */
  82. ULONG exp_smp; /* pointer to MEDINSTEXT array */
  83. UWORD s_ext_entries;
  84. UWORD s_ext_entrsz;
  85. ULONG annotxt; /* pointer to annotation text */
  86. ULONG annolen;
  87. ULONG iinfo; /* pointer to MEDINSTINFO array */
  88. UWORD i_ext_entries;
  89. UWORD i_ext_entrsz;
  90. ULONG jumpmask;
  91. ULONG rgbtable;
  92. ULONG channelsplit;
  93. ULONG n_info;
  94. ULONG songname; /* pointer to songname */
  95. ULONG songnamelen;
  96. ULONG dumps;
  97. ULONG reserved2[7];
  98. } MEDEXP;
  99. typedef struct MMD0NOTE {
  100. UBYTE a, b, c;
  101. } MMD0NOTE;
  102. typedef struct MMD1NOTE {
  103. UBYTE a, b, c, d;
  104. } MMD1NOTE;
  105. typedef struct MEDINSTHEADER {
  106. ULONG length;
  107. SWORD type;
  108. /* Followed by actual data */
  109. } MEDINSTHEADER;
  110. typedef struct MEDINSTEXT {
  111. UBYTE hold;
  112. UBYTE decay;
  113. UBYTE suppress_midi_off;
  114. SBYTE finetune;
  115. } MEDINSTEXT;
  116. typedef struct MEDINSTINFO {
  117. UBYTE name[40];
  118. } MEDINSTINFO;
  119. /*========== Loader variables */
  120. #define MMD0_string 0x4D4D4430
  121. #define MMD1_string 0x4D4D4431
  122. static MEDHEADER *mh = NULL;
  123. static MEDSONG *ms = NULL;
  124. static MEDEXP *me = NULL;
  125. static ULONG *ba = NULL;
  126. static MMD0NOTE *mmd0pat = NULL;
  127. static MMD1NOTE *mmd1pat = NULL;
  128. static BOOL decimalvolumes;
  129. static BOOL bpmtempos;
  130. #define d0note(row,col) mmd0pat[((row)*(UWORD)of.numchn)+(col)]
  131. #define d1note(row,col) mmd1pat[((row)*(UWORD)of.numchn)+(col)]
  132. static CHAR MED_Version[] = "OctaMED (MMDx)";
  133. /*========== Loader code */
  134. BOOL MED_Test(void)
  135. {
  136. UBYTE id[4];
  137. if (!_mm_read_UBYTES(id, 4, modreader))
  138. return 0;
  139. if ((!memcmp(id, "MMD0", 4)) || (!memcmp(id, "MMD1", 4)))
  140. return 1;
  141. return 0;
  142. }
  143. BOOL MED_Init(void)
  144. {
  145. if (!(me = (MEDEXP *)_mm_malloc(sizeof(MEDEXP))))
  146. return 0;
  147. if (!(mh = (MEDHEADER *)_mm_malloc(sizeof(MEDHEADER))))
  148. return 0;
  149. if (!(ms = (MEDSONG *)_mm_malloc(sizeof(MEDSONG))))
  150. return 0;
  151. return 1;
  152. }
  153. void MED_Cleanup(void)
  154. {
  155. _mm_free(me);
  156. _mm_free(mh);
  157. _mm_free(ms);
  158. _mm_free(ba);
  159. _mm_free(mmd0pat);
  160. _mm_free(mmd1pat);
  161. }
  162. static void EffectCvt(UBYTE eff, UBYTE dat)
  163. {
  164. switch (eff) {
  165. /* 0x0 0x1 0x2 0x3 0x4 PT effects */
  166.   case 0x5: /* PT vibrato with speed/depth nibbles swapped */
  167. UniPTEffect(0x4, (dat >> 4) | ((dat & 0xf) << 4));
  168. break;
  169. /* 0x6 0x7 not used */
  170.   case 0x6:
  171.   case 0x7:
  172. break;
  173.   case 0x8: /* midi hold/decay */
  174. break;
  175.   case 0x9:
  176. if (bpmtempos) {
  177. if (!dat)
  178. dat = of.initspeed;
  179. UniEffect(UNI_S3MEFFECTA, dat);
  180. } else {
  181. if (dat <= 0x20) {
  182. if (!dat)
  183. dat = of.initspeed;
  184. else
  185. dat /= 4;
  186. UniPTEffect(0xf, dat);
  187. } else
  188. UniEffect(UNI_MEDSPEED, ((UWORD)dat * 125) / (33 * 4));
  189. }
  190. break;
  191. /* 0xa 0xb PT effects */
  192.   case 0xc:
  193. if (decimalvolumes)
  194. dat = (dat >> 4) * 10 + (dat & 0xf);
  195. UniPTEffect(0xc, dat);
  196. break;
  197.   case 0xd: /* same as PT volslide */
  198. UniPTEffect(0xa, dat);
  199. break;
  200.   case 0xe: /* synth jmp - midi */
  201. break;
  202.   case 0xf:
  203. switch (dat) {
  204.   case 0: /* patternbreak */
  205. UniPTEffect(0xd, 0);
  206. break;
  207.   case 0xf1: /* play note twice */
  208. UniWriteByte(UNI_MEDEFFECTF1);
  209. break;
  210.   case 0xf2: /* delay note */
  211. UniWriteByte(UNI_MEDEFFECTF2);
  212. break;
  213.   case 0xf3: /* play note three times */
  214. UniWriteByte(UNI_MEDEFFECTF3);
  215. break;
  216.   case 0xfe: /* stop playing */
  217. UniPTEffect(0xb, of.numpat);
  218. break;
  219.   case 0xff: /* note cut */
  220. UniPTEffect(0xc, 0);
  221. break;
  222.   default:
  223. if (dat <= 10)
  224. UniPTEffect(0xf, dat);
  225. else if (dat <= 240) {
  226. if (bpmtempos)
  227. UniPTEffect(0xf, (dat < 32) ? 32 : dat);
  228. else
  229. UniEffect(UNI_MEDSPEED, ((UWORD)dat * 125) / 33);
  230. }
  231. }
  232. break;
  233.   default: /* all normal PT effects are handled here */
  234. UniPTEffect(eff, dat);
  235. break;
  236. }
  237. }
  238. static UBYTE *MED_Convert1(int count, int col)
  239. {
  240. int t;
  241. UBYTE inst, note, eff, dat;
  242. MMD1NOTE *n;
  243. UniReset();
  244. for (t = 0; t < count; t++) {
  245. n = &d1note(t, col);
  246. note = n->a & 0x7f;
  247. inst = n->b & 0x3f;
  248. eff = n->c & 0xf;
  249. dat = n->d;
  250. if (inst)
  251. UniInstrument(inst - 1);
  252. if (note)
  253. UniNote(note + 3 * OCTAVE - 1);
  254. EffectCvt(eff, dat);
  255. UniNewline();
  256. }
  257. return UniDup();
  258. }
  259. static UBYTE *MED_Convert0(int count, int col)
  260. {
  261. int t;
  262. UBYTE a, b, inst, note, eff, dat;
  263. MMD0NOTE *n;
  264. UniReset();
  265. for (t = 0; t < count; t++) {
  266. n = &d0note(t, col);
  267. a = n->a;
  268. b = n->b;
  269. note = a & 0x3f;
  270. a >>= 6;
  271. a = ((a & 1) << 1) | (a >> 1);
  272. inst = (b >> 4) | (a << 4);
  273. eff = b & 0xf;
  274. dat = n->c;
  275. if (inst)
  276. UniInstrument(inst - 1);
  277. if (note)
  278. UniNote(note + 3 * OCTAVE - 1);
  279. EffectCvt(eff, dat);
  280. UniNewline();
  281. }
  282. return UniDup();
  283. }
  284. static BOOL LoadMEDPatterns(void)
  285. {
  286. int t, row, col;
  287. UWORD numtracks, numlines, maxlines = 0, track = 0;
  288. MMD0NOTE *mmdp;
  289. /* first, scan patterns to see how many channels are used */
  290. for (t = 0; t < of.numpat; t++) {
  291. _mm_fseek(modreader, ba[t], SEEK_SET);
  292. numtracks = _mm_read_UBYTE(modreader);
  293. numlines = _mm_read_UBYTE(modreader);
  294. if (numtracks > of.numchn)
  295. of.numchn = numtracks;
  296. if (numlines > maxlines)
  297. maxlines = numlines;
  298. }
  299. of.numtrk = of.numpat * of.numchn;
  300. if (!AllocTracks())
  301. return 0;
  302. if (!AllocPatterns())
  303. return 0;
  304. if (!
  305. (mmd0pat =
  306.  (MMD0NOTE *)_mm_calloc(of.numchn * (maxlines + 1),
  307. sizeof(MMD0NOTE)))) return 0;
  308. /* second read: read and convert patterns */
  309. for (t = 0; t < of.numpat; t++) {
  310. _mm_fseek(modreader, ba[t], SEEK_SET);
  311. numtracks = _mm_read_UBYTE(modreader);
  312. numlines = _mm_read_UBYTE(modreader);
  313. of.pattrows[t] = ++numlines;
  314. memset(mmdp = mmd0pat, 0, of.numchn * maxlines * sizeof(MMD0NOTE));
  315. for (row = numlines; row; row--) {
  316. for (col = numtracks; col; col--, mmdp++) {
  317. mmdp->a = _mm_read_UBYTE(modreader);
  318. mmdp->b = _mm_read_UBYTE(modreader);
  319. mmdp->c = _mm_read_UBYTE(modreader);
  320. }
  321. }
  322. for (col = 0; col < of.numchn; col++)
  323. of.tracks[track++] = MED_Convert0(numlines, col);
  324. }
  325. return 1;
  326. }
  327. static BOOL LoadMMD1Patterns(void)
  328. {
  329. int t, row, col;
  330. UWORD numtracks, numlines, maxlines = 0, track = 0;
  331. MMD1NOTE *mmdp;
  332. /* first, scan patterns to see how many channels are used */
  333. for (t = 0; t < of.numpat; t++) {
  334. _mm_fseek(modreader, ba[t], SEEK_SET);
  335. numtracks = _mm_read_M_UWORD(modreader);
  336. numlines = _mm_read_M_UWORD(modreader);
  337. if (numtracks > of.numchn)
  338. of.numchn = numtracks;
  339. if (numlines > maxlines)
  340. maxlines = numlines;
  341. }
  342. of.numtrk = of.numpat * of.numchn;
  343. if (!AllocTracks())
  344. return 0;
  345. if (!AllocPatterns())
  346. return 0;
  347. if (!
  348. (mmd1pat =
  349.  (MMD1NOTE *)_mm_calloc(of.numchn * (maxlines + 1),
  350. sizeof(MMD1NOTE)))) return 0;
  351. /* second read: really read and convert patterns */
  352. for (t = 0; t < of.numpat; t++) {
  353. _mm_fseek(modreader, ba[t], SEEK_SET);
  354. numtracks = _mm_read_M_UWORD(modreader);
  355. numlines = _mm_read_M_UWORD(modreader);
  356. _mm_fseek(modreader, sizeof(ULONG), SEEK_CUR);
  357. of.pattrows[t] = ++numlines;
  358. memset(mmdp = mmd1pat, 0, of.numchn * maxlines * sizeof(MMD1NOTE));
  359. for (row = numlines; row; row--) {
  360. for (col = numtracks; col; col--, mmdp++) {
  361. mmdp->a = _mm_read_UBYTE(modreader);
  362. mmdp->b = _mm_read_UBYTE(modreader);
  363. mmdp->c = _mm_read_UBYTE(modreader);
  364. mmdp->d = _mm_read_UBYTE(modreader);
  365. }
  366. }
  367. for (col = 0; col < of.numchn; col++)
  368. of.tracks[track++] = MED_Convert1(numlines, col);
  369. }
  370. return 1;
  371. }
  372. BOOL MED_Load(BOOL curious)
  373. {
  374. int t;
  375. ULONG sa[64];
  376. MEDINSTHEADER s;
  377. SAMPLE *q;
  378. MEDSAMPLE *mss;
  379. /* try to read module header */
  380. mh->id = _mm_read_M_ULONG(modreader);
  381. mh->modlen = _mm_read_M_ULONG(modreader);
  382. mh->MEDSONGP = _mm_read_M_ULONG(modreader);
  383. mh->psecnum = _mm_read_M_UWORD(modreader);
  384. mh->pseq = _mm_read_M_UWORD(modreader);
  385. mh->MEDBlockPP = _mm_read_M_ULONG(modreader);
  386. mh->reserved1 = _mm_read_M_ULONG(modreader);
  387. mh->MEDINSTHEADERPP = _mm_read_M_ULONG(modreader);
  388. mh->reserved2 = _mm_read_M_ULONG(modreader);
  389. mh->MEDEXPP = _mm_read_M_ULONG(modreader);
  390. mh->reserved3 = _mm_read_M_ULONG(modreader);
  391. mh->pstate = _mm_read_M_UWORD(modreader);
  392. mh->pblock = _mm_read_M_UWORD(modreader);
  393. mh->pline = _mm_read_M_UWORD(modreader);
  394. mh->pseqnum = _mm_read_M_UWORD(modreader);
  395. mh->actplayline = _mm_read_M_SWORD(modreader);
  396. mh->counter = _mm_read_UBYTE(modreader);
  397. mh->extra_songs = _mm_read_UBYTE(modreader);
  398. /* Seek to MEDSONG struct */
  399. _mm_fseek(modreader, mh->MEDSONGP, SEEK_SET);
  400. /* Load the MED Song Header */
  401. mss = ms->sample; /* load the sample data first */
  402. for (t = 63; t; t--, mss++) {
  403. mss->rep = _mm_read_M_UWORD(modreader);
  404. mss->replen = _mm_read_M_UWORD(modreader);
  405. mss->midich = _mm_read_UBYTE(modreader);
  406. mss->midipreset = _mm_read_UBYTE(modreader);
  407. mss->svol = _mm_read_UBYTE(modreader);
  408. mss->strans = _mm_read_SBYTE(modreader);
  409. }
  410. ms->numblocks = _mm_read_M_UWORD(modreader);
  411. ms->songlen = _mm_read_M_UWORD(modreader);
  412. _mm_read_UBYTES(ms->playseq, 256, modreader);
  413. ms->deftempo = _mm_read_M_UWORD(modreader);
  414. ms->playtransp = _mm_read_SBYTE(modreader);
  415. ms->flags = _mm_read_UBYTE(modreader);
  416. ms->flags2 = _mm_read_UBYTE(modreader);
  417. ms->tempo2 = _mm_read_UBYTE(modreader);
  418. _mm_read_UBYTES(ms->trkvol, 16, modreader);
  419. ms->mastervol = _mm_read_UBYTE(modreader);
  420. ms->numsamples = _mm_read_UBYTE(modreader);
  421. /* check for a bad header */
  422. if (_mm_eof(modreader)) {
  423. _mm_errno = MMERR_LOADING_HEADER;
  424. return 0;
  425. }
  426. /* load extension structure */
  427. if (mh->MEDEXPP) {
  428. _mm_fseek(modreader, mh->MEDEXPP, SEEK_SET);
  429. me->nextmod = _mm_read_M_ULONG(modreader);
  430. me->exp_smp = _mm_read_M_ULONG(modreader);
  431. me->s_ext_entries = _mm_read_M_UWORD(modreader);
  432. me->s_ext_entrsz = _mm_read_M_UWORD(modreader);
  433. me->annotxt = _mm_read_M_ULONG(modreader);
  434. me->annolen = _mm_read_M_ULONG(modreader);
  435. me->iinfo = _mm_read_M_ULONG(modreader);
  436. me->i_ext_entries = _mm_read_M_UWORD(modreader);
  437. me->i_ext_entrsz = _mm_read_M_UWORD(modreader);
  438. me->jumpmask = _mm_read_M_ULONG(modreader);
  439. me->rgbtable = _mm_read_M_ULONG(modreader);
  440. me->channelsplit = _mm_read_M_ULONG(modreader);
  441. me->n_info = _mm_read_M_ULONG(modreader);
  442. me->songname = _mm_read_M_ULONG(modreader);
  443. me->songnamelen = _mm_read_M_ULONG(modreader);
  444. me->dumps = _mm_read_M_ULONG(modreader);
  445. }
  446. /* seek to and read the samplepointer array */
  447. _mm_fseek(modreader, mh->MEDINSTHEADERPP, SEEK_SET);
  448. if (!_mm_read_M_ULONGS(sa, ms->numsamples, modreader)) {
  449. _mm_errno = MMERR_LOADING_HEADER;
  450. return 0;
  451. }
  452. /* alloc and read the blockpointer array */
  453. if (!(ba = (ULONG *)_mm_calloc(ms->numblocks, sizeof(ULONG))))
  454. return 0;
  455. _mm_fseek(modreader, mh->MEDBlockPP, SEEK_SET);
  456. if (!_mm_read_M_ULONGS(ba, ms->numblocks, modreader)) {
  457. _mm_errno = MMERR_LOADING_HEADER;
  458. return 0;
  459. }
  460. /* copy song positions */
  461. if (!AllocPositions(ms->songlen))
  462. return 0;
  463. for (t = 0; t < ms->songlen; t++)
  464. of.positions[t] = ms->playseq[t];
  465. decimalvolumes = (ms->flags & 0x10) ? 0 : 1;
  466. bpmtempos = (ms->flags2 & 0x20) ? 1 : 0;
  467. if (bpmtempos) {
  468. int bpmlen = (ms->flags2 & 0x1f) + 1;
  469. of.initspeed = ms->tempo2;
  470. of.inittempo = ms->deftempo * bpmlen / 4;
  471. if (bpmlen != 4) {
  472. /* Let's do some math : compute GCD of BPM beat length and speed */
  473. int a, b;
  474. a = bpmlen;
  475. b = ms->tempo2;
  476. if (a > b) {
  477. t = b;
  478. b = a;
  479. a = t;
  480. }
  481. while ((a != b) && (a)) {
  482. t = a;
  483. a = b - a;
  484. b = t;
  485. if (a > b) {
  486. t = b;
  487. b = a;
  488. a = t;
  489. }
  490. }
  491. of.initspeed /= b;
  492. of.inittempo = ms->deftempo * bpmlen / (4 * b);
  493. }
  494. } else {
  495. of.initspeed = ms->tempo2;
  496. of.inittempo = ms->deftempo ? ((UWORD)ms->deftempo * 125) / 33 : 128;
  497. if ((ms->deftempo <= 10) && (ms->deftempo))
  498. of.inittempo = (of.inittempo * 33) / 6;
  499. of.flags |= UF_HIGHBPM;
  500. }
  501. MED_Version[12] = mh->id;
  502. of.modtype = strdup(MED_Version);
  503. of.numchn = 0; /* will be counted later */
  504. of.numpat = ms->numblocks;
  505. of.numpos = ms->songlen;
  506. of.numins = ms->numsamples;
  507. of.numsmp = of.numins;
  508. of.reppos = 0;
  509. if ((mh->MEDEXPP) && (me->songname) && (me->songnamelen)) {
  510. char *name;
  511. _mm_fseek(modreader, me->songname, SEEK_SET);
  512. name = _mm_malloc(me->songnamelen);
  513. _mm_read_UBYTES(name, me->songnamelen, modreader);
  514. of.songname = DupStr(name, me->songnamelen, 1);
  515. free(name);
  516. } else
  517. of.songname = DupStr(NULL, 0, 0);
  518. if ((mh->MEDEXPP) && (me->annotxt) && (me->annolen)) {
  519. _mm_fseek(modreader, me->annotxt, SEEK_SET);
  520. ReadComment(me->annolen);
  521. }
  522. if (!AllocSamples())
  523. return 0;
  524. q = of.samples;
  525. for (t = 0; t < of.numins; t++) {
  526. q->flags = SF_SIGNED;
  527. q->volume = 64;
  528. if (sa[t]) {
  529. _mm_fseek(modreader, sa[t], SEEK_SET);
  530. s.length = _mm_read_M_ULONG(modreader);
  531. s.type = _mm_read_M_SWORD(modreader);
  532. if (s.type) {
  533. #ifdef MIKMOD_DEBUG
  534. fprintf(stderr, "rNon-sample instruments not supported in MED loader yetn");
  535. #endif
  536. if (!curious) {
  537. _mm_errno = MMERR_MED_SYNTHSAMPLES;
  538. return 0;
  539. }
  540. s.length = 0;
  541. }
  542. if (_mm_eof(modreader)) {
  543. _mm_errno = MMERR_LOADING_SAMPLEINFO;
  544. return 0;
  545. }
  546. q->length = s.length;
  547. q->seekpos = _mm_ftell(modreader);
  548. q->loopstart = ms->sample[t].rep << 1;
  549. q->loopend = q->loopstart + (ms->sample[t].replen << 1);
  550. if (ms->sample[t].replen > 1)
  551. q->flags |= SF_LOOP;
  552. /* don't load sample if length>='MMD0'...
  553.    such kluges make libmikmod's code unique !!! */
  554. if (q->length >= MMD0_string)
  555. q->length = 0;
  556. } else
  557. q->length = 0;
  558. if ((mh->MEDEXPP) && (me->exp_smp) &&
  559. (t < me->s_ext_entries) && (me->s_ext_entrsz >= 4)) {
  560. MEDINSTEXT ie;
  561. _mm_fseek(modreader, me->exp_smp + t * me->s_ext_entrsz,
  562.   SEEK_SET);
  563. ie.hold = _mm_read_UBYTE(modreader);
  564. ie.decay = _mm_read_UBYTE(modreader);
  565. ie.suppress_midi_off = _mm_read_UBYTE(modreader);
  566. ie.finetune = _mm_read_SBYTE(modreader);
  567. q->speed = finetune[ie.finetune & 0xf];
  568. } else
  569. q->speed = 8363;
  570. if ((mh->MEDEXPP) && (me->iinfo) &&
  571. (t < me->i_ext_entries) && (me->i_ext_entrsz >= 40)) {
  572. MEDINSTINFO ii;
  573. _mm_fseek(modreader, me->iinfo + t * me->i_ext_entrsz, SEEK_SET);
  574. _mm_read_UBYTES(ii.name, 40, modreader);
  575. q->samplename = DupStr((char*)ii.name, 40, 1);
  576. } else
  577. q->samplename = NULL;
  578. q++;
  579. }
  580. if (mh->id == MMD0_string) {
  581. if (!LoadMEDPatterns()) {
  582. _mm_errno = MMERR_LOADING_PATTERN;
  583. return 0;
  584. }
  585. } else if (mh->id == MMD1_string) {
  586. if (!LoadMMD1Patterns()) {
  587. _mm_errno = MMERR_LOADING_PATTERN;
  588. return 0;
  589. }
  590. } else {
  591. _mm_errno = MMERR_NOT_A_MODULE;
  592. return 0;
  593. }
  594. return 1;
  595. }
  596. CHAR *MED_LoadTitle(void)
  597. {
  598. ULONG posit, namelen;
  599. CHAR *name, *retvalue = NULL;
  600. _mm_fseek(modreader, 0x20, SEEK_SET);
  601. posit = _mm_read_M_ULONG(modreader);
  602. if (posit) {
  603. _mm_fseek(modreader, posit + 0x2C, SEEK_SET);
  604. posit = _mm_read_M_ULONG(modreader);
  605. namelen = _mm_read_M_ULONG(modreader);
  606. _mm_fseek(modreader, posit, SEEK_SET);
  607. name = _mm_malloc(namelen);
  608. _mm_read_UBYTES(name, namelen, modreader);
  609. retvalue = DupStr(name, namelen, 1);
  610. free(name);
  611. }
  612. return retvalue;
  613. }
  614. /*========== Loader information */
  615. MIKMODAPI MLOADER load_med = {
  616. NULL,
  617. "MED",
  618. "MED (OctaMED)",
  619. MED_Init,
  620. MED_Test,
  621. MED_Load,
  622. MED_Cleanup,
  623. MED_LoadTitle
  624. };
  625. /* ex:set ts=4: */