1 /* OpenCP Module Player
2 * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3 * copyright (c) 2005-'20 Stian Skjelstad <stian.skjelstad@gmail.com>
4 *
5 * ITPlay .IT module loader
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * revision history: (please note changes here)
22 * -nb980510 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
23 * -first release
24 * -kb980717 Tammo Hinrichs <kb@nwn.de>
25 * -many many many many small memory allocation bugs fixed. the heap looked
26 * more like a swiss cheese than like anything else after the player had
27 * run. but now, everything's initialised, alloced and freed correctly
28 * (i hope).
29 * -added IT2.14 decompression. Thanks to daniel for handing me that
30 * not-fully-working source which i needed to completely find out the
31 * compression (see ITSEX.CPP).
32 * -added MIDI command and filter setting reading. This will become use-
33 * ful as soon i have a software mixing routine with filters, at the
34 * moment its only use is to prevent confusion of filter and pitch
35 * envelopes
36 */
37
38 #include "config.h"
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include "types.h"
43 #include "dev/mcp.h"
44 #include "filesel/filesystem.h"
45 #include "itplay.h"
46 #include "stuff/compat.h"
47 #include "stuff/err.h"
48
it_load(struct it_module * this,struct ocpfilehandle_t * file)49 int __attribute__ ((visibility ("internal"))) it_load(struct it_module *this, struct ocpfilehandle_t *file)
50 {
51 int i,j,k,n;
52
53 struct __attribute__((packed))
54 {
55 uint32_t sig;
56 uint8_t name[26];
57 uint16_t philite;
58 uint16_t nords;
59 uint16_t nins;
60 uint16_t nsmps;
61 uint16_t npats;
62 uint16_t cwtv;
63 uint16_t cmwt;
64 uint16_t flags;
65 uint16_t special;
66 uint8_t gvol;
67 uint8_t mvol;
68 uint8_t ispd;
69 uint8_t itmp;
70 uint8_t chsep;
71 uint8_t pwd;
72 uint16_t msglen;
73 uint32_t msgoff;
74 uint32_t _d3;
75 uint8_t pan[64];
76 uint8_t vol[64];
77 } hdr;
78
79 int signedsamp; /* boolean */
80 int maxchan;
81
82 #define MAX_ORDERS 256
83 #define MAX_SAMPLES 100
84 #define MAX_INSTRUMENTS 100
85 #define MAX_PATTERNS 200
86
87 uint8_t ords[MAX_ORDERS];
88 uint32_t sampoff[MAX_SAMPLES];
89 uint32_t insoff[MAX_INSTRUMENTS];
90 uint32_t patoff[MAX_PATTERNS];
91
92 this->nchan=0;
93 this->ninst=0;
94 this->nsampi=0;
95 this->nsamp=0;
96 this->npat=0;
97 this->nord=0;
98 this->orders=0;
99 this->patlens=0;
100 this->patterns=0;
101 this->samples=0;
102 this->instruments=0;
103 this->sampleinfos=0;
104 this->midicmds=0;
105 this->deltapacked=0;
106 this->message=0;
107
108 file->seek_set (file, 0);
109
110 if (file->read (file, &hdr, sizeof (hdr)) != sizeof (hdr))
111 {
112 fprintf(stderr, "[IT]: fread() failed #1\n");
113 return errFileRead;
114 }
115 hdr.sig = uint32_little (hdr.sig);
116 hdr.philite = uint16_little (hdr.philite);
117 hdr.nords = uint16_little (hdr.nords);
118 hdr.nins = uint16_little (hdr.nins);
119 hdr.nsmps = uint16_little (hdr.nsmps);
120 hdr.npats = uint16_little (hdr.npats);
121 hdr.cwtv = uint16_little (hdr.cwtv);
122 hdr.cmwt = uint16_little (hdr.cmwt);
123 hdr.flags = uint16_little (hdr.flags);
124 hdr.special = uint16_little (hdr.special);
125 hdr.msglen = uint16_little (hdr.msglen);
126 hdr.msgoff = uint32_little (hdr.msgoff);
127 hdr._d3 = uint32_little (hdr._d3);
128 #ifdef IT_LOAD_DEBUG
129 fprintf(stderr, __FILE__ ": hdr.sig %d\n", (int)hdr.sig);
130 fprintf(stderr, __FILE__ ": hdr.philite %d\n", (int)hdr.philite);
131 fprintf(stderr, __FILE__ ": hdr.nords %d\n", (int)hdr.nords);
132 fprintf(stderr, __FILE__ ": hdr.nins %d\n", (int)hdr.nins);
133 fprintf(stderr, __FILE__ ": hdr.nsmps %d\n", (int)hdr.nsmps);
134 fprintf(stderr, __FILE__ ": hdr.npats %d\n", (int)hdr.npats);
135 fprintf(stderr, __FILE__ ": hdr.cwtv %d\n", (int)hdr.cwtv);
136 fprintf(stderr, __FILE__ ": hdr.cmwt %d\n", (int)hdr.cmwt);
137 fprintf(stderr, __FILE__ ": hdr.flags %d\n", (int)hdr.flags);
138 fprintf(stderr, __FILE__ ": hdr.special %d\n", (int)hdr.special);
139 fprintf(stderr, __FILE__ ": hdr.msglen %d\n", (int)hdr.msglen);
140 fprintf(stderr, __FILE__ ": hdr.msgoff %d\n", (int)hdr.msgoff);
141 fprintf(stderr, __FILE__ ": hdr._d3 %d\n", (int)hdr._d3);
142 #endif
143 if (hdr.sig!=0x4D504D49)
144 {
145 fprintf(stderr, "IT: Invalid header\n");
146 return errFormSig;
147 }
148 if ((hdr.flags&4)&&(hdr.cmwt<0x200))
149 {
150 fprintf(stderr, "IT: Too old format\n");
151 return errFormOldVer;
152 }
153 if (hdr.nords>MAX_ORDERS)
154 {
155 fprintf(stderr, "IT: Too many orders\n");
156 return errFormStruc;
157 }
158 if (hdr.nins>MAX_INSTRUMENTS)
159 {
160 fprintf(stderr, "IT: Too many instruments\n");
161 return errFormStruc;
162 }
163 if (hdr.nsmps>MAX_SAMPLES)
164 {
165 fprintf(stderr, "IT: Too many samples\n");
166 return errFormStruc;
167 }
168 if (hdr.npats>MAX_PATTERNS)
169 {
170 fprintf(stderr, "IT: Too many patterns\n");
171 return errFormStruc;
172 }
173
174 signedsamp=!(hdr.cwtv<0x202);
175 this->deltapacked=(hdr.cmwt>=0x215);
176
177 if (file->read (file, ords, hdr.nords * sizeof(uint8_t)) != (hdr.nords * sizeof(uint8_t)))
178 {
179 fprintf(stderr, "[IT]: fread() failed #2\n");
180 return errFileRead;
181 }
182 if (hdr.nins)
183 {
184 if (file->read (file, insoff, hdr.nins * sizeof(uint32_t)) != (hdr.nins * sizeof(uint32_t)))
185 {
186 fprintf(stderr, "[IT]: fread() failed #3 (hdr.nins=%d)\n", hdr.nins);
187 return errFileRead;
188 }
189 }
190 if (file->read (file, sampoff, hdr.nsmps * sizeof(uint32_t)) != (hdr.nsmps * sizeof(uint32_t)))
191 {
192 fprintf(stderr, "[IT]: fread() failed #4\n");
193 return errFileRead;
194 }
195 if (file->read (file, patoff, hdr.npats * sizeof(uint32_t)) != (hdr.npats * sizeof(uint32_t)))
196 {
197 fprintf(stderr, "[IT]: fread() failed #5\n");
198 return errFileRead;
199 }
200 for (i=0;i<hdr.nins;i++)
201 insoff[i] = uint32_little (insoff[i]);
202 for (i=0;i<hdr.nsmps;i++)
203 sampoff[i] = uint32_little (sampoff[i]);
204 for (i=0;i<hdr.npats;i++)
205 patoff[i] = uint32_little (patoff[i]);
206
207 memcpy(this->name, hdr.name, 26);
208 for ( n=0; n<26; n++ )
209 if (!this->name[n])
210 this->name[n]=32;
211 this->name[26]=0;
212 this->linearfreq=!!(hdr.flags&8);
213
214 this->inispeed=hdr.ispd;
215 this->initempo=hdr.itmp;
216 this->inigvol=hdr.gvol;
217
218 this->chsep=(hdr.flags&1)?hdr.chsep:0;
219 this->instmode=hdr.flags&4;
220 this->linear=hdr.flags&8;
221 this->oldfx=hdr.flags&16;
222 this->geffect=hdr.flags&32;
223 this->instmode=hdr.flags&2;
224
225 memcpy(this->inipan, hdr.pan, 64);
226 memcpy(this->inivol, hdr.vol, 64);
227
228 if (hdr.special&4)
229 {
230 uint16_t usage;
231 char dummy[8];
232 if (ocpfilehandle_read_uint16_le (file, &usage))
233 {
234 fprintf(stderr, "[IT]: fread() failed #6\n");
235 return errFileRead;
236 }
237 for (i=0; i<usage; i++)
238 {
239 if (file->read (file, dummy, 8) != 8)
240 {
241 fprintf(stderr, "[IT]: fread() failed #7\n");
242 return errFileRead;
243 }
244 }
245 }
246
247
248 if (hdr.special&8)
249 {
250 char cmd[33];
251
252 if (!(this->midicmds=malloc(sizeof(char *)*(9+16+128))))
253 {
254 fprintf(stderr, __FILE__ ": malloc(%d) failed #1\n", (int)(sizeof(char *)*(9+16+128)));
255 return errAllocMem;
256 }
257
258 memset(cmd,0,sizeof(cmd));
259
260 for (i=0; i<(9+16+128); i++)
261 {
262 if (file->read (file, cmd, 32) != 32)
263 {
264 fprintf(stderr, "[IT]: fread() failed #8\n");
265 return errFileRead;
266 }
267 for ( n=0; n<32; n++ )
268 if (!cmd[n])
269 cmd[n]=32;
270 if (!(this->midicmds[i]=malloc(sizeof(char)*(strlen(cmd)+1))))
271 {
272 fprintf(stderr, __FILE__ ": malloc(%d) failed #2\n", (int)(sizeof(char)*(strlen(cmd)+1)));
273 return errAllocMem;
274 }
275 strcpy(this->midicmds[i], cmd);
276 strupr(this->midicmds[i]);
277 }
278 }
279
280 if (hdr.special&1)
281 {
282 int linect;
283 char *msg;
284
285 if (!(msg=malloc(sizeof(char)*(hdr.msglen+1))))
286 {
287 fprintf(stderr, __FILE__ ": malloc(%d) failed #3\n", (int)(sizeof(char)*(hdr.msglen+1)));
288 return errAllocMem;
289 }
290 linect=1;
291 file->seek_set (file, hdr.msgoff);
292 if (file->read (file, msg, hdr.msglen) != hdr.msglen)
293 {
294 fprintf(stderr, "[IT]: fread() failed #9\n");
295 free(msg);
296 return errFileRead;
297 }
298 msg[hdr.msglen]=0;
299 for (i=0; i<hdr.msglen; i++)
300 {
301 if (msg[i]==0)
302 break;
303 if (msg[i]==13)
304 linect++;
305 }
306 if (!(this->message=calloc(sizeof(char *), linect+1)))
307 {
308 fprintf(stderr, __FILE__ ": calloc(%d) failed #4\n", (int)(sizeof(char *)*linect+1));
309 free(msg);
310 return errAllocMem;
311 }
312 *this->message=msg;
313 linect=1;
314 for (i=0; i<hdr.msglen; i++)
315 {
316 if (msg[i]==0)
317 break;
318 if (msg[i]==13)
319 {
320 msg[i]=0;
321 this->message[linect++]=msg+i+1;
322 }
323 }
324 this->message[linect]=0;
325 }
326
327 this->npat=hdr.npats+1;
328
329 this->nord=hdr.nords;
330 for (i=this->nord-1; i>=0; i--)
331 {
332 if (ords[i]<254)
333 break;
334 this->nord--;
335 }
336 if (!this->nord)
337 {
338 fprintf(stderr, "IT: No orders\n");
339 return errFormMiss;
340 }
341
342 for (i=0; i<this->nord; i++)
343 if (ords[i]==255)
344 break;
345 for (; i>0; i--)
346 if (ords[i-1]!=254)
347 break;
348 this->endord=i;
349
350 if (!(this->orders=malloc(sizeof(uint16_t)*this->nord)))
351 {
352 fprintf(stderr, __FILE__ ": malloc(%d) failed #5\n", (int)(sizeof(uint16_t)*this->nord));
353 return errAllocMem;
354 }
355
356 for (i=0; i<this->nord; i++)
357 this->orders[i]=(ords[i]==254)?0xFFFF:(ords[i]>=hdr.npats)?hdr.npats:ords[i];
358
359 if (!(this->patlens=malloc(sizeof(uint16_t)*this->npat)))
360 {
361 fprintf(stderr, __FILE__ ": malloc(%d) failed #6\n", (int)(sizeof(uint16_t)*this->npat));
362 return errAllocMem;
363 }
364 if (!(this->patterns=calloc(sizeof(uint8_t*), this->npat)))
365 {
366 fprintf(stderr, __FILE__ ": malloc(%d) failed #7\n", (int)(sizeof(uint8_t*)*this->npat));
367 return errAllocMem;
368 }
369
370 this->patlens[this->npat-1]=64;
371 this->patterns[this->npat-1]=malloc(sizeof(uint8_t)*64);
372
373 if (!this->patterns[this->npat-1])
374 {
375 fprintf(stderr, __FILE__ ": malloc(%d) failed #8\n", (int)(sizeof(uint8_t)*64));
376 return errAllocMem;
377 }
378
379 memset(this->patterns[this->npat-1], 0, 64);
380
381 maxchan=0;
382
383 for (k=0; k<hdr.npats; k++)
384 {
385 uint16_t patlen, patrows;
386 uint8_t *patbuf;
387 uint8_t lastmask[64]={0}; /* init values */
388 uint8_t lastnote[64]={0}; /* init values */
389 uint8_t lastins[64]={0}; /* init values */
390 uint8_t lastvolpan[64]={0}; /* init values */
391 uint8_t lastcmd[64]={0}; /* init values */
392 uint8_t lastdata[64]={0}; /* init values */
393 uint8_t *pp;
394 uint8_t *wp;
395
396 if (!patoff[k])
397 {
398 this->patlens[k]=64;
399 if (!(this->patterns[k]=malloc(sizeof(uint8_t)*this->patlens[k])))
400 {
401 fprintf(stderr, __FILE__ ": malloc(%d) failed #9\n", (int)(sizeof(uint8_t)*this->patlens[k]));
402 return errAllocMem;
403 }
404 memset(this->patterns[k], 0, this->patlens[k]);
405 continue;
406 }
407 file->seek_set (file, patoff[k]);
408
409 if (ocpfilehandle_read_uint16_le (file, &patlen))
410 {
411 fprintf(stderr, "[IT]: fread() failed #10\n");
412 return errFileRead;
413 }
414 if (ocpfilehandle_read_uint16_le (file, &patrows))
415 {
416 fprintf(stderr, "[IT]: fread() failed #11\n");
417 return errFileRead;
418 }
419
420 file->seek_cur (file, 4);
421
422 if (!(patbuf=malloc(sizeof(uint8_t)*patlen)))
423 {
424 fprintf(stderr, __FILE__ ": malloc(%d) failed #10\n", (int)(sizeof(uint8_t)*patlen));
425 return errAllocMem;
426 }
427
428 if (file->read (file, patbuf, patlen) != patlen)
429 {
430 fprintf(stderr, "[IT]: fread() failed #12\n");
431 free(patbuf);
432 return errFileRead;
433 }
434 this->patlens[k]=patrows;
435 if (!(this->patterns[k]=malloc(sizeof(uint8_t)*((6*64+1)*this->patlens[k]))))
436 {
437 free(patbuf);
438 fprintf(stderr, __FILE__ ": malloc(%d) failed #11\n", (int)(sizeof(uint8_t)*((6*64+1)*this->patlens[k])));
439 return errAllocMem;
440 }
441
442 pp=patbuf;
443 wp=this->patterns[k];
444 for (i=0; i<this->patlens[k]; i++)
445 {
446 while (1)
447 {
448 int chvar=*pp++;
449 uint8_t chn;
450 int c;
451
452 if (!chvar)
453 break;
454 chn=(chvar-1)&63;
455 if (chvar&128)
456 lastmask[chn]=*pp++;
457 c=lastmask[chn];
458 if (!c)
459 continue;
460 if (maxchan<=chn)
461 maxchan=chn+1;
462 if (c&1)
463 {
464 lastnote[chn]=(*pp<=IT_KEYTABS)?(*pp+1):*pp;
465 pp++;
466 }
467 if (c&2)
468 lastins[chn]=*pp++;
469 if (c&4)
470 {
471 lastvolpan[chn]=1+*pp++;
472 }
473 if (c&8)
474 {
475 lastcmd[chn]=*pp++;
476 lastdata[chn]=*pp++;
477 }
478 *wp++=chn+1;
479 *wp++=(c&0x11)?lastnote[chn]:0;
480 *wp++=(c&0x22)?lastins[chn]:0;
481 *wp++=(c&0x44)?lastvolpan[chn]:0;
482 *wp++=(c&0x88)?lastcmd[chn]:0;
483 *wp++=(c&0x88)?lastdata[chn]:0;
484 }
485 *wp++=0;
486 }
487 free(patbuf);
488 {
489 void *new;
490 if (!(new=realloc(this->patterns[k], wp-this->patterns[k])))
491 {
492 /* we loose the pointer for-ever here */
493 fprintf(stderr, __FILE__ ": realloc(%d) failed #12\n", (int)(wp-this->patterns[k]));
494 return errAllocMem;
495 }
496 this->patterns[k]=(uint8_t *)new;
497 }
498 }
499
500 if (!maxchan)
501 {
502 fprintf(stderr, "IT: No channels used?\n");
503 return errFormSupp;
504 }
505 this->nchan=maxchan;
506
507 this->nsampi=hdr.nsmps;
508 this->nsamp=hdr.nsmps;
509
510 if (!(this->sampleinfos=malloc(sizeof(struct it_sampleinfo)*this->nsampi)))
511 {
512 fprintf(stderr, __FILE__ ": malloc(%d) failed #13\n", (int)(sizeof(struct it_sampleinfo)*this->nsampi));
513 return errAllocMem;
514 }
515 if (!(this->samples=malloc(sizeof(struct it_sample)*this->nsamp)))
516 {
517 fprintf(stderr, __FILE__ ": malloc(%d) failed #14\n", (int)(sizeof(struct it_sample)*this->nsamp));
518 return errAllocMem;
519 }
520 memset(this->sampleinfos, 0, this->nsampi*sizeof(struct it_sampleinfo));
521 memset(this->samples, 0, this->nsamp*sizeof(struct it_sample));
522
523 for (i=0; i<hdr.nsmps; i++)
524 this->samples[i].handle=0xFFFF;
525
526 for (i=0; i<hdr.nsmps; i++)
527 {
528 struct __attribute__((packed))
529 {
530 uint32_t sig;
531 char dosname[13];
532 uint8_t gvl;
533 uint8_t flags;
534 uint8_t vol;
535 char name[26];
536 uint8_t cvt;
537 uint8_t dfp;
538 uint32_t length;
539 uint32_t loopstart;
540 uint32_t loopend;
541 uint32_t c5spd;
542 uint32_t sloopstart;
543 uint32_t sloopend;
544 uint32_t off;
545 uint8_t vis;
546 uint8_t vid;
547 uint8_t vir;
548 uint8_t vit;
549 } shdr;
550
551 struct it_sampleinfo *sip=&this->sampleinfos[i];
552 struct it_sample *sp=&this->samples[i];
553
554 file->seek_set (file, sampoff[i]);
555 if (file->read (file, &shdr, sizeof(shdr)) != sizeof(shdr))
556 {
557 fprintf(stderr, "[IT]: fread() failed #13\n");
558 return errFileRead;
559 }
560 shdr.sig = uint32_little (shdr.sig);
561 shdr.length = uint32_little (shdr.length);
562 shdr.loopstart = uint32_little (shdr.loopstart);
563 shdr.loopend = uint32_little (shdr.loopend);
564 shdr.c5spd = uint32_little (shdr.c5spd);
565 shdr.sloopstart = uint32_little (shdr.sloopstart);
566 shdr.sloopend = uint32_little (shdr.sloopend);
567 shdr.off = uint32_little (shdr.off);
568
569 sampoff[i]=shdr.off;
570 strupr(shdr.dosname);
571
572 memcpy(sp->name, shdr.name, 26);
573 for ( n=0; n<26; n++ )
574 if (!sp->name[n])
575 sp->name[n]=32;
576 sp->name[26]=0;
577
578 if (!(shdr.flags&1))
579 {
580 fprintf(stderr, "itload.c: A sample with flag 0x01 set, skipped\n");
581 continue;
582 }
583
584 if (!(shdr.length))
585 {
586 fprintf(stderr, "itload.c: A sample with length=0, skipped\n");
587 continue;
588 }
589
590 sp->vol=shdr.vol;
591 sp->gvl=shdr.gvl;
592 sp->vir=shdr.vir;
593 sp->vid=shdr.vid;
594 sp->vit=shdr.vit;
595 sp->vis=shdr.vis;
596 sp->dfp=shdr.dfp;
597 sp->handle=i;
598 sp->normnote=-mcpGetNote8363(shdr.c5spd);
599 sip->length=shdr.length;
600 sip->samprate=shdr.c5spd>>((shdr.flags&2)?1:0);
601 sip->samprate=8363;
602
603 sip->loopstart=shdr.loopstart;
604 sip->loopend=shdr.loopend;
605 sip->sloopstart=shdr.sloopstart;
606 sip->sloopend=shdr.sloopend;
607 sip->type=((shdr.flags&2)?mcpSamp16Bit:0)|((shdr.flags&4)?mcpSampStereo:0)|(signedsamp?0:mcpSampUnsigned)|((shdr.flags&0x10)?mcpSampLoop:0)|((shdr.flags&0x40)?mcpSampBiDi:0)|((shdr.flags&0x80)?mcpSampSBiDi:0)|((shdr.flags&0x20)?mcpSampSLoop:0);
608
609 sp->packed=(shdr.flags&8?1:0);
610 if (sp->packed && this->deltapacked && (shdr.cvt & 4))
611 sp->packed|=2;
612
613 if (!(sip->ptr=malloc((sip->length+512)<<((sip->type&mcpSamp16Bit)?1:0))))
614 {
615 fprintf(stderr, __FILE__ ": malloc(%d) failed #15\n", (sip->length+512)<<((sip->type&mcpSamp16Bit)?1:0));
616 return errAllocMem;
617 }
618 }
619
620 for (i=0; i<hdr.nsmps; i++)
621 {
622 struct it_sampleinfo *sip=&this->sampleinfos[i];
623 struct it_sample *sp=&this->samples[i];
624
625 if (!sip->ptr)
626 continue;
627 file->seek_set (file, sampoff[i]);
628
629 if (sp->packed) {
630 if (sip->type & mcpSamp16Bit)
631 decompress16(file, sip->ptr, sip->length, sp->packed&2);
632 else
633 decompress8(file, sip->ptr, sip->length, sp->packed&2);
634 } else {
635 uint64_t len = sip->length<<((sip->type&mcpSamp16Bit)?1:0);
636 if (file->read (file, sip->ptr, len) != len)
637 {
638 fprintf(stderr, "[IT]: fread() failed #14 (sip-ptr=%p sip->length=%d 16bit=%d)\n", sip->ptr, (int)sip->length, !!(sip->type&mcpSamp16Bit));
639 return errFileRead;
640 }
641 }
642 }
643
644 this->ninst=(hdr.flags&4)?hdr.nins:hdr.nsmps;
645 if (!(this->instruments=malloc(sizeof(struct it_instrument)*this->ninst)))
646 {
647 fprintf(stderr, __FILE__ ": malloc(%d) failed #16\n", (int)(sizeof(struct it_instrument)*this->ninst));
648 return errAllocMem;
649 }
650 memset(this->instruments, 0, this->ninst*sizeof(*this->instruments));
651
652 for (k=0; k<this->ninst; k++)
653 {
654 struct __attribute__((packed)) envp
655 {
656 int8_t v;
657 uint16_t p;
658 };
659 struct __attribute__((packed)) env
660 {
661 uint8_t flags;
662 uint8_t num;
663 uint8_t lpb;
664 uint8_t lpe;
665 uint8_t slb;
666 uint8_t sle;
667 struct envp pts[25];
668 uint8_t _d1;
669 };
670 struct __attribute__((packed)) itiheader
671 {
672 uint32_t sig;
673 char dosname[13];
674 uint8_t nna;
675 uint8_t dct;
676 uint8_t dca;
677 uint16_t fadeout;
678 uint8_t pps;
679 uint8_t ppc;
680 uint8_t gbv;
681 uint8_t dfp;
682 uint8_t rv;
683 uint8_t rp;
684 uint16_t tver;
685 uint8_t nos;
686 uint8_t _d3;
687 char name[26];
688 uint8_t ifp;
689 uint8_t ifr;
690 uint8_t mch;
691 uint8_t mpr;
692 uint16_t midibnk;
693 uint8_t keytab[IT_KEYTABS][2];
694 struct env envs[3];
695 };
696 struct itiheader ihdr;
697
698 struct it_instrument *ip=&this->instruments[k];
699
700 if (hdr.flags&4)
701 {
702 int i, j;
703 file->seek_set (file, insoff[k]);
704 if (file->read (file, &ihdr, sizeof(ihdr)) != sizeof (ihdr))
705 {
706 fprintf(stderr, "[IT]: fread() failed #15\n");
707 return errFileRead;
708 }
709 ihdr.sig = uint32_little (ihdr.sig);
710 ihdr.fadeout = uint16_little (ihdr.fadeout);
711 ihdr.tver = uint16_little (ihdr.tver);
712 ihdr.midibnk = uint16_little (ihdr.midibnk);
713 for (i=0;i<4;i++)
714 for (j=0;j<25;j++)
715 ihdr.envs[i].pts[j].p = uint16_little (ihdr.envs[i].pts[j].p);
716 } else {
717 memset(&ihdr, 0, sizeof(ihdr));
718 ihdr.sig=ihdr.tver=ihdr.nos=ihdr._d3=0;
719 #ifdef _WATCOM_
720 if(ihdr.dosname); /*suppress stupid watcom warning */
721 #endif
722 for (i=0; i<IT_KEYTABS; i++)
723 {
724 ihdr.keytab[i][0]=i;
725 ihdr.keytab[i][1]=k+1;
726 }
727 memcpy(ihdr.name, this->samples[k].name, 26);
728 ihdr.name[25]=0;
729 ihdr.dfp=0x80;
730 ihdr.gbv=128;
731 }
732 memcpy(ip->name, ihdr.name, 26);
733 for ( n=0; n<26; n++ )
734 if (!ip->name[n])
735 ip->name[n]=32;
736 ip->name[26]=0;
737 ip->name[27]=0;
738 ip->name[28]=0;
739 ip->handle=k;
740 ip->fadeout=ihdr.fadeout;
741 ip->nna=ihdr.nna;
742 ip->dct=ihdr.dct;
743 ip->dca=ihdr.dca;
744 ip->pps=ihdr.pps;
745 ip->ppc=ihdr.ppc;
746 ip->gbv=ihdr.gbv;
747 ip->dfp=ihdr.dfp;
748 ip->ifp=ihdr.ifp;
749 ip->ifr=ihdr.ifr;
750 ip->mch=ihdr.mch;
751 ip->mpr=ihdr.mpr;
752 ip->midibnk=ihdr.midibnk;
753 ip->rv=ihdr.rv;
754 ip->rp=ihdr.rp;
755
756 memcpy(ip->keytab, ihdr.keytab, IT_KEYTABS*2);
757
758 for (i=0; i<3; i++)
759 {
760 struct env *ie=&ihdr.envs[i];
761 struct it_envelope *e=&ip->envs[i];
762 e->type=((ie->flags&1)?env_type_active:0)|
763 ((ie->flags&2)?env_type_looped:0)|
764 ((ie->flags&4)?env_type_slooped:0)|
765 ((ie->flags&8)?env_type_carry:0)|
766 ((ie->flags&128)?env_type_filter:0);
767 e->len=ie->num-1;
768 e->sloops=ie->slb;
769 e->sloope=ie->sle;
770 e->loops=ie->lpb;
771 e->loope=ie->lpe;
772
773 #ifdef _WATCOM_
774 ie->_d1=ie->_d1; /* suppress stupid watcom warning */
775 #endif
776
777 for (j=0; j<ie->num; j++)
778 {
779 e->y[j]=ie->pts[j].v;
780 e->x[j]=ie->pts[j].p;
781 }
782 }
783 }
784 return 0;
785 }
786
it_free(struct it_module * this)787 void __attribute__ ((visibility ("internal"))) it_free(struct it_module *this)
788 {
789 int i;
790
791 if (this->sampleinfos)
792 {
793 for (i=0; i<this->nsampi; i++)
794 if (this->sampleinfos[i].ptr)
795 free(this->sampleinfos[i].ptr);
796 free(this->sampleinfos);
797 }
798 if (this->samples)
799 free(this->samples);
800 if (this->instruments)
801 free(this->instruments);
802 if (this->patterns)
803 {
804 for (i=0; i<this->npat; i++)
805 if (this->patterns[i])
806 free(this->patterns[i]);
807 free(this->patterns);
808 }
809 if (this->patlens)
810 free(this->patlens);
811 if (this->orders)
812 free(this->orders);
813 if (this->message)
814 {
815 free(*this->message);
816 free(this->message);
817 }
818 if (this->midicmds)
819 {
820 for (i=0; i<(9+16+128); i++)
821 if (this->midicmds[i])
822 free(this->midicmds[i]);
823 free(this->midicmds);
824 }
825 }
826