1 /* _______ ____ __ ___ ___
2 * \ _ \ \ / \ / \ \ / / ' ' '
3 * | | \ \ | | || | \/ | . .
4 * | | | | | | || ||\ /| |
5 * | | | | | | || || \/ | | ' ' '
6 * | | | | | | || || | | . .
7 * | |_/ / \ \__// || | |
8 * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
9 * / \
10 * / . \
11 * reads3m.c - Code to read a ScreamTracker 3 / / \ \
12 * module from an open file. | < / \_
13 * | \/ /\ /
14 * By entheh. \_ / > /
15 * | \ / /
16 * | ' /
17 * \__/
18 */
19
20 // IT_STEREO... :o
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "dumb.h"
25 #include "internal/it.h"
26
it_s3m_read_sample_header(IT_SAMPLE * sample,int32 * offset,unsigned char * pack,int cwtv,DUMBFILE * f)27 static int it_s3m_read_sample_header(IT_SAMPLE *sample, int32 *offset, unsigned char *pack, int cwtv, DUMBFILE *f)
28 {
29 unsigned char type;
30 int flags;
31
32 type = dumbfile_getc(f);
33
34 dumbfile_getnc((char *)sample->filename, 12, f);
35 sample->filename[12] = 0;
36
37 if (type > 1) {
38 /** WARNING: no adlib support */
39 dumbfile_skip(f, 3 + 12 + 1 + 1 + 2 + 2 + 2 + 12);
40 dumbfile_getnc((char *)sample->name, 28, f);
41 sample->name[28] = 0;
42 dumbfile_skip(f, 4);
43 sample->flags &= ~IT_SAMPLE_EXISTS;
44 return dumbfile_error(f);
45 }
46
47 *offset = dumbfile_getc(f) << 20;
48 *offset += dumbfile_igetw(f) << 4;
49
50 sample->length = dumbfile_igetl(f);
51 sample->loop_start = dumbfile_igetl(f);
52 sample->loop_end = dumbfile_igetl(f);
53
54 sample->default_volume = dumbfile_getc(f);
55
56 dumbfile_skip(f, 1);
57
58 flags = dumbfile_getc(f);
59
60 if (flags < 0 || (flags != 0 && flags != 4))
61 /* Sample is packed apparently (or error reading from file). We don't
62 * know how to read packed samples.
63 */
64 return -1;
65
66 *pack = flags;
67
68 flags = dumbfile_getc(f);
69
70 sample->C5_speed = dumbfile_igetl(f) << 1;
71
72 /* Skip four unused bytes and three internal variables. */
73 dumbfile_skip(f, 4+2+2+4);
74
75 dumbfile_getnc((char *)sample->name, 28, f);
76 sample->name[28] = 0;
77
78 if (type == 0 || sample->length <= 0) {
79 /* Looks like no-existy. Anyway, there's for sure no 'SCRS' ... */
80 sample->flags &= ~IT_SAMPLE_EXISTS;
81 return dumbfile_error(f);
82 }
83
84 if (dumbfile_mgetl(f) != DUMB_ID('S','C','R','S'))
85 return -1;
86
87 sample->global_volume = 64;
88
89 sample->flags = IT_SAMPLE_EXISTS;
90 if (flags & 1) sample->flags |= IT_SAMPLE_LOOP;
91
92 /* The ST3 TECH.DOC is unclear on this, but IMAGO Orpheus is not. Piece of crap. */
93
94 if (flags & 2) {
95 sample->flags |= IT_SAMPLE_STEREO;
96
97 if ((cwtv & 0xF000) == 0x2000) {
98 sample->length >>= 1;
99 sample->loop_start >>= 1;
100 sample->loop_end >>= 1;
101 }
102 }
103
104 if (flags & 4) {
105 sample->flags |= IT_SAMPLE_16BIT;
106
107 if ((cwtv & 0xF000) == 0x2000) {
108 sample->length >>= 1;
109 sample->loop_start >>= 1;
110 sample->loop_end >>= 1;
111 }
112 }
113
114 sample->default_pan = 0; // 0 = don't use, or 160 = centre?
115
116 if (sample->flags & IT_SAMPLE_LOOP) {
117 if ((unsigned int)sample->loop_end > (unsigned int)sample->length)
118 /*sample->flags &= ~IT_SAMPLE_LOOP;*/
119 sample->loop_end = sample->length;
120 else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end)
121 sample->flags &= ~IT_SAMPLE_LOOP;
122 else
123 /* ScreamTracker seems not to save what comes after the loop end
124 * point, but rather to assume it is a duplicate of what comes at
125 * the loop start point. I am not completely sure of this though.
126 * It is easy to evade; simply truncate the sample.
127 */
128 sample->length = sample->loop_end;
129 }
130
131
132 //Do we need to set all these?
133 sample->vibrato_speed = 0;
134 sample->vibrato_depth = 0;
135 sample->vibrato_rate = 0;
136 sample->vibrato_waveform = IT_VIBRATO_SINE;
137 sample->finetune = 0;
138 sample->max_resampling_quality = -1;
139
140 return dumbfile_error(f);
141 }
142
143
144
it_s3m_read_sample_data(IT_SAMPLE * sample,int ffi,unsigned char pack,DUMBFILE * f)145 static int it_s3m_read_sample_data(IT_SAMPLE *sample, int ffi, unsigned char pack, DUMBFILE *f)
146 {
147 int32 n;
148
149 int32 datasize = sample->length;
150 if (sample->flags & IT_SAMPLE_STEREO) datasize <<= 1;
151
152 sample->data = malloc(datasize * (sample->flags & IT_SAMPLE_16BIT ? 2 : 1));
153 if (!sample->data)
154 return -1;
155
156 if (pack == 4) {
157 if (_dumb_it_read_sample_data_adpcm4(sample, f) < 0)
158 return -1;
159 }
160 else if (sample->flags & IT_SAMPLE_STEREO) {
161 if (sample->flags & IT_SAMPLE_16BIT) {
162 for (n = 0; n < datasize; n += 2)
163 ((short *)sample->data)[n] = dumbfile_igetw(f);
164 for (n = 1; n < datasize; n += 2)
165 ((short *)sample->data)[n] = dumbfile_igetw(f);
166 } else {
167 for (n = 0; n < datasize; n += 2)
168 ((signed char *)sample->data)[n] = dumbfile_getc(f);
169 for (n = 1; n < datasize; n += 2)
170 ((signed char *)sample->data)[n] = dumbfile_getc(f);
171 }
172 } else if (sample->flags & IT_SAMPLE_16BIT)
173 for (n = 0; n < sample->length; n++)
174 ((short *)sample->data)[n] = dumbfile_igetw(f);
175 else
176 for (n = 0; n < sample->length; n++)
177 ((signed char *)sample->data)[n] = dumbfile_getc(f);
178
179 if (dumbfile_error(f))
180 return -1;
181
182 if (ffi != 1) {
183 /* Convert to signed. */
184 if (sample->flags & IT_SAMPLE_16BIT)
185 for (n = 0; n < datasize; n++)
186 ((short *)sample->data)[n] ^= 0x8000;
187 else
188 for (n = 0; n < datasize; n++)
189 ((signed char *)sample->data)[n] ^= 0x80;
190 }
191
192 return 0;
193 }
194
195
196
it_s3m_read_pattern(IT_PATTERN * pattern,DUMBFILE * f,unsigned char * buffer)197 static int it_s3m_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer)
198 {
199 int length;
200 int buflen = 0;
201 int bufpos = 0;
202
203 IT_ENTRY *entry;
204
205 unsigned char channel;
206
207 /* Haha, this is hilarious!
208 *
209 * Well, after some experimentation, it seems that different S3M writers
210 * define the format in different ways. The S3M docs say that the first
211 * two bytes hold the "length of [the] packed pattern", and the packed
212 * pattern data follow. Judging by the contents of ARMANI.S3M, packaged
213 * with ScreamTracker itself, the measure of length _includes_ the two
214 * bytes used to store the length; in other words, we should read
215 * (length - 2) more bytes. However, aryx.s3m, packaged with ModPlug
216 * Tracker, excludes these two bytes, so (length) more bytes must be
217 * read.
218 *
219 * Call me crazy, but I just find it insanely funny that the format was
220 * misunderstood in this way :D
221 *
222 * Now we can't just risk reading two extra bytes, because then we
223 * overshoot, and DUMBFILEs don't support backward seeking (for a good
224 * reason). Luckily, there is a way. We can read the data little by
225 * little, and stop when we have 64 rows in memory. Provided we protect
226 * against buffer overflow, this method should work with all sensibly
227 * written S3M files. If you find one for which it does not work, please
228 * let me know at entheh@users.sf.net so I can look at it.
229 *
230 * "for a good reason" ? What's this nonsense? -kode54
231 *
232 */
233
234 length = dumbfile_igetw(f);
235
236 if (dumbfile_error(f) || !length)
237 return -1;
238
239 pattern->n_rows = 0;
240 pattern->n_entries = 0;
241
242 /* Read in the pattern data, little by little, and work out how many
243 * entries we need room for. Sorry, but this is just so funny...
244 */
245 for (;;) {
246 unsigned char b = buffer[buflen++] = dumbfile_getc(f);
247
248 #if 1
249 static const unsigned char used[8] = {0, 2, 1, 3, 2, 4, 3, 5};
250 channel = b & 31;
251 b >>= 5;
252 pattern->n_entries++;
253 if (b) {
254 if (buflen + used[b] >= 65536) return -1;
255 if (buflen + used[b] <= length)
256 dumbfile_getnc((char *)buffer + buflen, used[b], f);
257 else
258 memset(buffer + buflen, 0, used[b]);
259 buflen += used[b];
260 } else {
261 /* End of row */
262 if (++pattern->n_rows == 64) break;
263 if (buflen >= 65536) return -1;
264 }
265 #else
266 if (b == 0) {
267 /* End of row */
268 pattern->n_entries++;
269 if (++pattern->n_rows == 64) break;
270 if (buflen >= 65536) return -1;
271 } else {
272 static const unsigned char used[8] = {0, 2, 1, 3, 2, 4, 3, 5};
273 channel = b & 31;
274 b >>= 5;
275 if (b) {
276 pattern->n_entries++;
277 if (buflen + used[b] >= 65536) return -1;
278 dumbfile_getnc(buffer + buflen, used[b], f);
279 buflen += used[b];
280 }
281 }
282 #endif
283
284 /* We have ensured that buflen < 65536 at this point, so it is safe
285 * to iterate and read at least one more byte without checking.
286 * However, now would be a good time to check for errors reading from
287 * the file.
288 */
289
290 if (dumbfile_error(f))
291 return -1;
292
293 /* Great. We ran out of data, but there should be data for more rows.
294 * Fill the rest with null data...
295 */
296 if (buflen >= length && pattern->n_rows < 64)
297 {
298 while (pattern->n_rows < 64)
299 {
300 if (buflen >= 65536) return -1;
301 buffer[buflen++] = 0;
302 pattern->n_entries++;
303 pattern->n_rows++;
304 }
305 break;
306 }
307 }
308
309 pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
310
311 if (!pattern->entry)
312 return -1;
313
314 entry = pattern->entry;
315
316 while (bufpos < buflen) {
317 unsigned char b = buffer[bufpos++];
318
319 #if 1
320 if (!(b & ~31))
321 #else
322 if (b == 0)
323 #endif
324 {
325 /* End of row */
326 IT_SET_END_ROW(entry);
327 entry++;
328 continue;
329 }
330
331 channel = b & 31;
332
333 if (b & 224) {
334 entry->mask = 0;
335 entry->channel = channel;
336
337 if (b & 32) {
338 unsigned char n = buffer[bufpos++];
339 if (n != 255) {
340 if (n == 254)
341 entry->note = IT_NOTE_CUT;
342 else
343 entry->note = (n >> 4) * 12 + (n & 15);
344 entry->mask |= IT_ENTRY_NOTE;
345 }
346
347 entry->instrument = buffer[bufpos++];
348 if (entry->instrument)
349 entry->mask |= IT_ENTRY_INSTRUMENT;
350 }
351
352 if (b & 64) {
353 entry->volpan = buffer[bufpos++];
354 if (entry->volpan != 255)
355 entry->mask |= IT_ENTRY_VOLPAN;
356 }
357
358 if (b & 128) {
359 entry->effect = buffer[bufpos++];
360 entry->effectvalue = buffer[bufpos++];
361 // XXX woot
362 if (entry->effect && entry->effect < IT_MIDI_MACRO /*!= 255*/) {
363 entry->mask |= IT_ENTRY_EFFECT;
364 switch (entry->effect) {
365 case IT_BREAK_TO_ROW:
366 entry->effectvalue -= (entry->effectvalue >> 4) * 6;
367 break;
368
369 case IT_SET_CHANNEL_VOLUME:
370 case IT_CHANNEL_VOLUME_SLIDE:
371 case IT_PANNING_SLIDE:
372 case IT_GLOBAL_VOLUME_SLIDE:
373 case IT_PANBRELLO:
374 case IT_MIDI_MACRO:
375 entry->mask &= ~IT_ENTRY_EFFECT;
376 break;
377
378 case IT_S:
379 switch (entry->effectvalue >> 4) {
380 case IT_S_SET_PANBRELLO_WAVEFORM:
381 case IT_S_FINE_PATTERN_DELAY:
382 case IT_S7:
383 case IT_S_SET_SURROUND_SOUND:
384 case IT_S_SET_MIDI_MACRO:
385 entry->mask &= ~IT_ENTRY_EFFECT;
386 break;
387 }
388 break;
389 }
390 }
391 /** WARNING: ARGH! CONVERT TEH EFFECTS!@~ */
392 }
393
394 entry++;
395 }
396 }
397
398 ASSERT(entry == pattern->entry + pattern->n_entries);
399
400 return 0;
401 }
402
403
404
405 /** WARNING: this is duplicated in itread.c - also bad practice to use the same struct name unless they are unified in a header */
406 /* Currently we assume the sample data are stored after the sample headers in
407 * module files. This assumption may be unjustified; let me know if you have
408 * trouble.
409 */
410
411 #define S3M_COMPONENT_INSTRUMENT 1
412 #define S3M_COMPONENT_PATTERN 2
413 #define S3M_COMPONENT_SAMPLE 3
414
415 typedef struct S3M_COMPONENT
416 {
417 unsigned char type;
418 unsigned char n;
419 int32 offset;
420 short sampfirst; /* component[sampfirst] = first sample data after this */
421 short sampnext; /* sampnext is used to create linked lists of sample data */
422 }
423 S3M_COMPONENT;
424
425
426
s3m_component_compare(const void * e1,const void * e2)427 static int CDECL s3m_component_compare(const void *e1, const void *e2)
428 {
429 return ((const S3M_COMPONENT *)e1)->offset -
430 ((const S3M_COMPONENT *)e2)->offset;
431 }
432
433
434
it_s3m_load_sigdata(DUMBFILE * f,int * cwtv)435 static DUMB_IT_SIGDATA *it_s3m_load_sigdata(DUMBFILE *f, int * cwtv)
436 {
437 DUMB_IT_SIGDATA *sigdata;
438
439 int flags, ffi;
440 int default_pan_present;
441
442 int master_volume;
443
444 unsigned char sample_pack[256];
445
446 S3M_COMPONENT *component;
447 int n_components = 0;
448
449 int n;
450
451 unsigned char *buffer;
452
453 sigdata = malloc(sizeof(*sigdata));
454 if (!sigdata) return NULL;
455
456 dumbfile_getnc((char *)sigdata->name, 28, f);
457 sigdata->name[28] = 0;
458
459 n = dumbfile_getc(f);
460
461 if (n != 0x1A && n != 0) {
462 free(sigdata);
463 return NULL;
464 }
465
466 if (dumbfile_getc(f) != 16) {
467 free(sigdata);
468 return NULL;
469 }
470
471 dumbfile_skip(f, 2);
472
473 sigdata->song_message = NULL;
474 sigdata->order = NULL;
475 sigdata->instrument = NULL;
476 sigdata->sample = NULL;
477 sigdata->pattern = NULL;
478 sigdata->midi = NULL;
479 sigdata->checkpoint = NULL;
480
481 sigdata->n_orders = dumbfile_igetw(f);
482 sigdata->n_instruments = 0;
483 sigdata->n_samples = dumbfile_igetw(f);
484 sigdata->n_patterns = dumbfile_igetw(f);
485
486 if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_samples > 256 || sigdata->n_patterns > 256) {
487 _dumb_it_unload_sigdata(sigdata);
488 return NULL;
489 }
490
491 sigdata->order = malloc(sigdata->n_orders);
492 if (!sigdata->order) {
493 _dumb_it_unload_sigdata(sigdata);
494 return NULL;
495 }
496
497 if (sigdata->n_samples) {
498 sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
499 if (!sigdata->sample) {
500 _dumb_it_unload_sigdata(sigdata);
501 return NULL;
502 }
503 for (n = 0; n < sigdata->n_samples; n++)
504 sigdata->sample[n].data = NULL;
505 }
506
507 if (sigdata->n_patterns) {
508 sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
509 if (!sigdata->pattern) {
510 _dumb_it_unload_sigdata(sigdata);
511 return NULL;
512 }
513 for (n = 0; n < sigdata->n_patterns; n++)
514 sigdata->pattern[n].entry = NULL;
515 }
516
517 flags = dumbfile_igetw(f);
518
519 *cwtv = dumbfile_igetw(f);
520
521 if (*cwtv == 0x1300) {
522 /** WARNING: volume slides on every frame */
523 }
524
525 ffi = dumbfile_igetw(f);
526
527 /** WARNING: which ones? */
528 sigdata->flags = IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M;
529
530 if (dumbfile_mgetl(f) != DUMB_ID('S','C','R','M')) {
531 _dumb_it_unload_sigdata(sigdata);
532 return NULL;
533 }
534
535 sigdata->global_volume = dumbfile_getc(f);
536 if ( !sigdata->global_volume || sigdata->global_volume > 64 ) sigdata->global_volume = 64;
537 sigdata->speed = dumbfile_getc(f);
538 if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo?
539 sigdata->tempo = dumbfile_getc(f);
540 master_volume = dumbfile_getc(f); // 7 bits; +128 for stereo
541 sigdata->mixing_volume = master_volume & 127;
542
543 if (master_volume & 128) sigdata->flags |= IT_STEREO;
544
545 /* Skip GUS Ultra Click Removal byte. */
546 dumbfile_getc(f);
547
548 default_pan_present = dumbfile_getc(f);
549
550 dumbfile_skip(f, 8);
551
552 /* Skip Special Custom Data Pointer. */
553 /** WARNING: investigate this? */
554 dumbfile_igetw(f);
555
556 sigdata->n_pchannels = 0;
557 /* Channel settings for 32 channels, 255=unused, +128=disabled */
558 {
559 int i;
560 int sep = (7 * dumb_it_default_panning_separation + 50) / 100;
561 for (i = 0; i < 32; i++) {
562 int c = dumbfile_getc(f);
563 if (!(c & (128 | 16))) { /* +128=disabled, +16=Adlib */
564 if (sigdata->n_pchannels < i + 1) sigdata->n_pchannels = i + 1;
565 sigdata->channel_volume[i] = 64;
566 sigdata->channel_pan[i] = c & 8 ? 7 + sep : 7 - sep;
567 /** WARNING: ah, but it should be 7 for mono... */
568 } else {
569 /** WARNING: this could be improved if we support channel muting... */
570 sigdata->channel_volume[i] = 0;
571 sigdata->channel_pan[i] = 7;
572 }
573 }
574 }
575
576 /* Orders, byte each, length = sigdata->n_orders (should be even) */
577 dumbfile_getnc((char *)sigdata->order, sigdata->n_orders, f);
578 sigdata->restart_position = 0;
579
580 component = malloc(768*sizeof(*component));
581 if (!component) {
582 _dumb_it_unload_sigdata(sigdata);
583 return NULL;
584 }
585
586 for (n = 0; n < sigdata->n_samples; n++) {
587 component[n_components].type = S3M_COMPONENT_SAMPLE;
588 component[n_components].n = n;
589 component[n_components].offset = dumbfile_igetw(f) << 4;
590 component[n_components].sampfirst = -1;
591 n_components++;
592 }
593
594 for (n = 0; n < sigdata->n_patterns; n++) {
595 int32 offset = dumbfile_igetw(f) << 4;
596 if (offset) {
597 component[n_components].type = S3M_COMPONENT_PATTERN;
598 component[n_components].n = n;
599 component[n_components].offset = offset;
600 component[n_components].sampfirst = -1;
601 n_components++;
602 } else {
603 /** WARNING: Empty 64-row pattern ... ? (this does happen!) */
604 sigdata->pattern[n].n_rows = 64;
605 sigdata->pattern[n].n_entries = 0;
606 }
607 }
608
609 qsort(component, n_components, sizeof(S3M_COMPONENT), &s3m_component_compare);
610
611 /* I found a really dumb S3M file that claimed to contain default pan
612 * data but didn't contain any. Programs would load it by reading part of
613 * the first instrument header, assuming the data to be default pan
614 * positions, and then rereading the instrument module. We cannot do this
615 * without obfuscating the file input model, so we insert an extra check
616 * here that we won't overrun the start of the first component.
617 */
618 if (default_pan_present == 252 && component[0].offset >= dumbfile_pos(f) + 32) {
619 /* Channel default pan positions */
620 int i;
621 for (i = 0; i < 32; i++) {
622 int c = dumbfile_getc(f);
623 if (c & 32)
624 sigdata->channel_pan[i] = c & 15;
625 }
626 }
627
628 {
629 int i;
630 for (i = 0; i < 32; i++) {
631 sigdata->channel_pan[i] -= (sigdata->channel_pan[i] & 8) >> 3;
632 sigdata->channel_pan[i] = ((int)sigdata->channel_pan[i] << 5) / 7;
633 }
634 }
635
636 sigdata->pan_separation = 128;
637
638 if (dumbfile_error(f)) {
639 free(component);
640 _dumb_it_unload_sigdata(sigdata);
641 return NULL;
642 }
643
644 buffer = malloc(65536);
645 if (!buffer) {
646 free(component);
647 _dumb_it_unload_sigdata(sigdata);
648 return NULL;
649 }
650
651 for (n = 0; n < n_components; n++) {
652 int32 offset;
653 int m;
654
655 offset = 0;
656 if (dumbfile_seek(f, component[n].offset, DFS_SEEK_SET)) {
657 free(buffer);
658 free(component);
659 _dumb_it_unload_sigdata(sigdata);
660 return NULL;
661 }
662
663 switch (component[n].type) {
664
665 case S3M_COMPONENT_PATTERN:
666 if (it_s3m_read_pattern(&sigdata->pattern[component[n].n], f, buffer)) {
667 free(buffer);
668 free(component);
669 _dumb_it_unload_sigdata(sigdata);
670 return NULL;
671 }
672 break;
673
674 case S3M_COMPONENT_SAMPLE:
675 if (it_s3m_read_sample_header(&sigdata->sample[component[n].n], &offset, &sample_pack[component[n].n], *cwtv, f)) {
676 free(buffer);
677 free(component);
678 _dumb_it_unload_sigdata(sigdata);
679 return NULL;
680 }
681
682 if (sigdata->sample[component[n].n].flags & IT_SAMPLE_EXISTS) {
683 short *sample;
684
685 for (m = n + 1; m < n_components; m++)
686 if (component[m].offset > offset)
687 break;
688 m--;
689
690 sample = &component[m].sampfirst;
691
692 while (*sample >= 0 && component[*sample].offset <= offset)
693 sample = &component[*sample].sampnext;
694
695 component[n].sampnext = *sample;
696 *sample = n;
697
698 component[n].offset = offset;
699 }
700 }
701
702 m = component[n].sampfirst;
703
704 while (m >= 0) {
705 // XXX
706 if (dumbfile_seek(f, component[m].offset, DFS_SEEK_SET)) {
707 free(buffer);
708 free(component);
709 _dumb_it_unload_sigdata(sigdata);
710 return NULL;
711 }
712
713 if (it_s3m_read_sample_data(&sigdata->sample[component[m].n], ffi, sample_pack[component[m].n], f)) {
714 free(buffer);
715 free(component);
716 _dumb_it_unload_sigdata(sigdata);
717 return NULL;
718 }
719
720 m = component[m].sampnext;
721 }
722 }
723
724 free(buffer);
725 free(component);
726
727 _dumb_it_fix_invalid_orders(sigdata);
728
729 return sigdata;
730 }
731
hexdigit(int in)732 static char hexdigit(int in)
733 {
734 if (in < 10) return in + '0';
735 else return in + 'A' - 10;
736 }
737
dumb_read_s3m_quick(DUMBFILE * f)738 DUH *DUMBEXPORT dumb_read_s3m_quick(DUMBFILE *f)
739 {
740 sigdata_t *sigdata;
741 int cwtv;
742
743 DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
744
745 sigdata = it_s3m_load_sigdata(f, &cwtv);
746
747 if (!sigdata)
748 return NULL;
749
750 {
751 char version[8];
752 const char *tag[3][2];
753 tag[0][0] = "TITLE";
754 tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
755 tag[1][0] = "FORMAT";
756 tag[1][1] = "S3M";
757 tag[2][0] = "TRACKERVERSION";
758 version[0] = hexdigit((cwtv >> 8) & 15);
759 version[1] = '.';
760 version[2] = hexdigit((cwtv >> 4) & 15);
761 version[3] = hexdigit(cwtv & 15);
762 version[4] = 0;
763 tag[2][1] = (const char *) &version;
764 return make_duh(-1, 3, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
765 }
766 }
767