ref: 4e1db2adb05e53c50fe38102676889c22a4f2e66
parent: 3527875388468d5343c7958d4781f250d4c333d6
author: Chris Moeller <[email protected]>
date: Mon Jan 11 03:59:57 EST 2010
{5/26/2006 10:58:10 PM~5/26/2006 10:58:12 PM}2006-05-22 21:44 UTC - kode54 - XM reader now supports up to 256 instruments, even though FT2 only supports up to 128. ModPlug Tracker again. 2006-05-22 18:43 UTC - kode54 - S3M reader was using the incorrect index into component for sample packing when reading sample data. Was using n, should have been m. 2006-05-22 17:26 UTC - kode54 - IT renderer may have a bug with its time_lost / loop handling. Switchover from sustain loop would compound time_lost onto itself for every note-off. I'm not sure if this crap is even doing the right thing, especially in the case of a sample with a sustain loop, but no main loop. Working around for now by zeroing time_lost after note-off. (hall8.it) - S3M reader ignores effects outside of 1-25 range so nothing can hit internal effects which are XM or PTM only. (N4.S3M) - IT reader now supports ModPlug Tracker extensions for up to 4000 samples and mapping them with instruments. (hallowe.it.it) - XM reader now supports instrument vibrato 4, random. Yet another ModPlug extension. (hcw-st.xm) 2006-05-21 02:11 UTC - kode54 - S3M reader correctly reads all 24 bits of the sample memory segment offset, fixing at least one file with >1MB of sample data (d-t-x_x.s3m) - XM reader stops reading instruments when it has at least one valid instrument and encounters an error, fixing at least one file with too high instrument count in the header (drx-chri.xm) - IT reader ignores instrument header signatures, since there seem to be files with bad signatures on unused/filler instruments (dsouls.it) - MOD reader can now be restricted to handling 31 sample files with legal/known signatures only, so frontend can fall back on restricted MOD loading for files with incorrect extensions (dreamer_0g.s3m) 2006-05-20 xx:xx UTC - kode54 - Modified silence skipping to hack around some "S L O W" effects crap and a misused break to row effect git-tfs-id: [http://localhost:8080/tfs/DefaultCollection/]$/foobar2000/files/plugins.root;C84
--- a/dumb/include/dumb.h
+++ b/dumb/include/dumb.h
@@ -350,7 +350,7 @@
DUH *dumb_load_it(const char *filename);
DUH *dumb_load_xm(const char *filename);
DUH *dumb_load_s3m(const char *filename);
-DUH *dumb_load_mod(const char *filename);
+DUH *dumb_load_mod(const char *filename, int restrict);
DUH *dumb_load_ptm(const char *filename);
DUH *dumb_load_669(const char *filename);
DUH *dumb_load_psm(const char *filename, int subsong);
@@ -361,7 +361,7 @@
DUH *dumb_read_it(DUMBFILE *f);
DUH *dumb_read_xm(DUMBFILE *f);
DUH *dumb_read_s3m(DUMBFILE *f);
-DUH *dumb_read_mod(DUMBFILE *f);
+DUH *dumb_read_mod(DUMBFILE *f, int restrict);
DUH *dumb_read_ptm(DUMBFILE *f);
DUH *dumb_read_669(DUMBFILE *f);
DUH *dumb_read_psm(DUMBFILE *f, int subsong);
--- a/dumb/include/internal/it.h
+++ b/dumb/include/internal/it.h
@@ -61,6 +61,8 @@
#define IT_INSTRUMENT_SIGNATURE DUMB_ID('I', 'M', 'P', 'I')
#define IT_SAMPLE_SIGNATURE DUMB_ID('I', 'M', 'P', 'S')
+// olivier sux
+#define IT_MPTX_SIGNATURE DUMB_ID('X', 'T', 'P', 'M')
/* 1 minute per 4 rows, each row 6 ticks; this is divided by the tempo to get
--- a/dumb/src/it/itread.c
+++ b/dumb/src/it/itread.c
@@ -339,8 +339,10 @@
{
int n;
- if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
- return -1;
+ /*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
+ return -1;*/
+ // XXX
+ dumbfile_skip(f, 4);
dumbfile_getnc(instrument->filename, 13, f);
instrument->filename[13] = 0;
@@ -445,13 +447,18 @@
-static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f)
+static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f, int maxlen)
{
- int n;
+ int n, len;
- if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
- return -1;
+ /*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
+ return -1;*/
+ // XXX
+ if (maxlen) len = dumbfile_pos(f);
+
+ dumbfile_skip(f, 4);
+
dumbfile_getnc(instrument->filename, 13, f);
instrument->filename[13] = 0;
@@ -492,6 +499,20 @@
if (it_read_envelope(&instrument->pan_envelope, f)) return -1;
if (it_read_envelope(&instrument->pitch_envelope, f)) return -1;
+ if (maxlen) {
+ len = dumbfile_pos(f) - len;
+ if ( maxlen - len < 124 ) return 0;
+ }
+
+ if ( dumbfile_mgetl(f) == IT_MPTX_SIGNATURE ) {
+ for ( n = 0; n < 120; n++ ) {
+ instrument->map_sample[ n ] += dumbfile_getc( f ) << 8;
+ }
+
+ if (dumbfile_error(f))
+ return -1;
+ }
+
return 0;
}
@@ -876,7 +897,7 @@
typedef struct IT_COMPONENT
{
unsigned char type;
- unsigned char n;
+ unsigned short n;
long offset;
short sampfirst; /* component[sampfirst] = first sample data after this */
short sampnext; /* sampnext is used to create linked lists of sample data */
@@ -904,7 +925,7 @@
IT_COMPONENT *component;
int n_components = 0;
- unsigned char sample_convert[256];
+ unsigned char sample_convert[4096];
int n;
@@ -962,7 +983,8 @@
dumbfile_getnc(sigdata->channel_pan, DUMB_IT_N_CHANNELS, f);
dumbfile_getnc(sigdata->channel_volume, DUMB_IT_N_CHANNELS, f);
- if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 256 || sigdata->n_patterns > 256) {
+ // XXX sample count
+ if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 4000 || sigdata->n_patterns > 256) {
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
@@ -1188,7 +1210,7 @@
if (cmwt < 0x200)
m = it_read_old_instrument(&sigdata->instrument[component[n].n], f);
else
- m = it_read_instrument(&sigdata->instrument[component[n].n], f);
+ m = it_read_instrument(&sigdata->instrument[component[n].n], f, (n + 1 < n_components) ? (component[n+1].offset - component[n].offset) : 0);
if (m) {
free(buffer);
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -1322,6 +1322,8 @@
}
playing->resampler[1].pos = playing->resampler[0].pos += playing->time_lost;
+ // XXX what
+ playing->time_lost = 0;
}
}
@@ -4981,6 +4983,10 @@
case IT_S:
switch (entry->effectvalue >> 4) {
+ case 0: // meh bastard
+ if ( entry->effectvalue != 0 ) return 0;
+ break;
+
case IT_S_FINE_PATTERN_DELAY:
case IT_S_PATTERN_LOOP:
case IT_S_PATTERN_DELAY:
@@ -4997,6 +5003,18 @@
}
break;
+ // clever idiot with his S L O W crap; do nothing
+ case IT_VOLSLIDE_TONEPORTA:
+ case IT_SET_SAMPLE_OFFSET:
+ case IT_GLOBAL_VOLUME_SLIDE:
+ if ( entry->effectvalue != 0 ) return 0;
+ break;
+
+ // genius also uses this instead of jump to order by mistake, meh, and it's bloody BCD
+ case IT_BREAK_TO_ROW:
+ if ( ( ( entry->effectvalue >> 4 ) * 10 + ( entry->effectvalue & 15 ) ) != order ) return 0;
+ break;
+
default:
return 0;
}
@@ -5075,7 +5093,7 @@
for (n = 0; n < sigdata->n_orders; n++) {
if ((sigdata->order[n] >= sigdata->n_patterns) ||
- (is_pattern_silent(&sigdata->pattern[sigdata->order[n]], n)))
+ (is_pattern_silent(&sigdata->pattern[sigdata->order[n]], n) > 1))
bit_array_set(ba_played, n * 256);
}
--- a/dumb/src/it/loadmod.c
+++ b/dumb/src/it/loadmod.c
@@ -26,7 +26,7 @@
* to the DUH struct. When you have finished with it, you must pass the
* pointer to unload_duh() so that the memory can be freed.
*/
-DUH *dumb_load_mod(const char *filename)
+DUH *dumb_load_mod(const char *filename, int restrict)
{
DUH *duh;
DUMBFILE *f = dumbfile_open(filename);
@@ -34,7 +34,7 @@
if (!f)
return NULL;
- duh = dumb_read_mod(f);
+ duh = dumb_read_mod(f, restrict);
dumbfile_close(f);
--- a/dumb/src/it/readam.c
+++ b/dumb/src/it/readam.c
@@ -93,7 +93,7 @@
return 0;
}
- if ( flags & ~( 0x80 | 0x20 | 0x10 | 0x08 | 0x04 ) )
+ if ( flags & ~( 0x8000 | 0x80 | 0x20 | 0x10 | 0x08 | 0x04 ) )
return -1;
length_bytes = length << ( ( flags & 0x04 ) >> 2 );
@@ -298,11 +298,11 @@
case DUMB_ID( 'I', 'N', 'S', 'T' ):
{
- if ( c->size < 0x121 ) goto error;
+ if ( c->size < 0xE1 ) goto error;
ptr = ( unsigned char * ) c->data;
if ( ptr[ 1 ] >= sigdata->n_samples ) sigdata->n_samples = ptr[ 1 ] + 1;
- if ( ptr[ 0xE1 ] == 'S' && ptr[ 0xE2 ] == 'A' &&
- ptr[ 0xE3 ] == 'M' && ptr[ 0xE4 ] == 'P' )
+ if ( c->size >= 0x121 && ( ptr[ 0xE1 ] == 'S' && ptr[ 0xE2 ] == 'A' &&
+ ptr[ 0xE3 ] == 'M' && ptr[ 0xE4 ] == 'P' ) )
{
unsigned size = ptr[ 0xE5 ] | ( ptr[ 0xE6 ] << 8 ) | ( ptr[ 0xE7 ] << 16 ) | ( ptr[ 0xE8 ] << 24 );
if ( size + 0xE1 + 8 > c->size ) goto error;
@@ -409,11 +409,10 @@
case DUMB_ID( 'I', 'N', 'S', 'T' ):
{
IT_SAMPLE * sample;
- if ( c->size < 0x121 ) goto error;
ptr = ( unsigned char * ) c->data;
sample = sigdata->sample + ptr[ 1 ];
- if ( ptr[ 0xE1 ] == 'S' && ptr[ 0xE2 ] == 'A' &&
- ptr[ 0xE3 ] == 'M' && ptr[ 0xE4 ] == 'P' )
+ if ( c->size >= 0x121 && ( ptr[ 0xE1 ] == 'S' && ptr[ 0xE2 ] == 'A' &&
+ ptr[ 0xE3 ] == 'M' && ptr[ 0xE4 ] == 'P' ) )
{
unsigned size = ptr[ 0xE5 ] | ( ptr[ 0xE6 ] << 8 ) | ( ptr[ 0xE7 ] << 16 ) | ( ptr[ 0xE8 ] << 24 );
if ( it_riff_am_process_sample( sample, ptr + 0xE1 + 8, size, 0 ) ) goto error_usd;
--- a/dumb/src/it/readmod.c
+++ b/dumb/src/it/readmod.c
@@ -437,7 +437,7 @@
}
-static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f)
+static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
{
DUMB_IT_SIGDATA *sigdata;
int n_channels;
@@ -545,6 +545,14 @@
}
}
+ // moo
+ if ( restrict && sigdata->n_samples == 15 )
+ {
+ free(sigdata);
+ dumbfile_close(f);
+ return NULL;
+ }
+
sigdata->n_pchannels = n_channels ? n_channels : 8; /* special case for 0, see above */
sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
@@ -725,7 +733,7 @@
-DUH *dumb_read_mod(DUMBFILE *f)
+DUH *dumb_read_mod(DUMBFILE *f, int restrict)
{
sigdata_t *sigdata;
long length;
@@ -732,7 +740,7 @@
DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
- sigdata = it_mod_load_sigdata(f);
+ sigdata = it_mod_load_sigdata(f, restrict);
if (!sigdata)
return NULL;
--- a/dumb/src/it/readptm.c
+++ b/dumb/src/it/readptm.c
@@ -313,24 +313,24 @@
* trouble.
*/
-#define IT_COMPONENT_INSTRUMENT 1
-#define IT_COMPONENT_PATTERN 2
-#define IT_COMPONENT_SAMPLE 3
+#define PTM_COMPONENT_INSTRUMENT 1
+#define PTM_COMPONENT_PATTERN 2
+#define PTM_COMPONENT_SAMPLE 3
-typedef struct IT_COMPONENT
+typedef struct PTM_COMPONENT
{
unsigned char type;
unsigned char n;
long offset;
}
-IT_COMPONENT;
+PTM_COMPONENT;
-static int it_component_compare(const void *e1, const void *e2)
+static int ptm_component_compare(const void *e1, const void *e2)
{
- return ((const IT_COMPONENT *)e1)->offset -
- ((const IT_COMPONENT *)e2)->offset;
+ return ((const PTM_COMPONENT *)e1)->offset -
+ ((const PTM_COMPONENT *)e2)->offset;
}
@@ -339,7 +339,7 @@
{
DUMB_IT_SIGDATA *sigdata;
- IT_COMPONENT *component;
+ PTM_COMPONENT *component;
int n_components = 0;
int n;
@@ -460,7 +460,7 @@
}
for (n = 0; n < sigdata->n_patterns; n++) {
- component[n_components].type = IT_COMPONENT_PATTERN;
+ component[n_components].type = PTM_COMPONENT_PATTERN;
component[n_components].n = n;
component[n_components].offset = dumbfile_igetw(f) << 4;
n_components++;
@@ -477,12 +477,12 @@
return NULL;
}
if (!(sigdata->sample[n].flags & IT_SAMPLE_EXISTS)) continue;
- component[n_components].type = IT_COMPONENT_SAMPLE;
+ component[n_components].type = PTM_COMPONENT_SAMPLE;
component[n_components].n = n;
n_components++;
}
- qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
+ qsort(component, n_components, sizeof(PTM_COMPONENT), &ptm_component_compare);
{
int i;
@@ -518,7 +518,7 @@
switch (component[n].type) {
- case IT_COMPONENT_PATTERN:
+ case PTM_COMPONENT_PATTERN:
if (it_ptm_read_pattern(&sigdata->pattern[component[n].n], f, buffer, (n + 1 < n_components) ? (component[n+1].offset - component[n].offset) : 0)) {
free(buffer);
free(component);
@@ -527,7 +527,7 @@
}
break;
- case IT_COMPONENT_SAMPLE:
+ case PTM_COMPONENT_SAMPLE:
if (it_ptm_read_sample_data(&sigdata->sample[component[n].n], (n + 1 == n_components), f)) {
free(buffer);
free(component);
--- a/dumb/src/it/reads3m.c
+++ b/dumb/src/it/reads3m.c
@@ -24,6 +24,8 @@
#include "dumb.h"
#include "internal/it.h"
+//#define S3M_BROKEN_OVERLAPPED_SAMPLES
+
/** WARNING: this is duplicated in itread.c */
static int it_seek(DUMBFILE *f, long offset)
{
@@ -53,10 +55,11 @@
/** WARNING: no adlib support */
}
- dumbfile_getnc(sample->filename, 13, f);
- sample->filename[13] = 0;
+ dumbfile_getnc(sample->filename, 12, f);
+ sample->filename[12] = 0;
- *offset = dumbfile_igetw(f) << 4;
+ *offset = dumbfile_getc(f) << 20;
+ *offset += dumbfile_igetw(f) << 4;
sample->length = dumbfile_igetl(f);
sample->loop_start = dumbfile_igetl(f);
@@ -66,14 +69,16 @@
dumbfile_skip(f, 1);
- *pack = dumbfile_getc(f);
+ flags = dumbfile_getc(f);
- if (*pack < 0 || (*pack != 0 && *pack != 4))
+ if (flags < 0 || (flags != 0 && flags != 4))
/* Sample is packed apparently (or error reading from file). We don't
* know how to read packed samples.
*/
return -1;
+ *pack = flags;
+
flags = dumbfile_getc(f);
sample->C5_speed = dumbfile_igetl(f) << 1;
@@ -277,7 +282,10 @@
pattern->n_entries++;
if (b) {
if (buflen + used[b] >= 65536) return -1;
- dumbfile_getnc(buffer + buflen, used[b], f);
+ if (buflen + used[b] <= length)
+ dumbfile_getnc(buffer + buflen, used[b], f);
+ else
+ memset(buffer + buflen, 0, used[b]);
buflen += used[b];
} else {
/* End of row */
@@ -380,7 +388,8 @@
if (b & 128) {
entry->effect = buffer[bufpos++];
entry->effectvalue = buffer[bufpos++];
- if (entry->effect != 255) {
+ // XXX woot
+ if (entry->effect && entry->effect < IT_MIDI_MACRO /*!= 255*/) {
entry->mask |= IT_ENTRY_EFFECT;
switch (entry->effect) {
case IT_BREAK_TO_ROW:
@@ -429,11 +438,11 @@
* trouble.
*/
-#define IT_COMPONENT_INSTRUMENT 1
-#define IT_COMPONENT_PATTERN 2
-#define IT_COMPONENT_SAMPLE 3
+#define S3M_COMPONENT_INSTRUMENT 1
+#define S3M_COMPONENT_PATTERN 2
+#define S3M_COMPONENT_SAMPLE 3
-typedef struct IT_COMPONENT
+typedef struct S3M_COMPONENT
{
unsigned char type;
unsigned char n;
@@ -441,14 +450,14 @@
short sampfirst; /* component[sampfirst] = first sample data after this */
short sampnext; /* sampnext is used to create linked lists of sample data */
}
-IT_COMPONENT;
+S3M_COMPONENT;
-static int it_component_compare(const void *e1, const void *e2)
+static int s3m_component_compare(const void *e1, const void *e2)
{
- return ((const IT_COMPONENT *)e1)->offset -
- ((const IT_COMPONENT *)e2)->offset;
+ return ((const S3M_COMPONENT *)e1)->offset -
+ ((const S3M_COMPONENT *)e2)->offset;
}
@@ -464,7 +473,7 @@
unsigned char sample_pack[256];
- IT_COMPONENT *component;
+ S3M_COMPONENT *component;
int n_components = 0;
int n;
@@ -605,7 +614,7 @@
}
for (n = 0; n < sigdata->n_samples; n++) {
- component[n_components].type = IT_COMPONENT_SAMPLE;
+ component[n_components].type = S3M_COMPONENT_SAMPLE;
component[n_components].n = n;
component[n_components].offset = dumbfile_igetw(f) << 4;
component[n_components].sampfirst = -1;
@@ -615,7 +624,7 @@
for (n = 0; n < sigdata->n_patterns; n++) {
long offset = dumbfile_igetw(f) << 4;
if (offset) {
- component[n_components].type = IT_COMPONENT_PATTERN;
+ component[n_components].type = S3M_COMPONENT_PATTERN;
component[n_components].n = n;
component[n_components].offset = offset;
component[n_components].sampfirst = -1;
@@ -627,7 +636,7 @@
}
}
- qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
+ qsort(component, n_components, sizeof(S3M_COMPONENT), &s3m_component_compare);
/* I found a really dumb S3M file that claimed to contain default pan
* data but didn't contain any. Programs would load it by reading part of
@@ -674,10 +683,10 @@
*/
for (n = 0; n < n_components; n++) {
- if (component[n].type == IT_COMPONENT_PATTERN) {
+ if (component[n].type == S3M_COMPONENT_PATTERN) {
int m;
for (m = n + 1; m < n_components; m++) {
- if (component[m].type == IT_COMPONENT_PATTERN) {
+ if (component[m].type == S3M_COMPONENT_PATTERN) {
if (component[n].offset == component[m].offset) {
int o, pattern;
pattern = component[m].n;
@@ -703,6 +712,9 @@
for (n = 0; n < n_components; n++) {
long offset;
int m;
+#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
+ int last;
+#endif
if (it_seek(f, component[n].offset)) {
free(buffer);
@@ -713,7 +725,7 @@
switch (component[n].type) {
- case IT_COMPONENT_PATTERN:
+ case S3M_COMPONENT_PATTERN:
if (it_s3m_read_pattern(&sigdata->pattern[component[n].n], f, buffer, (n + 1 < n_components) ? (component[n+1].offset - component[n].offset) : 0)) {
free(buffer);
free(component);
@@ -722,7 +734,7 @@
}
break;
- case IT_COMPONENT_SAMPLE:
+ case S3M_COMPONENT_SAMPLE:
if (it_s3m_read_sample_header(&sigdata->sample[component[n].n], &offset, &sample_pack[component[n].n], *cwtv, f)) {
free(buffer);
free(component);
@@ -752,20 +764,58 @@
m = component[n].sampfirst;
+#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
+ last = -1;
+#endif
+
while (m >= 0) {
- if (it_seek(f, component[m].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
+ // XXX
+#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
+ if ( last >= 0 ) {
+ if ( dumbfile_pos( f ) > component[m].offset ) {
+ IT_SAMPLE * s1 = &sigdata->sample[component[last].n];
+ IT_SAMPLE * s2 = &sigdata->sample[component[m].n];
+ if ( ( s1->flags | s2->flags ) & ( IT_SAMPLE_16BIT | IT_SAMPLE_STEREO ) ) {
+ free(buffer);
+ free(component);
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ if ( component[m].offset >= component[last].offset &&
+ component[m].offset + s2->length <= component[last].offset + s1->length ) {
+ s2->left = malloc( s2->length );
+ if ( ! s2->left ) {
+ free(buffer);
+ free(component);
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ memcpy( s2->left, ( const char * ) s1->left + component[m].offset - component[last].offset, s2->length );
+ last = -1;
+ }
+ }
+ } else last = 0;
- if (it_s3m_read_sample_data(&sigdata->sample[component[m].n], ffi, sample_pack[component[n].n], f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
+ if ( last >= 0 ) {
+#endif
+ if (it_seek(f, component[m].offset)) {
+ free(buffer);
+ free(component);
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+
+ if (it_s3m_read_sample_data(&sigdata->sample[component[m].n], ffi, sample_pack[component[m].n], f)) {
+ free(buffer);
+ free(component);
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+
+#ifdef S3M_BROKEN_OVERLAPPED_SAMPLES
+ last = m;
}
+#endif
m = component[m].sampnext;
}
--- a/dumb/src/it/readxm.c
+++ b/dumb/src/it/readxm.c
@@ -91,7 +91,8 @@
IT_VIBRATO_SINE,
IT_VIBRATO_XM_SQUARE,
IT_VIBRATO_RAMP_DOWN,
- IT_VIBRATO_RAMP_UP
+ IT_VIBRATO_RAMP_UP,
+ IT_VIBRATO_RANDOM
};
@@ -367,7 +368,8 @@
if (extra->n_samples) {
/* sample header size */
- if (dumbfile_igetl(f) != 0x28) {
+ i = dumbfile_igetl(f);
+ if (i && i != 0x28) { // XXX some crap with 0 here
TRACE("XM error: unexpected sample header size\n");
return -1;
}
@@ -443,7 +445,7 @@
extra->vibrato_depth = dumbfile_getc(f);
extra->vibrato_speed = dumbfile_getc(f);
- if (dumbfile_error(f) || extra->vibrato_type >= 4)
+ if (dumbfile_error(f) || extra->vibrato_type > 4) // XXX
return -1;
/** WARNING: lossy approximation */
@@ -647,7 +649,7 @@
* (Never trust the documentation provided with a tracker.
* Real files are the only truth...)
*/
-/*static*/ DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
+static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
{
DUMB_IT_SIGDATA *sigdata;
char id_text[18];
@@ -724,7 +726,7 @@
n_channels = dumbfile_igetw(f); /* max 32 but we'll be lenient */
sigdata->n_pchannels = n_channels;
sigdata->n_patterns = dumbfile_igetw(f);
- sigdata->n_instruments = dumbfile_igetw(f); /* max 128 */
+ sigdata->n_instruments = dumbfile_igetw(f); /* max 128 */ /* XXX upped to 256 */
flags = dumbfile_igetw(f);
sigdata->speed = dumbfile_igetw(f);
if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo?
@@ -731,7 +733,8 @@
sigdata->tempo = dumbfile_igetw(f);
/* sanity checks */
- if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_orders > 256 || sigdata->n_patterns > 256 || sigdata->n_instruments > 128 || n_channels > DUMB_IT_N_CHANNELS) {
+ // XXX
+ if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_orders > 256 || sigdata->n_patterns > 256 || sigdata->n_instruments > 256 || n_channels > DUMB_IT_N_CHANNELS) {
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
@@ -814,9 +817,18 @@
XM_INSTRUMENT_EXTRA extra;
if (it_xm_read_instrument(&sigdata->instrument[i], &extra, f) < 0) {
- TRACE("XM error: instrument %d\n", i+1);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
+ // XXX
+ if ( ! i )
+ {
+ TRACE("XM error: instrument %d\n", i+1);
+ _dumb_it_unload_sigdata(sigdata);
+ return NULL;
+ }
+ else
+ {
+ sigdata->n_instruments = i;
+ break;
+ }
}
if (extra.n_samples) {