* Updated to ZDoom 4100:

- Updated DUMB revision.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1521 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
gez 2013-02-08 11:22:34 +00:00
parent 4cff6442cb
commit 726870fe1f
6 changed files with 431 additions and 122 deletions

View file

@ -1032,6 +1032,15 @@ static void update_retrig(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel)
}
static void update_smooth_effects_playing(IT_PLAYING *playing)
{
playing->vibrato_time += playing->vibrato_n *
(playing->vibrato_speed << 2);
playing->tremolo_time += playing->tremolo_speed << 2;
playing->panbrello_time += playing->panbrello_speed;
if (playing->panbrello_waveform == 3)
playing->panbrello_random = (rand() % 129) - 64;
}
static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer)
{
@ -1042,12 +1051,15 @@ static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer)
IT_PLAYING *playing = channel->playing;
if (playing) {
playing->vibrato_time += playing->vibrato_n *
(playing->vibrato_speed << 2);
playing->tremolo_time += playing->tremolo_speed << 2;
playing->panbrello_time += playing->panbrello_speed;
if (playing->panbrello_waveform == 3)
playing->panbrello_random = (rand() % 129) - 64;
update_smooth_effects_playing(playing);
}
}
for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
IT_PLAYING *playing = sigrenderer->playing[i];
if (playing) {
update_smooth_effects_playing(playing);
}
}
}
@ -1083,7 +1095,7 @@ static void update_invert_loop(IT_CHANNEL *channel, IT_SAMPLE *sample)
static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
{
int i;
int i, j;
if (sigrenderer->globalvolslide) {
sigrenderer->globalvolume += sigrenderer->globalvolslide;
@ -1167,6 +1179,10 @@ static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
}
if (channel->playing)
channel->playing->channel_volume = channel->channelvolume;
for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
if (sigrenderer->playing[j] && sigrenderer->playing[j]->channel == channel)
sigrenderer->playing[j]->channel_volume = channel->channelvolume;
}
}
update_tremor(channel);
@ -1177,80 +1193,121 @@ static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
if (channel->inv_loop_speed) update_invert_loop(channel, playing ? playing->sample : NULL);
if (playing) {
playing->slide += channel->portamento;
for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
if (sigrenderer->playing[j] && sigrenderer->playing[j]->channel == channel) break;
}
if (playing || j < DUMB_IT_N_NNA_CHANNELS) {
if (playing) playing->slide += channel->portamento;
for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
if (sigrenderer->playing[j] && sigrenderer->playing[j]->channel == channel)
sigrenderer->playing[j]->slide += channel->portamento;
}
if (channel->okt_toneslide) {
if (channel->okt_toneslide--) {
playing->note += channel->toneslide;
if (playing->note >= 120) {
if (channel->toneslide < 0) playing->note = 0;
else playing->note = 119;
if (playing) {
playing->note += channel->toneslide;
if (playing->note >= 120) {
if (channel->toneslide < 0) playing->note = 0;
else playing->note = 119;
}
}
for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
if (sigrenderer->playing[j] && sigrenderer->playing[j]->channel == channel) {
IT_PLAYING *playing = sigrenderer->playing[j];
playing->note += channel->toneslide;
if (playing->note >= 120) {
if (channel->toneslide < 0) playing->note = 0;
else playing->note = 119;
}
}
}
}
} else if (channel->ptm_toneslide) {
if (--channel->toneslide_tick == 0) {
channel->toneslide_tick = channel->ptm_toneslide;
playing->note += channel->toneslide;
if (playing->note >= 120) {
if (channel->toneslide < 0) playing->note = 0;
else playing->note = 119;
}
channel->note = channel->truenote = playing->note;
if (channel->toneslide_retrig) {
it_playing_reset_resamplers(playing, 0);
if (playing) {
playing->note += channel->toneslide;
if (playing->note >= 120) {
if (channel->toneslide < 0) playing->note = 0;
else playing->note = 119;
}
channel->note = channel->truenote = playing->note;
if (channel->toneslide_retrig) {
it_playing_reset_resamplers(playing, 0);
#ifdef END_RAMPING
playing->declick_stage = 0;
playing->declick_volume = 1.f / 256.f;
playing->declick_stage = 0;
playing->declick_volume = 1.f / 256.f;
#endif
}
}
for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
if (sigrenderer->playing[j] && sigrenderer->playing[j]->channel == channel) {
IT_PLAYING *playing = sigrenderer->playing[j];
playing->note += channel->toneslide;
if (playing->note >= 120) {
if (channel->toneslide < 0) playing->note = 0;
else playing->note = 119;
}
if (channel->toneslide_retrig) {
it_playing_reset_resamplers(playing, 0);
#ifdef END_RAMPING
playing->declick_stage = 0;
playing->declick_volume = 1.f / 256.f;
#endif
}
}
}
}
}
if (sigrenderer->sigdata->flags & IT_LINEAR_SLIDES) {
if (channel->toneporta && channel->destnote < 120) {
int currpitch = ((playing->note - 60) << 8) + playing->slide;
int destpitch = (channel->destnote - 60) << 8;
if (currpitch > destpitch) {
currpitch -= channel->toneporta;
if (currpitch < destpitch) {
currpitch = destpitch;
channel->destnote = IT_NOTE_OFF;
}
} else if (currpitch < destpitch) {
currpitch += channel->toneporta;
if (playing) {
if (sigrenderer->sigdata->flags & IT_LINEAR_SLIDES) {
if (channel->toneporta && channel->destnote < 120) {
int currpitch = ((playing->note - 60) << 8) + playing->slide;
int destpitch = (channel->destnote - 60) << 8;
if (currpitch > destpitch) {
currpitch = destpitch;
channel->destnote = IT_NOTE_OFF;
currpitch -= channel->toneporta;
if (currpitch < destpitch) {
currpitch = destpitch;
channel->destnote = IT_NOTE_OFF;
}
} else if (currpitch < destpitch) {
currpitch += channel->toneporta;
if (currpitch > destpitch) {
currpitch = destpitch;
channel->destnote = IT_NOTE_OFF;
}
}
playing->slide = currpitch - ((playing->note - 60) << 8);
}
playing->slide = currpitch - ((playing->note - 60) << 8);
}
} else {
if (channel->toneporta && channel->destnote < 120) {
float amiga_multiplier = playing->sample->C5_speed * (1.0f / AMIGA_DIVISOR);
} else {
if (channel->toneporta && channel->destnote < 120) {
float amiga_multiplier = playing->sample->C5_speed * (1.0f / AMIGA_DIVISOR);
float deltanote = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note);
/* deltanote is 1.0 for C-5, 0.5 for C-6, etc. */
float deltanote = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note);
/* deltanote is 1.0 for C-5, 0.5 for C-6, etc. */
float deltaslid = deltanote - playing->slide * amiga_multiplier;
float deltaslid = deltanote - playing->slide * amiga_multiplier;
float destdelta = (float)pow(DUMB_SEMITONE_BASE, 60 - channel->destnote);
if (deltaslid < destdelta) {
playing->slide -= channel->toneporta;
deltaslid = deltanote - playing->slide * amiga_multiplier;
if (deltaslid > destdelta) {
playing->note = channel->destnote;
playing->slide = 0;
channel->destnote = IT_NOTE_OFF;
}
} else {
playing->slide += channel->toneporta;
deltaslid = deltanote - playing->slide * amiga_multiplier;
float destdelta = (float)pow(DUMB_SEMITONE_BASE, 60 - channel->destnote);
if (deltaslid < destdelta) {
playing->note = channel->destnote;
playing->slide = 0;
channel->destnote = IT_NOTE_OFF;
playing->slide -= channel->toneporta;
deltaslid = deltanote - playing->slide * amiga_multiplier;
if (deltaslid > destdelta) {
playing->note = channel->destnote;
playing->slide = 0;
channel->destnote = IT_NOTE_OFF;
}
} else {
playing->slide += channel->toneporta;
deltaslid = deltanote - playing->slide * amiga_multiplier;
if (deltaslid < destdelta) {
playing->note = channel->destnote;
playing->slide = 0;
channel->destnote = IT_NOTE_OFF;
}
}
}
}
@ -1563,7 +1620,7 @@ static void it_retrigger_note(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *chan
nna = channel->playing->instrument->new_note_action;
#endif
if ((sigdata->flags & IT_USE_INSTRUMENTS) && (channel->playing->enabled_envelopes) && channel->playing->instnum == channel->instrument) {
if (!(channel->playing->flags & IT_PLAYING_DEAD) && (sigdata->flags & IT_USE_INSTRUMENTS) && (channel->playing->enabled_envelopes) && channel->playing->instnum == channel->instrument) {
IT_PLAYING * playing = channel->playing;
IT_INSTRUMENT * inst = &sigdata->instrument[channel->instrument-1];
if ((playing->enabled_envelopes & IT_ENV_VOLUME) && (inst->volume_envelope.flags & IT_ENVELOPE_CARRY)) {
@ -1684,7 +1741,8 @@ static void it_retrigger_note(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *chan
if (!flags && sigdata->flags & IT_USE_INSTRUMENTS) {
for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
IT_PLAYING * playing = sigrenderer->playing[i];
if (playing && (playing->enabled_envelopes) && playing->instnum == channel->instrument) {
if (!playing || playing->channel != channel) continue;
if (playing->enabled_envelopes && playing->instnum == channel->instrument) {
IT_INSTRUMENT * inst = &sigdata->instrument[channel->instrument-1];
if ((playing->enabled_envelopes & IT_ENV_VOLUME) && (inst->volume_envelope.flags & IT_ENVELOPE_CARRY)) {
flags |= 1;
@ -1974,10 +2032,19 @@ static void xm_envelope_calculate_value(IT_ENVELOPE *envelope, IT_PLAYING_ENVELO
extern const char xm_convert_vibrato[];
const char mod_convert_vibrato[] = {
IT_VIBRATO_SINE,
IT_VIBRATO_RAMP_UP, /* this will be inverted by IT_OLD_EFFECTS */
IT_VIBRATO_XM_SQUARE,
IT_VIBRATO_XM_SQUARE
};
/* Returns 1 if a callback caused termination of playback. */
static int process_effects(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry, int ignore_cxx)
{
DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
IT_PLAYING *playing;
int i;
IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
@ -2034,10 +2101,17 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
break;
case IT_VOLSLIDE_VIBRATO:
if (channel->playing) {
channel->playing->vibrato_speed = channel->lastHspeed;
channel->playing->vibrato_depth = channel->lastHdepth;
channel->playing->vibrato_n++;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
playing->vibrato_speed = channel->lastHspeed;
playing->vibrato_depth = channel->lastHdepth;
playing->vibrato_n++;
}
}
/* Fall through and process volume slide. */
case IT_VOLUME_SLIDE:
@ -2133,15 +2207,22 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
v = channel->lastEF;
channel->lastEF = v;
}
if (channel->playing) {
if ((v & 0xF0) == 0xF0)
channel->playing->slide -= (v & 15) << 4;
else if ((v & 0xF0) == 0xE0)
channel->playing->slide -= (v & 15) << 2;
else if (sigdata->flags & IT_WAS_A_669)
channel->portamento -= v << 3;
else
channel->portamento -= v << 4;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
if ((v & 0xF0) == 0xF0)
playing->slide -= (v & 15) << 4;
else if ((v & 0xF0) == 0xE0)
playing->slide -= (v & 15) << 2;
else if (i < 0 && sigdata->flags & IT_WAS_A_669)
channel->portamento -= v << 3;
else if (i < 0)
channel->portamento -= v << 4;
}
}
}
break;
@ -2168,15 +2249,22 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
v = channel->lastEF;
channel->lastEF = v;
}
if (channel->playing) {
if ((v & 0xF0) == 0xF0)
channel->playing->slide += (v & 15) << 4;
else if ((v & 0xF0) == 0xE0)
channel->playing->slide += (v & 15) << 2;
else if (sigdata->flags & IT_WAS_A_669)
channel->portamento += v << 3;
else
channel->portamento += v << 4;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (channel->playing) {
if ((v & 0xF0) == 0xF0)
channel->playing->slide += (v & 15) << 4;
else if ((v & 0xF0) == 0xE0)
channel->playing->slide += (v & 15) << 2;
else if (i < 0 && sigdata->flags & IT_WAS_A_669)
channel->portamento += v << 3;
else if (i < 0)
channel->portamento += v << 4;
}
}
}
break;
@ -2219,16 +2307,23 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
if (depth == 0)
depth = channel->lastHdepth;
else {
if (sigdata->flags & IT_OLD_EFFECTS)
if (sigdata->flags & IT_OLD_EFFECTS && !(sigdata->flags & IT_WAS_A_MOD))
depth <<= 3;
else
depth <<= 2;
channel->lastHdepth = depth;
}
if (channel->playing) {
channel->playing->vibrato_speed = speed;
channel->playing->vibrato_depth = depth;
channel->playing->vibrato_n++;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
playing->vibrato_speed = speed;
playing->vibrato_depth = depth;
playing->vibrato_n++;
}
}
}
}
@ -2284,8 +2379,15 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
else
channel->channelvolume = 64;
#endif
if (channel->playing)
channel->playing->channel_volume = channel->channelvolume;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing)
playing->channel_volume = channel->channelvolume;
}
break;
case IT_CHANNEL_VOLUME_SLIDE:
{
@ -2306,8 +2408,15 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
if (channel->channelvolume > 64) channel->channelvolume = 0;
} else
break;
if (channel->playing)
channel->playing->channel_volume = channel->channelvolume;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing)
playing->channel_volume = channel->channelvolume;
}
}
}
break;
@ -2460,9 +2569,16 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
depth = channel->lastRdepth;
channel->lastRdepth = depth;
}
if (channel->playing) {
channel->playing->tremolo_speed = speed;
channel->playing->tremolo_depth = depth;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
playing->tremolo_speed = speed;
playing->tremolo_depth = depth;
}
}
}
break;
@ -2491,7 +2607,8 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
case IT_S_SET_VIBRATO_WAVEFORM:
{
int waveform = effectvalue & 3;
if (sigdata->flags & IT_WAS_AN_XM) waveform = xm_convert_vibrato[waveform];
if (sigdata->flags & IT_WAS_A_MOD) waveform = mod_convert_vibrato[waveform];
else if (sigdata->flags & IT_WAS_AN_XM) waveform = xm_convert_vibrato[waveform];
channel->vibrato_waveform = waveform;
if (channel->playing) {
channel->playing->vibrato_waveform = waveform;
@ -2503,7 +2620,8 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
case IT_S_SET_TREMOLO_WAVEFORM:
{
int waveform = effectvalue & 3;
if (sigdata->flags & IT_WAS_AN_XM) waveform = xm_convert_vibrato[waveform];
if (sigdata->flags & IT_WAS_A_MOD) waveform = mod_convert_vibrato[waveform];
else if (sigdata->flags & IT_WAS_AN_XM) waveform = xm_convert_vibrato[waveform];
channel->tremolo_waveform = waveform;
if (channel->playing) {
channel->playing->tremolo_waveform = waveform;
@ -2681,10 +2799,17 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
depth <<= 1;
channel->lastHdepth = depth;
}
if (channel->playing) {
channel->playing->vibrato_speed = speed;
channel->playing->vibrato_depth = depth;
channel->playing->vibrato_n++;
for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if (i < 0) playing = channel->playing;
else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
playing->vibrato_speed = speed;
playing->vibrato_depth = depth;
playing->vibrato_n++;
}
}
}
break;
@ -3571,7 +3696,7 @@ static int it_envelope_end(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYIN
/* Returns 1 when fading should be initiated for a volume envelope. */
static int update_it_envelope(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe, int flags)
{
if (!(playing->enabled_envelopes & flags))
if (!(playing->enabled_envelopes & flags) || !envelope->n_nodes)
return 0;
ASSERT(envelope->n_nodes > 0);
@ -4287,13 +4412,13 @@ static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *play
vol = (rand() % 129) - 64;
break;
case 4:
vol = it_xm_squarewave[playing->vibrato_time];
vol = it_xm_squarewave[playing->tremolo_time];
break;
case 5:
vol = it_xm_ramp[playing->vibrato_time];
vol = it_xm_ramp[playing->tremolo_time];
break;
case 6:
vol = it_xm_ramp[255-playing->vibrato_time];
vol = it_xm_ramp[255-((sigrenderer->sigdata->flags & IT_WAS_A_MOD)?playing->vibrato_time:playing->tremolo_time)];
break;
}
vol *= playing->tremolo_depth;
@ -4314,7 +4439,7 @@ static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *play
volume *= 1.0f / ((64 << 5) * 64.0f * 64.0f * 128.0f * 128.0f);
if (volume && playing->instrument) {
if (playing->enabled_envelopes & IT_ENV_VOLUME) {
if (playing->enabled_envelopes & IT_ENV_VOLUME && playing->env_instrument->volume_envelope.n_nodes) {
volume *= envelope_get_y(&playing->env_instrument->volume_envelope, &playing->volume_envelope);
volume *= 1.0f / (64 << IT_ENVELOPE_SHIFT);
}

View file

@ -631,7 +631,7 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int rstrict)
/* Work out how many patterns there are. */
sigdata->n_patterns = -1;
for (i = 0; i < 128; i++)
for (i = 0; i < sigdata->n_orders; i++)
if (sigdata->n_patterns < sigdata->order[i])
sigdata->n_patterns = sigdata->order[i];
sigdata->n_patterns++;

View file

@ -497,7 +497,7 @@ static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f, int restrict)
j++;
}
}
for (; i < sigdata->n_samples; i++) {
for (; i < (unsigned)sigdata->n_samples; i++) {
sigdata->sample[i].flags = 0;
}

View file

@ -354,7 +354,7 @@ static DUMB_IT_SIGDATA *it_stm_load_sigdata(DUMBFILE *f, int * version)
for ( n = 0, q = o / 16; n < sigdata->n_samples; ++n ) {
if ( sample_offset[ n ] ) {
sample_offset[ n ] -= q;
sample_offset[ n ] = (unsigned short)(sample_offset[ n ] - q);
}
}

View file

@ -111,6 +111,7 @@ typedef struct XM_INSTRUMENT_EXTRA
int vibrato_sweep; /* 0-0xFF */
int vibrato_depth; /* 0-0x0F */
int vibrato_speed; /* 0-0x3F */
int sample_header_size;
}
XM_INSTRUMENT_EXTRA;
@ -359,19 +360,150 @@ static int it_xm_make_envelope(IT_ENVELOPE *envelope, const unsigned short *data
typedef struct LIMITED_XM LIMITED_XM;
struct LIMITED_XM
{
unsigned char *buffered;
long ptr, limit, allocated;
DUMBFILE *remaining;
};
/* XXX */
struct DUMBFILE
{
DUMBFILE_SYSTEM *dfs;
void *file;
long pos;
};
static int limit_xm_resize(void *f, long n)
{
DUMBFILE *df = f;
LIMITED_XM *lx = df->file;
if (lx->buffered || n) {
if (n > lx->allocated) {
unsigned char *buffered = realloc( lx->buffered, n );
if ( !buffered ) return -1;
lx->buffered = buffered;
memset( buffered + lx->allocated, 0, n - lx->allocated );
lx->allocated = n;
}
if ( dumbfile_getnc( lx->buffered, n, lx->remaining ) < n ) return -1;
} else if (!n) {
if ( lx->buffered ) free( lx->buffered );
lx->buffered = NULL;
lx->allocated = 0;
}
lx->limit = n;
lx->ptr = 0;
return 0;
}
static int limit_xm_skip_end(void *f, int32 n)
{
DUMBFILE *df = f;
LIMITED_XM *lx = df->file;
return dumbfile_skip( lx->remaining, n );
}
static int limit_xm_skip(void *f, int32 n)
{
LIMITED_XM *lx = f;
lx->ptr += n;
return 0;
}
static int limit_xm_getc(void *f)
{
LIMITED_XM *lx = f;
if (lx->ptr >= lx->allocated) {
return 0;
}
return lx->buffered[lx->ptr++];
}
static long limit_xm_getnc(char *ptr, int32 n, void *f)
{
LIMITED_XM *lx = f;
int left;
left = lx->allocated - lx->ptr;
if (n > left) {
if (left > 0) {
memcpy( ptr, lx->buffered + lx->ptr, left );
memset( ptr + left, 0, n - left );
} else {
memset( ptr, 0, n );
}
} else {
memcpy( ptr, lx->buffered + lx->ptr, n );
}
lx->ptr += n;
return n;
}
static void limit_xm_close(void *f)
{
LIMITED_XM *lx = f;
if (lx->buffered) free(lx->buffered);
/* Do NOT close lx->remaining */
free(f);
}
DUMBFILE_SYSTEM limit_xm_dfs = {
NULL,
&limit_xm_skip,
&limit_xm_getc,
&limit_xm_getnc,
&limit_xm_close
};
static DUMBFILE *dumbfile_limit_xm(DUMBFILE *f)
{
LIMITED_XM * lx = malloc(sizeof(*lx));
lx->remaining = f;
lx->buffered = NULL;
lx->ptr = 0;
lx->limit = 0;
lx->allocated = 0;
return dumbfile_open_ex( lx, &limit_xm_dfs );
}
static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA *extra, DUMBFILE *f)
{
uint32 size, bytes_read;
unsigned short vol_points[24];
unsigned short pan_points[24];
int i, type;
const unsigned long max_size = 4 + 22 + 1 + 2 + 4 + 96 + 48 + 48 + 1 * 14 + 2 + 2;
unsigned long skip_end = 0;
/* Header size. Tends to be more than the actual size of the structure.
* So unread bytes must be skipped before reading the first sample
* header.
*/
if ( limit_xm_resize( f, 4 ) < 0 ) return -1;
size = dumbfile_igetl(f);
if ( size == 0 ) size = max_size;
else if ( size > max_size )
{
skip_end = size - max_size;
size = max_size;
}
if ( limit_xm_resize( f, size - 4 ) < 0 ) return -1;
dumbfile_getnc(instrument->name, 22, f);
instrument->name[22] = 0;
instrument->filename[0] = 0;
@ -385,12 +517,11 @@ static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA
if (extra->n_samples) {
/* sample header size */
dumbfile_skip(f, 4); // XXX can't be trusted, as there are trackers that write the wrong value here
/*i = dumbfile_igetl(f);
if (i && i != 0x28) { // XXX some crap with 0 here
TRACE("XM error: unexpected sample header size\n");
return -1;
}*/
if (!i || i > 0x28) i = 0x28;*/
dumbfile_skip(f, 4);
i = 0x28;
extra->sample_header_size = i;
/* sample map */
for (i = 0; i < 96; i++) {
@ -476,7 +607,10 @@ static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA
for (i = 0; i < 96; i++)
instrument->map_sample[i] = 0;
if (dumbfile_skip(f, size - bytes_read))
if (size > bytes_read && dumbfile_skip(f, size - bytes_read))
return -1;
if (skip_end && limit_xm_skip_end(f, skip_end))
return -1;
instrument->new_note_action = NNA_NOTE_CUT;
@ -924,16 +1058,24 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
for (i = 0; i < sigdata->n_instruments; i++) {
XM_INSTRUMENT_EXTRA extra;
if (it_xm_read_instrument(&sigdata->instrument[i], &extra, f) < 0) {
DUMBFILE * lf = dumbfile_limit_xm( f );
if ( !lf ) {
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
if (it_xm_read_instrument(&sigdata->instrument[i], &extra, lf) < 0) {
// XXX
if ( ! i )
{
TRACE("XM error: instrument %d\n", i+1);
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
else
{
dumbfile_close( lf );
sigdata->n_instruments = i;
break;
}
@ -948,17 +1090,31 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
sigdata->sample = safe_realloc(sigdata->sample, sizeof(*sigdata->sample)*(total_samples+extra.n_samples));
if (!sigdata->sample) {
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
for (j = total_samples; j < total_samples+extra.n_samples; j++)
sigdata->sample[j].data = NULL;
if ( limit_xm_resize( lf, 0 ) < 0 ) {
dumbfile_close( lf );
_dumb_it_unload_sigdata( sigdata );
return NULL;
}
/* read instrument's samples */
for (j = 0; j < extra.n_samples; j++) {
IT_SAMPLE *sample = &sigdata->sample[total_samples+j];
int b = it_xm_read_sample_header(sample, f);
int b;
if ( limit_xm_resize( lf, extra.sample_header_size ) < 0 ) {
dumbfile_close( lf );
_dumb_it_unload_sigdata( sigdata );
return NULL;
}
b = it_xm_read_sample_header(sample, lf);
if (b < 0) {
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
@ -975,12 +1131,15 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
}
for (j = 0; j < extra.n_samples; j++) {
if (it_xm_read_sample_data(&sigdata->sample[total_samples+j], roguebytes[j], f) != 0) {
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
}
total_samples += extra.n_samples;
}
dumbfile_close( lf );
}
sigdata->n_samples = total_samples;
@ -1012,8 +1171,16 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
for (i = 0; i < sigdata->n_instruments; i++) {
XM_INSTRUMENT_EXTRA extra;
if (it_xm_read_instrument(&sigdata->instrument[i], &extra, f) < 0) {
DUMBFILE * lf = dumbfile_limit_xm( f );
if ( !lf ) {
free(roguebytes);
_dumb_it_unload_sigdata(sigdata);
return NULL;
}
if (it_xm_read_instrument(&sigdata->instrument[i], &extra, lf) < 0) {
TRACE("XM error: instrument %d\n", i+1);
dumbfile_close(lf);
free(roguebytes);
_dumb_it_unload_sigdata(sigdata);
return NULL;
@ -1026,6 +1193,7 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
sigdata->sample = safe_realloc(sigdata->sample, sizeof(*sigdata->sample)*(total_samples+extra.n_samples));
if (!sigdata->sample) {
dumbfile_close( lf );
free(roguebytes);
_dumb_it_unload_sigdata(sigdata);
return NULL;
@ -1033,10 +1201,24 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
for (j = total_samples; j < total_samples+extra.n_samples; j++)
sigdata->sample[j].data = NULL;
if ( limit_xm_resize( lf, 0 ) < 0 ) {
dumbfile_close( lf );
free( roguebytes );
_dumb_it_unload_sigdata( sigdata );
return NULL;
}
/* read instrument's samples */
for (j = 0; j < extra.n_samples; j++) {
IT_SAMPLE *sample = &sigdata->sample[total_samples+j];
int b = it_xm_read_sample_header(sample, f);
int b;
if ( limit_xm_resize( lf, extra.sample_header_size ) < 0 ) {
dumbfile_close( lf );
free( roguebytes );
_dumb_it_unload_sigdata( sigdata );
return NULL;
}
b = it_xm_read_sample_header(sample, lf);
if (b < 0) {
free(roguebytes);
_dumb_it_unload_sigdata(sigdata);
@ -1055,6 +1237,8 @@ static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f, int * version)
}
total_samples += extra.n_samples;
}
dumbfile_close( lf );
}
sigdata->n_samples = total_samples;

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "4090"
#define ZD_SVN_REVISION_NUMBER 4090
#define ZD_SVN_REVISION_STRING "4100"
#define ZD_SVN_REVISION_NUMBER 4100