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   15 instrument MOD loader
26   Also supports Ultimate Sound Tracker (old M15 format)
27 
28 ==============================================================================*/
29 
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 
38 #include <stdio.h>
39 #ifdef HAVE_MEMORY_H
40 #include <memory.h>
41 #endif
42 #include <string.h>
43 
44 #include "mikmod_internals.h"
45 #include "mikmod_ctype.h"
46 
47 #ifdef SUNOS
48 extern int fprintf(FILE *, const char *, ...);
49 #endif
50 
51 /*========== Module Structure */
52 
53 typedef struct MSAMPINFO {
54 	CHAR  samplename[23];	/* 22 in module, 23 in memory */
55 	UWORD length;
56 	UBYTE finetune;
57 	UBYTE volume;
58 	UWORD reppos;
59 	UWORD replen;
60 } MSAMPINFO;
61 
62 typedef struct MODULEHEADER {
63 	CHAR      songname[21];		/* the songname.., 20 in module, 21 in memory */
64 	MSAMPINFO samples[15];		/* all sampleinfo */
65 	UBYTE     songlength;		/* number of patterns used */
66 	UBYTE     magic1;       	/* should be 127 */
67 	UBYTE     positions[128];	/* which pattern to play at pos */
68 } MODULEHEADER;
69 
70 typedef struct MODNOTE {
71 	UBYTE a,b,c,d;
72 } MODNOTE;
73 
74 /*========== Loader variables */
75 
76 static MODULEHEADER *mh = NULL;
77 static MODNOTE *patbuf = NULL;
78 static BOOL ust_loader = 0;		/* if TRUE, load as an ust module. */
79 
80 /* known file formats which can confuse the loader */
81 #define REJECT 2
82 static const char *signatures[REJECT]={
83 	"CAKEWALK",	/* cakewalk midi files */
84 	"SZDD"		/* Microsoft compressed files */
85 };
86 static const int siglen[REJECT]={8,4};
87 
88 /*========== Loader code */
89 
LoadModuleHeader(MODULEHEADER * h)90 static BOOL LoadModuleHeader(MODULEHEADER *h)
91 {
92 	int t,u;
93 
94 	_mm_read_string(h->songname,20,modreader);
95 	h->songname[20]=0;	/* just in case */
96 
97 	/* sanity check : title should contain printable characters and a bunch
98 	   of null chars */
99 	for(t=0;t<20;t++)
100 		if((h->songname[t])&&(h->songname[t]<32)) return 0;
101 	for(t=0;(h->songname[t])&&(t<20);t++);
102 	if(t<20) for(;t<20;t++) if(h->songname[t]) return 0;
103 
104 	for(t=0;t<15;t++) {
105 		MSAMPINFO *s=&h->samples[t];
106 
107 		_mm_read_string(s->samplename,22,modreader);
108 		s->samplename[22]=0;	/* just in case */
109 		s->length   =_mm_read_M_UWORD(modreader);
110 		s->finetune =_mm_read_UBYTE(modreader);
111 		s->volume   =_mm_read_UBYTE(modreader);
112 		s->reppos   =_mm_read_M_UWORD(modreader);
113 		s->replen   =_mm_read_M_UWORD(modreader);
114 
115 		/* sanity check : sample title should contain printable characters and
116 		   a bunch of null chars */
117 		for(u=0;u<20;u++)
118 			if((s->samplename[u])&&(s->samplename[u]</*32*/14)) return 0;
119 		for(u=0;(s->samplename[u])&&(u<20);u++);
120 		if(u<20) for(;u<20;u++) if(s->samplename[u]) return 0;
121 
122 		/* sanity check : finetune values */
123 		if(s->finetune>>4) return 0;
124 	}
125 
126 	h->songlength  =_mm_read_UBYTE(modreader);
127 	h->magic1      =_mm_read_UBYTE(modreader);	/* should be 127 */
128 
129 	/* sanity check : no more than 128 positions, restart position in range */
130 	if((!h->songlength)||(h->songlength>128)) return 0;
131 	/* values encountered so far are 0x6a and 0x78 */
132 	if(((h->magic1&0xf8)!=0x78)&&(h->magic1!=0x6a)&&(h->magic1>h->songlength)) return 0;
133 
134 	_mm_read_UBYTES(h->positions,128,modreader);
135 
136 	/* sanity check : pattern range is 0..63 */
137 	for(t=0;t<128;t++)
138 		if(h->positions[t]>63) return 0;
139 
140 	return(!_mm_eof(modreader));
141 }
142 
143 /* Checks the patterns in the modfile for UST / 15-inst indications.
144    For example, if an effect 3xx is found, it is assumed that the song
145    is 15-inst.  If a 1xx effect has dat greater than 0x20, it is UST.
146 
147    Returns:  0 indecisive; 1 = UST; 2 = 15-inst                               */
CheckPatternType(int numpat)148 static int CheckPatternType(int numpat)
149 {
150 	int t;
151 	UBYTE eff, dat;
152 
153 	for(t=0;t<numpat*(64U*4);t++) {
154 		/* Load the pattern into the temp buffer and scan it */
155 		_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);
156 		eff = _mm_read_UBYTE(modreader);
157 		dat = _mm_read_UBYTE(modreader);
158 
159 		switch(eff) {
160 			case 1:
161 				if(dat>0x1f) return 1;
162 				if(dat<0x3)  return 2;
163 				break;
164 			case 2:
165 				if(dat>0x1f) return 1;
166 				return 2;
167 			case 3:
168 				if (dat) return 2;
169 				break;
170 			default:
171 				return 2;
172 		}
173 	}
174 	return 0;
175 }
176 
M15_Test(void)177 static BOOL M15_Test(void)
178 {
179 	int t, numpat;
180 	MODULEHEADER h;
181 
182 	ust_loader = 0;
183 	if(!LoadModuleHeader(&h)) return 0;
184 
185 	/* reject other file types */
186 	for(t=0;t<REJECT;t++)
187 		if(!memcmp(h.songname,signatures[t],siglen[t])) return 0;
188 
189 	if(h.magic1>127) return 0;
190 	if((!h.songlength)||(h.songlength>h.magic1)) return 0;
191 
192 	for(t=0;t<15;t++) {
193 		/* all finetunes should be zero */
194 		if(h.samples[t].finetune) return 0;
195 
196 		/* all volumes should be <= 64 */
197 		if(h.samples[t].volume>64) return 0;
198 
199 		/* all instrument names should begin with s, st-, or a number */
200 		if((h.samples[t].samplename[0]=='s')||
201 		   (h.samples[t].samplename[0]=='S')) {
202 			if((memcmp(h.samples[t].samplename,"st-",3)) &&
203 			   (memcmp(h.samples[t].samplename,"ST-",3)) &&
204 			   (*h.samples[t].samplename))
205 				ust_loader = 1;
206 		} else
207 		  if(!mik_isdigit((int)h.samples[t].samplename[0]))
208 				ust_loader = 1;
209 
210 		if(h.samples[t].length>4999||h.samples[t].reppos>9999) {
211 			ust_loader = 0;
212 			if(h.samples[t].length>32768) return 0;
213 		}
214 
215 		/* if loop information is incorrect as words, but correct as bytes,
216 		   this is likely to be an ust-style module */
217 		if((h.samples[t].reppos+h.samples[t].replen>h.samples[t].length)&&
218 		   (h.samples[t].reppos+h.samples[t].replen<(h.samples[t].length<<1))) {
219 			ust_loader = 1;
220 			return 1;
221 		}
222 
223 		if(!ust_loader) return 1;
224 	}
225 
226 	for(numpat=0,t=0;t<h.songlength;t++)
227 		if(h.positions[t]>numpat)
228 			numpat = h.positions[t];
229 	numpat++;
230 	switch(CheckPatternType(numpat)) {
231 		case 0:   /* indecisive, so check more clues... */
232 			break;
233 		case 1:
234 			ust_loader = 1;
235 			break;
236 		case 2:
237 			ust_loader = 0;
238 			break;
239 	}
240 	return 1;
241 }
242 
M15_Init(void)243 static BOOL M15_Init(void)
244 {
245 	if(!(mh=(MODULEHEADER*)MikMod_malloc(sizeof(MODULEHEADER)))) return 0;
246 	return 1;
247 }
248 
M15_Cleanup(void)249 static void M15_Cleanup(void)
250 {
251 	MikMod_free(mh);
252 	MikMod_free(patbuf);
253 	mh=NULL;
254 	patbuf=NULL;
255 }
256 
257 /*
258 Old (amiga) noteinfo:
259 
260  _____byte 1_____   byte2_    _____byte 3_____   byte4_
261 /                \ /      \  /                \ /      \
262 0000          0000-00000000  0000          0000-00000000
263 
264 Upper four    12 bits for    Lower four    Effect command.
265 bits of sam-  note period.   bits of sam-
266 ple number.                  ple number.
267 */
268 
M15_ConvertNote(MODNOTE * n,UBYTE lasteffect)269 static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect)
270 {
271 	UBYTE instrument,effect,effdat,note;
272 	UWORD period;
273 	UBYTE lastnote=0;
274 
275 	/* decode the 4 bytes that make up a single note */
276 	instrument = n->c>>4;
277 	period     = (((UWORD)n->a&0xf)<<8)+n->b;
278 	effect     = n->c&0xf;
279 	effdat     = n->d;
280 
281 	/* Convert the period to a note number */
282 	note=0;
283 	if(period) {
284 		for(note=0;note<7*OCTAVE;note++)
285 			if(period>=npertab[note]) break;
286 		if(note==7*OCTAVE) note=0;
287 		else note++;
288 	}
289 
290 	if(instrument) {
291 		/* if instrument does not exist, note cut */
292 		if((instrument>15)||(!mh->samples[instrument-1].length)) {
293 			UniPTEffect(0xc,0);
294 			if(effect==0xc) effect=effdat=0;
295 		} else {
296 			/* if we had a note, then change instrument... */
297 			if(note)
298 				UniInstrument(instrument-1);
299 			/* ...otherwise, only adjust volume... */
300 			else {
301 				/* ...unless an effect was specified, which forces a new note
302 				   to be played */
303 				if(effect||effdat) {
304 					UniInstrument(instrument-1);
305 					note=lastnote;
306 				} else
307 					UniPTEffect(0xc,mh->samples[instrument-1].volume&0x7f);
308 			}
309 		}
310 	}
311 	if(note) {
312 		UniNote(note+2*OCTAVE-1);
313 		lastnote=note;
314 	}
315 
316 	/* Convert pattern jump from Dec to Hex */
317 	if(effect == 0xd)
318 		effdat=(((effdat&0xf0)>>4)*10)+(effdat&0xf);
319 
320 	/* Volume slide, up has priority */
321 	if((effect==0xa)&&(effdat&0xf)&&(effdat&0xf0))
322 		effdat&=0xf0;
323 
324 	/* Handle ``heavy'' volumes correctly */
325 	if ((effect == 0xc) && (effdat > 0x40))
326 		effdat = 0x40;
327 
328 	if(ust_loader) {
329 		switch(effect) {
330 			case 0:
331 			case 3:
332 				break;
333 			case 1:
334 				UniPTEffect(0,effdat);
335 				break;
336 			case 2:
337 				if(effdat&0xf) UniPTEffect(1,effdat&0xf);
338 				else if(effdat>>2)  UniPTEffect(2,effdat>>2);
339 				break;
340 			default:
341 				UniPTEffect(effect,effdat);
342 				break;
343 		}
344 	} else {
345 		/* An isolated 100, 200 or 300 effect should be ignored (no
346 		   "standalone" porta memory in mod files). However, a sequence
347 		   such as 1XX, 100, 100, 100 is fine. */
348 		if ((!effdat) && ((effect == 1)||(effect == 2)||(effect ==3)) &&
349 			(lasteffect < 0x10) && (effect != lasteffect))
350 			effect = 0;
351 
352 		UniPTEffect(effect,effdat);
353 	}
354 	if (effect == 8)
355 		of.flags |= UF_PANNING;
356 
357 	return effect;
358 }
359 
M15_ConvertTrack(MODNOTE * n)360 static UBYTE *M15_ConvertTrack(MODNOTE* n)
361 {
362 	int t;
363 	UBYTE lasteffect = 0x10;	/* non existant effect */
364 
365 	UniReset();
366 	for(t=0;t<64;t++) {
367 		lasteffect = M15_ConvertNote(n,lasteffect);
368 		UniNewline();
369 		n+=4;
370 	}
371 	return UniDup();
372 }
373 
374 /* Loads all patterns of a modfile and converts them into the 3 byte format. */
M15_LoadPatterns(void)375 static BOOL M15_LoadPatterns(void)
376 {
377 	int t,s,tracks=0;
378 
379 	if(!AllocPatterns()) return 0;
380 	if(!AllocTracks()) return 0;
381 
382 	/* Allocate temporary buffer for loading and converting the patterns */
383 	if(!(patbuf=(MODNOTE*)MikMod_calloc(64U*4,sizeof(MODNOTE)))) return 0;
384 
385 	for(t=0;t<of.numpat;t++) {
386 		/* Load the pattern into the temp buffer and convert it */
387 		for(s=0;s<(64U*4);s++) {
388 			patbuf[s].a=_mm_read_UBYTE(modreader);
389 			patbuf[s].b=_mm_read_UBYTE(modreader);
390 			patbuf[s].c=_mm_read_UBYTE(modreader);
391 			patbuf[s].d=_mm_read_UBYTE(modreader);
392 		}
393 
394 		for(s=0;s<4;s++)
395 			if(!(of.tracks[tracks++]=M15_ConvertTrack(patbuf+s))) return 0;
396 	}
397 	return 1;
398 }
399 
M15_Load(BOOL curious)400 static BOOL M15_Load(BOOL curious)
401 {
402 	int t,scan;
403 	SAMPLE *q;
404 	MSAMPINFO *s;
405 
406 	/* try to read module header */
407 	if(!LoadModuleHeader(mh)) {
408 		_mm_errno = MMERR_LOADING_HEADER;
409 		return 0;
410 	}
411 
412 	if(ust_loader)
413 		of.modtype = MikMod_strdup("Ultimate Soundtracker");
414 	else
415 		of.modtype = MikMod_strdup("Soundtracker");
416 
417 	/* set module variables */
418 	of.initspeed = 6;
419 	of.inittempo = 125;
420 	of.numchn    = 4;
421 	of.songname  = DupStr(mh->songname,21,1);
422 	of.numpos    = mh->songlength;
423 	of.reppos    = 0;
424 
425 	/* Count the number of patterns */
426 	of.numpat = 0;
427 	for(t=0;t<of.numpos;t++)
428 		if(mh->positions[t]>of.numpat)
429 			of.numpat=mh->positions[t];
430 	/* since some old modules embed extra patterns, we have to check the
431 	   whole list to get the samples' file offsets right - however we can find
432 	   garbage here, so check carefully */
433 	scan=1;
434 	for(t=of.numpos;t<128;t++)
435 		if(mh->positions[t]>=0x80) scan=0;
436 	if (scan)
437 		for(t=of.numpos;t<128;t++) {
438 			if(mh->positions[t]>of.numpat)
439 				of.numpat=mh->positions[t];
440 			if((curious)&&(mh->positions[t])) of.numpos=t+1;
441 		}
442 	of.numpat++;
443 	of.numtrk = of.numpat*of.numchn;
444 
445 	if(!AllocPositions(of.numpos)) return 0;
446 	for(t=0;t<of.numpos;t++)
447 		of.positions[t]=mh->positions[t];
448 
449 	/* Finally, init the sampleinfo structures */
450 	of.numins=of.numsmp=15;
451 	if(!AllocSamples()) return 0;
452 
453 	s = mh->samples;
454 	q = of.samples;
455 
456 	for(t=0;t<of.numins;t++) {
457 		/* convert the samplename */
458 		q->samplename = DupStr(s->samplename,23,1);
459 
460 		/* init the sampleinfo variables and convert the size pointers */
461 		q->speed     = finetune[s->finetune&0xf];
462 		q->volume    = s->volume;
463 		if(ust_loader)
464 			q->loopstart = s->reppos;
465 		else
466 			q->loopstart = s->reppos<<1;
467 		q->loopend   = q->loopstart+(s->replen<<1);
468 		q->length    = s->length<<1;
469 
470 		q->flags = SF_SIGNED;
471 		if(ust_loader) q->flags |= SF_UST_LOOP;
472 		if(s->replen>2) q->flags |= SF_LOOP;
473 
474 		s++;
475 		q++;
476 	}
477 
478 	if(!M15_LoadPatterns()) return 0;
479 	ust_loader = 0;
480 
481 	return 1;
482 }
483 
M15_LoadTitle(void)484 static CHAR *M15_LoadTitle(void)
485 {
486 	CHAR s[21];
487 
488 	_mm_fseek(modreader,0,SEEK_SET);
489 	if(!_mm_read_UBYTES(s,20,modreader)) return NULL;
490 	s[20]=0;	/* just in case */
491 	return(DupStr(s,21,1));
492 }
493 
494 /*========== Loader information */
495 
496 MIKMODAPI MLOADER load_m15={
497 	NULL,
498 	"15-instrument module",
499 	"MOD (15 instrument)",
500 	M15_Init,
501 	M15_Test,
502 	M15_Load,
503 	M15_Cleanup,
504 	M15_LoadTitle
505 };
506 
507 /* ex:set ts=4: */
508