1 /*
2 * Copyright (c) 2009, The MilkyTracker Team.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * - Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * - Neither the name of the <ORGANIZATION> nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * LoaderMOD.cpp
32 * MilkyPlay Module Loader: Protracker compatible
33 * MilkyPlay Module Loader: Game Music Creator (very similiar to MOD, kept in here)
34 * MilkyPlay Module Loader: SoundFX (very similiar to MOD, kept in here)
35 */
36 #include "Loaders.h"
37
38 // get number of channels of protracker compatible song
getPTnumchannels(char * id)39 static mp_sint32 getPTnumchannels(char *id)
40 {
41 if(!memcmp(id, "M.K.", 4) || !memcmp(id, "M!K!", 4) || !memcmp(id, "FLT4", 4))
42 {
43 return 4;
44 }
45 if(!memcmp(id, "FLT8", 4) || !memcmp(id, "OKTA", 4) || !memcmp(id, "OCTA", 4) || !memcmp(id, "FA08", 4) || !memcmp(id, "CD81", 4))
46 {
47 return 8;
48 }
49 if(id[0] >= '1' && id[0] <= '9' && !memcmp(id + 1, "CHN", 3))
50 {
51 return id[0] - '0';
52 }
53 if(id[0] >= '1' && id[0] <= '9' && id[1]>='0' && id[1] <= '9' && (!memcmp(id + 2, "CH", 2) || !memcmp(id + 2, "CN", 2)))
54 {
55 return (id[0] - '0') * 10 + id[1] - '0';
56 }
57
58 return 0;
59 }
60
mot2int(mp_sint32 x)61 static mp_sint32 mot2int(mp_sint32 x)
62 {
63 return (x>>8)+((x&255)<<8);
64 }
65
identifyModule(const mp_ubyte * buffer)66 const char* LoaderMOD::identifyModule(const mp_ubyte* buffer)
67 {
68 // check for .MOD
69 if (getPTnumchannels((char*)buffer+1080))
70 {
71 return "MOD";
72 }
73
74 mp_sint32 i,j;
75 mp_ubyte* uBuffer = (mp_ubyte*)buffer;
76
77 // see if we're getting a song title
78 for (i = 0; i < 20; i++)
79 if (uBuffer[i] >= 126 || (uBuffer[i] < 32 && uBuffer[i]))
80 return NULL;
81
82 uBuffer+=20;
83
84 mp_sint32 lastAsciiValues = -1;
85 for (j = 0; j < 15; j++)
86 {
87 if (uBuffer[24])
88 break;
89
90 if (uBuffer[25] > 64)
91 break;
92
93 bool ascii = true;
94 for (i = 0; i < 22; i++)
95 {
96 if (uBuffer[i] >= 126 || (uBuffer[i] < 14 && uBuffer[i]))
97 {
98 ascii = false;
99 break;
100 }
101 }
102
103 if (ascii)
104 lastAsciiValues = j;
105 else
106 break;
107
108 uBuffer+=30;
109 }
110
111 if (lastAsciiValues != 14)
112 return NULL;
113
114 if (!*uBuffer || *uBuffer > 128)
115 return NULL;
116
117 *uBuffer+=2;
118
119 for (i = 0; i < 128; i++)
120 if (uBuffer[i] > 128)
121 return NULL;
122
123 return "M15";
124 }
125
load(XMFileBase & f,XModule * module)126 mp_sint32 LoaderMOD::load(XMFileBase& f, XModule* module)
127 {
128 enum ModuleTypes
129 {
130 ModuleTypeUnknown,
131 ModuleTypeIns31,
132 ModuleTypeIns15
133 };
134
135 module->cleanUp();
136
137 // this will make code much easier to read
138 TXMHeader* header = &module->header;
139 TXMInstrument* instr = module->instr;
140 TXMSample* smp = module->smp;
141 TXMPattern* phead = module->phead;
142
143 // we're already out of memory here
144 if (!phead || !instr || !smp)
145 return MP_OUT_OF_MEMORY;
146
147 char block[2048];
148 f.read(block, 1, 2048);
149
150 const char* id = identifyModule((mp_ubyte*)block);
151 if (!id)
152 return MP_LOADER_FAILED;
153
154 ModuleTypes moduleType = ModuleTypeUnknown;
155 if (strcmp(id, "M15") == 0)
156 moduleType = ModuleTypeIns15;
157 else if (strcmp(id, "MOD") == 0)
158 moduleType = ModuleTypeIns31;
159
160 if (moduleType == ModuleTypeUnknown)
161 return MP_LOADER_FAILED;
162
163 f.seekWithBaseOffset(0);
164
165 f.read(&header->name,1,20);
166
167 switch (moduleType)
168 {
169 case ModuleTypeIns15:
170 header->insnum = 15;
171 break;
172 case ModuleTypeIns31:
173 header->insnum = 31;
174 break;
175 default:
176 return MP_LOADER_FAILED;
177 }
178
179 #ifdef VERBOSE
180 printf("Loading...\n");
181 #endif
182
183 mp_sint32 i, s = 0;
184 for (i = 0; i < header->insnum; i++) {
185 mp_ubyte insname[22];
186 mp_uword smplen=0;
187 mp_ubyte finetune=0;
188 mp_ubyte vol=0;
189 mp_uword loopstart=0;
190 mp_uword looplen=0;
191 f.read(&insname,1,22);
192
193 smplen = f.readWord();
194 f.read(&finetune,1,1);
195 f.read(&vol,1,1);
196 loopstart = f.readWord();
197 looplen = f.readWord();
198
199 #ifdef VERBOSE
200 printf("Ins %i, smplen: %i, loopstart: %i, looplen: %i\n", i, mot2int(smplen), mot2int(loopstart), mot2int(looplen));
201 #endif
202
203 memcpy(instr[i].name, insname, 22);
204
205 // valid sample?
206 if ((mot2int(smplen)<<1) > 2)
207 {
208 TXMSample* smp = &module->smp[s];
209
210 memcpy(smp->name, insname, 22);
211
212 instr[i].samp=1;
213
214 for (mp_sint32 j=0;j<120;j++)
215 instr[i].snum[j] = s;
216
217 smp->finetune = XModule::modfinetunes[finetune & 15];
218 smp->relnote = 0;
219 //module->convertc4spd(module->sfinetunes[finetune],&smp->finetune,&smp->relnote);
220
221 smp->flags=1;
222 smp->samplen=mot2int(smplen)<<1;
223 smp->loopstart=mot2int(loopstart)<<1;
224 smp->looplen=mot2int(looplen)<<1;
225 smp->vol=XModule::vol64to255(vol);
226
227 if (smp->samplen<=2) {
228 smp->samplen=0;
229 instr[s].samp=0;
230 }
231
232 if ((smp->loopstart+smp->looplen)>smp->samplen)
233 {
234 // first correct loop start
235 mp_sint32 dx = (smp->loopstart+smp->looplen)-smp->samplen;
236 smp->loopstart-=dx;
237 // still incorrect? => correct loop length
238 if ((smp->loopstart+smp->looplen)>smp->samplen)
239 {
240 dx = (smp->loopstart+smp->looplen)-smp->samplen;
241 smp->looplen-=dx;
242 }
243 }
244
245 if (smp->loopstart<2 && smp->looplen>2)
246 {
247 if (smp->looplen < smp->samplen)
248 // smp->loopstart=0;
249 smp->type |= 32;
250 #ifdef VERBOSE
251 printf("Contains one shot samples %i...\n", s);
252 #endif
253 }
254
255 if (smp->looplen<=2)
256 smp->looplen=0;
257 else
258 {
259 /*if (smp->loopstart > 2)
260 {
261 smp->loopstart -=2;
262 smp->looplen+=2;
263 }*/
264 smp->type|=1;
265 }
266
267 smp->pan=0x80;
268
269 s++;
270 }
271 //ins[i].c4spd=sfinetunes[ins[i].finetune];
272
273 }
274
275 header->smpnum = s;
276
277 header->ordnum = f.readByte();
278
279 f.read(&header->whythis1a,1,1);
280 f.read(&header->ord,1,128);
281
282 if (moduleType == ModuleTypeIns31)
283 f.read(header->sig,1,4);
284
285 if ((memcmp(header->sig+2,"CH",2) != 0 &&
286 memcmp(header->sig+1,"CHN",3) != 0) ||
287 moduleType == ModuleTypeIns15)
288 header->flags = XModule::MODULE_PTNEWINSTRUMENT;
289
290 header->patnum=0;
291 for (i=0;i<128;i++)
292 if (header->ord[i]>header->patnum) header->patnum=header->ord[i];
293
294 header->patnum++;
295
296 //patterns = new mp_ubyte*[modhead.numpatts];
297
298 if (moduleType == ModuleTypeIns31)
299 header->channum = getPTnumchannels((char*)&header->sig);
300 else if (moduleType == ModuleTypeIns15)
301 header->channum = 4;
302
303 if (!header->channum)
304 {
305 return MP_LOADER_FAILED;
306 }
307
308 //mp_sint32 patternsize = modhead.numchannels*modhead.numrows*5;
309 mp_sint32 modpatternsize = header->channum*64*4;
310
311 mp_ubyte *buffer = new mp_ubyte[modpatternsize];
312
313 if (buffer == NULL)
314 {
315 return MP_OUT_OF_MEMORY;
316 }
317
318 for (i=0;i<header->patnum;i++) {
319 f.read(buffer,1,modpatternsize);
320
321 phead[i].rows=64;
322 phead[i].effnum=1;
323 phead[i].channum=(mp_ubyte)header->channum;
324
325 phead[i].patternData=new mp_ubyte[phead[i].rows*header->channum*4];
326
327 // out of memory?
328 if (phead[i].patternData == NULL)
329 {
330 delete[] buffer;
331 return MP_OUT_OF_MEMORY;
332 }
333
334 memset(phead[i].patternData,0,phead[i].rows*header->channum*4);
335
336 mp_sint32 r,c,cnt=0;
337 for (r=0;r<64;r++) {
338 for (c=0;c<header->channum;c++) {
339 mp_ubyte b1 = buffer[cnt];
340 mp_ubyte b2 = buffer[cnt+1];
341 mp_ubyte b3 = buffer[cnt+2];
342 mp_ubyte b4 = buffer[cnt+3];
343
344 mp_sint32 note,ins,eff,notenum = 0;
345 note = ((b1&0xf)<<8)+b2;
346 ins = (b1&0xf0)+(b3>>4);
347 eff = b3&0xf;
348
349 if (eff==0xE) {
350 eff=(b4>>4)+0x30;
351 b4&=0xf;
352 }
353
354 if ((!eff)&&b4)
355 eff=0x20;
356
357 // old style modules don't support last effect for:
358 // - portamento up/down
359 // - volume slide
360 if (eff==0x1&&(!b4)) eff = 0;
361 if (eff==0x2&&(!b4)) eff = 0;
362 if (eff==0xA&&(!b4)) eff = 0;
363
364 if (eff==0x5&&(!b4)) eff = 0x3;
365 if (eff==0x6&&(!b4)) eff = 0x4;
366
367 if (eff==0xC) {
368 b4 = XModule::vol64to255(b4);
369 }
370
371 if (note)
372 notenum = XModule::amigaPeriodToNote(note);
373
374 phead[i].patternData[cnt]=notenum;
375 phead[i].patternData[cnt+1]=ins;
376 phead[i].patternData[cnt+2]=eff;
377 phead[i].patternData[cnt+3]=b4;
378
379 cnt+=4;
380 }
381 }
382
383 }
384 delete[] buffer;
385
386 for (i=0; i < header->smpnum; i++)
387 {
388 // Take a peek of the sample and check if we have to do some nasty MODPLUG ADPCM decompression
389 bool adpcm = false;
390
391 if (f.posWithBaseOffset() + 5 <= f.sizeWithBaseOffset())
392 {
393 f.read(block, 1, 5);
394 adpcm = memcmp(block, "ADPCM", 5) == 0;
395 if (!adpcm)
396 f.seekWithBaseOffset(f.posWithBaseOffset() - 5);
397 }
398
399 mp_sint32 result = module->loadModuleSample(f, i, adpcm ? XModule::ST_PACKING_ADPCM : XModule::ST_DEFAULT);
400 if (result != MP_OK)
401 return result;
402 }
403
404 header->speed=125;
405 header->tempo=6;
406 header->mainvol=255;
407 //header->freqtab=1;
408
409 if (moduleType == ModuleTypeIns15)
410 strcpy(header->tracker,"Soundtracker");
411 else
412 strcpy(header->tracker,"Protracker");
413
414 module->postLoadAnalyser();
415
416 // Amiga panning LRRL
417 for (i = 0; i < header->channum; i++)
418 {
419 switch (i & 3)
420 {
421 case 0:
422 case 3:
423 header->pan[i] = 0;
424 break;
425 case 1:
426 case 2:
427 header->pan[i] = 255;
428 break;
429 }
430 }
431
432 module->postProcessSamples();
433
434 #ifdef VERBOSE
435 printf("%i / %i\n", f.pos(), f.size());
436 #endif
437
438 return MP_OK;
439 }
440
identifyModule(const mp_ubyte * buffer)441 const char* LoaderGMC::identifyModule(const mp_ubyte* buffer)
442 {
443 mp_sint32 i = 0;
444
445 // check instrument volume for value from 0x00 to 0x40
446
447 const mp_ubyte* ptr = buffer + 7;
448 bool ok = true;
449 for (i = 0; i < 15 && ok; i++)
450 {
451 if (*ptr > 0x40)
452 ok = false;
453 ptr+=16;
454 }
455
456 if (!ok)
457 return NULL;
458
459 // Those 3 bytes should all be zero
460 if (buffer[0xF0] || buffer[0xF1] || buffer[0xF2])
461 return NULL;
462
463 // this should not be zero
464 if (!buffer[0xF3])
465 return NULL;
466
467 ptr = buffer + 0xF4;
468 ok = true;
469 // check orders to be divisible by 0x400
470 for (i = 0; i < *(buffer + 0xF3) && ok; i++)
471 {
472 if (BigEndian::GET_WORD(ptr) & 0x3ff)
473 ok = false;
474 ptr+=2;
475 }
476
477 if (!ok)
478 return NULL;
479
480 return "GMC";
481 }
482
load(XMFileBase & f,XModule * module)483 mp_sint32 LoaderGMC::load(XMFileBase& f, XModule* module)
484 {
485 module->cleanUp();
486
487 // this will make code much easier to read
488 TXMHeader* header = &module->header;
489 TXMInstrument* instr = module->instr;
490 TXMSample* smp = module->smp;
491 TXMPattern* phead = module->phead;
492
493 // we're already out of memory here
494 if (!phead || !instr || !smp)
495 return MP_OUT_OF_MEMORY;
496
497 mp_sint32 i,j,k;
498
499 // read GMC instruments, always 15
500 header->insnum = 15;
501 // channels always 4
502 header->channum = 4;
503
504 j = 0;
505 for (i = 0; i < header->insnum; i++)
506 {
507 // Ignore DWORD (probably some address)
508 f.readDword();
509
510 mp_uint32 samplen = mot2int(f.readWord()) << 1;
511
512 mp_ubyte finetune = f.readByte();
513
514 mp_ubyte vol = f.readByte();
515
516 // Ignore DWORD (probably some address)
517 f.readDword();
518
519 mp_sint32 looplen = mot2int(f.readWord()) << 1;
520 mp_sint32 loopstart = mot2int(f.readWord()) << 1;
521
522 mp_sint32 newloopstart = samplen - looplen;
523 mp_sint32 newloopend = samplen - loopstart;
524
525 if (looplen > 4)
526 {
527 loopstart = newloopstart;
528 looplen = newloopend - loopstart;
529 }
530
531 // valid sample?
532 if (samplen)
533 {
534 TXMSample* smp = &module->smp[j];
535
536 instr[i].samp=1;
537
538 for (k = 0; k < 120; k++)
539 instr[i].snum[k] = j;
540
541 smp->finetune = XModule::modfinetunes[finetune & 15];
542 smp->relnote = 0;
543
544 smp->flags = 1;
545 smp->samplen = samplen;
546 smp->loopstart = loopstart;
547 smp->looplen = looplen;
548 smp->vol = XModule::vol64to255(vol);
549
550 if (smp->samplen <= 4) {
551 smp->samplen = 0;
552 instr[i].samp = 0;
553 }
554
555 if (smp->looplen <= 4)
556 smp->looplen = 0;
557 else
558 {
559 smp->type|=1;
560 }
561
562 smp->pan = 0x80;
563
564 j++;
565 }
566
567 }
568
569 header->smpnum = j;
570
571 // skip something
572 f.readByte();
573 f.readByte();
574 f.readByte();
575
576 header->ordnum = f.readByte();
577 mp_uword ord[100];
578
579 f.readWords(ord, 100);
580
581 mp_sint32 patnum = 0;
582 for (i = 0; i < 100; i++)
583 {
584 header->ord[i] = mot2int(ord[i]) >> 10;
585 if (header->ord[i] > patnum)
586 patnum = header->ord[i];
587 }
588
589 header->patnum = patnum+1;
590
591 mp_sint32 modpatternsize = header->channum*64*4;
592
593 mp_ubyte *buffer = new mp_ubyte[modpatternsize];
594
595 if (buffer == NULL)
596 {
597 return MP_OUT_OF_MEMORY;
598 }
599
600 for ( i = 0; i < header->patnum; i++) {
601 f.read(buffer, 1, modpatternsize);
602
603 phead[i].rows = 64;
604 phead[i].effnum = 1;
605 phead[i].channum = (mp_ubyte)header->channum;
606
607 phead[i].patternData = new mp_ubyte[phead[i].rows*header->channum*4];
608
609 // out of memory?
610 if (phead[i].patternData == NULL)
611 {
612 delete[] buffer;
613 return MP_OUT_OF_MEMORY;
614 }
615
616 memset(phead[i].patternData, 0, phead[i].rows*header->channum*4);
617
618 mp_sint32 r,c,cnt=0;
619 for (r = 0; r < 64; r++) {
620 for ( c = 0; c < header->channum; c++)
621 {
622 mp_ubyte b1 = buffer[cnt];
623 mp_ubyte b2 = buffer[cnt+1];
624 mp_ubyte b3 = buffer[cnt+2];
625 mp_ubyte b4 = buffer[cnt+3];
626
627 mp_sint32 note,ins,eff,notenum = 0;
628 note = ((b1&0xf)<<8)+b2;
629 ins = (b1&0xf0)+(b3>>4);
630 eff = b3&0xf;
631
632 switch (eff)
633 {
634 case 0x01:
635 case 0x02:
636 break;
637 case 0x03:
638 eff = 0x0C;
639 b4 = XModule::vol64to255(b4);
640 break;
641 case 0x04:
642 eff = 0x0D;
643 break;
644 case 0x05:
645 eff = 0x0B;
646 break;
647 case 0x08:
648 eff = 0x0F;
649 break;
650
651 default:
652 eff = b4 = 0;
653
654 }
655
656 if (note)
657 notenum = XModule::amigaPeriodToNote(note);
658
659 phead[i].patternData[cnt] = notenum;
660 phead[i].patternData[cnt+1] = ins;
661 phead[i].patternData[cnt+2] = eff;
662 phead[i].patternData[cnt+3] = b4;
663
664 cnt+=4;
665 }
666 }
667
668 }
669 delete[] buffer;
670
671 mp_sint32 result = module->loadModuleSamples(f);
672 if (result != MP_OK)
673 return result;
674
675 header->speed = 125;
676 header->tempo = 6;
677 header->mainvol = 255;
678
679 // Amiga panning LRRL
680 for (i = 0; i < header->channum; i++)
681 {
682 switch (i & 3)
683 {
684 case 0:
685 case 3:
686 header->pan[i] = 0;
687 break;
688 case 1:
689 case 2:
690 header->pan[i] = 255;
691 break;
692 }
693 }
694
695 module->postProcessSamples();
696
697 strcpy(header->tracker,"Game Music Creator");
698
699 return MP_OK;
700 }
701
identifyModule(const mp_ubyte * buffer)702 const char* LoaderSFX::identifyModule(const mp_ubyte* buffer)
703 {
704 // check for .SFX module
705 if (!memcmp(buffer+60,"SONG",4))
706 {
707 // Check if first 15 big endian DWORDS contain valid sample sizes
708 for (mp_sint32 i = 0; i < 15; i++)
709 if (BigEndian::GET_DWORD(buffer+i*4) > 65536*2)
710 return NULL;
711
712 return "SFX";
713 }
714
715 return NULL;
716 }
717
load(XMFileBase & f,XModule * module)718 mp_sint32 LoaderSFX::load(XMFileBase& f, XModule* module)
719 {
720 module->cleanUp();
721
722 // this will make code much easier to read
723 TXMHeader* header = &module->header;
724 TXMInstrument* instr = module->instr;
725 TXMSample* smp = module->smp;
726 TXMPattern* phead = module->phead;
727
728 // we're already out of memory here
729 if (!phead || !instr || !smp)
730 return MP_OUT_OF_MEMORY;
731
732 mp_sint32 i,j,k;
733
734 // read SoundFX instruments, always 15
735 header->insnum = header->smpnum = 15;
736 // channels always 4
737 header->channum = 4;
738
739 mp_dword sampSizeTab[15];
740 for (i = 0; i < header->smpnum; i++)
741 {
742 mp_ubyte temp[4];
743 f.read(temp, 1, 4);
744 sampSizeTab[i] = BigEndian::GET_DWORD(temp);
745 }
746
747 // read signature
748 f.read(header->sig, 1, 4);
749
750 mp_sint32 delayValue = mot2int(f.readWord());
751
752 // skip 14 bytes garbage
753 f.readDword();
754 f.readDword();
755 f.readDword();
756 f.readWord();
757
758 header->speed = 122 * 14565 / delayValue;
759 header->tempo = 6;
760 header->mainvol = 255;
761
762 j = 0;
763 for (i = 0; i < header->insnum; i++)
764 {
765 f.read(instr[i].name, 1, 22);
766
767 mp_uint32 samplen = mot2int(f.readWord()) << 1;
768 samplen = sampSizeTab[i];
769
770 mp_ubyte finetune = f.readByte();
771
772 mp_ubyte vol = f.readByte();
773
774 mp_sint32 loopstart = mot2int(f.readWord());
775 mp_sint32 looplen = mot2int(f.readWord()) << 1;
776
777 // valid sample?
778 if (samplen > 4)
779 {
780 TXMSample* smp = &module->smp[j];
781
782 instr[i].samp=1;
783
784 for (k = 0; k < 120; k++)
785 instr[i].snum[k] = j;
786
787 smp->finetune = XModule::modfinetunes[finetune & 15];
788 smp->relnote = 0;
789
790 smp->flags = 1;
791 smp->samplen = samplen;
792 smp->loopstart = loopstart;
793 smp->looplen = looplen;
794 smp->vol = XModule::vol64to255((mp_sint32)vol*64/63);
795
796 if (smp->samplen <= 4) {
797 smp->samplen = 0;
798 instr[i].samp = 0;
799 }
800
801 if (smp->looplen <= 4)
802 smp->looplen = 0;
803 else
804 {
805 smp->type|=1;
806 }
807
808 smp->pan = 0x80;
809
810 j++;
811 }
812
813 }
814
815 header->smpnum = j;
816 header->ordnum = f.readByte();
817 header->restart = f.readByte();
818 f.read(&header->ord, 1, 128);
819
820 header->patnum = 0;
821 for (i = 0; i < 128; i++)
822 if (header->ord[i] > header->patnum) header->patnum = header->ord[i];
823
824 header->patnum++;
825
826 mp_sint32 modpatternsize = header->channum*64*4;
827
828 mp_ubyte *buffer = new mp_ubyte[modpatternsize];
829
830 if (buffer == NULL)
831 {
832 return MP_OUT_OF_MEMORY;
833 }
834
835 for ( i = 0; i < header->patnum; i++) {
836 f.read(buffer, 1, modpatternsize);
837
838 phead[i].rows = 64;
839 phead[i].effnum = 1;
840 phead[i].channum = (mp_ubyte)header->channum;
841
842 phead[i].patternData = new mp_ubyte[phead[i].rows*header->channum*4];
843
844 // out of memory?
845 if (phead[i].patternData == NULL)
846 {
847 delete[] buffer;
848 return MP_OUT_OF_MEMORY;
849 }
850
851 memset(phead[i].patternData, 0, phead[i].rows*header->channum*4);
852
853 mp_sint32 r,c,cnt=0;
854 for (r = 0; r < 64; r++) {
855 for ( c = 0; c < header->channum; c++)
856 {
857 mp_ubyte b1 = buffer[cnt];
858 mp_ubyte b2 = buffer[cnt+1];
859 mp_ubyte b3 = buffer[cnt+2];
860 mp_ubyte b4 = buffer[cnt+3];
861
862 mp_sint32 note,ins,eff,notenum = 0;
863 note = ((b1&0xf)<<8)+b2;
864 ins = (b1&0xf0)+(b3>>4);
865 eff = b3&0xf;
866
867 if (b1 == 0xFF && b2 >= 0xFC)
868 {
869 if (b2 == 0xFE)
870 {
871 note = notenum = ins = 0;
872 eff = 0x0C;
873 b4 = 0;
874 }
875 else if (b2 == 0xFD)
876 {
877 ins = eff = b4 = 0;
878 }
879 else if (b2 == 0xFC)
880 {
881 note = notenum = 0;
882 }
883 }
884 else
885 {
886
887 switch (eff)
888 {
889 // arpeggio?
890 case 0x01:
891 if (b4)
892 eff = 0x20;
893 break;
894 // pitch bend?
895 case 0x02:
896 // portamento up
897 if (b4 & 0xf)
898 eff = 0x01;
899 // porta down
900 else if (b4 >> 4)
901 {
902 eff = 0x02;
903 b4>>=4;
904 }
905 break;
906 // add something to the volume?
907 case 0x05:
908 eff = 0x3A;
909 break;
910 // set volume
911 case 0x06:
912 eff = 0x0C;
913 b4 = 255-XModule::vol64to255(b4);
914 break;
915 // portamento again?
916 case 0x07:
917 eff = 0x01;
918 break;
919 // portamento again?
920 case 0x08:
921 eff = 0x02;
922 break;
923
924 default:
925 eff = b4 = 0;
926
927 }
928
929 }
930
931 if (note)
932 notenum = XModule::amigaPeriodToNote(note);
933
934 phead[i].patternData[cnt] = notenum;
935 phead[i].patternData[cnt+1] = ins;
936 phead[i].patternData[cnt+2] = eff;
937 phead[i].patternData[cnt+3] = b4;
938
939 cnt+=4;
940 }
941 }
942
943 }
944
945 delete[] buffer;
946
947 mp_sint32 result = module->loadModuleSamples(f);
948 if (result != MP_OK)
949 return result;
950
951 // Amiga panning LRRL
952 for (i = 0; i < header->channum; i++)
953 {
954 switch (i & 3)
955 {
956 case 0:
957 case 3:
958 header->pan[i] = 0;
959 break;
960 case 1:
961 case 2:
962 header->pan[i] = 255;
963 break;
964 }
965 }
966
967 module->postProcessSamples();
968
969 strcpy(header->tracker,"SoundFX");
970
971 return MP_OK;
972 }
973