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 * XModule.cpp
32 * MilkyPlay module (based on a hybrid of the XM, MDL, AMS and IT formats)
33 *
34 *
35 */
36 #include "XModule.h"
37 #include "Loaders.h"
38
39 #undef VERBOSE
40
41 #ifdef VERBOSE
42 #include <stdio.h>
43 #endif
44
45 // heavy processing removes some of the nasty clicks found
46 // in 669 and PLM songs (found in 8 bit samples only)
smoothLooping()47 void TXMSample::smoothLooping()
48 {
49 if ((type&16) || (type & 3) != 1 || sample == NULL || samplen < 1024 || looplen <= 32)
50 return;
51
52 mp_sbyte* data = (mp_sbyte*)this->sample;
53
54 const mp_sint32 blockSize = 8;
55
56 mp_sint32 max,t;
57
58 float v1 = data[loopstart];
59 float v2 = data[loopstart+looplen];
60
61 float avg = (v1+v2)*0.5f;
62
63 // step 1: Fade to avg from what's coming before loopstart
64 max = loopstart;
65 if (max > blockSize) max = blockSize;
66 for (t = 0; t < max; t++)
67 {
68 float ft = (float)t/(float)max;
69 mp_sint32 index = loopstart - max + t;
70 mp_sint32 src = data[index];
71 float final = src * (1.0f - ft) + (avg * ft);
72 data[index] = (mp_sbyte)final;
73 }
74
75 // step 2: Fade from avg into what's coming after loopstart
76 max = blockSize;
77 for (t = 0; t < max; t++)
78 {
79 float ft = (float)t/(float)max;
80 mp_sint32 index = loopstart + t;
81 mp_sint32 dst = data[index];
82 float final = avg * (1.0f - ft) + (dst * ft);
83 data[index] = (mp_sbyte)final;
84 }
85
86 // step 3
87 for (t = 0; t < blockSize; t++)
88 {
89 mp_sint32 index = loopstart+looplen - blockSize + t;
90
91 mp_sint32 src = data[index];
92
93 float ft = (float)t/(float)blockSize;
94 float final = src * (1.0f - ft) + (avg * ft);
95 data[index] = (mp_sbyte)final;
96 }
97 }
98
restoreLoopArea()99 void TXMSample::restoreLoopArea()
100 {
101 if (sample == NULL)
102 return;
103
104 mp_ubyte* originalSample = getPadStartAddr((mp_ubyte*)sample) + sizeof(TLoopDoubleBuffProps);
105 mp_uint32 saveLen = (type&16) ? LoopAreaBackupSize * sizeof(mp_sword) : LoopAreaBackupSize;
106
107 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
108
109 ASSERT(saveLen <= LeadingPadding / 2);
110
111 // 16 bit sample
112 if (type&16)
113 {
114 mp_sword* data = (mp_sword*)this->sample;
115
116 // save "real" loop area back from double buffer to sample
117 if ((loopBufferProps->state[1] & 16) == (type & 16))
118 memcpy(data+loopBufferProps->lastloopend, originalSample, saveLen);
119 else
120 {
121 // buffer has been 8 bit, now we're 16 bit => convert upwards
122 for (mp_sint32 i = 0; i < LoopAreaBackupSize; i++)
123 data[loopBufferProps->lastloopend+i] = ((mp_sbyte*)originalSample)[i] << 8;
124 }
125 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUnused;
126 }
127 // 8 bit sample
128 else
129 {
130 mp_sbyte* data = (mp_sbyte*)this->sample;
131
132 // save "real" loop area back from double buffer to sample
133 if ((loopBufferProps->state[1] & 16) == (type & 16))
134 memcpy(data+loopBufferProps->lastloopend, originalSample, saveLen);
135 else
136 {
137 // buffer has been 16 bit, now we're 8 bit => convert downwards
138 for (mp_sint32 i = 0; i < LoopAreaBackupSize; i++)
139 data[loopBufferProps->lastloopend+i] = ((mp_sword*)originalSample)[i] >> 8;
140 }
141 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUnused;
142 }
143 }
144
restoreOriginalState()145 void TXMSample::restoreOriginalState()
146 {
147 if (sample == NULL)
148 return;
149
150 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
151
152 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateDirty ||
153 loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUsed)
154 {
155 restoreLoopArea();
156 }
157 }
158
postProcessSamples()159 void TXMSample::postProcessSamples()
160 {
161 mp_ubyte buffer[8];
162
163 // Sanitize loop points
164 if(loopstart > samplen)
165 loopstart = samplen;
166 if(looplen > samplen - loopstart)
167 looplen = samplen - loopstart;
168
169 mp_sint32 loopend = loopstart + looplen;
170 mp_sint32 samplen = this->samplen;
171
172 if (looplen == 0)
173 type &= ~3;
174 if (sample == NULL)
175 return;
176
177 mp_ubyte* originalSample = getPadStartAddr((mp_ubyte*)sample) + sizeof(TLoopDoubleBuffProps);
178 mp_uint32 saveLen = (type&16) ? LoopAreaBackupSize * sizeof(mp_sword) : LoopAreaBackupSize;
179
180 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
181
182 ASSERT(saveLen <= sizeof(buffer));
183 ASSERT(saveLen <= LeadingPadding / 2);
184
185 const mp_ubyte importantFlags = 3 + 16;
186
187 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateDirty ||
188 (((loopBufferProps->lastloopend != loopend) ||
189 (loopBufferProps->state[1] != (type & importantFlags))) &&
190 loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUsed))
191 {
192 restoreLoopArea();
193 }
194
195 // 16 bit sample
196 if (type&16)
197 {
198 mp_sword* data = (mp_sword*)this->sample;
199
200 if (!(type&3))
201 {
202 data[-1]=data[0];
203 data[-2]=data[1];
204 data[-3]=data[2];
205 data[-4]=data[3];
206
207 data[samplen]=data[samplen-1];
208 data[samplen+1]=data[samplen-2];
209 data[samplen+3]=data[samplen-3];
210 data[samplen+4]=data[samplen-4];
211 }
212 else if ((type&3) &&
213 loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUnused)
214 {
215 // forward loop
216 if ((type&3) == 1)
217 {
218 // padding start
219 data[-1] = data[loopend-1];
220 data[-2] = data[loopend-2];
221 data[-3] = data[loopend-3];
222 data[-4] = data[loopend-4];
223
224 // save portions after loopend, gets overwritten now
225 memcpy(originalSample, data+loopend, saveLen);
226 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUsed;
227 loopBufferProps->state[1] = type & importantFlags;
228 loopBufferProps->lastloopend = loopend;
229
230 memcpy(buffer, data+loopstart, saveLen);
231 memcpy(data+loopend, buffer, saveLen);
232 }
233 else if ((type&3) == 2)
234 {
235 data[-1] = data[0];
236 data[-2] = data[1];
237 data[-3] = data[2];
238 data[-4] = data[3];
239
240 // save portions after loopend, gets overwritten now
241 memcpy(originalSample, data+loopend, saveLen);
242 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUsed;
243 loopBufferProps->state[1] = type & importantFlags;
244 loopBufferProps->lastloopend = loopend;
245
246 data[loopend] = data[loopend-1];
247 data[loopend+1] = data[loopend-2];
248 data[loopend+2] = data[loopend-3];
249 data[loopend+3] = data[loopend-4];
250 }
251 }
252 }
253 // 8 bit sample
254 else
255 {
256 mp_sbyte* data = (mp_sbyte*)this->sample;
257
258 if (!(type&3))
259 {
260 data[-1] = data[0];
261 data[-2] = data[1];
262 data[-3] = data[2];
263 data[-4] = data[3];
264
265 data[samplen] = data[samplen-1];
266 data[samplen+1] = data[samplen-2];
267 data[samplen+2] = data[samplen-3];
268 data[samplen+3] = data[samplen-4];
269 }
270 else if ((type&3) &&
271 loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUnused)
272 {
273 // forward loop
274 if ((type&3) == 1)
275 {
276 // leading padding
277 data[-1] = data[loopend-1];
278 data[-2] = data[loopend-2];
279 data[-3] = data[loopend-3];
280 data[-4] = data[loopend-4];
281
282 // save portions after loopend, gets overwritten now
283 memcpy(originalSample, data+loopend, saveLen);
284 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUsed;
285 loopBufferProps->state[1] = type & importantFlags;
286 loopBufferProps->lastloopend = loopend;
287
288 memcpy(buffer, data+loopstart, saveLen);
289 memcpy(data+loopend, buffer, saveLen);
290 }
291 // bidi loop
292 else if ((type&3) == 2)
293 {
294 data[-1] = data[0];
295 data[-2] = data[1];
296 data[-3] = data[2];
297 data[-4] = data[3];
298
299 // save portions after loopend, gets overwritten now
300 memcpy(originalSample, data+loopend, saveLen);
301 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUsed;
302 loopBufferProps->state[1] = type & importantFlags;
303 loopBufferProps->lastloopend = loopend;
304
305 data[loopend] = data[loopend-1];
306 data[loopend+1] = data[loopend-2];
307 data[loopend+2] = data[loopend-3];
308 data[loopend+3] = data[loopend-4];
309 }
310 }
311 }
312 }
313
314 // get sample value
315 // values range from [-32768,32767] in case of a 16 bit sample
316 // or from [-128,127] in case of an 8 bit sample
getSampleValue(mp_uint32 index)317 mp_sint32 TXMSample::getSampleValue(mp_uint32 index)
318 {
319 if (type & 16)
320 {
321 if ((type & 3) && index >= loopstart+looplen &&
322 index < loopstart+looplen+LoopAreaBackupSize)
323 {
324 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
325 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUnused)
326 return *(((mp_sword*)sample)+index);
327
328 mp_sword* buff = (mp_sword*)(getPadStartAddr((mp_ubyte*)sample) + sizeof(TLoopDoubleBuffProps));
329 return *(buff + (index - (loopstart+looplen)));
330 }
331 else
332 return *(((mp_sword*)sample)+index);
333 }
334 else
335 {
336 if ((type & 3) && index >= loopstart+looplen &&
337 index < loopstart+looplen+LoopAreaBackupSize)
338 {
339 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
340 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUnused)
341 return *(sample+index);
342
343 mp_sbyte* buff = (mp_sbyte*)(getPadStartAddr((mp_ubyte*)sample) + sizeof(TLoopDoubleBuffProps));
344 return *(buff + (index - (loopstart+looplen)));
345 }
346 else
347 return *(sample+index);
348 }
349 }
350
getSampleValue(mp_ubyte * sample,mp_uint32 index)351 mp_sint32 TXMSample::getSampleValue(mp_ubyte* sample, mp_uint32 index)
352 {
353 if (type & 16)
354 return *(((mp_sword*)sample)+index);
355 else
356 return *(sample+index);
357 }
358
setSampleValue(mp_uint32 index,mp_sint32 value)359 void TXMSample::setSampleValue(mp_uint32 index, mp_sint32 value)
360 {
361 if (type & 16)
362 {
363 if ((type & 3) && index >= loopstart+looplen &&
364 index < loopstart+looplen+LoopAreaBackupSize)
365 {
366 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
367 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUnused)
368 {
369 *(((mp_sword*)sample)+index) = (mp_sword)value;
370 return;
371 }
372
373 mp_sword* buff = (mp_sword*)(getPadStartAddr((mp_ubyte*)sample) + sizeof(TLoopDoubleBuffProps));
374 *(buff + (index - (loopstart+looplen))) = (mp_sword)value;
375
376 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateDirty;
377 }
378 else if ((type & 3) && index >= loopstart &&
379 index < loopstart+LoopAreaBackupSize)
380 {
381 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
382 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUsed)
383 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUnused;
384
385 *(((mp_sword*)sample)+index) = (mp_sword)value;
386 }
387 else
388 *(((mp_sword*)sample)+index) = (mp_sword)value;
389 }
390 else
391 {
392 if ((type & 3) && index >= loopstart+looplen &&
393 index < loopstart+looplen+LoopAreaBackupSize)
394 {
395 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
396 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUnused)
397 {
398 *(sample+index) = (mp_sbyte)value;
399 return;
400 }
401
402 mp_sbyte* buff = (mp_sbyte*)(getPadStartAddr((mp_ubyte*)sample) + sizeof(TLoopDoubleBuffProps));
403 *(buff + (index - (loopstart+looplen))) = (mp_sbyte)value;
404
405 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateDirty;
406 }
407 else if ((type & 3) && index >= loopstart &&
408 index < loopstart+LoopAreaBackupSize)
409 {
410 TLoopDoubleBuffProps* loopBufferProps = (TLoopDoubleBuffProps*)getPadStartAddr((mp_ubyte*)sample);
411 if (loopBufferProps->state[0] == TLoopDoubleBuffProps::StateUsed)
412 loopBufferProps->state[0] = TLoopDoubleBuffProps::StateUnused;
413
414 *(sample+index) = (mp_sbyte)value;
415 }
416 else
417 *(sample+index) = (mp_sbyte)value;
418 }
419 }
420
setSampleValue(mp_ubyte * sample,mp_uint32 index,mp_sint32 value)421 void TXMSample::setSampleValue(mp_ubyte* sample, mp_uint32 index, mp_sint32 value)
422 {
423 if (type & 16)
424 {
425 *(((mp_sword*)sample)+index) = (mp_sword)value;
426 }
427 else
428 *(sample+index) = (mp_sbyte)value;
429 }
430
431
432 #define FUNCTION_SUCCESS MP_OK
433 #define FUNCTION_FAILED MP_LOADER_FAILED
434
435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
436 //
437 // IT sample loading helper class
438 //
439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
440 class ITSampleLoader : public XModule::SampleLoader
441 {
442 private:
443 mp_dword* source_buffer; /* source buffer */
444 mp_dword* source_position; /* actual reading position */
445 mp_ubyte source_remaining_bits; /* bits remaining in read dword */
446
447 bool it215;
448
449 public:
ITSampleLoader(XMFileBase & file,bool isIt215=false)450 ITSampleLoader(XMFileBase& file, bool isIt215 = false) :
451 SampleLoader(file),
452 source_buffer(NULL),
453 source_position(NULL),
454 source_remaining_bits(0),
455 it215(isIt215)
456 {
457 }
458
~ITSampleLoader()459 virtual ~ITSampleLoader()
460 {
461 free_IT_compressed_block();
462 }
463
464 mp_dword read_n_bits_from_IT_compressed_block(mp_ubyte p_bits_to_read);
465
466 mp_sint32 read_IT_compressed_block ();
467
468 void free_IT_compressed_block ();
469
470 // second parameter is ignored
471 virtual mp_sint32 load_sample_8bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize);
472
473 // second parameter is ignored
474 virtual mp_sint32 load_sample_16bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize);
475 };
476
477 /* * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE
478
479 -The following sample decompression code is based on CheeseTracker code which is based on xmp's code.(http://xmp.helllabs.org) which is based in openCP code. :D
480
481 * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE */
482
read_n_bits_from_IT_compressed_block(mp_ubyte p_bits_to_read)483 mp_dword ITSampleLoader::read_n_bits_from_IT_compressed_block (mp_ubyte p_bits_to_read) {
484
485 mp_dword aux_return_value;
486
487 mp_dword val;
488 mp_ubyte *buffer=(mp_ubyte*)source_position;
489
490 if ( p_bits_to_read <= source_remaining_bits ) {
491
492 val=buffer[3];
493 val<<=8;
494 val|=buffer[2];
495 val<<=8;
496 val|=buffer[1];
497 val<<=8;
498 val|=buffer[0];
499
500 aux_return_value = val & ((1 << p_bits_to_read) - 1);
501 val >>= p_bits_to_read;
502 source_remaining_bits -= p_bits_to_read;
503
504 buffer[3]=val>>24;
505 buffer[2]=(val>>16)&0xFF;
506 buffer[1]=(val>>8)&0xFF;
507 buffer[0]=(val)&0xFF;
508
509 } else {
510 aux_return_value=buffer[3];
511 aux_return_value<<=8;
512 aux_return_value|=buffer[2];
513 aux_return_value<<=8;
514 aux_return_value|=buffer[1];
515 aux_return_value<<=8;
516 aux_return_value|=buffer[0];
517
518 mp_dword nbits = p_bits_to_read - source_remaining_bits;
519 // aux_return_value = *source_position;
520 source_position++;
521 buffer+=4;
522 val=buffer[3];
523 val<<=8;
524 val|=buffer[2];
525 val<<=8;
526 val|=buffer[1];
527 val<<=8;
528 val|=buffer[0];
529 aux_return_value |= ((val & ((1 << nbits) - 1)) << source_remaining_bits);
530 val >>= nbits;
531 source_remaining_bits = 32 - nbits;
532 buffer[3]=val>>24;
533 buffer[2]=(val>>16)&0xFF;
534 buffer[1]=(val>>8)&0xFF;
535 buffer[0]=(val)&0xFF;
536
537 }
538
539 return aux_return_value;
540 }
541
read_IT_compressed_block()542 mp_sint32 ITSampleLoader::read_IT_compressed_block () {
543
544 mp_uword size;
545
546 size=f.readWord();
547
548 if (f.isEOF()) return FUNCTION_FAILED;
549
550 mp_sint32 finalSize = 4 * ((size >> 2) + 2);
551 source_buffer = (mp_dword*)new mp_ubyte[finalSize];
552
553 if (source_buffer==NULL) return FUNCTION_FAILED;
554
555 memset(source_buffer, 0, finalSize);
556
557 mp_sint32 res = f.read(source_buffer, 1, size);
558 if (res != size)
559 {
560 delete[] (mp_ubyte*)source_buffer;
561 source_buffer = NULL;
562 return FUNCTION_FAILED;
563 }
564
565 source_position = source_buffer;
566 source_remaining_bits = 32;
567
568 return FUNCTION_SUCCESS;
569 }
570
free_IT_compressed_block()571 void ITSampleLoader::free_IT_compressed_block () {
572
573
574 if (source_buffer!=NULL) delete[] (mp_ubyte*)source_buffer;
575
576 source_buffer = NULL;
577
578 }
579
load_sample_8bits(void * p_dest_buffer,mp_sint32 compressedSize,mp_sint32 p_buffsize)580 mp_sint32 ITSampleLoader::load_sample_8bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize) {
581
582 mp_sbyte *dest_buffer; /* destination buffer which will be returned */
583 mp_uword block_length; /* length of compressed data block in samples */
584 mp_uword block_position; /* position in block */
585 mp_ubyte bit_width; /* actual "bit width" */
586 mp_uword aux_value; /* value read from file to be processed */
587 mp_sbyte d1, d2; /* integrator buffers (d2 for it2.15) */
588 mp_sbyte *dest_position; /* position in output buffer */
589 mp_sbyte v; /* sample value */
590
591 dest_buffer = (mp_sbyte *) p_dest_buffer;
592
593 if (dest_buffer==NULL) return FUNCTION_FAILED;
594
595 memset (dest_buffer, 0, p_buffsize);
596
597 dest_position = dest_buffer;
598
599 /* now unpack data till the dest buffer is full */
600
601 while (p_buffsize) {
602 /* read a new block of compressed data and reset variables */
603 if ( read_IT_compressed_block() ) return FUNCTION_FAILED;
604
605
606 block_length = (p_buffsize < 0x8000) ? p_buffsize : 0x8000;
607
608 block_position = 0;
609
610 bit_width = 9; /* start with width of 9 bits */
611
612 d1 = d2 = 0; /* reset integrator buffers */
613
614 /* now uncompress the data block */
615 while ( block_position < block_length ) {
616
617 aux_value = read_n_bits_from_IT_compressed_block(bit_width); /* read bits */
618
619 if ( bit_width < 7 ) { /* method 1 (1-6 bits) */
620
621 if ( aux_value == (1 << (bit_width - 1)) ) { /* check for "100..." */
622
623 aux_value = read_n_bits_from_IT_compressed_block(3) + 1; /* yes -> read new width; */
624 bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
625 /* and expand it */
626 continue; /* ... next value */
627 }
628
629 } else if ( bit_width < 9 ) { /* method 2 (7-8 bits) */
630
631 mp_ubyte border = (0xFF >> (9 - bit_width)) - 4;
632 /* lower border for width chg */
633
634 if ( aux_value > border && aux_value <= (border + 8) ) {
635
636 aux_value -= border; /* convert width to 1-8 */
637 bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
638 /* and expand it */
639 continue; /* ... next value */
640 }
641
642
643 } else if ( bit_width == 9 ) { /* method 3 (9 bits) */
644
645 if ( aux_value & 0x100 ) { /* bit 8 set? */
646
647 bit_width = (aux_value + 1) & 0xff; /* new width... */
648 continue; /* ... and next value */
649 }
650
651 } else { /* illegal width, abort */
652
653 free_IT_compressed_block();
654
655 return FUNCTION_FAILED;
656 }
657
658 /* now expand value to signed byte */
659 if ( bit_width < 8 ) {
660
661 mp_ubyte tmp_shift = 8 - bit_width;
662
663 v=(aux_value << tmp_shift);
664 v>>=tmp_shift;
665
666 } else v = (mp_sbyte) aux_value;
667
668 /* integrate upon the sample values */
669 d1 += v;
670 d2 += d1;
671
672 /* ... and store it into the buffer */
673 *(dest_position++) = it215 ? d2 : d1;
674 block_position++;
675
676 }
677
678 /* now subtract block lenght from total length and go on */
679 free_IT_compressed_block();
680 p_buffsize -= block_length;
681 }
682
683
684 return FUNCTION_SUCCESS;
685 }
686
load_sample_16bits(void * p_dest_buffer,mp_sint32 compressedSize,mp_sint32 p_buffsize)687 mp_sint32 ITSampleLoader::load_sample_16bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize) {
688
689 mp_sword *dest_buffer; /* destination buffer which will be returned */
690 mp_uword block_length; /* length of compressed data block in samples */
691 mp_uword block_position; /* position in block */
692 mp_ubyte bit_width; /* actual "bit width" */
693 mp_dword aux_value; /* value read from file to be processed */
694 mp_sword d1, d2; /* integrator buffers (d2 for it2.15) */
695 mp_sword *dest_position; /* position in output buffer */
696 mp_sword v; /* sample value */
697
698 dest_buffer = (mp_sword *) p_dest_buffer;
699
700 if (dest_buffer==NULL) return FUNCTION_FAILED;
701
702 memset (dest_buffer, 0, p_buffsize*2);
703
704 dest_position = dest_buffer;
705
706 while (p_buffsize) {
707 /* read a new block of compressed data and reset variables */
708 if ( read_IT_compressed_block() ) {
709
710 return FUNCTION_FAILED;
711 }
712
713
714 block_length = (p_buffsize < 0x4000) ? p_buffsize : 0x4000;
715
716 block_position = 0;
717
718 bit_width = 17; /* start with width of 9 bits */
719
720 d1 = d2 = 0; /* reset integrator buffers */
721
722 while ( block_position < block_length ) {
723
724 aux_value = read_n_bits_from_IT_compressed_block(bit_width); /* read bits */
725
726 if ( bit_width < 7 ) { /* method 1 (1-6 bits) */
727
728 if ( (signed)aux_value == (1 << (bit_width - 1)) ) { /* check for "100..." */
729
730 aux_value = read_n_bits_from_IT_compressed_block(4) + 1; /* yes -> read new width; */
731 bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
732 /* and expand it */
733 continue; /* ... next value */
734 }
735
736 } else if ( bit_width < 17 ) {
737
738 mp_uword border = (0xFFFF >> (17 - bit_width)) - 8;
739
740 if ( (signed)aux_value > border && (signed)aux_value <= (border + 16) ) {
741
742 aux_value -= border; /* convert width to 1-8 */
743 bit_width = (aux_value < bit_width) ? aux_value : aux_value + 1;
744 /* and expand it */
745 continue; /* ... next value */
746 }
747
748
749 } else if ( bit_width == 17 ) {
750
751 if ( aux_value & 0x10000 ) { /* bit 8 set? */
752
753 bit_width = (aux_value + 1) & 0xff; /* new width... */
754 continue; /* ... and next value */
755 }
756
757 } else { /* illegal width, abort */
758
759 //ERROR("Sample has illegal BitWidth ");
760
761 free_IT_compressed_block();
762
763 return FUNCTION_FAILED;
764 }
765
766 /* now expand value to signed byte */
767 if ( bit_width < 16 ) {
768
769 mp_ubyte tmp_shift = 16 - bit_width;
770
771 v=(aux_value << tmp_shift);
772 v>>=tmp_shift;
773
774 } else v = (mp_sword) aux_value;
775
776 /* integrate upon the sample values */
777 d1 += v;
778 d2 += d1;
779
780 /* ... and store it into the buffer */
781 *(dest_position++) = it215 ? d2 : d1;
782 block_position++;
783
784 }
785
786 /* now subtract block lenght from total length and go on */
787 free_IT_compressed_block();
788 p_buffsize -= block_length;
789 }
790
791
792 return FUNCTION_SUCCESS;
793
794 }
795
796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
797 //
798 // MDL sample loading helper class
799 //
800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
801 class MDLSampleLoader : public XModule::SampleLoader
802 {
803 private:
804 mp_ubyte* tmpBuffer;
805 mp_ubyte* dstBuffer;
806
807 // MDL unpacking
readbits(mp_ubyte * buffer,mp_uint32 & bitcount,mp_uint32 & bytecount,mp_sint32 numbits)808 static mp_ubyte readbits(mp_ubyte* buffer,mp_uint32& bitcount,mp_uint32& bytecount,mp_sint32 numbits)
809 {
810 mp_ubyte val=0,bitti=0;
811 for (mp_sint32 n=0;n<numbits;n++){
812 val+=((buffer[bytecount]>>bitcount)&1)<<(bitti++);
813 bitcount++;
814 if (bitcount==8) {
815 bitcount=0;
816 bytecount++;
817 }
818 }
819 return val;
820 }
821
822 // MDL unpacking
depackbyte(mp_ubyte * packed,mp_uint32 & bitcount,mp_uint32 & bytecount)823 static mp_ubyte depackbyte(mp_ubyte* packed,mp_uint32& bitcount,mp_uint32& bytecount)
824 {
825 mp_ubyte b = 0;
826 mp_ubyte sign = readbits(packed,bitcount,bytecount,1);
827 mp_ubyte bit = readbits(packed,bitcount,bytecount,1);
828
829 if (bit) {
830 b = readbits(packed,bitcount,bytecount,3);
831 goto next;
832 }
833 else b=8;
834 loop:;
835 bit=readbits(packed,bitcount,bytecount,1);
836 if (!bit) {
837 b+=16;
838 goto loop;
839 }
840 else b+=readbits(packed,bitcount,bytecount,4);
841 next:;
842 if (sign) b^=255;
843
844 return b;
845 }
846
cleanUp()847 void cleanUp()
848 {
849 if (tmpBuffer)
850 {
851 delete[] tmpBuffer;
852 tmpBuffer = NULL;
853 }
854
855 if (dstBuffer)
856 {
857 delete[] dstBuffer;
858 dstBuffer = NULL;
859 }
860 }
861
862 public:
MDLSampleLoader(XMFileBase & file)863 MDLSampleLoader(XMFileBase& file) :
864 SampleLoader(file),
865 tmpBuffer(NULL),
866 dstBuffer(NULL)
867 {
868 }
869
~MDLSampleLoader()870 virtual ~MDLSampleLoader()
871 {
872 cleanUp();
873 }
874
875 virtual mp_sint32 load_sample_8bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize);
876 virtual mp_sint32 load_sample_16bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize);
877 };
878
load_sample_8bits(void * buffer,mp_sint32 size,mp_sint32 length)879 mp_sint32 MDLSampleLoader::load_sample_8bits(void* buffer, mp_sint32 size, mp_sint32 length)
880 {
881 cleanUp();
882
883 tmpBuffer = new mp_ubyte[size+32];
884 memset(tmpBuffer,0,size+32);
885
886 if (tmpBuffer == NULL)
887 return FUNCTION_FAILED;
888
889 f.read(tmpBuffer,1,size);
890
891 dstBuffer = new mp_ubyte[length+64];
892
893 if (dstBuffer == NULL)
894 return FUNCTION_FAILED;
895
896 memset(dstBuffer,0,length+64);
897
898 mp_uint32 bitcount=0, bytecount=0;
899
900 mp_sint32 i=0;
901
902 while (bytecount < (unsigned)size && i < length)
903 {
904 dstBuffer[i++]=depackbyte((mp_ubyte*)tmpBuffer,bitcount,bytecount);
905 }
906
907 mp_sbyte b1=0;
908 for (i = 0; i < length; i++)
909 dstBuffer[i] = b1+=dstBuffer[i];
910
911 memcpy(buffer,dstBuffer,length);
912
913 return FUNCTION_SUCCESS;
914 }
915
load_sample_16bits(void * buffer,mp_sint32 size,mp_sint32 length)916 mp_sint32 MDLSampleLoader::load_sample_16bits(void* buffer, mp_sint32 size, mp_sint32 length)
917 {
918 cleanUp();
919
920 tmpBuffer = new mp_ubyte[size+32];
921 memset(tmpBuffer,0,size+32);
922
923 if (tmpBuffer == NULL)
924 return FUNCTION_FAILED;
925
926 f.read(tmpBuffer,1,size);
927
928 dstBuffer = new mp_ubyte[length*2+64];
929
930 if (dstBuffer == NULL)
931 return FUNCTION_FAILED;
932
933 memset(dstBuffer,0,length+64);
934
935 mp_uint32 bitcount=0, bytecount=0;
936
937 mp_sint32 i=0;
938
939 while (bytecount<(unsigned)size && i < length*2)
940 {
941 dstBuffer[i++]=readbits((mp_ubyte*)tmpBuffer,bitcount,bytecount,8);
942 dstBuffer[i++]=depackbyte((mp_ubyte*)tmpBuffer,bitcount,bytecount);
943 }
944
945 mp_sbyte b1=0;
946 for (i = 0; i < length; i++)
947 dstBuffer[i*2+1] = b1+=dstBuffer[i*2+1];
948
949 mp_sword* dstBuffer16 = (mp_sword*)buffer;
950 mp_ubyte* srcBuffer = (mp_ubyte*)dstBuffer;
951
952 for (i = 0; i < length; i++)
953 *dstBuffer16++ = LittleEndian::GET_WORD(srcBuffer+=2);
954
955 return FUNCTION_SUCCESS;
956 }
957
958 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
959 //
960 // ADPCM sample loading helper class:
961 //
962 // 4-bit ADPCM is coding the delta values between a sample and
963 // the next in 4-bits (starting value is zero). The delta values are
964 // stored as a 16-byte table at the start of the sample data:
965 // [16-bytes delta values][(length+1)/2 bytes of 4-bit indexes...]
966 //
967 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
968 class ADPCMSampleLoader : public XModule::SampleLoader
969 {
970 private:
971 mp_ubyte* tmpBuffer;
972
cleanUp()973 void cleanUp()
974 {
975 if (tmpBuffer)
976 {
977 delete[] tmpBuffer;
978 tmpBuffer = NULL;
979 }
980 }
981
982 public:
ADPCMSampleLoader(XMFileBase & file)983 ADPCMSampleLoader(XMFileBase& file) :
984 SampleLoader(file),
985 tmpBuffer(NULL)
986 {
987 }
988
~ADPCMSampleLoader()989 virtual ~ADPCMSampleLoader()
990 {
991 cleanUp();
992 }
993
load_sample_8bits(void * p_dest_buffer,mp_sint32 compressedSize,mp_sint32 p_buffsize)994 virtual mp_sint32 load_sample_8bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize)
995 {
996 cleanUp();
997
998 mp_sbyte deltaValues[16];
999
1000 // read delta values table
1001 f.read(deltaValues, 1, 16);
1002
1003 // this is the actual size of the compressed size
1004 const mp_uint32 blockSize = (p_buffsize + 1) / 2;
1005
1006 // allocate some memory for it
1007 tmpBuffer = new mp_ubyte[blockSize];
1008
1009 // read compressed data
1010 f.read(tmpBuffer, 1, blockSize);
1011
1012 mp_sbyte b1 = 0;
1013
1014 mp_sbyte* srcPtr = (mp_sbyte*)p_dest_buffer;
1015 for (mp_uint32 i = 0; i < blockSize; i++)
1016 {
1017 mp_uint32 index = tmpBuffer[i] & 0xF;
1018 *srcPtr++ = b1+=deltaValues[index];
1019 index = tmpBuffer[i] >> 4;
1020 *srcPtr++ = b1+=deltaValues[index];
1021 }
1022
1023 return FUNCTION_SUCCESS;
1024 }
1025
load_sample_16bits(void * p_dest_buffer,mp_sint32 compressedSize,mp_sint32 p_buffsize)1026 virtual mp_sint32 load_sample_16bits(void* p_dest_buffer, mp_sint32 compressedSize, mp_sint32 p_buffsize)
1027 {
1028 cleanUp();
1029
1030 return FUNCTION_SUCCESS;
1031 }
1032 };
1033
compress(mp_ubyte * dest) const1034 mp_sint32 TXMPattern::compress(mp_ubyte* dest) const
1035 {
1036 mp_sint32 patternSize = rows*channum*(2+effnum*2);
1037
1038 mp_ubyte* srcPtr = patternData;
1039 mp_ubyte* dstPtr = dest;
1040
1041 mp_sint32 i = 0;
1042 mp_sint32 len = 0;
1043
1044 // retrieve buffer size only
1045 if (!dest)
1046 {
1047 while (i < patternSize)
1048 {
1049 if (*srcPtr > 0 && *srcPtr < 128)
1050 {
1051 srcPtr++;
1052 i++;
1053 len++;
1054 }
1055 else if (*srcPtr >= 128)
1056 {
1057 srcPtr++;
1058 i++;
1059 len+=2;
1060 }
1061 else
1062 {
1063 mp_sint32 j = 0;
1064 while (i < patternSize && j < 125 && *srcPtr == 0)
1065 {
1066 srcPtr++;
1067 j++;
1068 i++;
1069 }
1070 if (j == 1)
1071 {
1072 len++;
1073 }
1074 else
1075 {
1076 ASSERT(128+j < 255);
1077 len++;
1078 }
1079 }
1080 }
1081
1082 return len;
1083 }
1084
1085 // compress and store
1086 while (i < patternSize)
1087 {
1088 if (*srcPtr > 0 && *srcPtr < 128)
1089 {
1090 *dstPtr++ = *srcPtr++;
1091 i++;
1092 len++;
1093 }
1094 else if (*srcPtr >= 128)
1095 {
1096 *dstPtr++ = 255;
1097 *dstPtr++ = *srcPtr++;
1098 i++;
1099 len+=2;
1100 }
1101 else
1102 {
1103 mp_sint32 j = 0;
1104 while (i < patternSize && j < 125 && *srcPtr == 0)
1105 {
1106 srcPtr++;
1107 j++;
1108 i++;
1109 }
1110 if (j == 1)
1111 {
1112 *dstPtr++ = 0;
1113 len++;
1114 }
1115 else
1116 {
1117 *dstPtr++ = 128 + j;
1118
1119 ASSERT(128+j < 255);
1120
1121 len++;
1122 }
1123 }
1124 }
1125
1126 return len;
1127 }
1128
decompress(mp_ubyte * src,mp_sint32 len)1129 mp_sint32 TXMPattern::decompress(mp_ubyte* src, mp_sint32 len)
1130 {
1131 mp_sint32 patternSize = rows*channum*(2+effnum*2);
1132
1133 mp_ubyte* srcPtr = src;
1134 mp_ubyte* dstPtr = patternData;
1135
1136 mp_sint32 i = 0;
1137 mp_sint32 j = 0;
1138 while (i < len && j < patternSize)
1139 {
1140 if (*srcPtr < 128)
1141 {
1142 *dstPtr++ = *srcPtr++;
1143 i++;
1144 j++;
1145 }
1146 else if (*srcPtr == 255)
1147 {
1148 srcPtr++;
1149 *dstPtr++ = *srcPtr++;
1150 i+=2;
1151 j++;
1152 }
1153 else
1154 {
1155 mp_sint32 k = *srcPtr++ & 127;
1156 for (mp_sint32 l = 0; l < k; l++)
1157 {
1158 if (j < patternSize)
1159 *dstPtr++ = 0;
1160 else
1161 {
1162 ASSERT(false);
1163 }
1164 j++;
1165 }
1166 i++;
1167 }
1168 }
1169
1170 return MP_OK;
1171 }
1172
1173 #ifdef MILKYTRACKER
1174
operator =(const TXMPattern & src)1175 const TXMPattern& TXMPattern::operator=(const TXMPattern& src)
1176 {
1177 if (this != &src)
1178 {
1179 delete[] patternData;
1180 const mp_uint32 size = (mp_uint32)src.channum*(2+(mp_uint32)src.effnum*2)*(mp_uint32)src.rows;
1181 patternData = new mp_ubyte[size];
1182 memcpy(patternData, src.patternData, size);
1183 channum = src.channum;
1184 effnum = src.effnum;
1185 len = src.len;
1186 patdata = src.patdata;
1187 ptype = src.ptype;
1188 rows = src.rows;
1189 }
1190
1191 return *this;
1192 }
1193
1194 #endif
1195
1196 // Constructor for loader manager (private)
LoaderManager()1197 XModule::LoaderManager::LoaderManager() :
1198 loaders(NULL),
1199 numLoaders(0),
1200 numAllocatedLoaders(0),
1201 iteratorCounter(-1)
1202 {
1203 #ifndef MP_XMONLY
1204 registerLoader(new Loader669(), ModuleType_669);
1205 registerLoader(new LoaderAMF_1(), ModuleType_AMF);
1206 registerLoader(new LoaderAMF_2(), ModuleType_AMF);
1207 registerLoader(new LoaderAMSv1(), ModuleType_AMS);
1208 registerLoader(new LoaderAMSv2(), ModuleType_AMS);
1209 registerLoader(new LoaderCBA(), ModuleType_CBA);
1210 registerLoader(new LoaderDBM(), ModuleType_DBM);
1211 registerLoader(new LoaderDIGI(), ModuleType_DIGI);
1212 registerLoader(new LoaderDSMv1(), ModuleType_DSM);
1213 registerLoader(new LoaderDSMv2(), ModuleType_DSM);
1214 registerLoader(new LoaderDSm(), ModuleType_DSm);
1215 registerLoader(new LoaderDTM_1(), ModuleType_DTM_1);
1216 registerLoader(new LoaderDTM_2(), ModuleType_DTM_2);
1217 registerLoader(new LoaderFAR(), ModuleType_FAR);
1218 registerLoader(new LoaderGDM(), ModuleType_GDM);
1219 registerLoader(new LoaderIMF(), ModuleType_IMF);
1220 registerLoader(new LoaderIT(), ModuleType_IT);
1221 //registerLoader(new LoaderFNK(), funk format sucks
1222 registerLoader(new LoaderMDL(), ModuleType_MDL);
1223 registerLoader(new LoaderMTM(), ModuleType_MTM);
1224 registerLoader(new LoaderMXM(), ModuleType_MXM);
1225 registerLoader(new LoaderOKT(), ModuleType_OKT);
1226 registerLoader(new LoaderPLM(), ModuleType_PLM);
1227 registerLoader(new LoaderPSMv1(), ModuleType_PSM);
1228 registerLoader(new LoaderPSMv2(), ModuleType_PSM);
1229 registerLoader(new LoaderPTM(), ModuleType_PTM);
1230 registerLoader(new LoaderS3M(), ModuleType_S3M);
1231 registerLoader(new LoaderSTM(), ModuleType_STM);
1232 registerLoader(new LoaderSFX(), ModuleType_SFX);
1233 registerLoader(new LoaderUNI(), ModuleType_UNI);
1234 registerLoader(new LoaderULT(), ModuleType_ULT);
1235 registerLoader(new LoaderXM(), ModuleType_XM);
1236 // Game Music Creator may not be recognized perfectly
1237 registerLoader(new LoaderGMC(), ModuleType_GMC);
1238 // Last loader is MOD because there is a slight chance that other formats will be misinterpreted as 15 ins. MODs
1239 registerLoader(new LoaderMOD(), ModuleType_MOD);
1240 #else
1241 registerLoader(new LoaderXM(), ModuleType_XM);
1242 #endif
1243 }
1244
~LoaderManager()1245 XModule::LoaderManager::~LoaderManager()
1246 {
1247 for (mp_uint32 i = 0; i < numLoaders; i++)
1248 delete loaders[i].loader;
1249
1250 delete[] loaders;
1251 }
1252
registerLoader(LoaderInterface * loader,ModuleTypes type)1253 void XModule::LoaderManager::registerLoader(LoaderInterface* loader, ModuleTypes type)
1254 {
1255 if (numLoaders+1 > numAllocatedLoaders)
1256 {
1257 numAllocatedLoaders+=16;
1258
1259 TLoaderInfo* newLoaders = new TLoaderInfo[numAllocatedLoaders];
1260 for (mp_uint32 i = 0; i < numLoaders; i++)
1261 newLoaders[i] = loaders[i];
1262
1263 delete[] loaders;
1264 loaders = newLoaders;
1265 }
1266
1267 loaders[numLoaders].loader = loader;
1268 loaders[numLoaders].moduleType = type;
1269
1270 numLoaders++;
1271 }
1272
getFirstLoaderInfo()1273 XModule::TLoaderInfo* XModule::LoaderManager::getFirstLoaderInfo()
1274 {
1275 if (numLoaders)
1276 {
1277 iteratorCounter = 0;
1278 return loaders;
1279 }
1280 else return NULL;
1281 }
1282
getNextLoaderInfo()1283 XModule::TLoaderInfo* XModule::LoaderManager::getNextLoaderInfo()
1284 {
1285 iteratorCounter++;
1286 if (iteratorCounter < (signed)numLoaders)
1287 return loaders+iteratorCounter;
1288 else
1289 {
1290 iteratorCounter = -1;
1291 return NULL;
1292 }
1293 }
1294
1295 const mp_sint32 XModule::periods[12] = {1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907};
1296
1297 const mp_sint32 XModule::sfinetunes[16] = {8363,8413,8463,8529,8581,8651,8723,8757,
1298 7895,7941,7985,8046,8107,8169,8232,8280};
1299
1300 const mp_sbyte XModule::modfinetunes[16] = {0,16,32,48,64,80,96,112,-128,-112,-96,-80,-64,-48,-32,-16};
1301
1302 const mp_ubyte XModule::numValidXMEffects = 24;
1303 const mp_ubyte XModule::validXMEffects[XModule::numValidXMEffects] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,20,21,25,27,29,33};
1304
1305 //////////////////////////////////////////////////////////////////////////
1306 // various tools for loading and converting modules //
1307 //////////////////////////////////////////////////////////////////////////
getc4spd(mp_sint32 relnote,mp_sint32 finetune)1308 mp_sint32 XModule::getc4spd(mp_sint32 relnote,mp_sint32 finetune)
1309 {
1310 static const mp_sint32 table[] = {65536,69432,73561,77935,82570,87480,92681,98193,104031,110217,116771,123715,
1311 65536,65565,65595,65624,65654,65684,65713,65743,65773,65802,65832,65862,65891,
1312 65921,65951,65981,66010,66040,66070,66100,66130,66160,66189,66219,66249,66279,
1313 66309,66339,66369,66399,66429,66459,66489,66519,66549,66579,66609,66639,66669,
1314 66699,66729,66759,66789,66820,66850,66880,66910,66940,66971,67001,67031,67061,
1315 67092,67122,67152,67182,67213,67243,67273,67304,67334,67365,67395,67425,67456,
1316 67486,67517,67547,67578,67608,67639,67669,67700,67730,67761,67792,67822,67853,
1317 67883,67914,67945,67975,68006,68037,68067,68098,68129,68160,68190,68221,68252,
1318 68283,68314,68344,68375,68406,68437,68468,68499,68530,68561,68592,68623,68654,
1319 68685,68716,68747,68778,68809,68840,68871,68902,68933,68964,68995,69026,69057,
1320 69089,69120,69151,69182,69213,69245,69276,69307,69339,69370,69401};
1321
1322 mp_sint32 c4spd = 8363;
1323 mp_sbyte xmfine = finetune;
1324
1325 mp_sbyte octave = (relnote+96)/12;
1326 mp_sbyte note = (relnote+96)%12;
1327
1328 mp_sbyte o2 = octave-8;
1329
1330 if (xmfine<0)
1331 {
1332 xmfine+=(mp_sbyte)128;
1333 note--;
1334 if (note<0)
1335 {
1336 note+=12;
1337 o2--;
1338 }
1339 }
1340
1341 if (o2>=0)
1342 {
1343 c4spd<<=o2;
1344 }
1345 else
1346 {
1347 c4spd>>=-o2;
1348 }
1349
1350 mp_sint32 f = FixedMUL(table[(mp_ubyte)note],c4spd);
1351 return (FixedMUL(f,table[(mp_ubyte)xmfine+12]));
1352 }
1353
convertc4spd(mp_uint32 c4spd,mp_sbyte * finetune,mp_sbyte * relnote)1354 void XModule::convertc4spd(mp_uint32 c4spd,mp_sbyte *finetune,mp_sbyte *relnote)
1355 {
1356 mp_sint32 xmfine = 0;
1357 mp_sbyte cl = 0;
1358 mp_sbyte ch = 0;
1359 mp_uint32 ebp = 0xFFFFFFFF;
1360 mp_uint32 ebx = c4spd;
1361 aloop:
1362 mp_uint32 c4s2 = ebx;
1363 mp_uint32 c4s = getc4spd((mp_sint32)cl-48,0);
1364 if (c4s<c4s2)
1365 {
1366 mp_sint32 s = c4s2;
1367 c4s2 = c4s;
1368 c4s = s;
1369 }
1370 mp_uint32 dc4 = c4s-c4s2;
1371 if (dc4<ebp)
1372 {
1373 ebp = dc4;
1374 ch = cl;
1375 cl++;
1376 if (cl<119) goto aloop;
1377 }
1378 cl = 0;
1379 aloop2:
1380 c4s2 = ebx;
1381 c4s = getc4spd((mp_sint32)ch-48,xmfine);
1382 if (c4s<c4s2)
1383 {
1384 mp_sint32 s = c4s2;
1385 c4s2 = c4s;
1386 c4s = s;
1387 }
1388 dc4 = c4s-c4s2;
1389 if (dc4<ebp)
1390 {
1391 ebp = dc4;
1392 cl = xmfine;
1393 }
1394 xmfine++;
1395 if (xmfine<256) goto aloop2;
1396
1397 ch-=48;
1398 *finetune = (mp_sbyte)cl;
1399 *relnote = (mp_sbyte)ch;
1400
1401 }
1402
amigaPeriodToNote(mp_uint32 period)1403 mp_uint32 XModule::amigaPeriodToNote(mp_uint32 period)
1404 {
1405 for (mp_sint32 y = 0; y < 120; y++)
1406 {
1407 mp_uint32 per = (periods[y%12]*16>>((y/12)))>>2;
1408 if (period >= per)
1409 return y+1;
1410 }
1411
1412 return 0;
1413 }
1414
1415 ////////////////////////////////////////////
1416 // Load sample into given memory. //
1417 // Sample size is in BYTES not in samples //
1418 // Sample length is number of samples, //
1419 ////////////////////////////////////////////
loadSample(XMFileBase & f,void * buffer,mp_uint32 size,mp_uint32 length,mp_sint32 flags)1420 bool XModule::loadSample(XMFileBase& f,void* buffer,mp_uint32 size,mp_uint32 length,mp_sint32 flags /* = ST_DEFAULT */)
1421 {
1422 mp_ubyte* tmpBuffer = NULL;
1423 mp_ubyte* dstBuffer = NULL;
1424
1425 // MDL style packing
1426 if (flags & ST_PACKING_MDL)
1427 {
1428
1429 MDLSampleLoader sampleLoader(f);
1430
1431 if (flags & ST_16BIT)
1432 {
1433 if (sampleLoader.load_sample_16bits(buffer, size, length))
1434 return false;
1435 }
1436 else
1437 {
1438 if (sampleLoader.load_sample_8bits(buffer, size, length))
1439 return false;
1440 }
1441
1442 return true;
1443 }
1444 else if ((flags & ST_PACKING_IT) || (flags & ST_PACKING_IT215))
1445 {
1446 ITSampleLoader sampleLoader(f, (flags & ST_PACKING_IT215));
1447
1448 if (flags & ST_16BIT)
1449 {
1450 if (sampleLoader.load_sample_16bits(buffer, -1, length))
1451 return false;
1452 }
1453 else
1454 {
1455 if (sampleLoader.load_sample_8bits(buffer, -1, length))
1456 return false;
1457 }
1458
1459 return true;
1460 }
1461 else if (flags & ST_PACKING_ADPCM)
1462 {
1463 ADPCMSampleLoader sampleLoader(f);
1464
1465 if (flags & ST_16BIT)
1466 {
1467 if (sampleLoader.load_sample_16bits(buffer, size, length))
1468 return false;
1469 }
1470 else
1471 {
1472 if (sampleLoader.load_sample_8bits(buffer, size, length))
1473 return false;
1474 }
1475
1476 return true;
1477 }
1478 else
1479 {
1480 memset(buffer, 0, size);
1481 f.read(buffer,flags & ST_16BIT ? 2 : 1, length);
1482 }
1483
1484 // 16 bit sample
1485 if (flags & ST_16BIT)
1486 {
1487 mp_sword* dstPtr = (mp_sword*)buffer;
1488 mp_ubyte* srcPtr = (mp_ubyte*)buffer;
1489
1490 // PTM delta storing
1491 if (flags & ST_DELTA_PTM)
1492 {
1493 mp_sbyte b1=0;
1494 for (mp_uint32 i = 0; i < length*2; i++)
1495 srcPtr[i] = b1+=srcPtr[i];
1496 }
1497
1498 mp_uint32 i;
1499 if (flags & ST_BIGENDIAN)
1500 {
1501 for (i = 0; i < length; i++)
1502 dstPtr[i] = BigEndian::GET_WORD(srcPtr+i*2);
1503 }
1504 else
1505 {
1506 for (i = 0; i < length; i++)
1507 dstPtr[i] = LittleEndian::GET_WORD(srcPtr+i*2);
1508 }
1509
1510 // delta-storing
1511 if (flags & ST_DELTA)
1512 {
1513 mp_sword b1=0;
1514 for (i = 0; i < length; i++)
1515 dstPtr[i] = b1+=dstPtr[i];
1516 }
1517
1518 // unsigned sample data
1519 if (flags & ST_UNSIGNED)
1520 {
1521 for (i = 0; i < length; i++)
1522 dstPtr[i] = (dstPtr[i]^32768);
1523 }
1524 }
1525 // 8 bit sample
1526 else
1527 {
1528 mp_sbyte* smpPtr = (mp_sbyte*)buffer;
1529
1530 // delta-storing
1531 if (flags & ST_DELTA)
1532 {
1533 mp_sbyte b1=0;
1534 for (mp_uint32 i = 0; i < length; i++)
1535 smpPtr[i] = b1+=smpPtr[i];
1536 }
1537
1538 // unsigned sample data
1539 if (flags & ST_UNSIGNED)
1540 {
1541 for (mp_uint32 i = 0; i < length; i++)
1542 smpPtr[i] ^= 128;
1543 }
1544 }
1545
1546 if (tmpBuffer)
1547 delete[] tmpBuffer;
1548
1549 if (dstBuffer)
1550 delete[] dstBuffer;
1551
1552 return true;
1553 }
1554
loadModuleSample(XMFileBase & f,mp_sint32 index,mp_sint32 flags8,mp_sint32 flags16,mp_uint32 alternateSize)1555 mp_sint32 XModule::loadModuleSample(XMFileBase& f, mp_sint32 index,
1556 mp_sint32 flags8/* = ST_DEFAULT*/, mp_sint32 flags16/* = ST_16BIT*/,
1557 mp_uint32 alternateSize/* = 0*/)
1558 {
1559 if (smp[index].type & 16)
1560 {
1561 mp_uint32 finalSize = alternateSize ? alternateSize : smp[index].samplen*2;
1562 if(finalSize < 8) finalSize = 8;
1563
1564 smp[index].sample = (mp_sbyte*)allocSampleMem(finalSize);
1565
1566 if (smp[index].sample == NULL)
1567 {
1568 return MP_OUT_OF_MEMORY;
1569 }
1570
1571 if (!loadSample(f,smp[index].sample, finalSize, smp[index].samplen, flags16))
1572 {
1573 return MP_OUT_OF_MEMORY;
1574 }
1575 }
1576 else
1577 {
1578 mp_uint32 finalSize = alternateSize ? alternateSize : smp[index].samplen;
1579 if(finalSize < 4) finalSize = 4;
1580
1581 smp[index].sample = (mp_sbyte*)allocSampleMem(finalSize);
1582
1583 if (smp[index].sample == NULL)
1584 {
1585 return MP_OUT_OF_MEMORY;
1586 }
1587
1588 if (!loadSample(f,smp[index].sample, finalSize, smp[index].samplen, flags8))
1589 {
1590 return MP_OUT_OF_MEMORY;
1591 }
1592 }
1593
1594 return MP_OK;
1595 }
1596
loadModuleSamples(XMFileBase & f,mp_sint32 flags8,mp_sint32 flags16)1597 mp_sint32 XModule::loadModuleSamples(XMFileBase& f, mp_sint32 flags8/* = ST_DEFAULT*/, mp_sint32 flags16/* = ST_16BIT*/)
1598 {
1599 for (mp_sint32 i = 0; i < header.smpnum; i++)
1600 {
1601 mp_sint32 res = loadModuleSample(f, i, flags8, flags16);
1602 if (res != MP_OK)
1603 return res;
1604 }
1605 return MP_OK;
1606 }
1607
1608 ////////////////////////////////////////////
1609 // Before using the sample postprocessing //
1610 // please make sure that the memory //
1611 // allocated for the samples has another //
1612 // 16 bytes padding space //
1613 ////////////////////////////////////////////
postProcessSamples(bool heavy)1614 void XModule::postProcessSamples(bool heavy/* = false*/)
1615 {
1616 for (mp_uint32 i = 0; i < header.smpnum; i++)
1617 {
1618
1619 TXMSample* smp = &this->smp[i];
1620
1621 #ifdef VERBOSE
1622 printf("%i: %i, %i, %i, %x\n",i,smp->samplen, smp->loopstart, smp->looplen,smp->pan);
1623 #endif
1624
1625 if (smp->samplen == 0)
1626 {
1627 freeSampleMem((mp_ubyte*)smp->sample, false);
1628 smp->sample = NULL;
1629 continue;
1630 }
1631
1632 if (heavy)
1633 smp->smoothLooping();
1634
1635 smp->postProcessSamples();
1636 }
1637
1638 }
1639
setDefaultPanning()1640 void XModule::setDefaultPanning()
1641 {
1642 for (mp_sint32 i = 0; i < header.channum; i++)
1643 {
1644 if (i & 1)
1645 header.pan[i] = 192;
1646 else
1647 header.pan[i] = 64;
1648 }
1649 }
1650
allocSampleMem(mp_uint32 size)1651 mp_ubyte* XModule::allocSampleMem(mp_uint32 size)
1652 {
1653 // sample is always padded at start and end with 16 bytes
1654 for (mp_sint32 i = 0; i < (signed)samplePointerIndex; i++)
1655 {
1656 if (samplePool[i] == NULL)
1657 {
1658 samplePool[i] = TXMSample::allocPaddedMem(size);
1659 return samplePool[i];
1660 }
1661 }
1662
1663 samplePool[samplePointerIndex] = TXMSample::allocPaddedMem(size);
1664 return samplePool[samplePointerIndex++];
1665 }
1666
freeSampleMem(mp_ubyte * mem,bool assertCheck)1667 void XModule::freeSampleMem(mp_ubyte* mem, bool assertCheck/* = true*/)
1668 {
1669 bool found = false;
1670 for (mp_sint32 i = 0; i < (signed)samplePointerIndex; i++)
1671 {
1672 if (samplePool[i] == mem)
1673 {
1674 found = true;
1675 TXMSample::freePaddedMem(samplePool[i]);
1676 samplePool[i] = NULL;
1677 if (i == (signed)samplePointerIndex - 1)
1678 {
1679 samplePointerIndex--;
1680 break;
1681 }
1682 }
1683 }
1684
1685 if (assertCheck)
1686 {
1687 ASSERT(found);
1688 }
1689 }
1690
1691 #ifdef MILKYTRACKER
insertSamplePtr(mp_ubyte * ptr)1692 void XModule::insertSamplePtr(mp_ubyte* ptr)
1693 {
1694 for (mp_sint32 i = 0; i < (signed)samplePointerIndex; i++)
1695 {
1696 if (samplePool[i] == NULL)
1697 {
1698 samplePool[i] = ptr;
1699 return;
1700 }
1701 }
1702
1703 samplePool[samplePointerIndex++] = ptr;
1704 }
removeSamplePtr(mp_ubyte * ptr)1705 void XModule::removeSamplePtr(mp_ubyte* ptr)
1706 {
1707 for (mp_sint32 i = 0; i < (signed)samplePointerIndex; i++)
1708 {
1709 if (samplePool[i] == ptr)
1710 {
1711 samplePool[i] = NULL;
1712 }
1713 }
1714 }
1715 #endif
1716
addEnvelope(TEnvelope * & envs,const TEnvelope & env,mp_uint32 & numEnvsAlloc,mp_uint32 & numEnvs)1717 bool XModule::addEnvelope(TEnvelope*& envs,
1718 const TEnvelope& env,
1719 mp_uint32& numEnvsAlloc,
1720 mp_uint32& numEnvs)
1721 {
1722 if (envs == NULL)
1723 {
1724 numEnvsAlloc = 8;
1725
1726 envs = new TEnvelope[numEnvsAlloc];
1727
1728 if (envs == NULL)
1729 return false;
1730
1731 envs[numEnvs++] = env;
1732 return true;
1733 }
1734 else
1735 {
1736 if (numEnvs >= numEnvsAlloc)
1737 {
1738
1739 numEnvsAlloc+=8;
1740
1741 TEnvelope* tmpEnvs = new TEnvelope[numEnvsAlloc];
1742
1743 if (tmpEnvs == NULL)
1744 return false;
1745
1746 memcpy(tmpEnvs,envs,numEnvs*sizeof(TEnvelope));
1747
1748 delete[] envs;
1749
1750 envs = tmpEnvs;
1751 }
1752
1753 envs[numEnvs++] = env;
1754
1755 }
1756
1757 return true;
1758 }
1759
1760 // fix broken envelopes (1 point envelope for example)
fixEnvelopes(TEnvelope * envs,mp_uint32 numEnvs)1761 void XModule::fixEnvelopes(TEnvelope* envs, mp_uint32 numEnvs)
1762 {
1763 TEnvelope* env = envs;
1764
1765 for (mp_uint32 i = 0; i < numEnvs; i++, env++)
1766 {
1767 // Check for envelope with single point (seen in a DBM module)
1768 if (env->num == 1)
1769 {
1770 // make sure point one starts at x-position 0
1771 env->env[0][0] = 0;
1772 // add second point with y-coordinate from point one
1773 env->env[1][1] = env->env[0][1];
1774 // x-coordinate is just a few ticks right from point one
1775 env->env[1][0] = env->env[0][0] + 64;
1776 env->num++;
1777 }
1778 }
1779 }
1780
1781 // better destructor, should be called before loading a song
1782 // just in case loading of a module failed and someone tries to load another
1783 // module right after that
cleanUp()1784 bool XModule::cleanUp()
1785 {
1786 if (venvs)
1787 {
1788 delete[] venvs;
1789 venvs = NULL;
1790 numVEnvsAlloc = numVEnvs = 0;
1791 }
1792 if (penvs)
1793 {
1794 delete[] penvs;
1795 penvs = NULL;
1796 numPEnvsAlloc = numPEnvs = 0;
1797 }
1798 if (fenvs)
1799 {
1800 delete[] fenvs;
1801 fenvs = NULL;
1802 numFEnvsAlloc = numFEnvs = 0;
1803 }
1804 if (vibenvs)
1805 {
1806 delete[] vibenvs;
1807 vibenvs = NULL;
1808 numVibEnvsAlloc = numVibEnvs = 0;
1809 }
1810 if (pitchenvs)
1811 {
1812 delete[] pitchenvs;
1813 pitchenvs = NULL;
1814 numPitchEnvsAlloc = numPitchEnvs = 0;
1815 }
1816
1817 if (message)
1818 {
1819 delete[] message;
1820 message = NULL;
1821 messageBytesAlloc = 0;
1822 }
1823
1824 // release pattern memory
1825 mp_uint32 i;
1826 #ifdef MILKYTRACKER
1827 for (i = 0; i < 256; i++)
1828 #else
1829 for (i = 0; i < header.patnum; i++)
1830 #endif
1831 {
1832 if (phead[i].patternData)
1833 {
1834 delete[] phead[i].patternData;
1835 phead[i].patternData = NULL;
1836 }
1837
1838 }
1839
1840 // release sample-memory
1841 for (i = 0; i < samplePointerIndex; i++)
1842 {
1843 if (samplePool[i])
1844 {
1845 TXMSample::freePaddedMem(samplePool[i]);
1846 samplePool[i] = NULL;
1847 }
1848 }
1849 samplePointerIndex = 0;
1850
1851 memset(&header,0,sizeof(TXMHeader));
1852
1853 if (instr)
1854 memset(instr,0,sizeof(TXMInstrument)*256);
1855
1856 if (smp)
1857 memset(smp,0,sizeof(TXMSample)*MP_MAXSAMPLES);
1858
1859 if (phead)
1860 memset(phead,0,sizeof(TXMPattern)*256);
1861
1862 // subsong stuff
1863 memset(subSongPositions, 0, sizeof(subSongPositions));
1864 numSubSongs = 0;
1865
1866 moduleLoaded = false;
1867
1868 return true;
1869 }
1870
XModule()1871 XModule::XModule()
1872 {
1873 // allocated necessary space for all possible patterns, instruments and samples
1874 phead = new TXMPattern[256];
1875 instr = new TXMInstrument[256];
1876 smp = new TXMSample[MP_MAXSAMPLES];
1877
1878 type = ModuleType_NONE;
1879
1880 // no module loaded (empty song)
1881 moduleLoaded = false;
1882
1883 // initialise all sample pointers to NULL
1884 memset(samplePool,0,sizeof(samplePool));
1885 // reset current sample index
1886 samplePointerIndex = 0;
1887
1888 memset(&header,0,sizeof(TXMHeader));
1889
1890 if (instr)
1891 memset(instr,0,sizeof(TXMInstrument)*256);
1892
1893 if (smp)
1894 memset(smp,0,sizeof(TXMSample)*MP_MAXSAMPLES);
1895
1896 if (phead)
1897 memset(phead,0,sizeof(TXMPattern)*256);
1898
1899 // subsong stuff
1900 memset(subSongPositions, 0, sizeof(subSongPositions));
1901 numSubSongs = 0;
1902
1903 venvs = NULL;
1904 numVEnvsAlloc = numVEnvs = 0;
1905
1906 penvs = NULL;
1907 numPEnvsAlloc = numPEnvs = 0;
1908
1909 fenvs = NULL;
1910 numFEnvsAlloc = numFEnvs = 0;
1911
1912 vibenvs = NULL;
1913 numVibEnvsAlloc = numVibEnvs = 0;
1914
1915 pitchenvs = NULL;
1916 numPitchEnvsAlloc = numPitchEnvs = 0;
1917
1918 message = NULL;
1919 messageBytesAlloc = 0;
1920 }
1921
~XModule()1922 XModule::~XModule()
1923 {
1924 cleanUp();
1925
1926 delete[] phead;
1927 delete[] instr;
1928 delete[] smp;
1929 }
1930
identifyModule(const mp_ubyte * buffer)1931 const char* XModule::identifyModule(const mp_ubyte* buffer)
1932 {
1933 // browse through all available loaders and find suitable
1934 LoaderManager loaderManager;
1935 TLoaderInfo* loaderInfo;
1936 loaderInfo = loaderManager.getFirstLoaderInfo();
1937 while (loaderInfo)
1938 {
1939 // if loader can identify module return ID
1940 const char* id = loaderInfo->loader->identifyModule(buffer);
1941 if (id)
1942 {
1943 return id;
1944 }
1945
1946 loaderInfo = loaderManager.getNextLoaderInfo();
1947 }
1948 return NULL;
1949 }
1950
loadModule(const SYSCHAR * fileName,bool scanForSubSongs)1951 mp_sint32 XModule::loadModule(const SYSCHAR* fileName, bool scanForSubSongs/* = false*/)
1952 {
1953 XMFile f(fileName);
1954 return f.isOpen() ? loadModule(f, scanForSubSongs) : -8;
1955 }
1956
loadModule(XMFileBase & f,bool scanForSubSongs)1957 mp_sint32 XModule::loadModule(XMFileBase& f, bool scanForSubSongs/* = false*/)
1958 {
1959 mp_ubyte buffer[IdentificationBufferSize];
1960 memset(buffer, 0, sizeof(buffer));
1961
1962 f.setBaseOffset(f.pos());
1963 f.read(buffer, 1, sizeof(buffer));
1964
1965 // browse through all available loaders and find suitable
1966 LoaderManager loaderManager;
1967 TLoaderInfo* loaderInfo;
1968 loaderInfo = loaderManager.getFirstLoaderInfo();
1969 while (loaderInfo)
1970 {
1971 // if loader can identify module take that loader
1972 if (loaderInfo->loader->identifyModule(buffer))
1973 {
1974 // try to load module
1975 f.seekWithBaseOffset(0);
1976 mp_sint32 err = loaderInfo->loader->load(f, this);
1977 if (err == MP_OK)
1978 {
1979 moduleLoaded = true;
1980
1981 bool res = validate();
1982
1983 if (!res)
1984 return MP_OUT_OF_MEMORY;
1985
1986 type = loaderInfo->moduleType;
1987 if (scanForSubSongs)
1988 buildSubSongTable();
1989 }
1990 return err;
1991 }
1992
1993 loaderInfo = loaderManager.getNextLoaderInfo();
1994 }
1995
1996 #ifdef MILKYTRACKER
1997 return MP_UNKNOWN_FORMAT;
1998 #else
1999 return MP_UNSPECIFIED;
2000 #endif
2001
2002 }
2003
validate()2004 bool XModule::validate()
2005 {
2006 if (header.channum == 0)
2007 header.channum++;
2008
2009 if (header.insnum == 0)
2010 header.insnum++;
2011
2012 /*for (mp_sint32 i = 0; i < header.ordnum; i++)
2013 if (header.ord[i] >= header.patnum)
2014 header.ord[i] = 0;*/
2015
2016 // if we're not having any pattern just create an empty dummy pattern
2017 if (!header.patnum)
2018 {
2019 header.patnum++;
2020
2021 phead[0].rows = 64;
2022 #ifdef MILKYTRACKER
2023 phead[0].effnum = 2;
2024 #else
2025 phead[0].effnum = 1;
2026 #endif
2027 phead[0].channum = (mp_ubyte)header.channum;
2028
2029 phead[0].patternData = new mp_ubyte[phead[0].rows*header.channum*(2+phead[0].effnum*2)];
2030
2031 // out of memory?
2032 if (phead[0].patternData == NULL)
2033 {
2034 return false;
2035 }
2036
2037 memset(phead[0].patternData,0,phead[0].rows*header.channum*(2+phead[0].effnum*2));
2038 }
2039
2040 removeOrderSkips();
2041
2042 if (!header.ordnum)
2043 {
2044 header.ordnum++;
2045 header.ord[0] = 0;
2046 }
2047
2048 fixEnvelopes(venvs, numVEnvs);
2049 fixEnvelopes(penvs, numPEnvs);
2050 fixEnvelopes(fenvs, numFEnvs);
2051 fixEnvelopes(vibenvs, numVibEnvs);
2052 fixEnvelopes(pitchenvs, numPitchEnvs);
2053
2054 return true;
2055 }
2056
convertStr(char * strIn,const char * strOut,mp_sint32 nLen,bool filter)2057 void XModule::convertStr(char* strIn, const char* strOut, mp_sint32 nLen, bool filter)
2058 {
2059 memset(strIn, 0, nLen);
2060 mp_sint32 i;
2061 for (i = 0; i < nLen; i++)
2062 {
2063 strIn[i] = strOut[i];
2064
2065 // must be an asciiz string
2066 if (strIn[i] == '\0')
2067 break;
2068
2069 // Filter non-viewable characters
2070 if (filter && (strIn[i]<32 || (unsigned)strIn[i]>127))
2071 strIn[i] = 32;
2072 }
2073
2074 i = nLen-1;
2075 while (i>=0 && strIn[i]<=32)
2076 i--;
2077
2078 i++;
2079 strIn[i] = '\0';
2080 }
2081
getTitle(char * str,bool filter) const2082 void XModule::getTitle(char* str, bool filter /* = true */) const
2083 {
2084 if (!moduleLoaded)
2085 {
2086 memset(str, 0, 33);
2087 return;
2088 }
2089
2090 convertStr(str, (const char*)&header.name, 32, filter);
2091 }
2092
getSignature(char * str,bool filter) const2093 void XModule::getSignature(char* str, bool filter /* = true */) const
2094 {
2095 if (!moduleLoaded)
2096 {
2097 memset(str, 0, 18);
2098 return;
2099 }
2100
2101 convertStr(str, (const char*)&header.sig, 17, filter);
2102 }
2103
getTracker(char * str,bool filter) const2104 void XModule::getTracker(char* str, bool filter /* = true */) const
2105 {
2106 if (!moduleLoaded)
2107 {
2108 memset(str, 0, 33);
2109 return;
2110 }
2111
2112 convertStr(str, (const char*)&header.tracker, 32, filter);
2113 }
2114
2115 ///////////////////////////////////////////////////
2116 // dealing with song messages //
2117 ///////////////////////////////////////////////////
allocateSongMessage(mp_uint32 initialSize)2118 void XModule::allocateSongMessage(mp_uint32 initialSize/* = 512*/)
2119 {
2120 if (message)
2121 {
2122 delete[] message;
2123 message = NULL;
2124 messageBytesAlloc = 0;
2125 }
2126
2127 message = new char[initialSize];
2128
2129 if (message)
2130 {
2131 memset(message, 0, initialSize);
2132 messageBytesAlloc = initialSize;
2133 }
2134 }
2135
2136 // add one more line of text to songmessage
addSongMessageLine(const char * line)2137 void XModule::addSongMessageLine(const char* line)
2138 {
2139
2140 if (!message)
2141 {
2142 allocateSongMessage();
2143 if (!message)
2144 return;
2145 }
2146
2147 mp_uint32 oSize = (mp_uint32)strlen(message) + 1;
2148 mp_uint32 nSize = (mp_uint32)strlen(line) + 1;
2149
2150 mp_uint32 size = oSize + nSize + 2;
2151
2152 if (size > messageBytesAlloc)
2153 {
2154 char* tempMessage = new char[size];
2155 if (tempMessage)
2156 {
2157 memset(tempMessage, 0, size);
2158 messageBytesAlloc = size;
2159
2160 strcpy(tempMessage, message);
2161 delete[] message;
2162 message = tempMessage;
2163 }
2164 else
2165 return;
2166 }
2167
2168 // if this is not the first line in song message,
2169 // add CR to the previous line
2170 if (strlen(message) != 0)
2171 {
2172 message[strlen(message)] = 0x0D;
2173 message[strlen(message)+1] = '\0';
2174 }
2175
2176 strcat(message, line);
2177
2178 }
2179
2180 // start iterating text lines (get size of line)
getFirstSongMessageLineLength()2181 mp_sint32 XModule::getFirstSongMessageLineLength()
2182 {
2183 if (message == NULL)
2184 return -1;
2185
2186 // no song message at all
2187 if (*message == '\0')
2188 return -1;
2189
2190 messagePtr = message;
2191
2192 mp_sint32 i = 0;
2193 while (messagePtr[i] != 0x0D && messagePtr[i] != '\0')
2194 i++;
2195
2196 return i;
2197 }
2198
2199 // get next size text line
getNextSongMessageLineLength()2200 mp_sint32 XModule::getNextSongMessageLineLength()
2201 {
2202
2203 if (message == NULL)
2204 return -1;
2205
2206 // advance to next line first
2207 while (*messagePtr != 0x0D && *messagePtr != '\0')
2208 messagePtr++;
2209
2210 // we reached end of song message
2211 if (*messagePtr == '\0')
2212 return -1;
2213
2214 ASSERT(*messagePtr == 0x0D);
2215
2216 // skip CR
2217 messagePtr++;
2218
2219 mp_sint32 i = 0;
2220 while (messagePtr[i] != 0x0D && messagePtr[i] != '\0')
2221 i++;
2222
2223 return i;
2224 }
2225
2226 // get line
getSongMessageLine(char * line)2227 void XModule::getSongMessageLine(char* line)
2228 {
2229 mp_sint32 i = 0;
2230 while (messagePtr[i] != 0x0D && messagePtr[i] != '\0')
2231 {
2232 line[i] = messagePtr[i];
2233 i++;
2234 }
2235
2236 line[i] = '\0';
2237 }
2238
2239 // search for subsongs
buildSubSongTable()2240 void XModule::buildSubSongTable()
2241 {
2242 if (!moduleLoaded)
2243 return;
2244
2245 mp_ubyte* positionLookup = new mp_ubyte[header.ordnum*256];
2246
2247 if (positionLookup == NULL)
2248 return;
2249
2250 memset(positionLookup, 0, header.ordnum*256);
2251
2252 // entire song = first subsong, starts at 0
2253 subSongPositions[numSubSongs*2] = 0;
2254 subSongPositions[numSubSongs*2+1] = 0;
2255
2256 mp_ubyte pbreak = 0;
2257 mp_ubyte pbreakpos = 0;
2258 mp_ubyte pjump = 0;
2259 mp_ubyte pjumppos = 0, pjumprow = 0;
2260
2261 mp_sint32 poscnt = 0, rowcnt = 0;
2262 mp_sint32 poscntMax = -1;
2263
2264 while (true)
2265 {
2266
2267 bool breakMain = false;
2268
2269 while (!breakMain)
2270 {
2271
2272 /*if (header.ord[poscnt]==254)
2273 {
2274 while (header.ord[poscnt]==254)
2275 {
2276 poscnt++;
2277 if (poscnt>=header.ordnum)
2278 {
2279 breakMain = true;
2280 break;
2281 }
2282 }
2283 }*/
2284
2285 if (!breakMain)
2286 {
2287
2288 mp_sint32 ord = header.ord[poscnt];
2289 if (ord < header.patnum)
2290 {
2291 mp_ubyte* pattern = phead[ord].patternData;
2292
2293 mp_sint32 r = rowcnt;
2294
2295 mp_sint32 i = poscnt*256+r;
2296
2297 if (!positionLookup[i])
2298 positionLookup[i]++;
2299 else
2300 {
2301 subSongPositions[numSubSongs*2+1] = poscntMax;
2302 numSubSongs++;
2303
2304 breakMain = true;
2305 continue;
2306 }
2307
2308 pbreak = pbreakpos = pjump = pjumppos = pjumprow = 0;
2309
2310 for (mp_sint32 c = 0; c < phead[ord].channum; c++)
2311 {
2312
2313 mp_sint32 slotSize = 2 + 2*phead[ord].effnum;
2314
2315 mp_ubyte* slot = pattern + r*phead[ord].channum*slotSize + c*slotSize;
2316
2317 for (mp_sint32 e = 0; e < phead[ord].effnum; e++)
2318 {
2319 mp_ubyte eff = slot[2+e*2];
2320 mp_ubyte eop = slot[2+e*2+1];
2321
2322 switch (eff)
2323 {
2324 case 0x0B :
2325 {
2326 pjump = 1;
2327 pjumppos = eop;
2328 pjumprow = 0;
2329 break;
2330 }
2331
2332 case 0x0D :
2333 {
2334 pbreak=1;
2335 pbreakpos = (eop>>4)*10+(eop&0xf);
2336 break;
2337 }
2338
2339 case 0x0F:
2340 {
2341 if (eop == 0)
2342 {
2343 subSongPositions[numSubSongs*2+1] = poscntMax;
2344 numSubSongs++;
2345 breakMain = true;
2346 poscnt++;
2347 rowcnt = 0;
2348 goto skipChannels;
2349 }
2350 break;
2351 }
2352
2353 case SubSongMarkEffect:
2354 {
2355 if (eop == SubSongMarkOperand)
2356 {
2357 subSongPositions[numSubSongs*2+1] = poscntMax;
2358 numSubSongs++;
2359 breakMain = true;
2360 continue;
2361 }
2362 }
2363
2364 case 0x2B:
2365 {
2366 pjump = 1;
2367 pjumppos = eop;
2368 pjumprow = slot[2+((e+1)%phead[ord].effnum)*2+1];
2369 break;
2370 }
2371 }
2372 } // effects
2373
2374 } // channels
2375
2376 if (poscnt > poscntMax)
2377 poscntMax = poscnt;
2378
2379 // player logic
2380 // break pattern?
2381 if (pbreak&&(poscnt<(header.ordnum-1)))
2382 {
2383 if (!pjump)
2384 poscnt++;
2385 rowcnt=pbreakpos-1;
2386 }
2387 else if (pbreak&&(poscnt==(header.ordnum-1)))
2388 {
2389 if (!pjump)
2390 poscnt=0;
2391 rowcnt=pbreakpos-1;
2392 }
2393
2394 // pattern jump?
2395 if (pjump)
2396 {
2397 if (!pbreak)
2398 rowcnt = pjumprow-1;
2399
2400 if (pjumppos < header.ordnum)
2401 poscnt = pjumppos;
2402 }
2403
2404 rowcnt++;
2405
2406 // make sure we're getting the right pattern, position might
2407 // have changed because of position jumps or pattern breaks
2408 ord = header.ord[poscnt];
2409 if (rowcnt >= phead[ord].rows)
2410 {
2411 poscnt++;
2412
2413 rowcnt = 0;
2414
2415 if (poscnt >= header.ordnum)
2416 {
2417 poscnt = 0;
2418 }
2419
2420 }
2421 skipChannels:;
2422 }
2423 else
2424 {
2425 mp_sint32 i = poscnt*256;
2426 memset(positionLookup+i, 1, 256);
2427 poscnt++;
2428 rowcnt = 0;
2429 if (poscnt >= header.ordnum)
2430 poscnt = 0;
2431 }
2432
2433 }
2434
2435 }
2436
2437 if (numSubSongs >= 256)
2438 break;
2439
2440 bool allPlayed = true;
2441 for (poscnt = 0; poscnt < header.ordnum; poscnt++)
2442 {
2443 mp_sint32 ord = header.ord[poscnt];
2444
2445 if (ord < header.patnum)
2446 {
2447 bool played = false;
2448
2449 mp_sint32 slotSize = 2 + 2*phead[ord].effnum;
2450
2451 for (mp_sint32 i = 0; i < phead[ord].rows; i++)
2452 {
2453 if (positionLookup[poscnt*256+i])
2454 {
2455 played = true;
2456 break;
2457 }
2458 }
2459
2460 if (!played)
2461 {
2462 bool empty = true;
2463 mp_sint32 offs = 0;
2464 mp_ubyte* pattern = phead[ord].patternData;
2465 for (mp_sint32 i = 0; i < phead[ord].rows*phead[ord].channum; i++)
2466 {
2467 if (pattern[offs])
2468 {
2469 empty = false;
2470 break;
2471 }
2472 offs+=slotSize;
2473 }
2474 if (empty)
2475 {
2476 memset(positionLookup+poscnt*256, 1, 256);
2477 played = true;
2478 }
2479 }
2480
2481 if (!played)
2482 {
2483 subSongPositions[numSubSongs*2] = poscnt;
2484 // make it safe
2485 subSongPositions[numSubSongs*2+1] = poscnt;
2486 poscntMax = poscnt;
2487 //numSubSongs++;
2488 rowcnt = 0;
2489 allPlayed = false;
2490 break;
2491 }
2492 }
2493 }
2494
2495 if (allPlayed)
2496 break;
2497
2498 }
2499
2500 delete[] positionLookup;
2501
2502 #if 0
2503 if (subSongPositions[(numSubSongs-1)*2+1] < header.ordnum - 1)
2504 {
2505 numSubSongs++;
2506 subSongPositions[(numSubSongs-1)*2] = subSongPositions[(numSubSongs-2)*2+1] + 1;
2507 subSongPositions[(numSubSongs-1)*2+1] = header.ordnum - 1;
2508 }
2509 #endif
2510
2511 //subSongPositions[3*2] = 3;
2512 //subSongPositions[3*2+1] = 10;
2513
2514 //for (mp_sint32 i = 0; i < numSubSongs*2; i++)
2515 // printf("%i: %i\n",i,subSongPositions[i]);
2516 //printf("\n\n");
2517
2518 mp_sint32 i,j = 0,k = 0;
2519 mp_sint32 tempSubSongPositions[256*2];
2520 for (i = 0; i < numSubSongs*2; i++)
2521 tempSubSongPositions[i] = subSongPositions[i];
2522
2523 // find subsets of sub songs and merge them
2524 for (i = 0; i < numSubSongs; i++)
2525 {
2526 mp_sint32 start = tempSubSongPositions[i*2];
2527 mp_sint32 end = tempSubSongPositions[i*2+1];
2528
2529 if (start != -1 && end != -1)
2530 {
2531
2532 for (j = 0; j < numSubSongs; j++)
2533 {
2534 if (j != i)
2535 {
2536 if ((start <= tempSubSongPositions[j*2]) &&
2537 (end >= tempSubSongPositions[j*2+1]))
2538 {
2539 tempSubSongPositions[j*2] = tempSubSongPositions[j*2+1] = -1;
2540 }
2541 else if ((start <= tempSubSongPositions[j*2]) &&
2542 (end >= tempSubSongPositions[j*2]))
2543 {
2544 end = tempSubSongPositions[j*2+1];
2545 tempSubSongPositions[j*2] = tempSubSongPositions[j*2+1] = -1;
2546 }
2547 else if ((start <= tempSubSongPositions[j*2+1]) &&
2548 (end >= tempSubSongPositions[j*2+1]))
2549 {
2550 start = tempSubSongPositions[j*2];
2551 tempSubSongPositions[j*2] = tempSubSongPositions[j*2+1] = -1;
2552 }
2553 }
2554 }
2555 }
2556
2557 tempSubSongPositions[i*2] = start;
2558 tempSubSongPositions[i*2+1] = end;
2559 }
2560
2561 // cut out sets which have been merged/replaced
2562 for (i = 0; i < numSubSongs; i++)
2563 {
2564 if ((tempSubSongPositions[i*2] != -1) && (tempSubSongPositions[i*2+1] != -1))
2565 {
2566 subSongPositions[k*2] = (mp_ubyte)tempSubSongPositions[i*2];
2567 subSongPositions[k*2+1] = (mp_ubyte)tempSubSongPositions[i*2+1];
2568 k++;
2569 }
2570 }
2571
2572 //printf("subsongs initial: %i, after: %i\n", numSubSongs, k);
2573
2574 numSubSongs = k;
2575
2576 //for (mp_sint32 i = 0; i < numSubSongs*2; i++)
2577 // printf("%i: %i\n",i,subSongPositions[i]);
2578
2579 // one subsong is no subsong
2580 if (numSubSongs == 1)
2581 numSubSongs = 0;
2582
2583 }
2584
2585 // get subsong pos
getSubSongPosStart(mp_sint32 i) const2586 mp_sint32 XModule::getSubSongPosStart(mp_sint32 i) const
2587 {
2588 if (i >= 0 && i < numSubSongs)
2589 return subSongPositions[i*2];
2590
2591 return 0;
2592 }
2593
getSubSongPosEnd(mp_sint32 i) const2594 mp_sint32 XModule::getSubSongPosEnd(mp_sint32 i) const
2595 {
2596 if (i >= 0 && i < numSubSongs)
2597 return subSongPositions[i*2+1];
2598
2599 return 0;
2600 }
2601
2602 // MilkyTracker additions
createEmptySong(bool clearPatterns,bool clearInstruments,mp_sint32 numChannels)2603 void XModule::createEmptySong(bool clearPatterns/* = true*/, bool clearInstruments/* = true*/, mp_sint32 numChannels/* = 8*/)
2604 {
2605 moduleLoaded = true;
2606
2607 type = ModuleType_XM;
2608
2609 mp_uint32 i;
2610
2611 if (clearPatterns)
2612 {
2613 #ifdef MILKYTRACKER
2614 for (i = 0; i < 256; i++)
2615 #else
2616 for (i = 0; i < header.patnum; i++)
2617 #endif
2618 {
2619 if (phead[i].patternData)
2620 {
2621 delete[] phead[i].patternData;
2622 phead[i].patternData = NULL;
2623 }
2624
2625 }
2626 memset(header.ord, 0, sizeof(header.ord));
2627 // song length
2628 header.ordnum = 1;
2629 header.patnum = 0;
2630 header.restart = 0;
2631 }
2632
2633 if (clearInstruments)
2634 {
2635 if (venvs)
2636 {
2637 delete[] venvs;
2638 venvs = NULL;
2639 numVEnvsAlloc = numVEnvs = 0;
2640 }
2641 if (penvs)
2642 {
2643 delete[] penvs;
2644 penvs = NULL;
2645 numPEnvsAlloc = numPEnvs = 0;
2646 }
2647 if (fenvs)
2648 {
2649 delete[] fenvs;
2650 fenvs = NULL;
2651 numFEnvsAlloc = numFEnvs = 0;
2652 }
2653 if (vibenvs)
2654 {
2655 delete[] vibenvs;
2656 vibenvs = NULL;
2657 numVibEnvsAlloc = numVibEnvs = 0;
2658 }
2659 if (pitchenvs)
2660 {
2661 delete[] pitchenvs;
2662 pitchenvs = NULL;
2663 numPitchEnvsAlloc = numPitchEnvs = 0;
2664 }
2665
2666 if (message)
2667 {
2668 delete[] message;
2669 message = NULL;
2670 messageBytesAlloc = 0;
2671 }
2672
2673 // release sample-memory
2674 for (i = 0; i < samplePointerIndex; i++)
2675 {
2676 if (samplePool[i])
2677 {
2678 TXMSample::freePaddedMem(samplePool[i]);
2679 samplePool[i] = NULL;
2680 }
2681 }
2682
2683 samplePointerIndex = 0;
2684
2685 if (instr)
2686 memset(instr,0,sizeof(TXMInstrument)*256);
2687
2688 // some default values please
2689 if (smp)
2690 {
2691 memset(smp,0,sizeof(TXMSample)*MP_MAXSAMPLES);
2692
2693 for (i = 0; i < MP_MAXSAMPLES; i++)
2694 {
2695 smp[i].vol = 0xff;
2696 smp[i].pan = 0x80;
2697 smp[i].flags = 3;
2698 smp[i].volfade = 65535;
2699 }
2700 }
2701
2702 header.insnum = 128;
2703 header.smpnum = 128*16;
2704 header.volenvnum = 0;
2705 header.panenvnum = 0;
2706 header.frqenvnum = 0;
2707 header.vibenvnum = 0;
2708 header.pitchenvnum = 0;
2709 }
2710
2711 // clear entire song
2712 if (clearPatterns && clearInstruments)
2713 {
2714 memset(&header,0,sizeof(TXMHeader));
2715
2716 header.insnum = 128;
2717 header.smpnum = 128*16;
2718
2719 header.ordnum = 1;
2720 header.patnum = 0;
2721 header.restart = 0;
2722
2723 header.channum = numChannels;
2724 header.freqtab = 1;
2725 header.mainvol = 255;
2726
2727 // number of patterns
2728
2729 header.speed = 125;
2730 header.tempo = 6;
2731
2732 if (message)
2733 {
2734 delete[] message;
2735 message = NULL;
2736 messageBytesAlloc = 0;
2737 }
2738
2739 setDefaultPanning();
2740 }
2741
2742 header.flags = XModule::MODULE_XMNOTECLIPPING |
2743 XModule::MODULE_XMARPEGGIO |
2744 XModule::MODULE_XMPORTANOTEBUFFER |
2745 XModule::MODULE_XMVOLCOLUMNVIBRATO;
2746
2747 }
2748
removeOrderSkips()2749 void XModule::removeOrderSkips()
2750 {
2751 mp_sint32 newOrderListReloc[256];
2752 mp_ubyte newOrderList[256];
2753
2754 mp_sint32 i,j;
2755
2756 j = 0;
2757 for (i = 0; i < header.ordnum; i++)
2758 {
2759 if (header.ord[i] < header.patnum)
2760 {
2761 newOrderListReloc[i] = j;
2762 newOrderList[j++] = header.ord[i];
2763 }
2764 else
2765 {
2766 newOrderListReloc[i] = -1;
2767 }
2768 }
2769
2770 mp_sint32 newLen = j;
2771
2772 for (i = 0; i < header.ordnum; i++)
2773 {
2774 if (newOrderListReloc[i] == -1)
2775 {
2776 j = i;
2777 mp_sint32 reloc = 0;
2778 while (newOrderListReloc[j] == -1 && j < header.ordnum) j++;
2779 if (j != header.ordnum)
2780 reloc = newOrderListReloc[j];
2781 newOrderListReloc[i] = reloc;
2782 }
2783 }
2784
2785 for (i = 0; i < header.patnum; i++)
2786 {
2787 if (phead[i].patternData)
2788 {
2789 mp_ubyte* data = phead[i].patternData;
2790
2791 mp_sint32 slotSize = phead[i].effnum * 2 + 2;
2792
2793 mp_sint32 patternSize = phead[i].channum * phead[i].rows;
2794 for (j = 0; j < patternSize; j++)
2795 {
2796 mp_ubyte* ptr = data+j*slotSize+2;
2797 for (mp_sint32 e = 0; e < phead[i].effnum; e++)
2798 {
2799 if (ptr[e*2] == 0x0B && ptr[e*2+1] < header.ordnum)
2800 {
2801 ptr[e*2+1] = newOrderListReloc[ptr[e*2+1]];
2802 }
2803 }
2804 }
2805 }
2806 }
2807
2808 header.ordnum = newLen;
2809
2810 memset(header.ord, 0, sizeof(header.ord));
2811
2812 memcpy(header.ord, newOrderList, newLen);
2813
2814 }
2815
removeUnusedPatterns(bool evaluate)2816 mp_sint32 XModule::removeUnusedPatterns(bool evaluate)
2817 {
2818 if (!header.patnum)
2819 return 0;
2820
2821 mp_sint32 i,j;
2822
2823 mp_ubyte* bitMap = new mp_ubyte[header.patnum];
2824
2825 memset(bitMap, 0, sizeof(mp_ubyte)*header.patnum);
2826
2827 mp_sint32 numUsedPatterns = 0;
2828 for (i = 0; i < header.ordnum; i++)
2829 {
2830 j = header.ord[i];
2831
2832 // this must *should* be always the case
2833 if (j < header.patnum && !bitMap[j])
2834 {
2835 bitMap[j] = 1;
2836 numUsedPatterns++;
2837 }
2838 }
2839
2840 if (!numUsedPatterns || numUsedPatterns == header.patnum)
2841 {
2842 delete[] bitMap;
2843 return 0;
2844 }
2845
2846 mp_sint32 result = abs(header.patnum - numUsedPatterns);
2847
2848 if (evaluate)
2849 {
2850 delete[] bitMap;
2851 return result;
2852 }
2853
2854 mp_sint32* patRelocTable = new mp_sint32[header.patnum];
2855
2856 for (i = 0, j = 0; i < header.patnum; i++)
2857 {
2858 if (bitMap[i])
2859 {
2860 patRelocTable[i] = j++;
2861 }
2862 }
2863
2864 TXMPattern* tempPHeads = new TXMPattern[header.patnum];
2865
2866 memcpy(tempPHeads, phead, header.patnum*sizeof(TXMPattern));
2867
2868 memset(phead, 0, header.patnum*sizeof(TXMPattern));
2869
2870 for (i = 0; i < header.patnum; i++)
2871 {
2872 if (bitMap[i])
2873 {
2874 j = patRelocTable[i];
2875 phead[j] = tempPHeads[i];
2876 }
2877 else
2878 {
2879 delete[] tempPHeads[i].patternData;
2880 tempPHeads[i].patternData = NULL;
2881 }
2882 }
2883
2884 for (i = 0; i < header.ordnum; i++)
2885 {
2886 header.ord[i] = (mp_ubyte)patRelocTable[header.ord[i]];
2887 }
2888
2889 delete[] tempPHeads;
2890 delete[] patRelocTable;
2891 delete[] bitMap;
2892
2893 header.patnum = numUsedPatterns;
2894
2895 return result;
2896 }
2897
postLoadAnalyser()2898 void XModule::postLoadAnalyser()
2899 {
2900 mp_sint32 i,r,c;
2901
2902 bool oldPTProbability = false;
2903
2904 for (i = 0; i < header.patnum; i++)
2905 {
2906
2907 if (phead[i].patternData)
2908 {
2909 mp_ubyte* data = phead[i].patternData;
2910
2911 mp_sint32 slotSize = phead[i].effnum * 2 + 2;
2912 mp_sint32 rowSize = slotSize * phead[i].channum;
2913
2914 for (c = 0; c < phead[i].channum; c++)
2915 {
2916 mp_sint32 insCycleCounter = 0;
2917 mp_sint32 lastCycleIns = -1;
2918 mp_sint32 lastIns = -1;
2919 bool hasCycled = false;
2920
2921 for (r = 0; r < phead[i].rows; r++)
2922 {
2923
2924 mp_ubyte* slot = data + r*rowSize + c*slotSize;
2925
2926 if (!oldPTProbability)
2927 {
2928 if (slot[1] && !slot[0] && (mp_sint32)slot[1] != lastCycleIns)
2929 {
2930 insCycleCounter++;
2931 hasCycled = true;
2932 lastCycleIns = slot[1];
2933 }
2934 else if (slot[1] && slot[0] && hasCycled)
2935 {
2936 insCycleCounter = 0;
2937 hasCycled = false;
2938 lastCycleIns = -1;
2939 }
2940
2941 if (insCycleCounter >= 3 && hasCycled)
2942 {
2943 #ifdef VERBOSE
2944 printf("pattern:%i, channel:%i, row:%i\n",i,c,r);
2945 #endif
2946 oldPTProbability = true;
2947 }
2948
2949 // another try:
2950 if (lastIns != -1)
2951 {
2952 if (slot[0] && slot[1] && (slot[1] != lastIns) && (slot[2] == 0x03 || slot[2] == 0x05))
2953 {
2954 #ifdef VERBOSE
2955 printf("pattern:%i, channel:%i, row:%i\n",i,c,r);
2956 #endif
2957 oldPTProbability = true;
2958 }
2959 }
2960 }
2961
2962 if (slot[1])
2963 lastIns = slot[1];
2964
2965 }
2966 }
2967 }
2968 }
2969
2970 if (oldPTProbability)
2971 header.flags |= MODULE_OLDPTINSTRUMENTCHANGE;
2972
2973 #ifdef VERBOSE
2974 printf("%s: %i\n", header.name, oldPTProbability);
2975 #endif
2976 }
2977
convertXMVolumeEffects(mp_ubyte vol,mp_ubyte & effect,mp_ubyte & operand)2978 void XModule::convertXMVolumeEffects(mp_ubyte vol, mp_ubyte& effect, mp_ubyte& operand)
2979 {
2980 effect = 0;
2981 operand = 0;
2982
2983 if (vol>=0x10&&vol<=0x50) {
2984 effect = 0x0C;
2985 operand = XModule::vol64to255(vol-0x10);
2986 }
2987
2988 if (vol>=0x60) {
2989 mp_ubyte eff = vol>>4;
2990 mp_ubyte op = vol&0xf;
2991 /*printf("%x, %x\r\n",eff,op);
2992 getch();*/
2993 if (op)
2994 {
2995 switch (eff) {
2996 case 0x6 : {
2997 effect=0x0A;
2998 operand=op;
2999 }; break;
3000 case 0x7 : {
3001 effect=0x0A;
3002 operand=op<<4;
3003 }; break;
3004 case 0x8 : {
3005 effect=0x3B;
3006 operand=op;
3007 }; break;
3008 case 0x9 : {
3009 effect=0x3A;
3010 operand=op;
3011 }; break;
3012 case 0xA : {
3013 effect=0x4;
3014 operand=op<<4;
3015 }; break;
3016 case 0xB : {
3017 effect=0x4;
3018 operand=op;
3019 }; break;
3020 case 0xC : {
3021 effect=0x8;
3022 operand=(mp_ubyte)XModule::pan15to255(op);
3023 }; break;
3024 case 0xD : {
3025 effect=0x19;
3026 operand=op;
3027 }; break;
3028 case 0xE : {
3029 effect=0x19;
3030 operand=op<<4;
3031 }; break;
3032 case 0xF : {
3033 effect=0x3;
3034 operand=op<<4;
3035 }; break;
3036
3037 }
3038 }
3039 else
3040 {
3041 switch (eff) {
3042 case 0xB : {
3043 effect=0x4;
3044 operand=op;
3045 }; break;
3046 case 0xC : {
3047 effect=0x8;
3048 operand=(mp_ubyte)XModule::pan15to255(op);
3049 }; break;
3050 case 0xF : {
3051 effect=0x3;
3052 operand=op;
3053 }; break;
3054
3055 }
3056 }
3057 }
3058
3059 }
3060
isPTCompatible()3061 XModule::IsPTCompatibleErrorCodes XModule::isPTCompatible()
3062 {
3063 mp_sint32 i;
3064
3065 // step 1: linear frequencies are used
3066 if (header.freqtab & 1)
3067 return IsPTCompatibleErrorCodeLinearFrequencyUsed;
3068
3069 // step 2: find last used instrument, if greater than 31 => too many samples
3070 mp_sint32 insNum = header.insnum;
3071 for (i = header.insnum - 1; i > 0; i--)
3072 {
3073 mp_ubyte buffer[MP_MAXTEXT+1];
3074
3075 convertStr(reinterpret_cast<char*>(buffer), reinterpret_cast<char*>(instr[i].name), MP_MAXTEXT, false);
3076
3077 if (strlen((char*)buffer))
3078 {
3079 insNum = i+1;
3080 break;
3081 }
3082
3083 if (instr[i].samp)
3084 {
3085
3086 mp_sint32 lasts = -1;
3087 #ifdef MILKYTRACKER
3088 for (mp_sint32 j = 0; j < 96; j++)
3089 #else
3090 for (mp_sint32 j = 0; j < 120; j++)
3091 #endif
3092 {
3093 mp_sint32 s = instr[i].snum[j];
3094
3095 if (lasts != -1 && s != lasts)
3096 return IsPTCompatibleErrorCodeIncompatibleInstruments;
3097
3098 lasts = s;
3099
3100 if (s >= 0)
3101 {
3102 convertStr(reinterpret_cast<char*>(buffer), reinterpret_cast<char*>(smp[s].name), MP_MAXTEXT, false);
3103 if (strlen((char*)buffer) || (smp[s].sample && smp[s].samplen))
3104 {
3105 insNum = i+1;
3106 goto insFound;
3107 }
3108 }
3109 }
3110 }
3111 }
3112
3113 insFound:
3114 if (i == 0)
3115 insNum = 1;
3116
3117 if (insNum > 31)
3118 return IsPTCompatibleErrorCodeTooManyInstruments;
3119
3120 // step 3: incompatible samples
3121 for (i = 0; i < MP_MAXSAMPLES; i++)
3122 {
3123 if (smp[i].samplen >= 0xffff || (smp[i].samplen &&
3124 ((smp[i].type & 16) || (smp[i].type & 3) == 2 ||
3125 smp[i].relnote || smp[i].pan != 0x80)))
3126 return IsPTCompatibleErrorCodeIncompatibleSamples;
3127
3128 if (smp[i].venvnum)
3129 {
3130 if (venvs[smp[i].venvnum-1].type & 1)
3131 return IsPTCompatibleErrorCodeIncompatibleInstruments;
3132 }
3133
3134 if (smp[i].penvnum)
3135 {
3136 if (penvs[smp[i].penvnum-1].type & 1)
3137 return IsPTCompatibleErrorCodeIncompatibleInstruments;
3138 }
3139
3140 if (smp[i].vibdepth && smp[i].vibrate)
3141 return IsPTCompatibleErrorCodeIncompatibleInstruments;
3142 }
3143
3144 // step 4: incompatible patterns
3145 for (i = 0; i < header.patnum; i++)
3146 {
3147 mp_sint32 slotSize = phead[i].effnum * 2 + 2;
3148 mp_sint32 rowSizeSrc = slotSize*phead[i].channum;
3149
3150 if (phead[i].rows != 64)
3151 return IsPTCompatibleErrorCodeIncompatiblePatterns;
3152
3153 for (mp_sint32 r = 0; r < phead[i].rows; r++)
3154 for (mp_sint32 c = 0; c < header.channum; c++)
3155 {
3156 if (c < phead[i].channum)
3157 {
3158 mp_ubyte* src = phead[i].patternData + r*rowSizeSrc+c*slotSize;
3159
3160 // check note range
3161 mp_ubyte note = *src;
3162 if (note)
3163 {
3164 note--;
3165 if (!(note >= 36 && note < 36+12*3))
3166 return IsPTCompatibleErrorCodeIncompatiblePatterns;
3167 }
3168
3169 // check volume command
3170 mp_ubyte eff = *(src+2);
3171 if (eff)
3172 return IsPTCompatibleErrorCodeIncompatiblePatterns;
3173
3174 // check for normal commands
3175 eff = *(src+4);
3176 if (eff > 0xF && (eff < 0x30 || eff >=0x3F) && eff != 0x20)
3177 return IsPTCompatibleErrorCodeIncompatiblePatterns;
3178 }
3179 }
3180
3181 }
3182
3183 return IsPTCompatibleErrorCodeNoError;
3184 }
3185