1 /*	MikMod sound library
2 	(c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
3 	AUTHORS for complete list.
4 
5 	This library is free software; you can redistribute it and/or modify
6 	it under the terms of the GNU Library General Public License as
7 	published by the Free Software Foundation; either version 2 of
8 	the License, or (at your option) any later version.
9 
10 	This program is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU Library General Public License for more details.
14 
15 	You should have received a copy of the GNU Library General Public
16 	License along with this library; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 	02111-1307, USA.
19 */
20 
21 /*==============================================================================
22 
23   $Id$
24 
25   Fasttracker (XM) module loader
26 
27 ==============================================================================*/
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 
37 #include <stdio.h>
38 #ifdef HAVE_MEMORY_H
39 #include <memory.h>
40 #endif
41 #include <string.h>
42 
43 #include "mikmod_internals.h"
44 
45 #ifdef SUNOS
46 extern int fprintf(FILE *, const char *, ...);
47 #endif
48 
49 /*========== Module structure */
50 
51 typedef struct XMHEADER {
52 	CHAR  id[17];          /* ID text: 'Extended module: ' */
53 	CHAR  songname[21];    /* Module name */
54 	CHAR  trackername[20]; /* Tracker name */
55 	UWORD version;         /* Version number */
56 	ULONG headersize;      /* Header size */
57 	UWORD songlength;      /* Song length (in patten order table) */
58 	UWORD restart;         /* Restart position */
59 	UWORD numchn;          /* Number of channels (2,4,6,8,10,...,32) */
60 	UWORD numpat;          /* Number of patterns (max 256) */
61 	UWORD numins;          /* Number of instruments (max 128) */
62 	UWORD flags;
63 	UWORD tempo;           /* Default tempo */
64 	UWORD bpm;             /* Default BPM */
65 	UBYTE orders[256];     /* Pattern order table  */
66 } XMHEADER;
67 
68 typedef struct XMINSTHEADER {
69 	ULONG size;     /* Instrument size */
70 	CHAR  name[22]; /* Instrument name */
71 	UBYTE type;     /* Instrument type (always 0) */
72 	UWORD numsmp;   /* Number of samples in instrument */
73 	ULONG ssize;
74 } XMINSTHEADER;
75 
76 #define XMENVCNT (12*2)
77 #define XMNOTECNT (8*OCTAVE)
78 typedef struct XMPATCHHEADER {
79 	UBYTE what[XMNOTECNT];  /*  Sample number for all notes */
80 	UWORD volenv[XMENVCNT]; /*  Points for volume envelope */
81 	UWORD panenv[XMENVCNT]; /*  Points for panning envelope */
82 	UBYTE volpts;      /*  Number of volume points */
83 	UBYTE panpts;      /*  Number of panning points */
84 	UBYTE volsus;      /*  Volume sustain point */
85 	UBYTE volbeg;      /*  Volume loop start point */
86 	UBYTE volend;      /*  Volume loop end point */
87 	UBYTE pansus;      /*  Panning sustain point */
88 	UBYTE panbeg;      /*  Panning loop start point */
89 	UBYTE panend;      /*  Panning loop end point */
90 	UBYTE volflg;      /*  Volume type: bit 0: On; 1: Sustain; 2: Loop */
91 	UBYTE panflg;      /*  Panning type: bit 0: On; 1: Sustain; 2: Loop */
92 	UBYTE vibflg;      /*  Vibrato type */
93 	UBYTE vibsweep;    /*  Vibrato sweep */
94 	UBYTE vibdepth;    /*  Vibrato depth */
95 	UBYTE vibrate;     /*  Vibrato rate */
96 	UWORD volfade;     /*  Volume fadeout */
97 } XMPATCHHEADER;
98 
99 typedef struct XMWAVHEADER {
100 	ULONG length;         /* Sample length */
101 	ULONG loopstart;      /* Sample loop start */
102 	ULONG looplength;     /* Sample loop length */
103 	UBYTE volume;         /* Volume  */
104 	SBYTE finetune;       /* Finetune (signed byte -128..+127) */
105 	UBYTE type;           /* Loop type */
106 	UBYTE panning;        /* Panning (0-255) */
107 	SBYTE relnote;        /* Relative note number (signed byte) */
108 	UBYTE reserved;
109 	CHAR  samplename[22]; /* Sample name */
110 	UBYTE vibtype;        /* Vibrato type */
111 	UBYTE vibsweep;       /* Vibrato sweep */
112 	UBYTE vibdepth;       /* Vibrato depth */
113 	UBYTE vibrate;        /* Vibrato rate */
114 } XMWAVHEADER;
115 
116 typedef struct XMPATHEADER {
117 	ULONG size;     /* Pattern header length  */
118 	UBYTE packing;  /* Packing type (always 0) */
119 	UWORD numrows;  /* Number of rows in pattern (1..256) */
120 	SWORD packsize; /* Packed patterndata size */
121 } XMPATHEADER;
122 
123 typedef struct XMNOTE {
124 	UBYTE note,ins,vol,eff,dat;
125 } XMNOTE;
126 
127 /*========== Loader variables */
128 
129 static	XMNOTE *xmpat=NULL;
130 static	XMHEADER *mh=NULL;
131 
132 /* increment unit for sample array reallocation */
133 #define XM_SMPINCR 64
134 static	ULONG *nextwav=NULL;
135 static	XMWAVHEADER *wh=NULL,*s=NULL;
136 
137 /*========== Loader code */
138 
XM_Test(void)139 static BOOL XM_Test(void)
140 {
141 	UBYTE id[38];
142 
143 	if(!_mm_read_UBYTES(id,38,modreader)) return 0;
144 	if(memcmp(id,"Extended Module: ",17)) return 0;
145 	if(id[37]==0x1a) return 1;
146 	return 0;
147 }
148 
XM_Init(void)149 static BOOL XM_Init(void)
150 {
151 	if(!(mh=(XMHEADER *)MikMod_malloc(sizeof(XMHEADER)))) return 0;
152 	return 1;
153 }
154 
XM_Cleanup(void)155 static void XM_Cleanup(void)
156 {
157 	MikMod_free(mh);
158 	mh=NULL;
159 }
160 
XM_ReadNote(XMNOTE * n)161 static int XM_ReadNote(XMNOTE* n)
162 {
163 	UBYTE cmp,result=1;
164 
165 	memset(n,0,sizeof(XMNOTE));
166 	cmp=_mm_read_UBYTE(modreader);
167 
168 	if(cmp&0x80) {
169 		if(cmp&1)  { result++;n->note = _mm_read_UBYTE(modreader); }
170 		if(cmp&2)  { result++;n->ins  = _mm_read_UBYTE(modreader); }
171 		if(cmp&4)  { result++;n->vol  = _mm_read_UBYTE(modreader); }
172 		if(cmp&8)  { result++;n->eff  = _mm_read_UBYTE(modreader); }
173 		if(cmp&16) { result++;n->dat  = _mm_read_UBYTE(modreader); }
174 	} else {
175 		n->note = cmp;
176 		n->ins  = _mm_read_UBYTE(modreader);
177 		n->vol  = _mm_read_UBYTE(modreader);
178 		n->eff  = _mm_read_UBYTE(modreader);
179 		n->dat  = _mm_read_UBYTE(modreader);
180 		result += 4;
181 	}
182 	return result;
183 }
184 
XM_Convert(XMNOTE * xmtrack,UWORD rows)185 static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows)
186 {
187 	int t;
188 	UBYTE note,ins,vol,eff,dat;
189 
190 	UniReset();
191 	for(t=0;t<rows;t++) {
192 		note = xmtrack->note;
193 		ins  = xmtrack->ins;
194 		vol  = xmtrack->vol;
195 		eff  = xmtrack->eff;
196 		dat  = xmtrack->dat;
197 
198 		if(note) {
199 			if(note>XMNOTECNT)
200 				UniEffect(UNI_KEYFADE,0);
201 			else
202 				UniNote(note-1);
203 		}
204 		if(ins) UniInstrument(ins-1);
205 
206 		switch(vol>>4) {
207 			case 0x6: /* volslide down */
208 				if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol&0xf);
209 				break;
210 			case 0x7: /* volslide up */
211 				if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol<<4);
212 				break;
213 
214 				/* volume-row fine volume slide is compatible with protracker
215 				   EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as
216 				   opposed to 'take the last sliding value'. */
217 			case 0x8: /* finevol down */
218 				UniPTEffect(0xe,0xb0|(vol&0xf));
219 				break;
220 			case 0x9: /* finevol up */
221 				UniPTEffect(0xe,0xa0|(vol&0xf));
222 				break;
223 			case 0xa: /* set vibrato speed */
224 				UniEffect(UNI_XMEFFECT4,vol<<4);
225 				break;
226 			case 0xb: /* vibrato */
227 				UniEffect(UNI_XMEFFECT4,vol&0xf);
228 				break;
229 			case 0xc: /* set panning */
230 				UniPTEffect(0x8,vol<<4);
231 				break;
232 			case 0xd: /* panning slide left (only slide when data not zero) */
233 				if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol&0xf);
234 				break;
235 			case 0xe: /* panning slide right (only slide when data not zero) */
236 				if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol<<4);
237 				break;
238 			case 0xf: /* tone porta */
239 				UniPTEffect(0x3,vol<<4);
240 				break;
241 			default:
242 				if((vol>=0x10)&&(vol<=0x50))
243 					UniPTEffect(0xc,vol-0x10);
244 		}
245 
246 		switch(eff) {
247 			case 0x4:
248 				UniEffect(UNI_XMEFFECT4,dat);
249 				break;
250 			case 0x6:
251 				UniEffect(UNI_XMEFFECT6,dat);
252 				break;
253 			case 0xa:
254 				UniEffect(UNI_XMEFFECTA,dat);
255 				break;
256 			case 0xe: /* Extended effects */
257 				switch(dat>>4) {
258 					case 0x1: /* XM fine porta up */
259 						UniEffect(UNI_XMEFFECTE1,dat&0xf);
260 						break;
261 					case 0x2: /* XM fine porta down */
262 						UniEffect(UNI_XMEFFECTE2,dat&0xf);
263 						break;
264 					case 0xa: /* XM fine volume up */
265 						UniEffect(UNI_XMEFFECTEA,dat&0xf);
266 						break;
267 					case 0xb: /* XM fine volume down */
268 						UniEffect(UNI_XMEFFECTEB,dat&0xf);
269 						break;
270 					default:
271 						UniPTEffect(eff,dat);
272 				}
273 				break;
274 			case 'G'-55: /* G - set global volume */
275 				UniEffect(UNI_XMEFFECTG,dat>64?128:dat<<1);
276 				break;
277 			case 'H'-55: /* H - global volume slide */
278 				UniEffect(UNI_XMEFFECTH,dat);
279 				break;
280 			case 'K'-55: /* K - keyOff and KeyFade */
281 				UniEffect(UNI_KEYFADE,dat);
282 				break;
283 			case 'L'-55: /* L - set envelope position */
284 				UniEffect(UNI_XMEFFECTL,dat);
285 				break;
286 			case 'P'-55: /* P - panning slide */
287 				UniEffect(UNI_XMEFFECTP,dat);
288 				break;
289 			case 'R'-55: /* R - multi retrig note */
290 				UniEffect(UNI_S3MEFFECTQ,dat);
291 				break;
292 			case 'T'-55: /* T - Tremor */
293 				UniEffect(UNI_S3MEFFECTI,dat);
294 				break;
295 			case 'X'-55:
296 				switch(dat>>4) {
297 					case 1: /* X1 - Extra Fine Porta up */
298 						UniEffect(UNI_XMEFFECTX1,dat&0xf);
299 						break;
300 					case 2: /* X2 - Extra Fine Porta down */
301 						UniEffect(UNI_XMEFFECTX2,dat&0xf);
302 						break;
303 				}
304 				break;
305 			default:
306 				if(eff<=0xf) {
307 					/* the pattern jump destination is written in decimal,
308 					   but it seems some poor tracker software writes them
309 					   in hexadecimal... (sigh) */
310 					if (eff==0xd)
311 						/* don't change anything if we're sure it's in hexa */
312 						if ((((dat&0xf0)>>4)<=9)&&((dat&0xf)<=9))
313 							/* otherwise, convert from dec to hex */
314 							dat=(((dat&0xf0)>>4)*10)+(dat&0xf);
315 					UniPTEffect(eff,dat);
316 				}
317 				break;
318 		}
319 		UniNewline();
320 		xmtrack++;
321 	}
322 	return UniDup();
323 }
324 
LoadPatterns(BOOL dummypat)325 static BOOL LoadPatterns(BOOL dummypat)
326 {
327 	int t,u,v,numtrk;
328 
329 	if(!AllocTracks()) return 0;
330 	if(!AllocPatterns()) return 0;
331 
332 	numtrk=0;
333 	for(t=0;t<mh->numpat;t++) {
334 		XMPATHEADER ph;
335 
336 		ph.size     =_mm_read_I_ULONG(modreader);
337 		if (ph.size<(mh->version==0x0102?8:9)) {
338 			_mm_errno=MMERR_LOADING_PATTERN;
339 			return 0;
340 		}
341 		ph.packing  =_mm_read_UBYTE(modreader);
342 		if(ph.packing) {
343 			_mm_errno=MMERR_LOADING_PATTERN;
344 			return 0;
345 		}
346 		if(mh->version==0x0102)
347 			ph.numrows  =_mm_read_UBYTE(modreader)+1;
348 		else
349 			ph.numrows  =_mm_read_I_UWORD(modreader);
350 		ph.packsize =_mm_read_I_UWORD(modreader);
351 
352 		ph.size-=(mh->version==0x0102?8:9);
353 		if(ph.size)
354 			_mm_fseek(modreader,ph.size,SEEK_CUR);
355 
356 		of.pattrows[t]=ph.numrows;
357 
358 		if(ph.numrows) {
359 			if(!(xmpat=(XMNOTE*)MikMod_calloc(ph.numrows*of.numchn,sizeof(XMNOTE))))
360 				return 0;
361 
362 			/* when packsize is 0, don't try to load a pattern.. it's empty. */
363 			if(ph.packsize)
364 				for(u=0;u<ph.numrows;u++)
365 					for(v=0;v<of.numchn;v++) {
366 						if(!ph.packsize) break;
367 
368 						ph.packsize-=XM_ReadNote(&xmpat[(v*ph.numrows)+u]);
369 						if(ph.packsize<0) {
370 							MikMod_free(xmpat);xmpat=NULL;
371 							_mm_errno=MMERR_LOADING_PATTERN;
372 							return 0;
373 						}
374 					}
375 
376 			if(ph.packsize) {
377 				_mm_fseek(modreader,ph.packsize,SEEK_CUR);
378 			}
379 
380 			if(_mm_eof(modreader)) {
381 				MikMod_free(xmpat);xmpat=NULL;
382 				_mm_errno=MMERR_LOADING_PATTERN;
383 				return 0;
384 			}
385 
386 			for(v=0;v<of.numchn;v++)
387 				of.tracks[numtrk++]=XM_Convert(&xmpat[v*ph.numrows],ph.numrows);
388 
389 			MikMod_free(xmpat);xmpat=NULL;
390 		} else {
391 			for(v=0;v<of.numchn;v++)
392 				of.tracks[numtrk++]=XM_Convert(NULL,ph.numrows);
393 		}
394 	}
395 
396 	if(dummypat) {
397 		of.pattrows[t]=64;
398 		if(!(xmpat=(XMNOTE*)MikMod_calloc(64*of.numchn,sizeof(XMNOTE)))) return 0;
399 		for(v=0;v<of.numchn;v++)
400 			of.tracks[numtrk++]=XM_Convert(&xmpat[v*64],64);
401 		MikMod_free(xmpat);xmpat=NULL;
402 	}
403 
404 	return 1;
405 }
406 
FixEnvelope(ENVPT * cur,int pts)407 static void FixEnvelope(ENVPT *cur, int pts)
408 {
409 		int u, old, tmp;
410 		ENVPT *prev;
411 
412 		/* Some broken XM editing program will only save the low byte
413 		   of the position value. Try to compensate by adding the
414 		   missing high byte. */
415 
416 		prev = cur++;
417 		old = prev->pos;
418 
419 		for (u = 1; u < pts; u++, prev++, cur++) {
420 			if (cur->pos < prev->pos) {
421 				if (cur->pos < 0x100) {
422 					if (cur->pos > old)	/* same hex century */
423 							tmp = cur->pos + (prev->pos - old);
424 					else
425 							tmp = cur->pos | ((prev->pos + 0x100) & 0xff00);
426 					old = cur->pos;
427 					cur->pos = tmp;
428 #ifdef MIKMOD_DEBUG
429 					fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d -> %d\n",
430 					    u, pts, prev->pos, old, cur->pos);
431 #endif
432 				} else {
433 #ifdef MIKMOD_DEBUG
434 					/* different brokenness style... fix unknown */
435 					fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d\n",
436 					    u, pts, old, cur->pos);
437 #endif
438 					old = cur->pos;
439 				}
440 			} else
441 				old = cur->pos;
442 		}
443 }
444 
LoadInstruments(void)445 static BOOL LoadInstruments(void)
446 {
447 	long filend,ck;
448 	int t,u;
449 	INSTRUMENT *d;
450 	ULONG next=0;
451 	UWORD wavcnt=0;
452 
453 	ck = _mm_ftell(modreader);
454 	_mm_fseek(modreader,0,SEEK_END);
455 	filend = _mm_ftell(modreader);
456 	_mm_fseek(modreader,ck,SEEK_SET);
457 
458 	if(!AllocInstruments()) return 0;
459 	d=of.instruments;
460 	for(t=0;t<of.numins;t++,d++) {
461 		XMINSTHEADER ih;
462 		long headend;
463 
464 		memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
465 
466 		/* read instrument header */
467 		headend     = _mm_ftell(modreader);
468 		ih.size     = _mm_read_I_ULONG(modreader);
469 		headend    += ih.size;
470 		ck = _mm_ftell(modreader);
471 		if ((headend<0) || (filend<headend) || (headend<ck)) {
472 			break;
473 		}
474 		_mm_read_string(ih.name, 22, modreader);
475 		ih.type     = _mm_read_UBYTE(modreader);
476 		ih.numsmp   = _mm_read_I_UWORD(modreader);
477 
478 		d->insname  = DupStr(ih.name,22,1);
479 
480 		if((SWORD)ih.size>29) {
481 			ih.ssize    = _mm_read_I_ULONG(modreader);
482 			if(((SWORD)ih.numsmp>0)&&(ih.numsmp<=XMNOTECNT)) {
483 				XMPATCHHEADER pth;
484 				int p;
485 
486 				_mm_read_UBYTES (pth.what,XMNOTECNT,modreader);
487 				_mm_read_I_UWORDS (pth.volenv, XMENVCNT, modreader);
488 				_mm_read_I_UWORDS (pth.panenv, XMENVCNT, modreader);
489 				pth.volpts      =  _mm_read_UBYTE(modreader);
490 				pth.panpts      =  _mm_read_UBYTE(modreader);
491 				pth.volsus      =  _mm_read_UBYTE(modreader);
492 				pth.volbeg      =  _mm_read_UBYTE(modreader);
493 				pth.volend      =  _mm_read_UBYTE(modreader);
494 				pth.pansus      =  _mm_read_UBYTE(modreader);
495 				pth.panbeg      =  _mm_read_UBYTE(modreader);
496 				pth.panend      =  _mm_read_UBYTE(modreader);
497 				pth.volflg      =  _mm_read_UBYTE(modreader);
498 				pth.panflg      =  _mm_read_UBYTE(modreader);
499 				pth.vibflg      =  _mm_read_UBYTE(modreader);
500 				pth.vibsweep    =  _mm_read_UBYTE(modreader);
501 				pth.vibdepth    =  _mm_read_UBYTE(modreader);
502 				pth.vibrate     =  _mm_read_UBYTE(modreader);
503 				pth.volfade     =  _mm_read_I_UWORD(modreader);
504 
505 				/* read the remainder of the header
506 				   (2 bytes for 1.03, 22 for 1.04) */
507 				if (headend>=_mm_ftell(modreader)) {
508 					for(u=headend-_mm_ftell(modreader);u;u--) {
509 						_mm_skip_BYTE(modreader);
510 					}
511 				}
512 
513 				/* we can't trust the envelope point count here, as some
514 				   modules have incorrect values (K_OSPACE.XM reports 32 volume
515 				   points, for example). */
516 				if(pth.volpts>XMENVCNT/2) pth.volpts=XMENVCNT/2;
517 				if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;
518 
519 				if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {
520 					MikMod_free(nextwav);nextwav=NULL;
521 					MikMod_free(wh);wh=NULL;
522 					_mm_errno = MMERR_LOADING_SAMPLEINFO;
523 					return 0;
524 				}
525 
526 				for(u=0;u<XMNOTECNT;u++)
527 					d->samplenumber[u]=pth.what[u]+of.numsmp;
528 				d->volfade = pth.volfade;
529 
530 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
531 #define XM_ProcessEnvelope(name) 										\
532 				for (u = 0; u < (XMENVCNT >> 1); u++) {					\
533 					d-> name##env[u].pos = pth. name##env[u << 1];		\
534 					d-> name##env[u].val = pth. name##env[(u << 1)+ 1];	\
535 				}														\
536 				if (pth. name##flg&1) d-> name##flg|=EF_ON;				\
537 				if (pth. name##flg&2) d-> name##flg|=EF_SUSTAIN;		\
538 				if (pth. name##flg&4) d-> name##flg|=EF_LOOP;			\
539 				d-> name##susbeg=d-> name##susend=pth. name##sus;		\
540 				d-> name##beg=pth. name##beg;							\
541 				d-> name##end=pth. name##end;							\
542 				d-> name##pts=pth. name##pts;							\
543 																		\
544 				/* scale envelope */									\
545 				for (p=0;p<XMENVCNT/2;p++)								\
546 					d-> name##env[p].val<<=2;							\
547 																		\
548 				if ((d-> name##flg&EF_ON)&&(d-> name##pts<2))			\
549 					d-> name##flg&=~EF_ON
550 #else
551 #define XM_ProcessEnvelope(name) 											\
552 				for (u = 0; u < (XMENVCNT >> 1); u++) {						\
553 					d-> name/**/env[u].pos = pth. name/**/env[u << 1];		\
554 					d-> name/**/env[u].val = pth. name/**/env[(u << 1)+ 1];	\
555 				}															\
556 				if (pth. name/**/flg&1) d-> name/**/flg|=EF_ON;				\
557 				if (pth. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN;		\
558 				if (pth. name/**/flg&4) d-> name/**/flg|=EF_LOOP;			\
559 				d-> name/**/susbeg=d-> name/**/susend=						\
560 				                      pth. name/**/sus;						\
561 				d-> name/**/beg=pth. name/**/beg;							\
562 				d-> name/**/end=pth. name/**/end;							\
563 				d-> name/**/pts=pth. name/**/pts;							\
564 																			\
565 				/* scale envelope */										\
566 				for (p=0;p<XMENVCNT/2;p++)									\
567 					d-> name/**/env[p].val<<=2;								\
568 																			\
569 				if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2))			\
570 					d-> name/**/flg&=~EF_ON
571 #endif
572 
573 				XM_ProcessEnvelope(vol);
574 				XM_ProcessEnvelope(pan);
575 #undef XM_ProcessEnvelope
576 
577 				if (d->volflg & EF_ON)
578 					FixEnvelope(d->volenv, d->volpts);
579 				if (d->panflg & EF_ON)
580 					FixEnvelope(d->panenv, d->panpts);
581 
582 				/* Samples are stored outside the instrument struct now, so we
583 				   have to load them all into a temp area, count the of.numsmp
584 				   along the way and then do an AllocSamples() and move
585 				   everything over */
586 				if(mh->version>0x0103) next = 0;
587 				for(u=0;u<ih.numsmp;u++,s++) {
588 					/* XM sample header is 40 bytes: make sure we won't hit EOF */
589 					/* Note: last instrument is at the end of file in version 0x0104 */
590 					if(_mm_ftell(modreader)+40>filend) {
591 						MikMod_free(nextwav);MikMod_free(wh);
592 						nextwav=NULL;wh=NULL;
593 						_mm_errno = MMERR_LOADING_SAMPLEINFO;
594 						return 0;
595 					}
596 					/* Allocate more room for sample information if necessary */
597 					if(of.numsmp+u==wavcnt) {
598 						wavcnt+=XM_SMPINCR;
599 						if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
600 							MikMod_free(wh);wh=NULL;
601 							_mm_errno = MMERR_OUT_OF_MEMORY;
602 							return 0;
603 						}
604 						if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
605 							MikMod_free(nextwav);nextwav=NULL;
606 							_mm_errno = MMERR_OUT_OF_MEMORY;
607 							return 0;
608 						}
609 						s=wh+(wavcnt-XM_SMPINCR);
610 					}
611 
612 					s->length       =_mm_read_I_ULONG (modreader);
613 					s->loopstart    =_mm_read_I_ULONG (modreader);
614 					s->looplength   =_mm_read_I_ULONG (modreader);
615 					s->volume       =_mm_read_UBYTE (modreader);
616 					s->finetune     =_mm_read_SBYTE (modreader);
617 					s->type         =_mm_read_UBYTE (modreader);
618 					s->panning      =_mm_read_UBYTE (modreader);
619 					s->relnote      =_mm_read_SBYTE (modreader);
620 					s->vibtype      = pth.vibflg;
621 					s->vibsweep     = pth.vibsweep;
622 					s->vibdepth     = pth.vibdepth*4;
623 					s->vibrate      = pth.vibrate;
624 					s->reserved     =_mm_read_UBYTE (modreader);
625 					_mm_read_string(s->samplename, 22, modreader);
626 
627 					nextwav[of.numsmp+u]=next;
628 					next+=s->length;
629 				}
630 
631 				if(mh->version>0x0103) {
632 					for(u=0;u<ih.numsmp;u++)
633 						nextwav[of.numsmp++]+=_mm_ftell(modreader);
634 					_mm_fseek(modreader,next,SEEK_CUR);
635 				} else
636 					of.numsmp+=ih.numsmp;
637 			} else {
638 				/* read the remainder of the header */
639 				ck = _mm_ftell(modreader);
640 				if ((headend<0) || (filend<headend) || (headend<ck)) {
641 					break;
642 				}
643 				for(u=headend-_mm_ftell(modreader);u;u--) {
644 					_mm_skip_BYTE(modreader);
645 				}
646 
647 				/* last instrument is at the end of file in version 0x0104 */
648 				if(_mm_eof(modreader) && (mh->version<0x0104 || t<of.numins-1)) {
649 					MikMod_free(nextwav);MikMod_free(wh);
650 					nextwav=NULL;wh=NULL;
651 					_mm_errno = MMERR_LOADING_SAMPLEINFO;
652 					return 0;
653 				}
654 			}
655 		}
656 	}
657 
658 	/* sanity check */
659 	if(!of.numsmp) {
660 		MikMod_free(nextwav);nextwav=NULL;
661 		MikMod_free(wh);wh=NULL;
662 		_mm_errno = MMERR_LOADING_SAMPLEINFO;
663 		return 0;
664 	}
665 
666 	return 1;
667 }
668 
XM_Load(BOOL curious)669 static BOOL XM_Load(BOOL curious)
670 {
671 	INSTRUMENT *d;
672 	SAMPLE *q;
673 	int t,u;
674 	BOOL dummypat=0;
675 	char tracker[21],modtype[60];
676 
677 	/* try to read module header */
678 	_mm_read_string(mh->id,17,modreader);
679 	_mm_read_string(mh->songname,21,modreader);
680 	_mm_read_string(mh->trackername,20,modreader);
681 	mh->version     =_mm_read_I_UWORD(modreader);
682 	if(mh->version < 0x102 || mh->version > 0x104)
683 		goto bad_xm;
684 	mh->headersize  =_mm_read_I_ULONG(modreader);
685 	mh->songlength  =_mm_read_I_UWORD(modreader);
686 	mh->restart     =_mm_read_I_UWORD(modreader);
687 	mh->numchn      =_mm_read_I_UWORD(modreader);
688 	mh->numpat      =_mm_read_I_UWORD(modreader);
689 	mh->numins      =_mm_read_I_UWORD(modreader);
690 	mh->flags       =_mm_read_I_UWORD(modreader);
691 	mh->tempo       =_mm_read_I_UWORD(modreader);
692 	mh->bpm         =_mm_read_I_UWORD(modreader);
693 	if(mh->numchn > 64) goto bad_xm;
694 	if(mh->tempo > 32 || mh->bpm < 32 || mh->bpm > 255)
695 		goto bad_xm;
696 	if(mh->songlength > 256 || mh->headersize < 20 || mh->headersize > 20+256)
697 		goto bad_xm;
698 	if(mh->numpat > 256 || mh->numins > 255 || mh->restart > 255)
699 		goto bad_xm;
700 /*	_mm_read_UBYTES(mh->orders,256,modreader);*/
701 /*	_mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);*/
702 	_mm_read_UBYTES(mh->orders,mh->songlength,modreader);
703 	if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) || _mm_eof(modreader))
704 		goto bad_hdr;
705 
706 	/* set module variables */
707 	of.initspeed = mh->tempo;
708 	of.inittempo = mh->bpm;
709 	strncpy(tracker,mh->trackername,20);tracker[20]=0;
710 	for(t=20;(t>=0)&&(tracker[t]<=' ');t--) tracker[t]=0;
711 
712 	/* some modules have the tracker name empty */
713 	if (!tracker[0])
714 		strcpy(tracker,"Unknown tracker");
715 
716 #ifdef HAVE_SNPRINTF
717 	snprintf(modtype,60,"%s (XM format %d.%02d)",
718 	                    tracker,mh->version>>8,mh->version&0xff);
719 #else
720 	sprintf(modtype,"%s (XM format %d.%02d)",
721 	                tracker,mh->version>>8,mh->version&0xff);
722 #endif
723 	of.modtype   = MikMod_strdup(modtype);
724 	of.numchn    = mh->numchn;
725 	of.numpat    = mh->numpat;
726 	of.numtrk    = (UWORD)of.numpat*of.numchn;   /* get number of channels */
727 	of.songname  = DupStr(mh->songname,20,1);
728 	of.numpos    = mh->songlength;               /* copy the songlength */
729 	of.reppos    = mh->restart<mh->songlength?mh->restart:0;
730 	of.numins    = mh->numins;
731 	of.flags    |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | UF_PANNING;
732 	if(mh->flags&1) of.flags |= UF_LINEAR;
733 	of.bpmlimit  = 32;
734 
735 	memset(of.chanvol,64,of.numchn);             /* store channel volumes */
736 
737 	if(!AllocPositions(of.numpos+1)) return 0;
738 	for(t=0;t<of.numpos;t++)
739 		of.positions[t]=mh->orders[t];
740 
741 	/* We have to check for any pattern numbers in the order list greater than
742 	   the number of patterns total. If one or more is found, we set it equal to
743 	   the pattern total and make a dummy pattern to workaround the problem */
744 	for(t=0;t<of.numpos;t++) {
745 		if(of.positions[t]>=of.numpat) {
746 			of.positions[t]=of.numpat;
747 			dummypat=1;
748 		}
749 	}
750 	if(dummypat) {
751 		of.numpat++;of.numtrk+=of.numchn;
752 	}
753 
754 	if(mh->version<0x0104) {
755 		if(!LoadInstruments()) return 0;
756 		if(!LoadPatterns(dummypat)) return 0;
757 		for(t=0;t<of.numsmp;t++)
758 			nextwav[t]+=_mm_ftell(modreader);
759 	} else {
760 		if(!LoadPatterns(dummypat)) return 0;
761 		if(!LoadInstruments()) return 0;
762 	}
763 
764 	if(!AllocSamples()) {
765 		MikMod_free(nextwav);MikMod_free(wh);
766 		nextwav=NULL;wh=NULL;
767 		return 0;
768 	}
769 	q = of.samples;
770 	s = wh;
771 	for(u=0;u<of.numsmp;u++,q++,s++) {
772 		q->samplename   = DupStr(s->samplename,22,1);
773 		q->length       = s->length;
774 		q->loopstart    = s->loopstart;
775 		q->loopend      = s->loopstart+s->looplength;
776 		q->volume       = s->volume;
777 		q->speed        = s->finetune+128;
778 		q->panning      = s->panning;
779 		q->seekpos      = nextwav[u];
780 		q->vibtype      = s->vibtype;
781 		q->vibsweep     = s->vibsweep;
782 		q->vibdepth     = s->vibdepth;
783 		q->vibrate      = s->vibrate;
784 
785 		if(s->type & 0x10) {
786 			q->length    >>= 1;
787 			q->loopstart >>= 1;
788 			q->loopend   >>= 1;
789 		}
790 
791 		q->flags|=SF_OWNPAN|SF_DELTA|SF_SIGNED;
792 		if(s->type&0x3) q->flags|=SF_LOOP;
793 		if(s->type&0x2) q->flags|=SF_BIDI;
794 		if(s->type&0x10) q->flags|=SF_16BITS;
795 	}
796 
797 	d=of.instruments;
798 	s=wh;
799 	for(u=0;u<of.numins;u++,d++)
800 		for(t=0;t<XMNOTECNT;t++) {
801 			if (d->samplenumber[t]>=of.numsmp)
802 				d->samplenote[t]=255;
803 			else {
804 				int note=t+s[d->samplenumber[t]].relnote;
805 				d->samplenote[t]=(note<0)?0:note;
806 			}
807 		}
808 
809 	MikMod_free(wh);MikMod_free(nextwav);
810 	wh=NULL;nextwav=NULL;
811 	return 1;
812 
813 bad_hdr: _mm_errno = MMERR_LOADING_HEADER;	return 0;
814 bad_xm:  _mm_errno = MMERR_NOT_A_MODULE;	return 0;
815 }
816 
XM_LoadTitle(void)817 static CHAR *XM_LoadTitle(void)
818 {
819 	CHAR str[21];
820 
821 	_mm_fseek(modreader,17,SEEK_SET);
822 	if(!_mm_read_UBYTES(str, 21, modreader)) return NULL;
823 
824 	return(DupStr(str,21,1));
825 }
826 
827 /*========== Loader information */
828 
829 MIKMODAPI MLOADER load_xm={
830 	NULL,
831 	"XM",
832 	"XM (FastTracker 2)",
833 	XM_Init,
834 	XM_Test,
835 	XM_Load,
836 	XM_Cleanup,
837 	XM_LoadTitle
838 };
839 
840 /* ex:set ts=4: */
841