diff --git a/dumb/include/internal/it.h b/dumb/include/internal/it.h index 0c8bf144..74a08d56 100644 --- a/dumb/include/internal/it.h +++ b/dumb/include/internal/it.h @@ -54,7 +54,7 @@ sigdata->flags & IT_COMPATIBLE_GXX * handle ambiguities in the format specification. The correct code in each * case will be determined most likely by experimentation. */ -#define STEREO_SAMPLES_COUNT_AS_TWO +//#define STEREO_SAMPLES_COUNT_AS_TWO #define INVALID_ORDERS_END_SONG #define INVALID_NOTES_CAUSE_NOTE_CUT #define SUSTAIN_LOOP_OVERRIDES_NORMAL_LOOP @@ -899,4 +899,6 @@ void _dumb_it_ptm_convert_effect(int effect, int value, IT_ENTRY *entry); int32 _dumb_it_read_sample_data_adpcm4(IT_SAMPLE *sample, DUMBFILE *f); +void _dumb_it_interleave_stereo_sample(IT_SAMPLE *sample); + #endif /* INTERNAL_IT_H */ diff --git a/dumb/src/it/itread.c b/dumb/src/it/itread.c index b06fbbca..12cd6828 100644 --- a/dumb/src/it/itread.c +++ b/dumb/src/it/itread.c @@ -306,6 +306,8 @@ static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f) envelope->loop_end = dumbfile_getc(f); envelope->sus_loop_start = dumbfile_getc(f); envelope->sus_loop_end = dumbfile_getc(f); + if (envelope->n_nodes > 25) + envelope->n_nodes = 25; for (n = 0; n < envelope->n_nodes; n++) { envelope->node_y[n] = dumbfile_getc(f); envelope->node_t[n] = dumbfile_igetw(f); @@ -682,15 +684,36 @@ static int32 it_read_sample_data(int cmwt, IT_SAMPLE *sample, unsigned char conv else decompress8(f, sample->data, datasize, ((cmwt >= 0x215) && (convert & 4))); } else if (sample->flags & IT_SAMPLE_16BIT) { - if (convert & 2) + if (sample->flags & IT_SAMPLE_STEREO) { + if (convert & 2) { + for (n = 0; n < datasize; n += 2) + ((short *)sample->data)[n] = dumbfile_mgetw(f); + for (n = 1; n < datasize; n += 2) + ((short *)sample->data)[n] = dumbfile_mgetw(f); + } else { + for (n = 0; n < datasize; n += 2) + ((short *)sample->data)[n] = dumbfile_igetw(f); + for (n = 1; n < datasize; n += 2) + ((short *)sample->data)[n] = dumbfile_igetw(f); + } + } else { + if (convert & 2) + for (n = 0; n < datasize; n++) + ((short *)sample->data)[n] = dumbfile_mgetw(f); + else + for (n = 0; n < datasize; n++) + ((short *)sample->data)[n] = dumbfile_igetw(f); + } + } else { + if (sample->flags & IT_SAMPLE_STEREO) { + for (n = 0; n < datasize; n += 2) + ((signed char *)sample->data)[n] = dumbfile_getc(f); + for (n = 1; n < datasize; n += 2) + ((signed char *)sample->data)[n] = dumbfile_getc(f); + } else for (n = 0; n < datasize; n++) - ((short *)sample->data)[n] = dumbfile_mgetw(f); - else - for (n = 0; n < datasize; n++) - ((short *)sample->data)[n] = dumbfile_igetw(f); - } else - for (n = 0; n < datasize; n++) - ((signed char *)sample->data)[n] = dumbfile_getc(f); + ((signed char *)sample->data)[n] = dumbfile_getc(f); + } if (dumbfile_error(f)) return -1; diff --git a/dumb/src/it/itrender.c b/dumb/src/it/itrender.c index 34a698d7..d71bdac7 100644 --- a/dumb/src/it/itrender.c +++ b/dumb/src/it/itrender.c @@ -1120,10 +1120,11 @@ static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer) } if (channel->volslide) { + int clip = (sigrenderer->sigdata->flags & IT_WAS_AN_S3M) ? 63 : 64; channel->volume += channel->volslide; - if (channel->volume > 64) { + if (channel->volume > clip) { if (channel->volslide >= 0) - channel->volume = 64; + channel->volume = clip; else channel->volume = 0; } @@ -1286,8 +1287,14 @@ static int update_pattern_variables(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY * case IT_S: { unsigned char effectvalue = entry->effectvalue; - if (effectvalue == 0) - effectvalue = channel->lastS; + if (sigrenderer->sigdata->flags & IT_WAS_AN_S3M) { + if (effectvalue == 0) + effectvalue = channel->lastDKL; + channel->lastDKL = effectvalue; + } else { + if (effectvalue == 0) + effectvalue = channel->lastS; + } channel->lastS = effectvalue; switch (effectvalue >> 4) { case IT_S_PATTERN_LOOP: @@ -1612,7 +1619,7 @@ static void it_retrigger_note(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *chan for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { IT_PLAYING * playing = sigrenderer->playing[i]; if (playing && playing->channel == channel && playing->instrument->dup_check_type) { - int match = 0; + int match = 1; switch (playing->instrument->dup_check_type) { case DCT_NOTE: @@ -2043,24 +2050,43 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than v = channel->lastDKL; channel->lastDKL = v; } - if ((v & 0x0F) == 0) { /* Dx0 */ - channel->volslide = v >> 4; - if (channel->volslide == 15 && !(sigdata->flags & IT_WAS_AN_XM)) { - channel->volume += 15; - if (channel->volume > 64) channel->volume = 64; + if (!(sigdata->flags & IT_WAS_AN_XM)) { + int clip = (sigdata->flags & IT_WAS_AN_S3M) ? 63 : 64; + if ((v & 0x0F) == 0x0F) { + if (!(v & 0xF0)) { + channel->volslide = -15; + channel->volume -= 15; + if (channel->volume > clip) channel->volume = 0; + } else { + channel->volume += v >> 4; + if (channel->volume > clip) channel->volume = clip; + } + } else if ((v & 0xF0) == 0xF0) { + if (!(v & 0x0F)) { + channel->volslide = 15; + channel->volume += 15; + if (channel->volume > clip) channel->volume = clip; + } else { + channel->volume -= v & 15; + if (channel->volume > clip) channel->volume = 0; + } + } else if (!(v & 0x0F)) { + channel->volslide = v >> 4; + } else { + channel->volslide = -(v & 15); } - } else if ((v & 0xF0) == 0) { /* D0x */ - channel->volslide = -v; - if (channel->volslide == -15 && !(sigdata->flags & IT_WAS_AN_XM)) { - channel->volume -= 15; + } else { + if ((v & 0x0F) == 0) { /* Dx0 */ + channel->volslide = v >> 4; + } else if ((v & 0xF0) == 0) { /* D0x */ + channel->volslide = -v; + } else if ((v & 0x0F) == 0x0F) { /* DxF */ + channel->volume += v >> 4; + if (channel->volume > 64) channel->volume = 64; + } else if ((v & 0xF0) == 0xF0) { /* DFx */ + channel->volume -= v & 15; if (channel->volume > 64) channel->volume = 0; } - } else if ((v & 0x0F) == 0x0F) { /* DxF */ - channel->volume += v >> 4; - if (channel->volume > 64) channel->volume = 64; - } else if ((v & 0xF0) == 0xF0) { /* DFx */ - channel->volume -= v & 15; - if (channel->volume > 64) channel->volume = 0; } } break; @@ -2098,6 +2124,10 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than else channel->xm_lastX2 = v & 15; } + } else if (sigdata->flags & IT_WAS_AN_S3M) { + if (v == 0) + v = channel->lastDKL; + channel->lastDKL = v; } else { if (v == 0) v = channel->lastEF; @@ -2129,6 +2159,10 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than else channel->xm_lastX1 = v & 15; } + } else if (sigdata->flags & IT_WAS_AN_S3M) { + if (v == 0) + v = channel->lastDKL; + channel->lastDKL = v; } else { if (v == 0) v = channel->lastEF; @@ -2202,13 +2236,20 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than case IT_TREMOR: { unsigned char v = entry->effectvalue; - if (v == 0) - v = channel->lastI; + if (v == 0) { + if (sigdata->flags & IT_WAS_AN_S3M) + v = channel->lastDKL; + else + v = channel->lastI; + } else if (!(sigdata->flags & IT_OLD_EFFECTS)) { if (v & 0xF0) v -= 0x10; if (v & 0x0F) v -= 0x01; } - channel->lastI = v; + if (sigdata->flags & IT_WAS_AN_S3M) + channel->lastDKL = v; + else + channel->lastI = v; channel->tremor_time |= 128; } update_tremor(channel); @@ -2220,9 +2261,15 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than * and we use lastJ for portamento down instead. */ if (!(sigdata->flags & IT_WAS_AN_XM)) { - if (v == 0) - v = channel->lastJ; - channel->lastJ = v; + if (sigdata->flags & IT_WAS_AN_S3M) { + if (v == 0) + v = channel->lastDKL; + channel->lastDKL = v; + } else { + if (v == 0) + v = channel->lastJ; + channel->lastJ = v; + } } channel->arpeggio = ((v & 0xF0) << 4) | (v & 0x0F); channel->arpeggio_shift = 16; @@ -2361,11 +2408,16 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than if (sigdata->flags & IT_WAS_AN_XM) { if ((v & 0x0F) == 0) v |= channel->lastQ & 0x0F; if ((v & 0xF0) == 0) v |= channel->lastQ & 0xF0; + channel->lastQ = v; + } else if (sigdata->flags & IT_WAS_AN_S3M) { + if (v == 0) + v = channel->lastDKL; + channel->lastDKL = v; } else { if (v == 0) v = channel->lastQ; + channel->lastQ = v; } - channel->lastQ = v; if ((v & 0x0F) == 0) v |= 0x01; channel->retrig = v; if (entry->mask & IT_ENTRY_NOTE) { @@ -2390,14 +2442,24 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than break; case IT_TREMOLO: { - unsigned char speed = entry->effectvalue >> 4; - unsigned char depth = entry->effectvalue & 15; - if (speed == 0) - speed = channel->lastRspeed; - channel->lastRspeed = speed; - if (depth == 0) - depth = channel->lastRdepth; - channel->lastRdepth = depth; + unsigned char speed, depth; + if (sigdata->flags & IT_WAS_AN_S3M) { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->lastDKL; + channel->lastDKL = v; + speed = v >> 4; + depth = v & 15; + } else { + speed = entry->effectvalue >> 4; + depth = entry->effectvalue & 15; + if (speed == 0) + speed = channel->lastRspeed; + channel->lastRspeed = speed; + if (depth == 0) + depth = channel->lastRdepth; + channel->lastRdepth = depth; + } if (channel->playing) { channel->playing->tremolo_speed = speed; channel->playing->tremolo_depth = depth; diff --git a/dumb/src/it/readam.c b/dumb/src/it/readam.c index 9910b1d8..6a4994df 100644 --- a/dumb/src/it/readam.c +++ b/dumb/src/it/readam.c @@ -331,6 +331,7 @@ static DUMB_IT_SIGDATA *it_riff_amff_load_sigdata( struct riff * stream ) sigdata->n_instruments = 0; sigdata->n_orders = 0; + sigdata->restart_position = 0; memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS); @@ -553,6 +554,7 @@ static DUMB_IT_SIGDATA *it_riff_am_load_sigdata( struct riff * stream ) sigdata->n_instruments = 0; sigdata->n_orders = 0; + sigdata->restart_position = 0; memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS); diff --git a/dumb/src/it/readdsmf.c b/dumb/src/it/readdsmf.c index 275f37ff..5db09a75 100644 --- a/dumb/src/it/readdsmf.c +++ b/dumb/src/it/readdsmf.c @@ -265,6 +265,7 @@ static DUMB_IT_SIGDATA *it_riff_dsmf_load_sigdata( struct riff * stream ) sigdata->n_instruments = 0; sigdata->n_orders = 0; + sigdata->restart_position = 0; memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS); diff --git a/dumb/src/it/readoldpsm.c b/dumb/src/it/readoldpsm.c index 3c764af2..5c0441c7 100644 --- a/dumb/src/it/readoldpsm.c +++ b/dumb/src/it/readoldpsm.c @@ -296,7 +296,7 @@ static int it_old_psm_read_patterns(IT_PATTERN * pattern, DUMBFILE * f, int num, if (flags & 0x80) { if ((*ptr < 60) && (channel < pchans)) { entry->mask |= IT_ENTRY_NOTE; - entry->note = *ptr + 36; + entry->note = *ptr + 35; } ptr++; if (*ptr) { diff --git a/dumb/src/it/reads3m.c b/dumb/src/it/reads3m.c index c9266ac6..c55e9f61 100644 --- a/dumb/src/it/reads3m.c +++ b/dumb/src/it/reads3m.c @@ -557,8 +557,8 @@ static DUMB_IT_SIGDATA *it_s3m_load_sigdata(DUMBFILE *f, int * cwtv) return NULL; } - sigdata->global_volume = dumbfile_getc(f) << 1; - if ( !sigdata->global_volume || sigdata->global_volume > 128 ) sigdata->global_volume = 128; + sigdata->global_volume = dumbfile_getc(f) * 16 / 11; + if ( !sigdata->global_volume || sigdata->global_volume > 93 ) sigdata->global_volume = 93; sigdata->speed = dumbfile_getc(f); if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo? sigdata->tempo = dumbfile_getc(f); diff --git a/dumb/src/it/readstm.c b/dumb/src/it/readstm.c index 8b8e8c82..be1b1572 100644 --- a/dumb/src/it/readstm.c +++ b/dumb/src/it/readstm.c @@ -28,14 +28,16 @@ #define strnicmp strncasecmp #endif -static int it_stm_read_sample_header( IT_SAMPLE *sample, DUMBFILE *f ) +static int it_stm_read_sample_header( IT_SAMPLE *sample, DUMBFILE *f, unsigned short *offset ) { dumbfile_getnc( sample->filename, 12, f ); sample->filename[12] = 0; memcpy( sample->name, sample->filename, 13 ); - dumbfile_skip( f, 2 + 2 ); + dumbfile_skip( f, 2 ); + + *offset = dumbfile_igetw( f ); sample->length = dumbfile_igetw( f ); sample->loop_start = dumbfile_igetw( f ); @@ -78,24 +80,15 @@ static int it_stm_read_sample_header( IT_SAMPLE *sample, DUMBFILE *f ) return dumbfile_error(f); } -static int it_stm_read_sample_data( IT_SAMPLE *sample, DUMBFILE *f ) +static int it_stm_read_sample_data( IT_SAMPLE *sample, void *data_block, long offset ) { - int32 n; - if ( ! sample->length ) return 0; - n = dumbfile_pos( f ); - if ( n & 15 ) { - if ( dumbfile_skip( f, 16 - ( n & 15 ) ) ) - return -1; - } - sample->data = malloc( sample->length ); if (!sample->data) return -1; - if ( dumbfile_getnc( sample->data, sample->length, f ) != sample->length ) - return -1; + memcpy( sample->data, (unsigned char*)data_block + offset, sample->length ); return 0; } @@ -141,10 +134,6 @@ static int it_stm_read_pattern( IT_PATTERN *pattern, DUMBFILE *f, unsigned char entry->effectvalue = buffer[ pos + 3 ]; if ( entry->instrument && entry->instrument < 32 ) entry->mask |= IT_ENTRY_INSTRUMENT; - if ( note == 0xFC || note == 0xFE ) { - entry->mask |= IT_ENTRY_NOTE; - entry->note = IT_NOTE_CUT; - } if ( note < 251 ) { entry->mask |= IT_ENTRY_NOTE; entry->note = ( note >> 4 ) * 12 + ( note & 0x0F ); @@ -192,14 +181,20 @@ static int it_stm_read_pattern( IT_PATTERN *pattern, DUMBFILE *f, unsigned char -static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f /*, int * version*/) +static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f, int * version) { DUMB_IT_SIGDATA *sigdata; char tracker_name[ 8 ]; + unsigned short sample_offset[ 31 ]; + + void *data_block; + int n; + long o, p, q; + sigdata = malloc(sizeof(*sigdata)); if (!sigdata) return NULL; @@ -227,8 +222,7 @@ static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f /*, int * version*/) return NULL; } - /* *version = dumbfile_mgetw(f); */ - dumbfile_skip( f, 2 ); + *version = dumbfile_mgetw(f); sigdata->song_message = NULL; sigdata->order = NULL; @@ -247,7 +241,7 @@ static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f /*, int * version*/) sigdata->pan_separation = 128; /** WARNING: which ones? */ - sigdata->flags = IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M; + sigdata->flags = IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M | IT_STEREO; sigdata->speed = dumbfile_getc(f) >> 4; if ( sigdata->speed < 1 ) sigdata->speed = 1; @@ -287,7 +281,7 @@ static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f /*, int * version*/) sigdata->channel_pan[ 3 ] = 16; for ( n = 0; n < sigdata->n_samples; ++n ) { - if ( it_stm_read_sample_header( &sigdata->sample[ n ], f ) ) { + if ( it_stm_read_sample_header( &sigdata->sample[ n ], f, &sample_offset[ n ] ) ) { _dumb_it_unload_sigdata( sigdata ); return NULL; } @@ -300,7 +294,8 @@ static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f /*, int * version*/) } /* Orders, byte each, length = sigdata->n_orders (should be even) */ - dumbfile_getnc( sigdata->order, 128, f ); + dumbfile_getnc( sigdata->order, *version >= 0x200 ? 128 : 64, f ); + if (*version < 0x200) memset( sigdata->order + 64, 0xFF, 64 ); sigdata->restart_position = 0; for ( n = 127; n >= 0; --n ) { @@ -332,54 +327,105 @@ static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f /*, int * version*/) free( buffer ); } + o = LONG_MAX; + p = 0; + for ( n = 0; n < sigdata->n_samples; ++n ) { - if ( it_stm_read_sample_data( &sigdata->sample[ n ], f ) ) { + if ((sigdata->sample[ n ].flags & IT_SAMPLE_EXISTS) && sample_offset[ n ]) { + q = ((long)sample_offset[ n ]) * 16; + if (q < o) { + o = q; + } + if (q + sigdata->sample[ n ].length > p) { + p = q + sigdata->sample[ n ].length; + } + } + else { + sigdata->sample[ n ].flags = 0; + sigdata->sample[ n ].length = 0; + } + } + + data_block = malloc( p - o ); + if ( !data_block ) { + _dumb_it_unload_sigdata( sigdata ); + return NULL; + } + + for ( n = 0, q = o / 16; n < sigdata->n_samples; ++n ) { + if ( sample_offset[ n ] ) { + sample_offset[ n ] -= q; + } + } + + q = o - dumbfile_pos( f ); + p -= o; + o = 0; + if ( q >= 0 ) dumbfile_skip( f, q ); + else { + o = -q; + memset ( data_block, 0, o ); + } + if ( dumbfile_getnc( (char*)data_block + o, p - o, f ) != p - o ) { + free( data_block ); + _dumb_it_unload_sigdata( sigdata ); + return NULL; + } + + for ( n = 0; n < sigdata->n_samples; ++n ) { + if ( it_stm_read_sample_data( &sigdata->sample[ n ], data_block, ((long)sample_offset[ n ]) * 16 ) ) { + free( data_block ); _dumb_it_unload_sigdata( sigdata ); return NULL; } } + free( data_block ); + _dumb_it_fix_invalid_orders(sigdata); return sigdata; } -/*static char hexdigit(int in) -{ - if (in < 10) return in + '0'; - else return in + 'A' - 10; -}*/ - DUH *DUMBEXPORT dumb_read_stm_quick(DUMBFILE *f) { sigdata_t *sigdata; - /*int ver;*/ + int ver; DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it; - sigdata = it_stm_load_sigdata(f /*, &ver*/); + sigdata = it_stm_load_sigdata(f , &ver); if (!sigdata) return NULL; { - /*char version[16];*/ + char version[16]; const char *tag[2][2]; tag[0][0] = "TITLE"; tag[0][1] = ((DUMB_IT_SIGDATA *)sigdata)->name; tag[1][0] = "FORMAT"; - tag[1][1] = "STM"; - /*version[0] = 'S'; + version[0] = 'S'; version[1] = 'T'; version[2] = 'M'; version[3] = ' '; version[4] = 'v'; - version[5] = hexdigit((ver >> 8) & 15); + version[5] = '0' + ((ver >> 8) & 15); version[6] = '.'; - version[7] = hexdigit((ver >> 4) & 15); - version[8] = hexdigit(ver & 15); - version[9] = 0; - tag[1][1] = (const char *) &version;*/ + if ((ver & 255) > 99) + { + version[7] = '0' + ((ver & 255) / 100 ); + version[8] = '0' + (((ver & 255) / 10) % 10); + version[9] = '0' + ((ver & 255) % 10); + version[10] = 0; + } + else + { + version[7] = '0' + ((ver & 255) / 10); + version[8] = '0' + ((ver & 255) % 10); + version[9] = 0; + } + tag[1][1] = (const char *) &version; return make_duh(-1, 2, (const char *const (*)[2])tag, 1, &descptr, &sigdata); } } diff --git a/src/svnrevision.h b/src/svnrevision.h index 7468fd8a..cea54423 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "4081" -#define ZD_SVN_REVISION_NUMBER 4081 +#define ZD_SVN_REVISION_STRING "4090" +#define ZD_SVN_REVISION_NUMBER 4090