PageRenderTime 1064ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/lib/mikxbox/Source/loaders/load_uni.c

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