PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/timidity/libunimod/load_uni.c

http://github.com/xbmc/xbmc
C | 782 lines | 650 code | 83 blank | 49 comment | 130 complexity | 020211cb633d8332dd56e0fb25dec0a6 MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, LGPL-2.0, 0BSD, Unlicense, GPL-2.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0
  1. /* MikMod sound library
  2. (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
  3. 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. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA.
  16. */
  17. /*==============================================================================
  18. $Id: load_uni.c,v 1.13 1999/10/25 16:31:41 miod Exp $
  19. UNIMOD (libmikmod's and APlayer's internal module format) loader
  20. ==============================================================================*/
  21. #ifdef HAVE_CONFIG_H
  22. #include "config.h"
  23. #endif
  24. #include <string.h>
  25. #include "unimod_priv.h"
  26. /*========== Module structure */
  27. typedef struct UNIHEADER
  28. {
  29. CHAR id[4];
  30. UBYTE numchn;
  31. UWORD numpos;
  32. UWORD reppos;
  33. UWORD numpat;
  34. UWORD numtrk;
  35. UWORD numins;
  36. UWORD numsmp;
  37. UBYTE initspeed;
  38. UBYTE inittempo;
  39. UBYTE initvolume;
  40. UBYTE flags;
  41. UBYTE numvoices;
  42. UBYTE positions[256];
  43. UBYTE panning[32];
  44. }
  45. UNIHEADER;
  46. typedef struct UNISMP05
  47. {
  48. UWORD c2spd;
  49. UWORD transpose;
  50. UBYTE volume;
  51. UBYTE panning;
  52. ULONG length;
  53. ULONG loopstart;
  54. ULONG loopend;
  55. UWORD flags;
  56. CHAR *samplename;
  57. UBYTE vibtype;
  58. UBYTE vibsweep;
  59. UBYTE vibdepth;
  60. UBYTE vibrate;
  61. }
  62. UNISMP05;
  63. /*========== Loader variables */
  64. static UWORD universion;
  65. static UNIHEADER mh;
  66. #define UNI_SMPINCR 64
  67. static UNISMP05 *wh = NULL, *s = NULL;
  68. /*========== Loader code */
  69. static char *
  70. readstring (void)
  71. {
  72. char *s = NULL;
  73. UWORD len;
  74. len = _mm_read_I_UWORD (modreader);
  75. if (len)
  76. {
  77. s = _mm_malloc (len + 1);
  78. _mm_read_UBYTES (s, len, modreader);
  79. s[len] = 0;
  80. }
  81. return s;
  82. }
  83. BOOL
  84. UNI_Test (void)
  85. {
  86. char id[6];
  87. if (!_mm_read_UBYTES (id, 6, modreader))
  88. return 0;
  89. /* UNIMod created by MikCvt */
  90. if (!(memcmp (id, "UN0", 3)))
  91. {
  92. if ((id[3] >= '4') && (id[3] <= '6'))
  93. return 1;
  94. }
  95. /* UNIMod created by APlayer */
  96. if (!(memcmp (id, "APUN\01", 5)))
  97. {
  98. if ((id[5] >= 1) && (id[5] <= 4))
  99. return 1;
  100. }
  101. return 0;
  102. }
  103. BOOL
  104. UNI_Init (void)
  105. {
  106. return 1;
  107. }
  108. void
  109. UNI_Cleanup (void)
  110. {
  111. _mm_free (wh);
  112. s = NULL;
  113. }
  114. static UBYTE *
  115. readtrack (void)
  116. {
  117. UBYTE *t;
  118. UWORD len;
  119. int cur = 0, chunk;
  120. if (universion >= 6)
  121. len = _mm_read_M_UWORD (modreader);
  122. else
  123. len = _mm_read_I_UWORD (modreader);
  124. if (!len)
  125. return NULL;
  126. if (!(t = _mm_malloc (len)))
  127. return NULL;
  128. _mm_read_UBYTES (t, len, modreader);
  129. /* Check if the track is correct */
  130. while (1)
  131. {
  132. chunk = t[cur++];
  133. if (!chunk)
  134. break;
  135. chunk = (chunk & 0x1f) - 1;
  136. while (chunk > 0)
  137. {
  138. int opcode, oplen;
  139. if (cur >= len)
  140. {
  141. free (t);
  142. return NULL;
  143. }
  144. opcode = t[cur];
  145. /* Remap opcodes */
  146. if (universion <= 5)
  147. {
  148. if (opcode > 29)
  149. {
  150. free (t);
  151. return NULL;
  152. }
  153. switch (opcode)
  154. {
  155. /* UNI_NOTE .. UNI_S3MEFFECTQ are the same */
  156. case 25:
  157. opcode = UNI_S3MEFFECTT;
  158. break;
  159. case 26:
  160. opcode = UNI_XMEFFECTA;
  161. break;
  162. case 27:
  163. opcode = UNI_XMEFFECTG;
  164. break;
  165. case 28:
  166. opcode = UNI_XMEFFECTH;
  167. break;
  168. case 29:
  169. opcode = UNI_XMEFFECTP;
  170. break;
  171. }
  172. }
  173. else
  174. {
  175. if (opcode > UNI_ITEFFECTP)
  176. {
  177. /* APlayer < 1.03 does not have ITEFFECTT */
  178. if (universion < 0x103)
  179. opcode++;
  180. /* APlayer < 1.02 does not have ITEFFECTZ */
  181. if ((opcode > UNI_ITEFFECTY) && (universion < 0x102))
  182. opcode++;
  183. }
  184. }
  185. if ((!opcode) || (opcode >= UNI_LAST))
  186. {
  187. free (t);
  188. return NULL;
  189. }
  190. oplen = unioperands[opcode] + 1;
  191. cur += oplen;
  192. chunk -= oplen;
  193. }
  194. if ((chunk < 0) || (cur >= len))
  195. {
  196. free (t);
  197. return NULL;
  198. }
  199. }
  200. return t;
  201. }
  202. static BOOL
  203. loadsmp6 (void)
  204. {
  205. int t;
  206. SAMPLE *s;
  207. s = of.samples;
  208. for (t = 0; t < of.numsmp; t++, s++)
  209. {
  210. int flags;
  211. flags = _mm_read_M_UWORD (modreader);
  212. s->flags = 0;
  213. if (flags & 0x0100)
  214. s->flags |= SF_REVERSE;
  215. if (flags & 0x0004)
  216. s->flags |= SF_STEREO;
  217. if (flags & 0x0002)
  218. s->flags |= SF_SIGNED;
  219. if (flags & 0x0001)
  220. s->flags |= SF_16BITS;
  221. /* convert flags */
  222. if (universion >= 0x102)
  223. {
  224. if (flags & 0x0800)
  225. s->flags |= SF_UST_LOOP;
  226. if (flags & 0x0400)
  227. s->flags |= SF_OWNPAN;
  228. if (flags & 0x0200)
  229. s->flags |= SF_SUSTAIN;
  230. if (flags & 0x0080)
  231. s->flags |= SF_BIDI;
  232. if (flags & 0x0040)
  233. s->flags |= SF_LOOP;
  234. if (flags & 0x0020)
  235. s->flags |= SF_ITPACKED;
  236. if (flags & 0x0010)
  237. s->flags |= SF_DELTA;
  238. if (flags & 0x0008)
  239. s->flags |= SF_BIG_ENDIAN;
  240. }
  241. else
  242. {
  243. if (flags & 0x400)
  244. s->flags |= SF_UST_LOOP;
  245. if (flags & 0x200)
  246. s->flags |= SF_OWNPAN;
  247. if (flags & 0x080)
  248. s->flags |= SF_SUSTAIN;
  249. if (flags & 0x040)
  250. s->flags |= SF_BIDI;
  251. if (flags & 0x020)
  252. s->flags |= SF_LOOP;
  253. if (flags & 0x010)
  254. s->flags |= SF_BIG_ENDIAN;
  255. if (flags & 0x008)
  256. s->flags |= SF_DELTA;
  257. }
  258. s->speed = _mm_read_M_ULONG (modreader);
  259. s->volume = _mm_read_UBYTE (modreader);
  260. s->panning = _mm_read_M_UWORD (modreader);
  261. s->length = _mm_read_M_ULONG (modreader);
  262. s->loopstart = _mm_read_M_ULONG (modreader);
  263. s->loopend = _mm_read_M_ULONG (modreader);
  264. s->susbegin = _mm_read_M_ULONG (modreader);
  265. s->susend = _mm_read_M_ULONG (modreader);
  266. s->globvol = _mm_read_UBYTE (modreader);
  267. s->vibflags = _mm_read_UBYTE (modreader);
  268. s->vibtype = _mm_read_UBYTE (modreader);
  269. s->vibsweep = _mm_read_UBYTE (modreader);
  270. s->vibdepth = _mm_read_UBYTE (modreader);
  271. s->vibrate = _mm_read_UBYTE (modreader);
  272. s->samplename = readstring ();
  273. if (_mm_eof (modreader))
  274. {
  275. _mm_errno = MMERR_LOADING_SAMPLEINFO;
  276. return 0;
  277. }
  278. }
  279. return 1;
  280. }
  281. static BOOL
  282. loadinstr6 (void)
  283. {
  284. int t, w;
  285. INSTRUMENT *i;
  286. i = of.instruments;
  287. for (t = 0; t < of.numins; t++, i++)
  288. {
  289. i->flags = _mm_read_UBYTE (modreader);
  290. i->nnatype = _mm_read_UBYTE (modreader);
  291. i->dca = _mm_read_UBYTE (modreader);
  292. i->dct = _mm_read_UBYTE (modreader);
  293. i->globvol = _mm_read_UBYTE (modreader);
  294. i->panning = _mm_read_M_UWORD (modreader);
  295. i->pitpansep = _mm_read_UBYTE (modreader);
  296. i->pitpancenter = _mm_read_UBYTE (modreader);
  297. i->rvolvar = _mm_read_UBYTE (modreader);
  298. i->rpanvar = _mm_read_UBYTE (modreader);
  299. i->volfade = _mm_read_M_UWORD (modreader);
  300. #define UNI_LoadEnvelope6(name) \
  301. i->name##flg=_mm_read_UBYTE(modreader); \
  302. i->name##pts=_mm_read_UBYTE(modreader); \
  303. i->name##susbeg=_mm_read_UBYTE(modreader); \
  304. i->name##susend=_mm_read_UBYTE(modreader); \
  305. i->name##beg=_mm_read_UBYTE(modreader); \
  306. i->name##end=_mm_read_UBYTE(modreader); \
  307. for(w=0;w<(universion>=0x100?32:i->name##pts);w++) { \
  308. i->name##env[w].pos=_mm_read_M_SWORD(modreader); \
  309. i->name##env[w].val=_mm_read_M_SWORD(modreader); \
  310. }
  311. UNI_LoadEnvelope6 (vol);
  312. UNI_LoadEnvelope6 (pan);
  313. UNI_LoadEnvelope6 (pit);
  314. #undef UNI_LoadEnvelope6
  315. if (universion == 0x103)
  316. _mm_read_M_UWORDS (i->samplenumber, 120, modreader);
  317. else
  318. for (w = 0; w < 120; w++)
  319. i->samplenumber[w] = _mm_read_UBYTE (modreader);
  320. _mm_read_UBYTES (i->samplenote, 120, modreader);
  321. i->insname = readstring ();
  322. if (_mm_eof (modreader))
  323. {
  324. _mm_errno = MMERR_LOADING_SAMPLEINFO;
  325. return 0;
  326. }
  327. }
  328. return 1;
  329. }
  330. static BOOL
  331. loadinstr5 (void)
  332. {
  333. INSTRUMENT *i;
  334. int t;
  335. UWORD wavcnt = 0;
  336. UBYTE vibtype, vibsweep, vibdepth, vibrate;
  337. i = of.instruments;
  338. for (of.numsmp = t = 0; t < of.numins; t++, i++)
  339. {
  340. int u, numsmp;
  341. numsmp = _mm_read_UBYTE (modreader);
  342. memset (i->samplenumber, 0xff, INSTNOTES * sizeof (UWORD));
  343. for (u = 0; u < 96; u++)
  344. i->samplenumber[u] = of.numsmp + _mm_read_UBYTE (modreader);
  345. #define UNI_LoadEnvelope5(name) \
  346. i->name##flg=_mm_read_UBYTE(modreader); \
  347. i->name##pts=_mm_read_UBYTE(modreader); \
  348. i->name##susbeg=_mm_read_UBYTE(modreader); \
  349. i->name##susend=i->name##susbeg; \
  350. i->name##beg=_mm_read_UBYTE(modreader); \
  351. i->name##end=_mm_read_UBYTE(modreader); \
  352. for(u=0;u<12;u++) { \
  353. i->name##env[u].pos=_mm_read_I_SWORD(modreader); \
  354. i->name##env[u].val=_mm_read_I_SWORD(modreader); \
  355. }
  356. UNI_LoadEnvelope5 (vol);
  357. UNI_LoadEnvelope5 (pan);
  358. #undef UNI_LoadEnvelope5
  359. vibtype = _mm_read_UBYTE (modreader);
  360. vibsweep = _mm_read_UBYTE (modreader);
  361. vibdepth = _mm_read_UBYTE (modreader);
  362. vibrate = _mm_read_UBYTE (modreader);
  363. i->volfade = _mm_read_I_UWORD (modreader);
  364. i->insname = readstring ();
  365. for (u = 0; u < numsmp; u++, s++, of.numsmp++)
  366. {
  367. /* Allocate more room for sample information if necessary */
  368. if (of.numsmp + u == wavcnt)
  369. {
  370. wavcnt += UNI_SMPINCR;
  371. if (!(wh = realloc (wh, wavcnt * sizeof (UNISMP05))))
  372. {
  373. _mm_errno = MMERR_OUT_OF_MEMORY;
  374. return 0;
  375. }
  376. s = wh + (wavcnt - UNI_SMPINCR);
  377. }
  378. s->c2spd = _mm_read_I_UWORD (modreader);
  379. s->transpose = _mm_read_SBYTE (modreader);
  380. s->volume = _mm_read_UBYTE (modreader);
  381. s->panning = _mm_read_UBYTE (modreader);
  382. s->length = _mm_read_I_ULONG (modreader);
  383. s->loopstart = _mm_read_I_ULONG (modreader);
  384. s->loopend = _mm_read_I_ULONG (modreader);
  385. s->flags = _mm_read_I_UWORD (modreader);
  386. s->samplename = readstring ();
  387. s->vibtype = vibtype;
  388. s->vibsweep = vibsweep;
  389. s->vibdepth = vibdepth;
  390. s->vibrate = vibrate;
  391. if (_mm_eof (modreader))
  392. {
  393. free (wh);
  394. wh = NULL;
  395. _mm_errno = MMERR_LOADING_SAMPLEINFO;
  396. return 0;
  397. }
  398. }
  399. }
  400. /* sanity check */
  401. if (!of.numsmp)
  402. {
  403. if (wh)
  404. {
  405. free (wh);
  406. wh = NULL;
  407. }
  408. _mm_errno = MMERR_LOADING_SAMPLEINFO;
  409. return 0;
  410. }
  411. return 1;
  412. }
  413. static BOOL
  414. loadsmp5 (void)
  415. {
  416. int t, u;
  417. SAMPLE *q;
  418. INSTRUMENT *d;
  419. q = of.samples;
  420. s = wh;
  421. for (u = 0; u < of.numsmp; u++, q++, s++)
  422. {
  423. q->samplename = s->samplename;
  424. q->length = s->length;
  425. q->loopstart = s->loopstart;
  426. q->loopend = s->loopend;
  427. q->volume = s->volume;
  428. q->speed = s->c2spd;
  429. q->panning = s->panning;
  430. q->vibtype = s->vibtype;
  431. q->vibsweep = s->vibsweep;
  432. q->vibdepth = s->vibdepth;
  433. q->vibrate = s->vibrate;
  434. /* convert flags */
  435. q->flags = 0;
  436. if (s->flags & 128)
  437. q->flags |= SF_REVERSE;
  438. if (s->flags & 64)
  439. q->flags |= SF_SUSTAIN;
  440. if (s->flags & 32)
  441. q->flags |= SF_BIDI;
  442. if (s->flags & 16)
  443. q->flags |= SF_LOOP;
  444. if (s->flags & 8)
  445. q->flags |= SF_BIG_ENDIAN;
  446. if (s->flags & 4)
  447. q->flags |= SF_DELTA;
  448. if (s->flags & 2)
  449. q->flags |= SF_SIGNED;
  450. if (s->flags & 1)
  451. q->flags |= SF_16BITS;
  452. }
  453. d = of.instruments;
  454. s = wh;
  455. for (u = 0; u < of.numins; u++, d++)
  456. for (t = 0; t < INSTNOTES; t++)
  457. d->samplenote[t] = (d->samplenumber[t] >= of.numsmp) ?
  458. 255 : (t + s[d->samplenumber[t]].transpose);
  459. free (wh);
  460. wh = NULL;
  461. return 1;
  462. }
  463. BOOL
  464. UNI_Load (BOOL curious)
  465. {
  466. int t;
  467. char *modtype, *oldtype = NULL;
  468. INSTRUMENT *d;
  469. SAMPLE *q;
  470. /* read module header */
  471. _mm_read_UBYTES (mh.id, 4, modreader);
  472. if (mh.id[3] != 'N')
  473. universion = mh.id[3] - '0';
  474. else
  475. universion = 0x100;
  476. if (universion >= 6)
  477. {
  478. if (universion == 6)
  479. _mm_read_UBYTE (modreader);
  480. else
  481. universion = _mm_read_M_UWORD (modreader);
  482. mh.flags = _mm_read_M_UWORD (modreader);
  483. mh.numchn = _mm_read_UBYTE (modreader);
  484. mh.numvoices = _mm_read_UBYTE (modreader);
  485. mh.numpos = _mm_read_M_UWORD (modreader);
  486. mh.numpat = _mm_read_M_UWORD (modreader);
  487. mh.numtrk = _mm_read_M_UWORD (modreader);
  488. mh.numins = _mm_read_M_UWORD (modreader);
  489. mh.numsmp = _mm_read_M_UWORD (modreader);
  490. mh.reppos = _mm_read_M_UWORD (modreader);
  491. mh.initspeed = _mm_read_UBYTE (modreader);
  492. mh.inittempo = _mm_read_UBYTE (modreader);
  493. mh.initvolume = _mm_read_UBYTE (modreader);
  494. mh.flags &= (UF_XMPERIODS | UF_LINEAR | UF_INST | UF_NNA);
  495. }
  496. else
  497. {
  498. mh.numchn = _mm_read_UBYTE (modreader);
  499. mh.numpos = _mm_read_I_UWORD (modreader);
  500. mh.reppos = (universion == 5) ? _mm_read_I_UWORD (modreader) : 0;
  501. mh.numpat = _mm_read_I_UWORD (modreader);
  502. mh.numtrk = _mm_read_I_UWORD (modreader);
  503. mh.numins = _mm_read_I_UWORD (modreader);
  504. mh.initspeed = _mm_read_UBYTE (modreader);
  505. mh.inittempo = _mm_read_UBYTE (modreader);
  506. _mm_read_UBYTES (mh.positions, 256, modreader);
  507. _mm_read_UBYTES (mh.panning, 32, modreader);
  508. mh.flags = _mm_read_UBYTE (modreader);
  509. mh.flags &= (UF_XMPERIODS | UF_LINEAR);
  510. mh.flags |= UF_INST | UF_NOWRAP;
  511. }
  512. /* set module parameters */
  513. of.flags = mh.flags;
  514. of.numchn = mh.numchn;
  515. of.numpos = mh.numpos;
  516. of.numpat = mh.numpat;
  517. of.numtrk = mh.numtrk;
  518. of.numins = mh.numins;
  519. of.reppos = mh.reppos;
  520. of.initspeed = mh.initspeed;
  521. of.inittempo = mh.inittempo;
  522. of.songname = readstring ();
  523. if (universion < 0x102)
  524. oldtype = readstring ();
  525. if (oldtype)
  526. {
  527. int len = strlen (oldtype) + 20;
  528. if (!(modtype = _mm_malloc (len)))
  529. return 0;
  530. #ifdef HAVE_SNPRINTF
  531. snprintf (modtype, len, "%s (was %s)", (universion >= 0x100) ? "APlayer" : "MikCvt2", oldtype);
  532. #else
  533. sprintf (modtype, "%s (was %s)", (universion >= 0x100) ? "APlayer" : "MikCvt2", oldtype);
  534. #endif
  535. }
  536. else
  537. {
  538. if (!(modtype = _mm_malloc (10)))
  539. return 0;
  540. #ifdef HAVE_SNPRINTF
  541. snprintf (modtype, 10, "%s", (universion >= 0x100) ? "APlayer" : "MikCvt3");
  542. #else
  543. sprintf (modtype, "%s", (universion >= 0x100) ? "APlayer" : "MikCvt3");
  544. #endif
  545. }
  546. of.modtype = strdup (modtype);
  547. free (modtype);
  548. free (oldtype);
  549. of.comment = readstring ();
  550. if (universion >= 6)
  551. {
  552. of.numvoices = mh.numvoices;
  553. of.initvolume = mh.initvolume;
  554. }
  555. if (_mm_eof (modreader))
  556. {
  557. _mm_errno = MMERR_LOADING_HEADER;
  558. return 0;
  559. }
  560. /* positions */
  561. if (!AllocPositions (of.numpos))
  562. return 0;
  563. if (universion >= 6)
  564. {
  565. if (universion >= 0x100)
  566. _mm_read_M_UWORDS (of.positions, of.numpos, modreader);
  567. else
  568. for (t = 0; t < of.numpos; t++)
  569. of.positions[t] = _mm_read_UBYTE (modreader);
  570. _mm_read_M_UWORDS (of.panning, of.numchn, modreader);
  571. _mm_read_UBYTES (of.chanvol, of.numchn, modreader);
  572. }
  573. else
  574. {
  575. if ((mh.numpos > 256) || (mh.numchn > 32))
  576. {
  577. _mm_errno = MMERR_LOADING_HEADER;
  578. return 0;
  579. }
  580. for (t = 0; t < of.numpos; t++)
  581. of.positions[t] = mh.positions[t];
  582. for (t = 0; t < of.numchn; t++)
  583. of.panning[t] = mh.panning[t];
  584. }
  585. /* instruments and samples */
  586. if (universion >= 6)
  587. {
  588. of.numsmp = mh.numsmp;
  589. if (!AllocSamples ())
  590. return 0;
  591. if (!loadsmp6 ())
  592. return 0;
  593. if (of.flags & UF_INST)
  594. {
  595. if (!AllocInstruments ())
  596. return 0;
  597. if (!loadinstr6 ())
  598. return 0;
  599. }
  600. }
  601. else
  602. {
  603. if (!AllocInstruments ())
  604. return 0;
  605. if (!loadinstr5 ())
  606. return 0;
  607. if (!AllocSamples ())
  608. {
  609. if (wh)
  610. {
  611. free (wh);
  612. wh = NULL;
  613. }
  614. return 0;
  615. }
  616. if (!loadsmp5 ())
  617. return 0;
  618. /* check if the original file had no instruments */
  619. if (of.numsmp == of.numins)
  620. {
  621. for (t = 0, d = of.instruments; t < of.numins; t++, d++)
  622. {
  623. int u;
  624. if ((d->volpts) || (d->panpts) || (d->globvol != 64))
  625. break;
  626. for (u = 0; u < 96; u++)
  627. if ((d->samplenumber[u] != t) || (d->samplenote[u] != u))
  628. break;
  629. if (u != 96)
  630. break;
  631. }
  632. if (t == of.numins)
  633. {
  634. of.flags &= ~UF_INST;
  635. of.flags &= ~UF_NOWRAP;
  636. for (t = 0, d = of.instruments, q = of.samples; t < of.numins; t++, d++, q++)
  637. {
  638. q->samplename = d->insname;
  639. d->insname = NULL;
  640. }
  641. }
  642. }
  643. }
  644. /* patterns */
  645. if (!AllocPatterns ())
  646. return 0;
  647. if (universion >= 6)
  648. {
  649. _mm_read_M_UWORDS (of.pattrows, of.numpat, modreader);
  650. _mm_read_M_UWORDS (of.patterns, of.numpat * of.numchn, modreader);
  651. }
  652. else
  653. {
  654. _mm_read_I_UWORDS (of.pattrows, of.numpat, modreader);
  655. _mm_read_I_UWORDS (of.patterns, of.numpat * of.numchn, modreader);
  656. }
  657. /* tracks */
  658. if (!AllocTracks ())
  659. return 0;
  660. for (t = 0; t < of.numtrk; t++)
  661. if (!(of.tracks[t] = readtrack ()))
  662. {
  663. _mm_errno = MMERR_LOADING_TRACK;
  664. return 0;
  665. }
  666. return 1;
  667. }
  668. CHAR *
  669. UNI_LoadTitle (void)
  670. {
  671. UBYTE ver;
  672. int posit[3] =
  673. {304, 306, 26};
  674. _mm_fseek (modreader, 3, SEEK_SET);
  675. ver = _mm_read_UBYTE (modreader);
  676. if (ver == 'N')
  677. ver = '6';
  678. _mm_fseek (modreader, posit[ver - '4'], SEEK_SET);
  679. return readstring ();
  680. }
  681. /*========== Loader information */
  682. MLOADER load_uni =
  683. {
  684. NULL,
  685. "UNI",
  686. "APUN (APlayer) and UNI (MikMod)",
  687. UNI_Init,
  688. UNI_Test,
  689. UNI_Load,
  690. UNI_Cleanup,
  691. UNI_LoadTitle
  692. };
  693. /* ex:set ts=4: */