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

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