summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/load_imf.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/load_imf.c')
-rw-r--r--apps/plugins/mikmod/load_imf.c738
1 files changed, 738 insertions, 0 deletions
diff --git a/apps/plugins/mikmod/load_imf.c b/apps/plugins/mikmod/load_imf.c
new file mode 100644
index 0000000000..0b85c0ecc3
--- /dev/null
+++ b/apps/plugins/mikmod/load_imf.c
@@ -0,0 +1,738 @@
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: load_imf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
24
25 Imago Orpheus (IMF) 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
46extern int fprintf(FILE *, const char *, ...);
47#endif
48
49/*========== Module structure */
50
51/* module header */
52typedef struct IMFHEADER {
53 CHAR songname[32];
54 UWORD ordnum;
55 UWORD patnum;
56 UWORD insnum;
57 UWORD flags;
58 UBYTE initspeed;
59 UBYTE inittempo;
60 UBYTE mastervol;
61 UBYTE mastermult;
62 UBYTE orders[256];
63} IMFHEADER;
64
65/* channel settings */
66typedef struct IMFCHANNEL {
67 CHAR name[12];
68 UBYTE chorus;
69 UBYTE reverb;
70 UBYTE pan;
71 UBYTE status;
72} IMFCHANNEL;
73
74/* instrument header */
75#define IMFNOTECNT (10*OCTAVE)
76#define IMFENVCNT (16*2)
77typedef struct IMFINSTHEADER {
78 CHAR name[32];
79 UBYTE what[IMFNOTECNT];
80 UWORD volenv[IMFENVCNT];
81 UWORD panenv[IMFENVCNT];
82 UWORD pitenv[IMFENVCNT];
83 UBYTE volpts;
84 UBYTE volsus;
85 UBYTE volbeg;
86 UBYTE volend;
87 UBYTE volflg;
88 UBYTE panpts;
89 UBYTE pansus;
90 UBYTE panbeg;
91 UBYTE panend;
92 UBYTE panflg;
93 UBYTE pitpts;
94 UBYTE pitsus;
95 UBYTE pitbeg;
96 UBYTE pitend;
97 UBYTE pitflg;
98 UWORD volfade;
99 UWORD numsmp;
100 ULONG signature;
101} IMFINSTHEADER;
102
103/* sample header */
104typedef struct IMFWAVHEADER {
105 CHAR samplename[13];
106 ULONG length;
107 ULONG loopstart;
108 ULONG loopend;
109 ULONG samplerate;
110 UBYTE volume;
111 UBYTE pan;
112 UBYTE flags;
113} IMFWAVHEADER;
114
115typedef struct IMFNOTE {
116 UBYTE note,ins,eff1,dat1,eff2,dat2;
117} IMFNOTE;
118
119/*========== Loader variables */
120
121static CHAR IMF_Version[]="Imago Orpheus";
122
123static IMFNOTE *imfpat=NULL;
124static IMFHEADER *mh=NULL;
125
126/*========== Loader code */
127
128int IMF_Test(void)
129{
130 UBYTE id[4];
131
132 _mm_fseek(modreader,0x3c,SEEK_SET);
133 if(!_mm_read_UBYTES(id,4,modreader)) return 0;
134 if(!memcmp(id,"IM10",4)) return 1;
135 return 0;
136}
137
138int IMF_Init(void)
139{
140 if(!(imfpat=(IMFNOTE*)MikMod_malloc(32*256*sizeof(IMFNOTE)))) return 0;
141 if(!(mh=(IMFHEADER*)MikMod_malloc(sizeof(IMFHEADER)))) return 0;
142
143 return 1;
144}
145
146void IMF_Cleanup(void)
147{
148 FreeLinear();
149
150 MikMod_free(imfpat);
151 MikMod_free(mh);
152}
153
154static int IMF_ReadPattern(SLONG size,UWORD rows)
155{
156 int row=0,flag,ch;
157 IMFNOTE *n,dummy;
158
159 /* clear pattern data */
160 memset(imfpat,255,32*256*sizeof(IMFNOTE));
161
162 while((size>0)&&(row<rows)) {
163 flag=_mm_read_UBYTE(modreader);size--;
164
165 if(_mm_eof(modreader)) {
166 _mm_errno=MMERR_LOADING_PATTERN;
167 return 0;
168 }
169
170 if(flag) {
171 ch=remap[flag&31];
172
173 if(ch!=-1)
174 n=&imfpat[256*ch+row];
175 else
176 n=&dummy;
177
178 if(flag&32) {
179 n->note=_mm_read_UBYTE(modreader);
180 if(n->note>=0xa0) n->note=0xa0; /* note off */
181 n->ins =_mm_read_UBYTE(modreader);
182 size-=2;
183 }
184 if(flag&64) {
185 size-=2;
186 n->eff2=_mm_read_UBYTE(modreader);
187 n->dat2=_mm_read_UBYTE(modreader);
188 }
189 if(flag&128) {
190 n->eff1=_mm_read_UBYTE(modreader);
191 n->dat1=_mm_read_UBYTE(modreader);
192 size-=2;
193 }
194 } else row++;
195 }
196 if((size)||(row!=rows)) {
197 _mm_errno=MMERR_LOADING_PATTERN;
198 return 0;
199 }
200 return 1;
201}
202
203static void IMF_ProcessCmd(UBYTE eff,UBYTE inf)
204{
205 if((eff)&&(eff!=255))
206 switch (eff) {
207 case 0x01: /* set tempo */
208 UniEffect(UNI_S3MEFFECTA,inf);
209 break;
210 case 0x02: /* set BPM */
211 if(inf>=0x20) UniEffect(UNI_S3MEFFECTT,inf);
212 break;
213 case 0x03: /* tone portamento */
214 UniEffect(UNI_ITEFFECTG,inf);
215 break;
216 case 0x04: /* porta + volslide */
217 UniEffect(UNI_ITEFFECTG,inf);
218 UniEffect(UNI_S3MEFFECTD,0);
219 break;
220 case 0x05: /* vibrato */
221 UniEffect(UNI_XMEFFECT4,inf);
222 break;
223 case 0x06: /* vibrato + volslide */
224 UniEffect(UNI_XMEFFECT6,inf);
225 break;
226 case 0x07: /* fine vibrato */
227 UniEffect(UNI_ITEFFECTU,inf);
228 break;
229 case 0x08: /* tremolo */
230 UniEffect(UNI_S3MEFFECTR,inf);
231 break;
232 case 0x09: /* arpeggio */
233 UniPTEffect(0x0,inf);
234 break;
235 case 0x0a: /* panning */
236 UniPTEffect(0x8,(inf>=128)?255:(inf<<1));
237 break;
238 case 0x0b: /* pan slide */
239 UniEffect(UNI_XMEFFECTP,inf);
240 break;
241 case 0x0c: /* set channel volume */
242 if(inf<=64) UniPTEffect(0xc,inf);
243 break;
244 case 0x0d: /* volume slide */
245 UniEffect(UNI_S3MEFFECTD,inf);
246 break;
247 case 0x0e: /* fine volume slide */
248 if(inf) {
249 if(inf>>4)
250 UniEffect(UNI_S3MEFFECTD,0x0f|inf);
251 else
252 UniEffect(UNI_S3MEFFECTD,0xf0|inf);
253 } else
254 UniEffect(UNI_S3MEFFECTD,0);
255 break;
256 case 0x0f: /* set finetune */
257 UniPTEffect(0xe,0x50|(inf>>4));
258 break;
259#ifdef MIKMOD_DEBUG
260 case 0x10: /* note slide up */
261 case 0x11: /* not slide down */
262 fprintf(stderr,"\rIMF effect 0x10/0x11 (note slide)"
263 " not implemented (eff=%2X inf=%2X)\n",eff,inf);
264 break;
265#endif
266 case 0x12: /* slide up */
267 UniEffect(UNI_S3MEFFECTF,inf);
268 break;
269 case 0x13: /* slide down */
270 UniEffect(UNI_S3MEFFECTE,inf);
271 break;
272 case 0x14: /* fine slide up */
273 if (inf) {
274 if (inf<0x40)
275 UniEffect(UNI_S3MEFFECTF,0xe0|(inf>>2));
276 else
277 UniEffect(UNI_S3MEFFECTF,0xf0|(inf>>4));
278 } else
279 UniEffect(UNI_S3MEFFECTF,0);
280 break;
281 case 0x15: /* fine slide down */
282 if (inf) {
283 if (inf<0x40)
284 UniEffect(UNI_S3MEFFECTE,0xe0|(inf>>2));
285 else
286 UniEffect(UNI_S3MEFFECTE,0xf0|(inf>>4));
287 } else
288 UniEffect(UNI_S3MEFFECTE,0);
289 break;
290 /* 0x16 set filter cutoff (awe32) */
291 /* 0x17 filter side + resonance (awe32) */
292 case 0x18: /* sample offset */
293 UniPTEffect(0x9,inf);
294 break;
295#ifdef MIKMOD_DEBUG
296 case 0x19: /* set fine sample offset */
297 fprintf(stderr,"\rIMF effect 0x19 (fine sample offset)"
298 " not implemented (inf=%2X)\n",inf);
299 break;
300#endif
301 case 0x1a: /* keyoff */
302 UniWriteByte(UNI_KEYOFF);
303 break;
304 case 0x1b: /* retrig */
305 UniEffect(UNI_S3MEFFECTQ,inf);
306 break;
307 case 0x1c: /* tremor */
308 UniEffect(UNI_S3MEFFECTI,inf);
309 break;
310 case 0x1d: /* position jump */
311 UniPTEffect(0xb,inf);
312 break;
313 case 0x1e: /* pattern break */
314 UniPTEffect(0xd,(inf>>4)*10+(inf&0xf));
315 break;
316 case 0x1f: /* set master volume */
317 if(inf<=64) UniEffect(UNI_XMEFFECTG,inf<<1);
318 break;
319 case 0x20: /* master volume slide */
320 UniEffect(UNI_XMEFFECTH,inf);
321 break;
322 case 0x21: /* extended effects */
323 switch(inf>>4) {
324 case 0x1: /* set filter */
325 case 0x5: /* vibrato waveform */
326 case 0x8: /* tremolo waveform */
327 UniPTEffect(0xe,inf-0x10);
328 break;
329 case 0xa: /* pattern loop */
330 UniPTEffect(0xe,0x60|(inf&0xf));
331 break;
332 case 0xb: /* pattern delay */
333 UniPTEffect(0xe,0xe0|(inf&0xf));
334 break;
335 case 0x3: /* glissando */
336 case 0xc: /* note cut */
337 case 0xd: /* note delay */
338 case 0xf: /* invert loop */
339 UniPTEffect(0xe,inf);
340 break;
341 case 0xe: /* ignore envelope */
342 UniEffect(UNI_ITEFFECTS0, 0x77); /* vol */
343 UniEffect(UNI_ITEFFECTS0, 0x79); /* pan */
344 UniEffect(UNI_ITEFFECTS0, 0x7b); /* pit */
345 break;
346 }
347 break;
348 /* 0x22 chorus (awe32) */
349 /* 0x23 reverb (awe32) */
350 }
351}
352
353static UBYTE* IMF_ConvertTrack(IMFNOTE* tr,UWORD rows)
354{
355 int t;
356 UBYTE note,ins;
357
358 UniReset();
359 for(t=0;t<rows;t++) {
360 note=tr[t].note;
361 ins=tr[t].ins;
362
363 if((ins)&&(ins!=255)) UniInstrument(ins-1);
364 if(note!=255) {
365 if(note==0xa0) {
366 UniPTEffect(0xc,0); /* Note cut */
367 if(tr[t].eff1==0x0c) tr[t].eff1=0;
368 if(tr[t].eff2==0x0c) tr[t].eff2=0;
369 } else
370 UniNote(((note>>4)*OCTAVE)+(note&0xf));
371 }
372
373 IMF_ProcessCmd(tr[t].eff1,tr[t].dat1);
374 IMF_ProcessCmd(tr[t].eff2,tr[t].dat2);
375 UniNewline();
376 }
377 return UniDup();
378}
379
380int IMF_Load(int curious)
381{
382#define IMF_SMPINCR 64
383 int t,u,track=0,oldnumsmp;
384 IMFCHANNEL channels[32];
385 INSTRUMENT *d;
386 SAMPLE *q;
387 IMFWAVHEADER *wh=NULL,*s=NULL;
388 ULONG *nextwav=NULL;
389 UWORD wavcnt=0;
390 UBYTE id[4];
391
392 /* try to read the module header */
393 _mm_read_string(mh->songname,32,modreader);
394 mh->ordnum=_mm_read_I_UWORD(modreader);
395 mh->patnum=_mm_read_I_UWORD(modreader);
396 mh->insnum=_mm_read_I_UWORD(modreader);
397 mh->flags =_mm_read_I_UWORD(modreader);
398 _mm_fseek(modreader,8,SEEK_CUR);
399 mh->initspeed =_mm_read_UBYTE(modreader);
400 mh->inittempo =_mm_read_UBYTE(modreader);
401 mh->mastervol =_mm_read_UBYTE(modreader);
402 mh->mastermult=_mm_read_UBYTE(modreader);
403 _mm_fseek(modreader,64,SEEK_SET);
404
405 if(_mm_eof(modreader)) {
406 _mm_errno = MMERR_LOADING_HEADER;
407 return 0;
408 }
409
410 /* set module variables */
411 of.songname=DupStr(mh->songname,31,1);
412 of.modtype=StrDup(IMF_Version);
413 of.numpat=mh->patnum;
414 of.numins=mh->insnum;
415 of.reppos=0;
416 of.initspeed=mh->initspeed;
417 of.inittempo=mh->inittempo;
418 of.initvolume=mh->mastervol<<1;
419 of.flags |= UF_INST | UF_ARPMEM | UF_PANNING;
420 if(mh->flags&1) of.flags |= UF_LINEAR;
421 of.bpmlimit=32;
422
423 /* read channel information */
424 of.numchn=0;
425 memset(remap,-1,32*sizeof(UBYTE));
426 for(t=0;t<32;t++) {
427 _mm_read_string(channels[t].name,12,modreader);
428 channels[t].chorus=_mm_read_UBYTE(modreader);
429 channels[t].reverb=_mm_read_UBYTE(modreader);
430 channels[t].pan =_mm_read_UBYTE(modreader);
431 channels[t].status=_mm_read_UBYTE(modreader);
432 }
433 /* bug in Imago Orpheus ? If only channel 1 is enabled, in fact we have to
434 enable 16 channels */
435 if(!channels[0].status) {
436 for(t=1;t<16;t++) if(channels[t].status!=1) break;
437 if(t==16) for(t=1;t<16;t++) channels[t].status=0;
438 }
439 for(t=0;t<32;t++) {
440 if(channels[t].status!=2)
441 remap[t]=of.numchn++;
442 else
443 remap[t]=-1;
444 }
445 for(t=0;t<32;t++)
446 if(remap[t]!=-1) {
447 of.panning[remap[t]]=channels[t].pan;
448 of.chanvol[remap[t]]=channels[t].status?0:64;
449 }
450
451 if(_mm_eof(modreader)) {
452 _mm_errno = MMERR_LOADING_HEADER;
453 return 0;
454 }
455
456 /* read order list */
457 _mm_read_UBYTES(mh->orders,256,modreader);
458 if(_mm_eof(modreader)) {
459 _mm_errno = MMERR_LOADING_HEADER;
460 return 0;
461 }
462
463 of.numpos=0;
464 for(t=0;t<mh->ordnum;t++)
465 if(mh->orders[t]!=0xff) of.numpos++;
466 if(!AllocPositions(of.numpos)) return 0;
467 for(t=u=0;t<mh->ordnum;t++)
468 if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t];
469
470 /* load pattern info */
471 of.numtrk=of.numpat*of.numchn;
472 if(!AllocTracks()) return 0;
473 if(!AllocPatterns()) return 0;
474
475 for(t=0;t<of.numpat;t++) {
476 SLONG size;
477 UWORD rows;
478
479 size=(SLONG)_mm_read_I_UWORD(modreader);
480 rows=_mm_read_I_UWORD(modreader);
481 if((rows>256)||(size<4)) {
482 _mm_errno=MMERR_LOADING_PATTERN;
483 return 0;
484 }
485
486 of.pattrows[t]=rows;
487 if(!IMF_ReadPattern(size-4,rows)) return 0;
488 for(u=0;u<of.numchn;u++)
489 if(!(of.tracks[track++]=IMF_ConvertTrack(&imfpat[u*256],rows)))
490 return 0;
491 }
492
493 /* load instruments */
494 if(!AllocInstruments()) return 0;
495 d=of.instruments;
496
497 for(oldnumsmp=t=0;t<of.numins;t++) {
498 IMFINSTHEADER ih;
499
500 memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
501
502 /* read instrument header */
503 _mm_read_string(ih.name,32,modreader);
504 d->insname=DupStr(ih.name,31,1);
505 _mm_read_UBYTES(ih.what,IMFNOTECNT,modreader);
506 _mm_fseek(modreader,8,SEEK_CUR);
507 _mm_read_I_UWORDS(ih.volenv,IMFENVCNT,modreader);
508 _mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader);
509 _mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader);
510
511#if defined __STDC__ || defined _MSC_VER || defined MPW_C
512#define IMF_FinishLoadingEnvelope(name) \
513 ih. name##pts=_mm_read_UBYTE(modreader); \
514 ih. name##sus=_mm_read_UBYTE(modreader); \
515 ih. name##beg=_mm_read_UBYTE(modreader); \
516 ih. name##end=_mm_read_UBYTE(modreader); \
517 ih. name##flg=_mm_read_UBYTE(modreader); \
518 _mm_read_UBYTE(modreader); \
519 _mm_read_UBYTE(modreader); \
520 _mm_read_UBYTE(modreader)
521#else
522#define IMF_FinishLoadingEnvelope(name) \
523 ih. name/**/pts=_mm_read_UBYTE(modreader); \
524 ih. name/**/sus=_mm_read_UBYTE(modreader); \
525 ih. name/**/beg=_mm_read_UBYTE(modreader); \
526 ih. name/**/end=_mm_read_UBYTE(modreader); \
527 ih. name/**/flg=_mm_read_UBYTE(modreader); \
528 _mm_read_UBYTE(modreader); \
529 _mm_read_UBYTE(modreader); \
530 _mm_read_UBYTE(modreader)
531#endif
532
533 IMF_FinishLoadingEnvelope(vol);
534 IMF_FinishLoadingEnvelope(pan);
535 IMF_FinishLoadingEnvelope(pit);
536
537 ih.volfade=_mm_read_I_UWORD(modreader);
538 ih.numsmp =_mm_read_I_UWORD(modreader);
539
540 _mm_read_UBYTES(id,4,modreader);
541 /* Looks like Imago Orpheus forgets the signature for empty
542 instruments following a multi-sample instrument... */
543 if(memcmp(id,"II10",4) &&
544 (oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) {
545 if(nextwav) MikMod_free(nextwav);
546 if(wh) MikMod_free(wh);
547 _mm_errno=MMERR_LOADING_SAMPLEINFO;
548 return 0;
549 }
550 oldnumsmp=ih.numsmp;
551
552 if((ih.numsmp>16)||(ih.volpts>IMFENVCNT/2)||(ih.panpts>IMFENVCNT/2)||
553 (ih.pitpts>IMFENVCNT/2)||(_mm_eof(modreader))) {
554 if(nextwav) MikMod_free(nextwav);
555 if(wh) MikMod_free(wh);
556 _mm_errno=MMERR_LOADING_SAMPLEINFO;
557 return 0;
558 }
559
560 for(u=0;u<IMFNOTECNT;u++)
561 d->samplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp;
562 d->volfade=ih.volfade;
563
564#if defined __STDC__ || defined _MSC_VER || defined MPW_C
565#define IMF_ProcessEnvelope(name) \
566 for (u = 0; u < (IMFENVCNT >> 1); u++) { \
567 d-> name##env[u].pos = ih. name##env[u << 1]; \
568 d-> name##env[u].val = ih. name##env[(u << 1)+ 1]; \
569 } \
570 if (ih. name##flg&1) d-> name##flg|=EF_ON; \
571 if (ih. name##flg&2) d-> name##flg|=EF_SUSTAIN; \
572 if (ih. name##flg&4) d-> name##flg|=EF_LOOP; \
573 d-> name##susbeg=d-> name##susend=ih. name##sus; \
574 d-> name##beg=ih. name##beg; \
575 d-> name##end=ih. name##end; \
576 d-> name##pts=ih. name##pts; \
577 \
578 if ((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \
579 d-> name##flg&=~EF_ON
580#else
581#define IMF_ProcessEnvelope(name) \
582 for (u = 0; u < (IMFENVCNT >> 1); u++) { \
583 d-> name/**/env[u].pos = ih. name/**/env[u << 1]; \
584 d-> name/**/env[u].val = ih. name/**/env[(u << 1)+ 1]; \
585 } \
586 if (ih. name/**/flg&1) d-> name/**/flg|=EF_ON; \
587 if (ih. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN; \
588 if (ih. name/**/flg&4) d-> name/**/flg|=EF_LOOP; \
589 d-> name/**/susbeg=d-> name/**/susend=ih. name/**/sus; \
590 d-> name/**/beg=ih. name/**/beg; \
591 d-> name/**/end=ih. name/**/end; \
592 d-> name/**/pts=ih. name/**/pts; \
593 \
594 if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
595 d-> name/**/flg&=~EF_ON
596#endif
597
598 IMF_ProcessEnvelope(vol);
599 IMF_ProcessEnvelope(pan);
600 IMF_ProcessEnvelope(pit);
601#undef IMF_ProcessEnvelope
602
603 if(ih.pitflg&1) {
604 d->pitflg&=~EF_ON;
605#ifdef MIKMOD_DEBUG
606 fprintf(stderr, "\rFilter envelopes not supported yet\n");
607#endif
608 }
609
610 /* gather sample information */
611 for(u=0;u<ih.numsmp;u++,s++) {
612 /* allocate more room for sample information if necessary */
613 if(of.numsmp+u==wavcnt) {
614 wavcnt+=IMF_SMPINCR;
615 if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) {
616 if(wh) MikMod_free(wh);
617 _mm_errno=MMERR_OUT_OF_MEMORY;
618 return 0;
619 }
620 if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) {
621 MikMod_free(nextwav);
622 _mm_errno=MMERR_OUT_OF_MEMORY;
623 return 0;
624 }
625 s=wh+(wavcnt-IMF_SMPINCR);
626 }
627
628 _mm_read_string(s->samplename,13,modreader);
629 _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);
630 s->length =_mm_read_I_ULONG(modreader);
631 s->loopstart =_mm_read_I_ULONG(modreader);
632 s->loopend =_mm_read_I_ULONG(modreader);
633 s->samplerate=_mm_read_I_ULONG(modreader);
634 s->volume =_mm_read_UBYTE(modreader)&0x7f;
635 s->pan =_mm_read_UBYTE(modreader);
636 _mm_fseek(modreader,14,SEEK_CUR);
637 s->flags =_mm_read_UBYTE(modreader);
638 _mm_fseek(modreader,11,SEEK_CUR);
639 _mm_read_UBYTES(id,4,modreader);
640 if(((memcmp(id,"IS10",4))&&(memcmp(id,"IW10",4)))||
641 (_mm_eof(modreader))) {
642 MikMod_free(nextwav);MikMod_free(wh);
643 _mm_errno=MMERR_LOADING_SAMPLEINFO;
644 return 0;
645 }
646 nextwav[of.numsmp+u]=_mm_ftell(modreader);
647 _mm_fseek(modreader,s->length,SEEK_CUR);
648 }
649
650 of.numsmp+=ih.numsmp;
651 d++;
652 }
653
654 /* sanity check */
655 if(!of.numsmp) {
656 if(nextwav) MikMod_free(nextwav);
657 if(wh) MikMod_free(wh);
658 _mm_errno=MMERR_LOADING_SAMPLEINFO;
659 return 0;
660 }
661
662 /* load samples */
663 if(!AllocSamples()) {
664 MikMod_free(nextwav);MikMod_free(wh);
665 return 0;
666 }
667 if(!AllocLinear()) {
668 MikMod_free(nextwav);MikMod_free(wh);
669 return 0;
670 }
671 q=of.samples;
672 s=wh;
673 for(u=0;u<of.numsmp;u++,s++,q++) {
674 q->samplename=DupStr(s->samplename,12,1);
675 q->length =s->length;
676 q->loopstart=s->loopstart;
677 q->loopend =s->loopend;
678 q->volume =s->volume;
679 q->speed =s->samplerate;
680 if(of.flags&UF_LINEAR)
681 q->speed=speed_to_finetune(s->samplerate<<1,u);
682 q->panning =s->pan;
683 q->seekpos =nextwav[u];
684
685 q->flags|=SF_SIGNED;
686 if(s->flags&0x1) q->flags|=SF_LOOP;
687 if(s->flags&0x2) q->flags|=SF_BIDI;
688 if(s->flags&0x8) q->flags|=SF_OWNPAN;
689 if(s->flags&0x4) {
690 q->flags|=SF_16BITS;
691 q->length >>=1;
692 q->loopstart>>=1;
693 q->loopend >>=1;
694 }
695 }
696
697 d=of.instruments;
698 s=wh;
699 for(u=0;u<of.numins;u++,d++) {
700 for(t=0;t<IMFNOTECNT;t++) {
701 if(d->samplenumber[t]>=of.numsmp)
702 d->samplenote[t]=255;
703 else if (of.flags&UF_LINEAR) {
704 int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]];
705 d->samplenote[u]=(note<0)?0:(note>255?255:note);
706 } else
707 d->samplenote[t]=t;
708 }
709 }
710
711 MikMod_free(wh);MikMod_free(nextwav);
712 return 1;
713}
714
715CHAR *IMF_LoadTitle(void)
716{
717 CHAR s[31];
718
719 _mm_fseek(modreader,0,SEEK_SET);
720 if(!_mm_read_UBYTES(s,31,modreader)) return NULL;
721
722 return(DupStr(s,31,1));
723}
724
725/*========== Loader information */
726
727MIKMODAPI MLOADER load_imf={
728 NULL,
729 "IMF",
730 "IMF (Imago Orpheus)",
731 IMF_Init,
732 IMF_Test,
733 IMF_Load,
734 IMF_Cleanup,
735 IMF_LoadTitle
736};
737
738/* ex:set ts=4: */