comparison playercode/load_it.c @ 4:5d614bcc4287

Initial entry of mikmod into the CVS tree.
author darius
date Fri, 23 Jan 1998 16:05:08 +0000
parents
children
comparison
equal deleted inserted replaced
3:71e20a32bd84 4:5d614bcc4287
1 /*
2
3 Name: LOAD_IT.C
4
5 Description:
6 ImpulseTracker (IT) module loader
7
8 Portability:
9 All systems - all compilers (hopefully)
10
11 Copyright 1997 by Jake Stine and Divine Entertainment
12
13 If this module is found to not be portable to any particular platform,
14 please contact Jake Stine at dracoirs@epix.net (see MIKMOD.TXT for
15 more information on contacting the author).
16 */
17
18 #include <string.h>
19 #include "mikmod.h"
20
21 /**************************************************************************
22 **************************************************************************/
23
24 typedef struct ITNOTE
25 { UBYTE note,ins,volpan,cmd,inf;
26 } ITNOTE;
27
28 UBYTE *IT_ConvertTrack(ITNOTE *tr,UWORD numrows);
29
30
31 // Raw IT header struct:
32
33 typedef struct ITHEADER
34 { CHAR songname[26];
35 UBYTE blank01[2];
36 UWORD ordnum;
37 UWORD insnum;
38 UWORD smpnum;
39 UWORD patnum;
40 UWORD cwt; // Created with tracker (y.xx = 0x0yxx)
41 UWORD cmwt; // Compatable with tracker ver > than val.
42 UWORD flags;
43 UWORD special; // bit 0 set = song message attached
44 UBYTE globvol;
45 UBYTE mixvol; // mixing volume [ignored]
46 UBYTE initspeed;
47 UBYTE inittempo;
48 UBYTE pansep; // panning separation between channels
49 UBYTE zerobyte;
50 UWORD msglength;
51 ULONG msgoffset;
52 UBYTE blank02[4];
53
54 UBYTE pantable[64];
55 UBYTE voltable[64];
56 } ITHEADER;
57
58
59 // Raw IT sampleinfo struct:
60
61 typedef struct ITSAMPLE
62 { CHAR filename[12];
63 UBYTE zerobyte;
64 UBYTE globvol;
65 UBYTE flag;
66 UBYTE volume;
67 UBYTE panning;
68 CHAR sampname[28];
69 UWORD convert; // sample conversion flag
70 ULONG length;
71 ULONG loopbeg;
72 ULONG loopend;
73 ULONG c5spd;
74 ULONG susbegin;
75 ULONG susend;
76 ULONG sampoffset;
77 UBYTE vibspeed;
78 UBYTE vibdepth;
79 UBYTE vibrate;
80 UBYTE vibwave; // 0 = sine; 1 = rampdown; 2 = square; 3 = random (speed ignored)
81
82 UBYTE noteindex; // for converting c5spd to finetune
83 } ITSAMPLE;
84
85
86 typedef struct ITINSTHEADER
87 { ULONG size; // (dword) Instrument size
88 CHAR filename[12]; // (char) Instrument filename
89 UBYTE zerobyte; // (byte) Instrument type (always 0)
90 UBYTE volflg;
91 UBYTE volpts;
92 UBYTE volbeg; // (byte) Volume loop start (node)
93 UBYTE volend; // (byte) Volume loop end (node)
94 UBYTE volsusbeg; // (byte) Volume sustain begin (node)
95 UBYTE volsusend; // (byte) Volume Sustain end (node)
96 UBYTE panflg;
97 UBYTE panpts;
98 UBYTE panbeg; // (byte) channel loop start (node)
99 UBYTE panend; // (byte) channel loop end (node)
100 UBYTE pansusbeg; // (byte) cahnnel sustain begin (node)
101 UBYTE pansusend; // (byte) channel Sustain end (node)
102 UBYTE pitflg;
103 UBYTE pitpts;
104 UBYTE pitbeg; // (byte) pitch loop start (node)
105 UBYTE pitend; // (byte) pitch loop end (node)
106 UBYTE pitsusbeg; // (byte) pitch sustain begin (node)
107 UBYTE pitsusend; // (byte) pitch Sustain end (node)
108 UWORD blank;
109 UBYTE globvol;
110 UBYTE chanpan;
111 UWORD fadeout; // Envelope end / NNA volume fadeout
112 UBYTE dnc; // Duplicate note check
113 UBYTE dca; // Duplicate check action
114 UBYTE dct; // Duplicate check type
115 UBYTE nna; // New Note Action [0,1,2,3]
116 UWORD trkvers; // tracker version used to save [in files only]
117 UBYTE ppsep; // Pitch-pan Separation
118 UBYTE ppcenter; // Pitch-pan Center
119 UBYTE rvolvar; // random volume varations
120 UBYTE rpanvar; // random panning varations
121 UWORD numsmp; // Number of samples in instrument [in files only]
122 CHAR name[26]; // Instrument name
123 UBYTE blank01[6];
124 UWORD samptable[120]; // sample for each note [note / samp pairs]
125
126 UBYTE volenv[200]; // volume envelope (IT 1.x stuff)
127 UBYTE oldvoltick[25]; // volume tick position (IT 1.x stuff)
128 UBYTE volnode[25]; // aplitude of volume nodes
129 UWORD voltick[25]; // tick value of volume nodes
130 SBYTE pannode[25]; // panenv - node points
131 UWORD pantick[25]; // tick value of panning nodes
132 SBYTE pitnode[25]; // pitchenv - node points
133 UWORD pittick[25]; // tick value of pitch nodes
134 } ITINSTHEADER;
135
136
137 /**************************************************************************
138 **************************************************************************/
139
140 extern SBYTE remap[64]; // for removing empty channels
141 extern UBYTE *poslookup; // S3M/IT fix - removing blank patterns needs a
142 // lookup table to fix position-jump commands
143 static ULONG *paraptr = NULL; // parapointer array (see IT docs)
144 static ITHEADER *mh = NULL;
145 static ITNOTE *itpat = NULL; // allocate to space for one full pattern
146 static UBYTE *mask = NULL; // arrays allocated to 64 elements and used for
147 static ITNOTE *last = NULL; // uncompressing IT's pattern information
148 static int numtrk = 0;
149 static int old_effect; // if set, use S3M old-effects stuffs
150 static int *noteindex;
151
152 CHAR IT_Version[] = "ImpulseTracker x.xx";
153
154
155 BOOL IT_Test(void)
156 {
157 UBYTE id[4];
158
159 if(!_mm_read_UBYTES(id,4,modfp)) return 0;
160 if(!memcmp(id,"IMPM",4)) return 1;
161 return 0;
162 }
163
164 BOOL IT_Init(void)
165 {
166 if((mh=(ITHEADER *)_mm_calloc(1,sizeof(ITHEADER)))==NULL) return 0;
167 if((poslookup=(UBYTE *)_mm_malloc(256*sizeof(UBYTE)))==NULL) return 0;
168 if((itpat=(ITNOTE *)_mm_malloc(200*64*sizeof(ITNOTE)))==NULL) return 0;
169 if((mask=(UBYTE *)_mm_malloc(64*sizeof(UBYTE)))==NULL) return 0;
170 if((last=(ITNOTE *)_mm_malloc(64*sizeof(ITNOTE)))==NULL) return 0;
171
172 return 1;
173 }
174
175 void IT_Cleanup(void)
176 {
177 if(mh!=NULL) free(mh);
178 if(poslookup!=NULL) free(poslookup);
179 if(itpat!=NULL) free(itpat);
180 if(mask!=NULL) free(mask);
181 if(last!=NULL) free(last);
182 if(paraptr!=NULL) free(paraptr);
183 if(noteindex!=NULL) free(noteindex);
184
185 mh = NULL;
186 poslookup = NULL;
187 itpat = NULL;
188 mask = NULL;
189 last = NULL;
190 paraptr = NULL;
191 noteindex = NULL;
192 }
193
194
195 BOOL IT_GetNumChannels(UWORD patrows)
196
197 // Because so many IT files have 64 channels as the set number used, but really
198 // only use far less (usually 8 to 12 still), I had to make this function,
199 // which determines the number of channels that are actually USED by a pattern.
200 //
201 // For every channel that's used, it sets the appropriate array entry of the
202 // global varialbe 'isused'
203 //
204 // NOTE: You must first seek to the file location of the pattern before calling
205 // this procedure.
206 // Returns 1 on error
207 {
208 int row=0,flag,ch;
209
210 do
211 { flag = _mm_read_UBYTE(modfp);
212 if(flag == EOF)
213 { _mm_errno = MMERR_LOADING_PATTERN;
214 return 1;
215 }
216
217 if(flag == 0)
218 { row++;
219 } else
220 { ch = (flag-1) & 63;
221 remap[ch] = 0;
222 if(flag & 128) mask[ch] = _mm_read_UBYTE(modfp);
223 if(mask[ch] & 1) _mm_read_UBYTE(modfp);
224 if(mask[ch] & 2) _mm_read_UBYTE(modfp);
225 if(mask[ch] & 4) _mm_read_UBYTE(modfp);
226 if(mask[ch] & 8) { _mm_read_UBYTE(modfp); _mm_read_UBYTE(modfp); }
227 }
228 } while(row < patrows);
229
230 return 0;
231 }
232
233
234 BOOL IT_ReadPattern(UWORD patrows)
235 {
236 int blah;
237 int row=0,flag,ch;
238 ITNOTE *itt = itpat, dummy,*n,*l;
239
240 memset(itt,255,patrows*of.numchn*sizeof(ITNOTE));
241
242 do
243 { flag = _mm_read_UBYTE(modfp);
244 if(feof(modfp))
245 { _mm_errno = MMERR_LOADING_PATTERN;
246 return 0;
247 }
248 if(flag == 0)
249 { itt = &itt[of.numchn];
250 row++;
251 } else
252 { ch = remap[(flag-1) & 63];
253 if(ch != -1)
254 { n = &itt[ch];
255 l = &last[ch];
256 } else
257 { n = l = &dummy; }
258
259 if(flag & 128) mask[ch] = _mm_read_UBYTE(modfp);
260 if(mask[ch] & 1) if((l->note = n->note = _mm_read_UBYTE(modfp)) == 255)
261 { l->note = n->note = 253; }
262 if(mask[ch] & 2) l->ins = n->ins = _mm_read_UBYTE(modfp);
263 if(mask[ch] & 4) l->volpan = n->volpan = _mm_read_UBYTE(modfp);
264 if(mask[ch] & 8) { l->cmd = n->cmd = _mm_read_UBYTE(modfp);
265 l->inf = n->inf = _mm_read_UBYTE(modfp); }
266 if(mask[ch] & 16) n->note = l->note;
267 if(mask[ch] & 32) n->ins = l->ins;
268 if(mask[ch] & 64) n->volpan = l->volpan;
269 if(mask[ch] & 128) { n->cmd = l->cmd;
270 n->inf = l->inf; }
271 }
272 } while(row < patrows);
273
274 for(blah=0; blah<of.numchn; blah++)
275 of.tracks[numtrk++] = IT_ConvertTrack(&itpat[blah],patrows);
276
277 return 1;
278 }
279
280
281 void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, BOOL oldeffect);
282
283 // table for porta-to-note command within volume/panning column
284 static UBYTE portatable[] = "1, 4, 8, 16, 32, 64, 96, 128, 255";
285
286 UBYTE *IT_ConvertTrack(ITNOTE *tr, UWORD numrows)
287 {
288 int t;
289
290 UBYTE note,ins,volpan;
291
292 UniReset();
293
294 for(t=0; t<numrows; t++)
295 { note = tr[t*of.numchn].note;
296 ins = tr[t*of.numchn].ins;
297 volpan = tr[t*of.numchn].volpan;
298
299 if(note!=255)
300 { if(note==253)
301 UniWrite(UNI_KEYOFF);
302 else if(note==254)
303 UniPTEffect(0xc,0); // <- note cut command
304 else
305 UniNote(note);
306 }
307
308 if((ins != 0) && (ins < 100)) UniInstrument(ins-1);
309
310 // process volume / panning column
311 // volume / panning effects do NOT all share the same memory address
312 // yet. That requires more work than I care to apply at the moment ;)
313
314 if(volpan<=64)
315 { UniVolEffect(VOL_VOLUME,volpan);
316 } else if((volpan>=65) && (volpan<=74)) // fine volume slide up (65-74)
317 { UniVolEffect(VOL_VOLSLIDE,0x0f + ((volpan-65)<<4));
318 } else if((volpan>=75) && (volpan<=84)) // fine volume slide down (75-84)
319 { UniVolEffect(VOL_VOLSLIDE,0xf0 + (volpan-75));
320 } else if((volpan>=85) && (volpan<=94)) // volume slide up (85-94)
321 { UniVolEffect(VOL_VOLSLIDE,((volpan-85)<<4));
322 } else if((volpan>=95) && (volpan<=104)) // volume slide down (95-104)
323 { UniVolEffect(VOL_VOLSLIDE,(volpan-95));
324 } else if((volpan>=105) && (volpan<=114)) // pitch slide up (105-114)
325 { UniVolEffect(VOL_PITCHSLIDEDN,((volpan-105)<<4));
326 } else if((volpan>=115) && (volpan<=124)) // pitch slide down (115-124)
327 { UniVolEffect(VOL_PITCHSLIDEUP,(volpan-115));
328 } else if((volpan>=128) && (volpan<=192))
329 { UniVolEffect(VOL_PANNING,((volpan-128) == 64) ? 255 : ((volpan-128) << 2));
330 } else if((volpan>=193) && (volpan<=202)) // portamento to note
331 { UniVolEffect(VOL_PORTAMENTO,portatable[volpan-193]);
332 } else if((volpan>=203) && (volpan<=212)) // vibrato
333 { UniVolEffect(VOL_VIBRATO,(volpan-203));
334 }
335
336 S3MIT_ProcessCmd(tr[t*of.numchn].cmd,tr[t*of.numchn].inf,old_effect);
337
338 UniNewline();
339 }
340 return UniDup();
341 }
342
343
344 int cvt_c5spd_to_finetune(ULONG c5spd, int sampnum)
345 {
346 int ctmp=0,tmp,note=1,finetune=0;
347
348 c5spd/=2;
349
350 do
351 { tmp = getfrequency(of.flags,getlinearperiod(note,0));
352 if(tmp >= c5spd) break;
353 ctmp = tmp;
354 note++;
355 } while(1);
356
357 if(tmp != c5spd)
358 { if((tmp-c5spd) < (c5spd-ctmp))
359 while(tmp>c5spd) tmp = getfrequency(of.flags,getlinearperiod(note,--finetune));
360 else
361 { note--;
362 while(ctmp<c5spd) ctmp = getfrequency(of.flags,getlinearperiod(note,++finetune));
363 }
364 }
365
366 noteindex[sampnum] = note-48;
367 return finetune;
368 }
369
370
371 BOOL IT_Load(void)
372 {
373 int t,u,lp;
374 INSTRUMENT *d;
375 SAMPLE *q;
376
377 numtrk = 0;
378
379 // try to read module header
380
381 _mm_read_I_ULONG(modfp); // kill the 4 byte header
382 _mm_read_string(mh->songname,26,modfp);
383 _mm_read_UBYTES(mh->blank01,2,modfp);
384 mh->ordnum =_mm_read_I_UWORD(modfp);
385 mh->insnum =_mm_read_I_UWORD(modfp);
386 mh->smpnum =_mm_read_I_UWORD(modfp);
387 mh->patnum =_mm_read_I_UWORD(modfp);
388 mh->cwt =_mm_read_I_UWORD(modfp);
389 mh->cmwt =_mm_read_I_UWORD(modfp);
390 mh->flags =_mm_read_I_UWORD(modfp);
391 mh->special =_mm_read_I_UWORD(modfp);
392
393 mh->globvol =_mm_read_UBYTE(modfp);
394 mh->mixvol =_mm_read_UBYTE(modfp);
395 mh->initspeed =_mm_read_UBYTE(modfp);
396 mh->inittempo =_mm_read_UBYTE(modfp);
397 mh->pansep =_mm_read_UBYTE(modfp);
398 mh->zerobyte =_mm_read_UBYTE(modfp);
399 mh->msglength =_mm_read_I_UWORD(modfp);
400 mh->msgoffset =_mm_read_I_ULONG(modfp);
401 _mm_read_UBYTES(mh->blank02,4,modfp);
402 _mm_read_UBYTES(mh->pantable,64,modfp);
403 _mm_read_UBYTES(mh->voltable,64,modfp);
404
405 if(feof(modfp))
406 { _mm_errno = MMERR_LOADING_HEADER;
407 return 0;
408 }
409
410 // set module variables
411
412 of.modtype = strdup(IT_Version);
413 of.modtype[15] = (mh->cwt >> 8) + 0x30;
414 of.modtype[17] = ((mh->cwt >> 4) & 0xf) + 0x30;
415 of.modtype[18] = ((mh->cwt) & 0xf) + 0x30;
416 of.songname = DupStr(mh->songname,26); // make a cstr of songname
417 of.reppos = 0;
418 of.numpat = mh->patnum;
419 of.numins = mh->insnum;
420 of.numsmp = mh->smpnum;
421 of.initspeed = mh->initspeed;
422 of.inittempo = mh->inittempo;
423 of.initvolume = mh->globvol;
424
425 old_effect = 0;
426 if(mh->flags & 8) { of.flags |= (UF_XMPERIODS | UF_LINEAR); old_effect |= 2; }
427 if((mh->cwt >= 0x106) && (mh->flags & 16)) old_effect |= 1;
428
429 // set panning positions
430 for(t=0; t<64; t++)
431 { if(mh->pantable[t] < 64) of.panning[t] = mh->pantable[t] << 2;
432 else if(mh->pantable[t]==64) of.panning[t] = 255;
433 else if(mh->pantable[t]==100) of.panning[t] = PAN_SURROUND;
434 }
435
436 // set channel volumes
437 memcpy(of.chanvol,mh->voltable,64);
438
439 // read the order data
440 if(!AllocPositions(mh->ordnum)) return 0;
441
442 for(t=0; t<mh->ordnum; t++)
443 of.positions[t] = _mm_read_UBYTE(modfp);
444
445 if(feof(modfp))
446 { _mm_errno = MMERR_LOADING_HEADER;
447 return 0;
448 }
449
450 of.numpos = 0;
451 for(t=0; t<mh->ordnum; t++)
452 { of.positions[of.numpos] = of.positions[t];
453 poslookup[t] = of.numpos; // bug fix for FREAKY S3Ms / ITs
454 if(of.positions[t]<254) of.numpos++;
455 }
456
457 if((paraptr=(ULONG *)_mm_malloc((mh->insnum+mh->smpnum+of.numpat)*sizeof(ULONG))) == NULL) return 0;
458
459 // read the instrument, sample, and pattern parapointers
460 _mm_read_I_ULONGS(paraptr,mh->insnum+mh->smpnum+of.numpat,modfp);
461
462 // now is a good time to check if the header was too short :)
463 if(feof(modfp))
464 { _mm_errno = MMERR_LOADING_HEADER;
465 return 0;
466 }
467
468 // Check for and load song comment
469 if(mh->special & 1)
470 { _mm_fseek(modfp,(long)(mh->msgoffset),SEEK_SET);
471 if(!ReadComment(mh->msglength)) return 0;
472 }
473
474 if(!(mh->flags & 4)) of.numins = of.numsmp;
475 if(!AllocSamples()) return 0;
476
477 if((noteindex=(int *)_mm_malloc(mh->smpnum*sizeof(int)))==NULL) return 0;
478
479 q = of.samples;
480
481 // Load all samples (they're used either way)
482 for(t=0; t<mh->smpnum; t++)
483 { ITSAMPLE s;
484
485 // seek to sample position
486 _mm_fseek(modfp,(long)(paraptr[mh->insnum+t] + 4),SEEK_SET);
487
488 // and load sample info
489 _mm_read_string(s.filename,12,modfp);
490 s.zerobyte = _mm_read_UBYTE(modfp);
491 s.globvol = _mm_read_UBYTE(modfp);
492 s.flag = _mm_read_UBYTE(modfp);
493 s.volume = _mm_read_UBYTE(modfp);
494 _mm_read_string(s.sampname,26,modfp);
495 s.convert = _mm_read_UBYTE(modfp);
496 s.panning = _mm_read_UBYTE(modfp);
497 s.length = _mm_read_I_ULONG(modfp);
498 s.loopbeg = _mm_read_I_ULONG(modfp);
499 s.loopend = _mm_read_I_ULONG(modfp);
500 s.c5spd = _mm_read_I_ULONG(modfp);
501 s.susbegin = _mm_read_I_ULONG(modfp);
502 s.susend = _mm_read_I_ULONG(modfp);
503 s.sampoffset = _mm_read_I_ULONG(modfp);
504 s.vibspeed = _mm_read_UBYTE(modfp);
505 s.vibdepth = _mm_read_UBYTE(modfp);
506 s.vibrate = _mm_read_UBYTE(modfp);
507 s.vibwave = _mm_read_UBYTE(modfp);
508
509
510 // Generate an error if c5spd is > 512k, or samplelength > 256 megs
511 // (nothing would EVER be that high)
512
513 if(feof(modfp) || (s.c5spd > 0x7ffffL) || (s.length > 0xfffffffUL) ||
514 (s.loopbeg > 0xfffffffUL) || (s.loopend > 0xfffffffUL))
515 { _mm_errno = MMERR_LOADING_SAMPLEINFO;
516 return 0;
517 }
518
519 q->samplename = DupStr(s.sampname,26);
520
521 q->speed = s.c5spd / 2;
522 q->panning = ((s.panning & 127)==64) ? 255 : (s.panning & 127) << 2;
523 q->length = s.length;
524 q->loopstart = s.loopbeg;
525 q->loopend = s.loopend;
526 q->volume = s.volume;
527 q->globvol = s.globvol;
528 q->seekpos = s.sampoffset;
529
530 // ===================================
531 // Convert speed to XM linear finetune
532
533 if(of.flags & UF_LINEAR)
534 q->speed = cvt_c5spd_to_finetune(s.c5spd, t);
535
536 if(s.panning & 128) q->flags |= SF_OWNPAN;
537
538 if(s.vibrate)
539 { q->vibflags |= AV_IT;
540 q->vibtype = s.vibwave;
541 q->vibsweep = s.vibrate * 2;
542 q->vibdepth = s.vibdepth;
543 q->vibrate = s.vibspeed;
544 }
545
546 if(s.flag & 2) q->flags |= SF_16BITS;
547 if(s.flag & 16) q->flags |= SF_LOOP;
548 if(s.flag & 64) q->flags |= SF_BIDI;
549
550 if(mh->cwt >= 0x200)
551 { if(s.convert & 1) q->flags |= SF_SIGNED;
552 if(s.convert & 4) q->flags |= SF_DELTA;
553 }
554
555 q++;
556 }
557
558 // Load instruments if instrument mode flag enabled
559
560 if(mh->flags & 4)
561 { if(!AllocInstruments()) return 0;
562 d = of.instruments;
563 of.flags |= UF_NNA | UF_INST;
564
565 for(t=0; t<mh->insnum; t++)
566 { ITINSTHEADER ih;
567
568 // seek to instrument position
569 _mm_fseek(modfp,paraptr[t]+4,SEEK_SET);
570
571 // and load instrument info
572 _mm_read_string(ih.filename,12,modfp);
573 ih.zerobyte = _mm_read_UBYTE(modfp);
574 if(mh->cwt < 0x200) // load IT 1.xx inst header
575 { ih.volflg = _mm_read_UBYTE(modfp);
576 ih.volbeg = _mm_read_UBYTE(modfp);
577 ih.volend = _mm_read_UBYTE(modfp);
578 ih.volsusbeg = _mm_read_UBYTE(modfp);
579 ih.volsusend = _mm_read_UBYTE(modfp);
580 _mm_read_I_UWORD(modfp);
581 ih.fadeout = _mm_read_I_UWORD(modfp);
582 ih.nna = _mm_read_UBYTE(modfp);
583 ih.dnc = _mm_read_UBYTE(modfp);
584 } else // Read IT200+ header
585 { ih.nna = _mm_read_UBYTE(modfp);
586 ih.dct = _mm_read_UBYTE(modfp);
587 ih.dca = _mm_read_UBYTE(modfp);
588 ih.fadeout = _mm_read_I_UWORD(modfp);
589 ih.ppsep = _mm_read_UBYTE(modfp);
590 ih.ppcenter = _mm_read_UBYTE(modfp);
591 ih.globvol = _mm_read_UBYTE(modfp);
592 ih.chanpan = _mm_read_UBYTE(modfp);
593 ih.rvolvar = _mm_read_UBYTE(modfp);
594 ih.rpanvar = _mm_read_UBYTE(modfp);
595 }
596
597 ih.trkvers = _mm_read_I_UWORD(modfp);
598 ih.numsmp = _mm_read_UBYTE(modfp);
599 _mm_read_UBYTE(modfp);
600 _mm_read_string(ih.name,26,modfp);
601 _mm_read_UBYTES(ih.blank01,6,modfp);
602 _mm_read_I_UWORDS(ih.samptable,120,modfp);
603 if(mh->cwt < 0x200) // load IT 1xx volume envelope
604 { _mm_read_UBYTES(ih.volenv,200,modfp);
605 for(lp=0; lp<25; lp++)
606 { ih.oldvoltick[lp] = _mm_read_UBYTE(modfp);
607 ih.volnode[lp] = _mm_read_UBYTE(modfp);
608 }
609 } else // load IT 2xx vol & chanpan & pitch envs
610 { ih.volflg = _mm_read_UBYTE(modfp);
611 ih.volpts = _mm_read_UBYTE(modfp);
612 ih.volbeg = _mm_read_UBYTE(modfp);
613 ih.volend = _mm_read_UBYTE(modfp);
614 ih.volsusbeg = _mm_read_UBYTE(modfp);
615 ih.volsusend = _mm_read_UBYTE(modfp);
616 for(lp=0; lp<25; lp++)
617 { ih.volnode[lp] = _mm_read_UBYTE(modfp);
618 ih.voltick[lp] = _mm_read_I_UWORD(modfp);
619 }
620 _mm_read_UBYTE(modfp);
621
622 ih.panflg = _mm_read_UBYTE(modfp);
623 ih.panpts = _mm_read_UBYTE(modfp);
624 ih.panbeg = _mm_read_UBYTE(modfp);
625 ih.panend = _mm_read_UBYTE(modfp);
626 ih.pansusbeg = _mm_read_UBYTE(modfp);
627 ih.pansusend = _mm_read_UBYTE(modfp);
628 for(lp=0; lp<25; lp++)
629 { ih.pannode[lp] = _mm_read_SBYTE(modfp);
630 ih.pantick[lp] = _mm_read_I_UWORD(modfp);
631 }
632 _mm_read_UBYTE(modfp);
633
634 ih.pitflg = _mm_read_UBYTE(modfp);
635 ih.pitpts = _mm_read_UBYTE(modfp);
636 ih.pitbeg = _mm_read_UBYTE(modfp);
637 ih.pitend = _mm_read_UBYTE(modfp);
638 ih.pitsusbeg = _mm_read_UBYTE(modfp);
639 ih.pitsusend = _mm_read_UBYTE(modfp);
640 for(lp=0; lp<25; lp++)
641 { ih.pitnode[lp] = _mm_read_SBYTE(modfp);
642 ih.pittick[lp] = _mm_read_I_UWORD(modfp);
643 }
644 _mm_read_UBYTE(modfp);
645 }
646
647 if(feof(modfp))
648 { _mm_errno = MMERR_LOADING_SAMPLEINFO;
649 return 0;
650 }
651
652 d->volflg |= EF_VOLENV;
653 d->insname = DupStr(ih.name,26);
654 d->nnatype = ih.nna;
655
656 if(mh->cwt < 0x200)
657 { d->volfade = ih.fadeout << 6;
658 if(ih.dnc)
659 { d->dct = DCT_NOTE;
660 d->dca = DCA_CUT;
661 }
662
663 if(ih.volflg & 1) d->volflg |= EF_ON;
664 if(ih.volflg & 2) d->volflg |= EF_LOOP;
665 if(ih.volflg & 4) d->volflg |= EF_SUSTAIN;
666
667 // XM conversion of IT envelope Array
668
669 d->volbeg = ih.volbeg;
670 d->volend = ih.volend;
671 d->volsusbeg = ih.volsusbeg;
672 d->volsusend = ih.volsusend;
673
674 if(ih.volflg & 1)
675 { for(u=0; u<25; u++)
676 if(ih.oldvoltick[d->volpts] != 0xff)
677 { d->volenv[d->volpts].val = (ih.volnode[d->volpts] << 2);
678 d->volenv[d->volpts].pos = ih.oldvoltick[d->volpts];
679 d->volpts++;
680 } else break;
681 }
682 } else
683 { d->panning = ((ih.chanpan&127) == 64) ? 255 : (ih.chanpan&127)<<2;
684 if(!(ih.chanpan & 128)) d->flags |= IF_OWNPAN;
685
686 if(!(ih.ppsep & 128))
687 { d->pitpansep = ih.ppsep << 2;
688 d->pitpancenter= ih.ppcenter;
689 d->flags |= IF_PITCHPAN;
690 }
691 d->globvol = ih.globvol >> 1;
692 d->volfade = ih.fadeout << 5;
693 d->dct = ih.dct;
694 d->dca = ih.dca;
695
696 if(mh->cwt >= 0x204)
697 { d->rvolvar = ih.rvolvar;
698 d->rpanvar = ih.rpanvar;
699 }
700
701 if(ih.volflg & 1) d->volflg |= EF_ON;
702 if(ih.volflg & 2) d->volflg |= EF_LOOP;
703 if(ih.volflg & 4) d->volflg |= EF_SUSTAIN;
704
705 if(ih.panflg & 1) d->panflg |= EF_ON;
706 if(ih.panflg & 2) d->panflg |= EF_LOOP;
707 if(ih.panflg & 4) d->panflg |= EF_SUSTAIN;
708
709 if(ih.pitflg & 1) d->pitflg |= EF_ON;
710 if(ih.pitflg & 2) d->pitflg |= EF_LOOP;
711 if(ih.pitflg & 4) d->pitflg |= EF_SUSTAIN;
712
713 d->volpts = ih.volpts;
714 d->volbeg = ih.volbeg;
715 d->volend = ih.volend;
716 d->volsusbeg = ih.volsusbeg;
717 d->volsusend = ih.volsusend;
718
719 for(u=0; u<ih.volpts; u++)
720 { d->volenv[u].val = (ih.volnode[u] << 2);
721 d->volenv[u].pos = ih.voltick[u];
722 }
723
724 d->panpts = ih.panpts;
725 d->panbeg = ih.panbeg;
726 d->panend = ih.panend;
727 d->pansusbeg = ih.pansusbeg;
728 d->pansusend = ih.pansusend;
729
730 for(u=0; u<ih.panpts; u++)
731 { d->panenv[u].val = (ih.pannode[u]+32) << 2;
732 d->panenv[u].pos = ih.pantick[u];
733 }
734
735 d->pitpts = ih.pitpts;
736 d->pitbeg = ih.pitbeg;
737 d->pitend = ih.pitend;
738 d->pitsusbeg = ih.pitsusbeg;
739 d->pitsusend = ih.pitsusend;
740
741 for(u=0; u<ih.pitpts; u++)
742 { d->pitenv[u].val = (ih.pitnode[u]+32);
743 d->pitenv[u].pos = ih.pittick[u];
744 }
745 }
746
747 if(of.flags & UF_LINEAR)
748 { for(u=0; u<120; u++)
749 { d->samplenote[u] = (ih.samptable[u] & 255);
750 d->samplenumber[u] = (ih.samptable[u] >> 8) ? ((ih.samptable[u] >> 8) - 1) : 255;
751 if(d->samplenumber[u]!=255)
752 d->samplenote[u] += noteindex[d->samplenumber[u]];
753 }
754 } else
755 { for(u=0; u<120; u++)
756 { d->samplenote[u] = (ih.samptable[u] & 255);
757 d->samplenumber[u] = (ih.samptable[u] >> 8) ? ((ih.samptable[u] >> 8) - 1) : 255;
758 }
759 }
760
761 d++;
762 }
763 } else if(of.flags & UF_LINEAR)
764 { if(!AllocInstruments()) return 0;
765 d = of.instruments;
766 of.flags |= UF_INST;
767
768 for(t=0; t<mh->smpnum; t++, d++)
769 { for(u=0; u<120; u++)
770 d->samplenote[u] += noteindex[d->samplenumber[u]];
771 }
772 }
773
774
775 // Figure out how many channels this blasted song actually uses (what
776 // ever happened to common courtesy of storing this simple value
777 // somewhere in the damn module, eh!?)
778
779 of.numchn = 0;
780 memset(remap,-1,64*sizeof(UBYTE));
781
782 for(t=0; t<of.numpat; t++)
783 { UWORD packlen;
784
785 // seek to pattern position
786 if(paraptr[mh->insnum+mh->smpnum+t] != 0) // No parapointer = pattern of 64 rows, EMPTY
787 { _mm_fseek(modfp,(((long)paraptr[mh->insnum+mh->smpnum+t])),SEEK_SET);
788 packlen = _mm_read_I_UWORD(modfp);
789 packlen = _mm_read_I_UWORD(modfp); // read pattern length (# of rows)
790 _mm_read_I_ULONG(modfp);
791 if(IT_GetNumChannels(packlen)) return 0;
792 }
793 }
794
795 // give each of them a different number
796 for(t=0; t<64; t++)
797 { if(remap[t]==0)
798 { remap[t] = of.numchn;
799 of.numchn++;
800 }
801 }
802
803 of.numtrk = of.numpat*of.numchn;
804
805
806 if(!AllocPatterns()) return 0;
807 if(!AllocTracks()) return 0;
808
809 for(t=0; t<of.numpat; t++)
810 { UWORD packlen;
811
812 // seek to pattern position
813 if(paraptr[mh->insnum+mh->smpnum+t] == 0) // No parapointer = pattern of 64 rows, EMPTY
814 { of.pattrows[t] = 64;
815 for(u=0; u<of.numchn; u++)
816 { int k;
817 UniReset();
818 for(k=0; k<64; k++) UniNewline();
819 of.tracks[numtrk++] = UniDup();
820 }
821 } else
822 { _mm_fseek(modfp,(((long)paraptr[mh->insnum+mh->smpnum+t])),SEEK_SET);
823 packlen = _mm_read_I_UWORD(modfp);
824 of.pattrows[t] = _mm_read_I_UWORD(modfp);
825 _mm_read_I_ULONG(modfp);
826
827 if(!IT_ReadPattern(of.pattrows[t])) return 0;
828 }
829 }
830
831 return 1;
832 }
833
834
835 CHAR *IT_LoadTitle(void)
836 {
837 CHAR s[26];
838
839 _mm_fseek(modfp,4,SEEK_SET);
840 if(!fread(s,26,1,modfp)) return NULL;
841
842 return(DupStr(s,26));
843 }
844
845
846 MLOADER load_it =
847 { NULL,
848 "IT",
849 "Portable IT loader v0.2",
850 IT_Init,
851 IT_Test,
852 IT_Load,
853 IT_Cleanup,
854
855 IT_LoadTitle
856 };
857