1 /* MikMod sound library
\r
2 (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
\r
3 AUTHORS for complete list.
\r
5 This library is free software; you can redistribute it and/or modify
\r
6 it under the terms of the GNU Library General Public License as
\r
7 published by the Free Software Foundation; either version 2 of
\r
8 the License, or (at your option) any later version.
\r
10 This program is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 GNU Library General Public License for more details.
\r
15 You should have received a copy of the GNU Library General Public
\r
16 License along with this library; if not, write to the Free Software
\r
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
\r
21 /*==============================================================================
\r
23 $Id: load_it.c,v 1.2 2004/02/06 19:29:03 raph Exp $
\r
25 Impulse tracker (IT) module loader
\r
27 ==============================================================================*/
\r
29 #ifdef HAVE_CONFIG_H
\r
33 #ifdef HAVE_UNISTD_H
\r
37 //#include <ctype.h>
\r
39 #ifdef HAVE_MEMORY_H
\r
44 #include "mikmod_internals.h"
\r
47 extern int fprintf(FILE *, const char *, ...);
\r
48 extern int toupper(int);
\r
51 /*========== Module structure */
\r
54 typedef struct ITHEADER {
\r
61 UWORD cwt; /* Created with tracker (y.xx = 0x0yxx) */
\r
62 UWORD cmwt; /* Compatible with tracker ver > than val. */
\r
64 UWORD special; /* bit 0 set = song message attached */
\r
66 UBYTE mixvol; /* mixing volume [ignored] */
\r
69 UBYTE pansep; /* panning separation between channels */
\r
78 /* sample information */
\r
79 typedef struct ITSAMPLE {
\r
87 UWORD convert; /* sample conversion flag */
\r
98 UBYTE vibwave; /* 0=sine, 1=rampdown, 2=square, 3=random (speed ignored) */
\r
101 /* instrument information */
\r
103 #define ITENVCNT 25
\r
104 #define ITNOTECNT 120
\r
105 typedef struct ITINSTHEADER {
\r
106 ULONG size; /* (dword) Instrument size */
\r
107 CHAR filename[12]; /* (char) Instrument filename */
\r
108 UBYTE zerobyte; /* (byte) Instrument type (always 0) */
\r
111 UBYTE volbeg; /* (byte) Volume loop start (node) */
\r
112 UBYTE volend; /* (byte) Volume loop end (node) */
\r
113 UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */
\r
114 UBYTE volsusend; /* (byte) Volume Sustain end (node) */
\r
117 UBYTE panbeg; /* (byte) channel loop start (node) */
\r
118 UBYTE panend; /* (byte) channel loop end (node) */
\r
119 UBYTE pansusbeg; /* (byte) channel sustain begin (node) */
\r
120 UBYTE pansusend; /* (byte) channel Sustain end (node) */
\r
123 UBYTE pitbeg; /* (byte) pitch loop start (node) */
\r
124 UBYTE pitend; /* (byte) pitch loop end (node) */
\r
125 UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */
\r
126 UBYTE pitsusend; /* (byte) pitch Sustain end (node) */
\r
130 UWORD fadeout; /* Envelope end / NNA volume fadeout */
\r
131 UBYTE dnc; /* Duplicate note check */
\r
132 UBYTE dca; /* Duplicate check action */
\r
133 UBYTE dct; /* Duplicate check type */
\r
134 UBYTE nna; /* New Note Action [0,1,2,3] */
\r
135 UWORD trkvers; /* tracker version used to save [files only] */
\r
136 UBYTE ppsep; /* Pitch-pan Separation */
\r
137 UBYTE ppcenter; /* Pitch-pan Center */
\r
138 UBYTE rvolvar; /* random volume varations */
\r
139 UBYTE rpanvar; /* random panning varations */
\r
140 UWORD numsmp; /* Number of samples in instrument [files only] */
\r
141 CHAR name[26]; /* Instrument name */
\r
143 UWORD samptable[ITNOTECNT];/* sample for each note [note / samp pairs] */
\r
144 UBYTE volenv[200]; /* volume envelope (IT 1.x stuff) */
\r
145 UBYTE oldvoltick[ITENVCNT];/* volume tick position (IT 1.x stuff) */
\r
146 UBYTE volnode[ITENVCNT]; /* amplitude of volume nodes */
\r
147 UWORD voltick[ITENVCNT]; /* tick value of volume nodes */
\r
148 SBYTE pannode[ITENVCNT]; /* panenv - node points */
\r
149 UWORD pantick[ITENVCNT]; /* tick value of panning nodes */
\r
150 SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */
\r
151 UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */
\r
154 /* unpacked note */
\r
156 typedef struct ITNOTE {
\r
157 UBYTE note,ins,volpan,cmd,inf;
\r
160 /*========== Loader data */
\r
162 static ULONG *paraptr=NULL; /* parapointer array (see IT docs) */
\r
163 static ITHEADER *mh=NULL;
\r
164 static ITNOTE *itpat=NULL; /* allocate to space for one full pattern */
\r
165 static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */
\r
166 static ITNOTE *last=NULL; /* uncompressing IT's pattern information */
\r
167 static int numtrk=0;
\r
168 static unsigned int old_effect; /* if set, use S3M old-effects stuffs */
\r
170 static CHAR* IT_Version[]={
\r
171 "ImpulseTracker . ",
\r
172 "Compressed ImpulseTracker . ",
\r
173 "ImpulseTracker 2.14p3",
\r
174 "Compressed ImpulseTracker 2.14p3",
\r
175 "ImpulseTracker 2.14p4",
\r
176 "Compressed ImpulseTracker 2.14p4",
\r
179 /* table for porta-to-note command within volume/panning column */
\r
180 static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
\r
182 /*========== Loader code */
\r
188 if(!_mm_read_UBYTES(id,4,modreader)) return 0;
\r
189 if(!memcmp(id,"IMPM",4)) return 1;
\r
195 if(!(mh=(ITHEADER*)_mm_malloc(sizeof(ITHEADER)))) return 0;
\r
196 if(!(poslookup=(UBYTE*)_mm_malloc(256*sizeof(UBYTE)))) return 0;
\r
197 if(!(itpat=(ITNOTE*)_mm_malloc(200*64*sizeof(ITNOTE)))) return 0;
\r
198 if(!(mask=(UBYTE*)_mm_malloc(64*sizeof(UBYTE)))) return 0;
\r
199 if(!(last=(ITNOTE*)_mm_malloc(64*sizeof(ITNOTE)))) return 0;
\r
204 void IT_Cleanup(void)
\r
209 _mm_free(poslookup);
\r
214 _mm_free(origpositions);
\r
217 /* Because so many IT files have 64 channels as the set number used, but really
\r
218 only use far less (usually from 8 to 24 still), I had to make this function,
\r
219 which determines the number of channels that are actually USED by a pattern.
\r
221 NOTE: You must first seek to the file location of the pattern before calling
\r
226 static BOOL IT_GetNumChannels(UWORD patrows)
\r
231 if((flag=_mm_read_UBYTE(modreader))==EOF) {
\r
232 _mm_errno=MMERR_LOADING_PATTERN;
\r
240 if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader);
\r
241 if(mask[ch]&1) _mm_read_UBYTE(modreader);
\r
242 if(mask[ch]&2) _mm_read_UBYTE(modreader);
\r
243 if(mask[ch]&4) _mm_read_UBYTE(modreader);
\r
244 if(mask[ch]&8) { _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader); }
\r
246 } while(row<patrows);
\r
251 static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
\r
254 UBYTE note,ins,volpan;
\r
258 for(t=0;t<numrows;t++) {
\r
259 note=tr[t*of.numchn].note;
\r
260 ins=tr[t*of.numchn].ins;
\r
261 volpan=tr[t*of.numchn].volpan;
\r
265 UniWriteByte(UNI_KEYOFF);
\r
266 else if(note==254) {
\r
267 UniPTEffect(0xc,-1); /* note cut command */
\r
273 if((ins)&&(ins<100))
\r
274 UniInstrument(ins-1);
\r
276 UniWriteByte(UNI_KEYOFF);
\r
277 else if(ins!=255) { /* crap */
\r
278 _mm_errno=MMERR_LOADING_PATTERN;
\r
282 /* process volume / panning column
\r
283 volume / panning effects do NOT all share the same memory address
\r
286 UniVolEffect(VOL_VOLUME,volpan);
\r
287 else if(volpan==65) /* fine volume slide up (65-74) - A0 case */
\r
288 UniVolEffect(VOL_VOLSLIDE,0);
\r
289 else if(volpan<=74) { /* fine volume slide up (65-74) - general case */
\r
290 UniVolEffect(VOL_VOLSLIDE,0x0f+((volpan-65)<<4));
\r
291 } else if(volpan==75) /* fine volume slide down (75-84) - B0 case */
\r
292 UniVolEffect(VOL_VOLSLIDE,0);
\r
293 else if(volpan<=84) { /* fine volume slide down (75-84) - general case*/
\r
294 UniVolEffect(VOL_VOLSLIDE,0xf0+(volpan-75));
\r
295 } else if(volpan<=94) /* volume slide up (85-94) */
\r
296 UniVolEffect(VOL_VOLSLIDE,((volpan-85)<<4));
\r
297 else if(volpan<=104)/* volume slide down (95-104) */
\r
298 UniVolEffect(VOL_VOLSLIDE,(volpan-95));
\r
299 else if(volpan<=114)/* pitch slide down (105-114) */
\r
300 UniVolEffect(VOL_PITCHSLIDEDN,(volpan-105));
\r
301 else if(volpan<=124)/* pitch slide up (115-124) */
\r
302 UniVolEffect(VOL_PITCHSLIDEUP,(volpan-115));
\r
303 else if(volpan<=127) { /* crap */
\r
304 _mm_errno=MMERR_LOADING_PATTERN;
\r
306 } else if(volpan<=192)
\r
307 UniVolEffect(VOL_PANNING,((volpan-128)==64)?255:((volpan-128)<<2));
\r
308 else if(volpan<=202)/* portamento to note */
\r
309 UniVolEffect(VOL_PORTAMENTO,portatable[volpan-193]);
\r
310 else if(volpan<=212)/* vibrato */
\r
311 UniVolEffect(VOL_VIBRATO,(volpan-203));
\r
312 else if((volpan!=239)&&(volpan!=255)) { /* crap */
\r
313 _mm_errno=MMERR_LOADING_PATTERN;
\r
317 S3MIT_ProcessCmd(tr[t*of.numchn].cmd,tr[t*of.numchn].inf,
\r
318 old_effect|S3MIT_IT);
\r
325 static BOOL IT_ReadPattern(UWORD patrows)
\r
327 int row=0,flag,ch,blah;
\r
328 ITNOTE *itt=itpat,dummy,*n,*l;
\r
330 memset(itt,255,200*64*sizeof(ITNOTE));
\r
333 if((flag=_mm_read_UBYTE(modreader))==EOF) {
\r
334 _mm_errno = MMERR_LOADING_PATTERN;
\r
338 itt=&itt[of.numchn];
\r
341 ch=remap[(flag-1)&63];
\r
348 if(flag&128) mask[ch]=_mm_read_UBYTE(modreader);
\r
350 /* convert IT note off to internal note off */
\r
351 if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
\r
352 l->note=n->note=253;
\r
354 l->ins=n->ins=_mm_read_UBYTE(modreader);
\r
356 l->volpan=n->volpan=_mm_read_UBYTE(modreader);
\r
358 l->cmd=n->cmd=_mm_read_UBYTE(modreader);
\r
359 l->inf=n->inf=_mm_read_UBYTE(modreader);
\r
366 n->volpan=l->volpan;
\r
372 } while(row<patrows);
\r
374 for(blah=0;blah<of.numchn;blah++) {
\r
375 if(!(of.tracks[numtrk++]=IT_ConvertTrack(&itpat[blah],patrows)))
\r
382 static void LoadMidiString(MREADER* modreader,CHAR* dest)
\r
386 _mm_read_UBYTES(dest,32,modreader);
\r
388 /* remove blanks and uppercase all */
\r
390 if(isalnum((int)*last)) *(cur++)=toupper((int)*last);
\r
396 /* Load embedded midi information for resonant filters */
\r
397 static void IT_LoadMidiConfiguration(MREADER* modreader)
\r
401 memset(filtermacros,0,sizeof(filtermacros));
\r
402 memset(filtersettings,0,sizeof(filtersettings));
\r
404 if (modreader) { /* information is embedded in file */
\r
408 dat=_mm_read_I_UWORD(modreader);
\r
409 _mm_fseek(modreader,8*dat+0x120,SEEK_CUR);
\r
411 /* read midi macros */
\r
412 for(i=0;i<UF_MAXMACRO;i++) {
\r
413 LoadMidiString(modreader,midiline);
\r
414 if((!strncmp(midiline,"F0F00",5))&&
\r
415 ((midiline[5]=='0')||(midiline[5]=='1')))
\r
416 filtermacros[i]=(midiline[5]-'0')|0x80;
\r
419 /* read standalone filters */
\r
420 for(i=0x80;i<0x100;i++) {
\r
421 LoadMidiString(modreader,midiline);
\r
422 if((!strncmp(midiline,"F0F00",5))&&
\r
423 ((midiline[5]=='0')||(midiline[5]=='1'))) {
\r
424 filtersettings[i].filter=(midiline[5]-'0')|0x80;
\r
425 dat=(midiline[6])?(midiline[6]-'0'):0;
\r
426 if(midiline[7])dat=(dat<<4)|(midiline[7]-'0');
\r
427 filtersettings[i].inf=dat;
\r
430 } else { /* use default information */
\r
431 filtermacros[0]=FILT_CUT;
\r
432 for(i=0x80;i<0x90;i++) {
\r
433 filtersettings[i].filter=FILT_RESONANT;
\r
434 filtersettings[i].inf=(i&0x7f)<<3;
\r
438 for(i=0;i<0x80;i++) {
\r
439 filtersettings[i].filter=filtermacros[0];
\r
440 filtersettings[i].inf=i;
\r
444 BOOL IT_Load(BOOL curious)
\r
454 /* try to read module header */
\r
455 _mm_read_I_ULONG(modreader); /* kill the 4 byte header */
\r
456 _mm_read_string(mh->songname,26,modreader);
\r
457 _mm_read_UBYTES(mh->blank01,2,modreader);
\r
458 mh->ordnum =_mm_read_I_UWORD(modreader);
\r
459 mh->insnum =_mm_read_I_UWORD(modreader);
\r
460 mh->smpnum =_mm_read_I_UWORD(modreader);
\r
461 mh->patnum =_mm_read_I_UWORD(modreader);
\r
462 mh->cwt =_mm_read_I_UWORD(modreader);
\r
463 mh->cmwt =_mm_read_I_UWORD(modreader);
\r
464 mh->flags =_mm_read_I_UWORD(modreader);
\r
465 mh->special =_mm_read_I_UWORD(modreader);
\r
466 mh->globvol =_mm_read_UBYTE(modreader);
\r
467 mh->mixvol =_mm_read_UBYTE(modreader);
\r
468 mh->initspeed =_mm_read_UBYTE(modreader);
\r
469 mh->inittempo =_mm_read_UBYTE(modreader);
\r
470 mh->pansep =_mm_read_UBYTE(modreader);
\r
471 mh->zerobyte =_mm_read_UBYTE(modreader);
\r
472 mh->msglength =_mm_read_I_UWORD(modreader);
\r
473 mh->msgoffset =_mm_read_I_ULONG(modreader);
\r
474 _mm_read_UBYTES(mh->blank02,4,modreader);
\r
475 _mm_read_UBYTES(mh->pantable,64,modreader);
\r
476 _mm_read_UBYTES(mh->voltable,64,modreader);
\r
478 if(_mm_eof(modreader)) {
\r
479 _mm_errno=MMERR_LOADING_HEADER;
\r
483 /* set module variables */
\r
484 of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */
\r
486 of.numpat = mh->patnum;
\r
487 of.numins = mh->insnum;
\r
488 of.numsmp = mh->smpnum;
\r
489 of.initspeed = mh->initspeed;
\r
490 of.inittempo = mh->inittempo;
\r
491 of.initvolume = mh->globvol;
\r
492 of.flags |= UF_BGSLIDES | UF_ARPMEM;
\r
493 if (!(mh->flags & 1))
\r
494 of.flags |= UF_PANNING;
\r
497 if(mh->songname[25]) {
\r
498 of.numvoices=1+mh->songname[25];
\r
499 #ifdef MIKMOD_DEBUG
\r
500 fprintf(stderr,"Embedded IT limitation to %d voices\n",of.numvoices);
\r
504 /* set the module type */
\r
505 /* 2.17 : IT 2.14p4 */
\r
506 /* 2.16 : IT 2.14p3 with resonant filters */
\r
507 /* 2.15 : IT 2.14p3 (improved compression) */
\r
508 if((mh->cwt<=0x219)&&(mh->cwt>=0x217))
\r
509 of.modtype=strdup(IT_Version[mh->cmwt<0x214?4:5]);
\r
510 else if (mh->cwt>=0x215)
\r
511 of.modtype=strdup(IT_Version[mh->cmwt<0x214?2:3]);
\r
513 of.modtype = strdup(IT_Version[mh->cmwt<0x214?0:1]);
\r
514 of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0';
\r
515 of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0';
\r
516 of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0';
\r
520 of.flags |= UF_XMPERIODS | UF_LINEAR;
\r
522 if((mh->cwt>=0x106)&&(mh->flags&16))
\r
523 old_effect=S3MIT_OLDSTYLE;
\r
527 /* set panning positions */
\r
529 for(t=0;t<64;t++) {
\r
530 mh->pantable[t]&=0x7f;
\r
531 if(mh->pantable[t]<64)
\r
532 of.panning[t]=mh->pantable[t]<<2;
\r
533 else if(mh->pantable[t]==64)
\r
535 else if(mh->pantable[t]==100)
\r
536 of.panning[t]=PAN_SURROUND;
\r
537 else if(mh->pantable[t]==127)
\r
538 of.panning[t]=PAN_CENTER;
\r
540 _mm_errno=MMERR_LOADING_HEADER;
\r
546 of.panning[t]=PAN_CENTER;
\r
548 /* set channel volumes */
\r
549 memcpy(of.chanvol,mh->voltable,64);
\r
551 /* read the order data */
\r
552 if(!AllocPositions(mh->ordnum)) return 0;
\r
553 if(!(origpositions=_mm_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
\r
555 for(t=0;t<mh->ordnum;t++) {
\r
556 origpositions[t]=_mm_read_UBYTE(modreader);
\r
557 if((origpositions[t]>mh->patnum)&&(origpositions[t]<254))
\r
558 origpositions[t]=255;
\r
561 if(_mm_eof(modreader)) {
\r
562 _mm_errno = MMERR_LOADING_HEADER;
\r
566 poslookupcnt=mh->ordnum;
\r
567 S3MIT_CreateOrders(curious);
\r
569 if(!(paraptr=(ULONG*)_mm_malloc((mh->insnum+mh->smpnum+of.numpat)*
\r
570 sizeof(ULONG)))) return 0;
\r
572 /* read the instrument, sample, and pattern parapointers */
\r
573 _mm_read_I_ULONGS(paraptr,mh->insnum+mh->smpnum+of.numpat,modreader);
\r
575 if(_mm_eof(modreader)) {
\r
576 _mm_errno = MMERR_LOADING_HEADER;
\r
580 /* Check for and load midi information for resonant filters */
\r
581 if(mh->cmwt>=0x216) {
\r
582 if(mh->special&8) {
\r
583 IT_LoadMidiConfiguration(modreader);
\r
584 if(_mm_eof(modreader)) {
\r
585 _mm_errno = MMERR_LOADING_HEADER;
\r
589 IT_LoadMidiConfiguration(NULL);
\r
593 /* Check for and load song comment */
\r
594 if((mh->special&1)&&(mh->cwt>=0x104)&&(mh->msglength)) {
\r
595 _mm_fseek(modreader,(long)(mh->msgoffset),SEEK_SET);
\r
596 if(!ReadComment(mh->msglength)) return 0;
\r
599 if(!(mh->flags&4)) of.numins=of.numsmp;
\r
600 if(!AllocSamples()) return 0;
\r
602 if(!AllocLinear()) return 0;
\r
604 /* Load all samples */
\r
606 for(t=0;t<mh->smpnum;t++) {
\r
609 /* seek to sample position */
\r
610 _mm_fseek(modreader,(long)(paraptr[mh->insnum+t]+4),SEEK_SET);
\r
612 /* load sample info */
\r
613 _mm_read_string(s.filename,12,modreader);
\r
614 s.zerobyte = _mm_read_UBYTE(modreader);
\r
615 s.globvol = _mm_read_UBYTE(modreader);
\r
616 s.flag = _mm_read_UBYTE(modreader);
\r
617 s.volume = _mm_read_UBYTE(modreader);
\r
618 _mm_read_string(s.sampname,26,modreader);
\r
619 s.convert = _mm_read_UBYTE(modreader);
\r
620 s.panning = _mm_read_UBYTE(modreader);
\r
621 s.length = _mm_read_I_ULONG(modreader);
\r
622 s.loopbeg = _mm_read_I_ULONG(modreader);
\r
623 s.loopend = _mm_read_I_ULONG(modreader);
\r
624 s.c5spd = _mm_read_I_ULONG(modreader);
\r
625 s.susbegin = _mm_read_I_ULONG(modreader);
\r
626 s.susend = _mm_read_I_ULONG(modreader);
\r
627 s.sampoffset = _mm_read_I_ULONG(modreader);
\r
628 s.vibspeed = _mm_read_UBYTE(modreader);
\r
629 s.vibdepth = _mm_read_UBYTE(modreader);
\r
630 s.vibrate = _mm_read_UBYTE(modreader);
\r
631 s.vibwave = _mm_read_UBYTE(modreader);
\r
633 /* Generate an error if c5spd is > 512k, or samplelength > 256 megs
\r
634 (nothing would EVER be that high) */
\r
636 if(_mm_eof(modreader)||(s.c5spd>0x7ffffL)||(s.length>0xfffffffUL)) {
\r
637 _mm_errno = MMERR_LOADING_SAMPLEINFO;
\r
641 /* Reality check for sample loop information */
\r
643 ((s.loopbeg>0xfffffffUL)||(s.loopend>0xfffffffUL))) {
\r
644 _mm_errno = MMERR_LOADING_SAMPLEINFO;
\r
648 q->samplename = DupStr(s.sampname,26,0);
\r
649 q->speed = s.c5spd / 2;
\r
650 q->panning = ((s.panning&127)==64)?255:(s.panning&127)<<2;
\r
651 q->length = s.length;
\r
652 q->loopstart = s.loopbeg;
\r
653 q->loopend = s.loopend;
\r
654 q->volume = s.volume;
\r
655 q->globvol = s.globvol;
\r
656 q->seekpos = s.sampoffset;
\r
658 /* Convert speed to XM linear finetune */
\r
659 if(of.flags&UF_LINEAR)
\r
660 q->speed=speed_to_finetune(s.c5spd,t);
\r
662 if(s.panning&128) q->flags|=SF_OWNPAN;
\r
665 q->vibflags |= AV_IT;
\r
666 q->vibtype = s.vibwave;
\r
667 q->vibsweep = s.vibrate * 2;
\r
668 q->vibdepth = s.vibdepth;
\r
669 q->vibrate = s.vibspeed;
\r
672 if(s.flag&2) q->flags|=SF_16BITS;
\r
673 if((s.flag&8)&&(mh->cwt>=0x214)) {
\r
674 q->flags|=SF_ITPACKED;
\r
677 if(s.flag&16) q->flags|=SF_LOOP;
\r
678 if(s.flag&64) q->flags|=SF_BIDI;
\r
680 if(mh->cwt>=0x200) {
\r
681 if(s.convert&1) q->flags|=SF_SIGNED;
\r
682 if(s.convert&4) q->flags|=SF_DELTA;
\r
687 /* Load instruments if instrument mode flag enabled */
\r
689 if(!AllocInstruments()) return 0;
\r
691 of.flags|=UF_NNA|UF_INST;
\r
693 for(t=0;t<mh->insnum;t++) {
\r
696 /* seek to instrument position */
\r
697 _mm_fseek(modreader,paraptr[t]+4,SEEK_SET);
\r
699 /* load instrument info */
\r
700 _mm_read_string(ih.filename,12,modreader);
\r
701 ih.zerobyte = _mm_read_UBYTE(modreader);
\r
702 if(mh->cwt<0x200) {
\r
703 /* load IT 1.xx inst header */
\r
704 ih.volflg = _mm_read_UBYTE(modreader);
\r
705 ih.volbeg = _mm_read_UBYTE(modreader);
\r
706 ih.volend = _mm_read_UBYTE(modreader);
\r
707 ih.volsusbeg = _mm_read_UBYTE(modreader);
\r
708 ih.volsusend = _mm_read_UBYTE(modreader);
\r
709 _mm_read_I_UWORD(modreader);
\r
710 ih.fadeout = _mm_read_I_UWORD(modreader);
\r
711 ih.nna = _mm_read_UBYTE(modreader);
\r
712 ih.dnc = _mm_read_UBYTE(modreader);
\r
714 /* Read IT200+ header */
\r
715 ih.nna = _mm_read_UBYTE(modreader);
\r
716 ih.dct = _mm_read_UBYTE(modreader);
\r
717 ih.dca = _mm_read_UBYTE(modreader);
\r
718 ih.fadeout = _mm_read_I_UWORD(modreader);
\r
719 ih.ppsep = _mm_read_UBYTE(modreader);
\r
720 ih.ppcenter = _mm_read_UBYTE(modreader);
\r
721 ih.globvol = _mm_read_UBYTE(modreader);
\r
722 ih.chanpan = _mm_read_UBYTE(modreader);
\r
723 ih.rvolvar = _mm_read_UBYTE(modreader);
\r
724 ih.rpanvar = _mm_read_UBYTE(modreader);
\r
727 ih.trkvers = _mm_read_I_UWORD(modreader);
\r
728 ih.numsmp = _mm_read_UBYTE(modreader);
\r
729 _mm_read_UBYTE(modreader);
\r
730 _mm_read_string(ih.name,26,modreader);
\r
731 _mm_read_UBYTES(ih.blank01,6,modreader);
\r
732 _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader);
\r
733 if(mh->cwt<0x200) {
\r
734 /* load IT 1xx volume envelope */
\r
735 _mm_read_UBYTES(ih.volenv,200,modreader);
\r
736 for(lp=0;lp<ITENVCNT;lp++) {
\r
737 ih.oldvoltick[lp] = _mm_read_UBYTE(modreader);
\r
738 ih.volnode[lp] = _mm_read_UBYTE(modreader);
\r
741 /* load IT 2xx volume, pan and pitch envelopes */
\r
742 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
\r
743 #define IT_LoadEnvelope(name,type) \
\r
744 ih. name##flg =_mm_read_UBYTE(modreader); \
\r
745 ih. name##pts =_mm_read_UBYTE(modreader); \
\r
746 ih. name##beg =_mm_read_UBYTE(modreader); \
\r
747 ih. name##end =_mm_read_UBYTE(modreader); \
\r
748 ih. name##susbeg=_mm_read_UBYTE(modreader); \
\r
749 ih. name##susend=_mm_read_UBYTE(modreader); \
\r
750 for(lp=0;lp<ITENVCNT;lp++) { \
\r
751 ih. name##node[lp]=_mm_read_##type (modreader); \
\r
752 ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \
\r
754 _mm_read_UBYTE(modreader)
\r
756 #define IT_LoadEnvelope(name,type) \
\r
757 ih. name/**/flg =_mm_read_UBYTE(modreader); \
\r
758 ih. name/**/pts =_mm_read_UBYTE(modreader); \
\r
759 ih. name/**/beg =_mm_read_UBYTE(modreader); \
\r
760 ih. name/**/end =_mm_read_UBYTE(modreader); \
\r
761 ih. name/**/susbeg=_mm_read_UBYTE(modreader); \
\r
762 ih. name/**/susend=_mm_read_UBYTE(modreader); \
\r
763 for(lp=0;lp<ITENVCNT;lp++) { \
\r
764 ih. name/**/node[lp]=_mm_read_/**/type (modreader); \
\r
765 ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \
\r
767 _mm_read_UBYTE(modreader)
\r
770 IT_LoadEnvelope(vol,UBYTE);
\r
771 IT_LoadEnvelope(pan,SBYTE);
\r
772 IT_LoadEnvelope(pit,SBYTE);
\r
773 #undef IT_LoadEnvelope
\r
776 if(_mm_eof(modreader)) {
\r
777 _mm_errno = MMERR_LOADING_SAMPLEINFO;
\r
781 d->volflg|=EF_VOLENV;
\r
782 d->insname = DupStr(ih.name,26,0);
\r
783 d->nnatype = ih.nna & NNA_MASK;
\r
785 if(mh->cwt<0x200) {
\r
786 d->volfade=ih.fadeout<< 6;
\r
792 if(ih.volflg&1) d->volflg|=EF_ON;
\r
793 if(ih.volflg&2) d->volflg|=EF_LOOP;
\r
794 if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
\r
796 /* XM conversion of IT envelope Array */
\r
797 d->volbeg = ih.volbeg;
\r
798 d->volend = ih.volend;
\r
799 d->volsusbeg = ih.volsusbeg;
\r
800 d->volsusend = ih.volsusend;
\r
803 for(u=0;u<ITENVCNT;u++)
\r
804 if(ih.oldvoltick[d->volpts]!=0xff) {
\r
805 d->volenv[d->volpts].val=(ih.volnode[d->volpts]<<2);
\r
806 d->volenv[d->volpts].pos=ih.oldvoltick[d->volpts];
\r
812 d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2;
\r
813 if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN;
\r
815 if(!(ih.ppsep & 128)) {
\r
816 d->pitpansep=ih.ppsep<<2;
\r
817 d->pitpancenter=ih.ppcenter;
\r
818 d->flags|=IF_PITCHPAN;
\r
820 d->globvol=ih.globvol>>1;
\r
821 d->volfade=ih.fadeout<<5;
\r
825 if(mh->cwt>=0x204) {
\r
826 d->rvolvar = ih.rvolvar;
\r
827 d->rpanvar = ih.rpanvar;
\r
830 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
\r
831 #define IT_ProcessEnvelope(name) \
\r
832 if(ih. name##flg&1) d-> name##flg|=EF_ON; \
\r
833 if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \
\r
834 if(ih. name##flg&4) d-> name##flg|=EF_SUSTAIN; \
\r
835 d-> name##pts=ih. name##pts; \
\r
836 d-> name##beg=ih. name##beg; \
\r
837 d-> name##end=ih. name##end; \
\r
838 d-> name##susbeg=ih. name##susbeg; \
\r
839 d-> name##susend=ih. name##susend; \
\r
841 for(u=0;u<ih. name##pts;u++) \
\r
842 d-> name##env[u].pos=ih. name##tick[u]; \
\r
844 if((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \
\r
845 d-> name##flg&=~EF_ON
\r
847 #define IT_ProcessEnvelope(name) \
\r
848 if(ih. name/**/flg&1) d-> name/**/flg|=EF_ON; \
\r
849 if(ih. name/**/flg&2) d-> name/**/flg|=EF_LOOP; \
\r
850 if(ih. name/**/flg&4) d-> name/**/flg|=EF_SUSTAIN; \
\r
851 d-> name/**/pts=ih. name/**/pts; \
\r
852 d-> name/**/beg=ih. name/**/beg; \
\r
853 d-> name/**/end=ih. name/**/end; \
\r
854 d-> name/**/susbeg=ih. name/**/susbeg; \
\r
855 d-> name/**/susend=ih. name/**/susend; \
\r
857 for(u=0;u<ih. name/**/pts;u++) \
\r
858 d-> name/**/env[u].pos=ih. name/**/tick[u]; \
\r
860 if((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
\r
861 d-> name/**/flg&=~EF_ON
\r
864 IT_ProcessEnvelope(vol);
\r
865 for(u=0;u<ih.volpts;u++)
\r
866 d->volenv[u].val=(ih.volnode[u]<<2);
\r
868 IT_ProcessEnvelope(pan);
\r
869 for(u=0;u<ih.panpts;u++)
\r
871 ih.pannode[u]==32?255:(ih.pannode[u]+32)<<2;
\r
873 IT_ProcessEnvelope(pit);
\r
874 for(u=0;u<ih.pitpts;u++)
\r
875 d->pitenv[u].val=ih.pitnode[u]+32;
\r
876 #undef IT_ProcessEnvelope
\r
878 if(ih.pitflg&0x80) {
\r
879 /* filter envelopes not supported yet */
\r
881 ih.pitpts=ih.pitbeg=ih.pitend=0;
\r
882 #ifdef MIKMOD_DEBUG
\r
887 fprintf(stderr, "\rFilter envelopes not supported yet\n");
\r
894 for(u=0;u<ITNOTECNT;u++) {
\r
895 d->samplenote[u]=(ih.samptable[u]&255);
\r
896 d->samplenumber[u]=
\r
897 (ih.samptable[u]>>8)?((ih.samptable[u]>>8)-1):0xffff;
\r
898 if(d->samplenumber[u]>=of.numsmp)
\r
899 d->samplenote[u]=255;
\r
900 else if (of.flags&UF_LINEAR) {
\r
901 int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]];
\r
902 d->samplenote[u]=(note<0)?0:(note>255?255:note);
\r
908 } else if(of.flags & UF_LINEAR) {
\r
909 if(!AllocInstruments()) return 0;
\r
913 for(t=0;t<mh->smpnum;t++,d++)
\r
914 for(u=0;u<ITNOTECNT;u++) {
\r
915 if(d->samplenumber[u]>=of.numsmp)
\r
916 d->samplenote[u]=255;
\r
918 int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]];
\r
919 d->samplenote[u]=(note<0)?0:(note>255?255:note);
\r
924 /* Figure out how many channels this song actually uses */
\r
926 memset(remap,-1,UF_MAXCHAN*sizeof(UBYTE));
\r
927 for(t=0;t<of.numpat;t++) {
\r
930 /* seek to pattern position */
\r
931 if(paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */
\r
932 _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
\r
933 _mm_read_I_UWORD(modreader);
\r
934 /* read pattern length (# of rows)
\r
935 Impulse Tracker never creates patterns with less than 32 rows,
\r
936 but some other trackers do, so we only check for more than 256
\r
938 packlen=_mm_read_I_UWORD(modreader);
\r
940 _mm_errno=MMERR_LOADING_PATTERN;
\r
943 _mm_read_I_ULONG(modreader);
\r
944 if(IT_GetNumChannels(packlen)) return 0;
\r
948 /* give each of them a different number */
\r
949 for(t=0;t<UF_MAXCHAN;t++)
\r
951 remap[t]=of.numchn++;
\r
953 of.numtrk = of.numpat*of.numchn;
\r
955 if (of.numvoices<of.numchn) of.numvoices=of.numchn;
\r
957 if(!AllocPatterns()) return 0;
\r
958 if(!AllocTracks()) return 0;
\r
960 for(t=0;t<of.numpat;t++) {
\r
963 /* seek to pattern position */
\r
964 if(!paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */
\r
966 for(u=0;u<of.numchn;u++) {
\r
970 for(k=0;k<64;k++) UniNewline();
\r
971 of.tracks[numtrk++]=UniDup();
\r
974 _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
\r
975 packlen=_mm_read_I_UWORD(modreader);
\r
976 of.pattrows[t]=_mm_read_I_UWORD(modreader);
\r
977 _mm_read_I_ULONG(modreader);
\r
978 if(!IT_ReadPattern(of.pattrows[t])) return 0;
\r
985 CHAR *IT_LoadTitle(void)
\r
989 _mm_fseek(modreader,4,SEEK_SET);
\r
990 if(!_mm_read_UBYTES(s,26,modreader)) return NULL;
\r
992 return(DupStr(s,26,0));
\r
995 /*========== Loader information */
\r
997 MIKMODAPI MLOADER load_it={
\r
1000 "IT (Impulse Tracker)",
\r
1008 /* ex:set ts=4: */
\r