* 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) 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; IT_PLAYING *playing = channel->playing;
if (playing) { if (playing) {
playing->vibrato_time += playing->vibrato_n * update_smooth_effects_playing(playing);
(playing->vibrato_speed << 2); }
playing->tremolo_time += playing->tremolo_speed << 2; }
playing->panbrello_time += playing->panbrello_speed;
if (playing->panbrello_waveform == 3) for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
playing->panbrello_random = (rand() % 129) - 64; 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) static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
{ {
int i; int i, j;
if (sigrenderer->globalvolslide) { if (sigrenderer->globalvolslide) {
sigrenderer->globalvolume += sigrenderer->globalvolslide; sigrenderer->globalvolume += sigrenderer->globalvolslide;
@ -1167,6 +1179,10 @@ static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
} }
if (channel->playing) if (channel->playing)
channel->playing->channel_volume = channel->channelvolume; 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); 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 (channel->inv_loop_speed) update_invert_loop(channel, playing ? playing->sample : NULL);
if (playing) { for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
playing->slide += channel->portamento; 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) {
if (channel->okt_toneslide--) { if (channel->okt_toneslide--) {
playing->note += channel->toneslide; if (playing) {
if (playing->note >= 120) { playing->note += channel->toneslide;
if (channel->toneslide < 0) playing->note = 0; if (playing->note >= 120) {
else playing->note = 119; 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) { } else if (channel->ptm_toneslide) {
if (--channel->toneslide_tick == 0) { if (--channel->toneslide_tick == 0) {
channel->toneslide_tick = channel->ptm_toneslide; channel->toneslide_tick = channel->ptm_toneslide;
playing->note += channel->toneslide; if (playing) {
if (playing->note >= 120) { playing->note += channel->toneslide;
if (channel->toneslide < 0) playing->note = 0; if (playing->note >= 120) {
else playing->note = 119; if (channel->toneslide < 0) playing->note = 0;
} else playing->note = 119;
channel->note = channel->truenote = playing->note; }
if (channel->toneslide_retrig) { channel->note = channel->truenote = playing->note;
it_playing_reset_resamplers(playing, 0); if (channel->toneslide_retrig) {
it_playing_reset_resamplers(playing, 0);
#ifdef END_RAMPING #ifdef END_RAMPING
playing->declick_stage = 0; playing->declick_stage = 0;
playing->declick_volume = 1.f / 256.f; playing->declick_volume = 1.f / 256.f;
#endif #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 (playing) {
if (channel->toneporta && channel->destnote < 120) { if (sigrenderer->sigdata->flags & IT_LINEAR_SLIDES) {
int currpitch = ((playing->note - 60) << 8) + playing->slide; if (channel->toneporta && channel->destnote < 120) {
int destpitch = (channel->destnote - 60) << 8; int currpitch = ((playing->note - 60) << 8) + playing->slide;
if (currpitch > destpitch) { int destpitch = (channel->destnote - 60) << 8;
currpitch -= channel->toneporta;
if (currpitch < destpitch) {
currpitch = destpitch;
channel->destnote = IT_NOTE_OFF;
}
} else if (currpitch < destpitch) {
currpitch += channel->toneporta;
if (currpitch > destpitch) { if (currpitch > destpitch) {
currpitch = destpitch; currpitch -= channel->toneporta;
channel->destnote = IT_NOTE_OFF; 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) {
} else { float amiga_multiplier = playing->sample->C5_speed * (1.0f / AMIGA_DIVISOR);
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); float deltanote = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note);
/* deltanote is 1.0 for C-5, 0.5 for C-6, etc. */ /* 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); 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;
if (deltaslid < destdelta) { if (deltaslid < destdelta) {
playing->note = channel->destnote; playing->slide -= channel->toneporta;
playing->slide = 0; deltaslid = deltanote - playing->slide * amiga_multiplier;
channel->destnote = IT_NOTE_OFF; 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; nna = channel->playing->instrument->new_note_action;
#endif #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_PLAYING * playing = channel->playing;
IT_INSTRUMENT * inst = &sigdata->instrument[channel->instrument-1]; IT_INSTRUMENT * inst = &sigdata->instrument[channel->instrument-1];
if ((playing->enabled_envelopes & IT_ENV_VOLUME) && (inst->volume_envelope.flags & IT_ENVELOPE_CARRY)) { 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) { if (!flags && sigdata->flags & IT_USE_INSTRUMENTS) {
for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
IT_PLAYING * playing = sigrenderer->playing[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]; IT_INSTRUMENT * inst = &sigdata->instrument[channel->instrument-1];
if ((playing->enabled_envelopes & IT_ENV_VOLUME) && (inst->volume_envelope.flags & IT_ENVELOPE_CARRY)) { if ((playing->enabled_envelopes & IT_ENV_VOLUME) && (inst->volume_envelope.flags & IT_ENVELOPE_CARRY)) {
flags |= 1; flags |= 1;
@ -1974,10 +2032,19 @@ static void xm_envelope_calculate_value(IT_ENVELOPE *envelope, IT_PLAYING_ENVELO
extern const char xm_convert_vibrato[]; 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. */ /* Returns 1 if a callback caused termination of playback. */
static int process_effects(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry, int ignore_cxx) static int process_effects(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry, int ignore_cxx)
{ {
DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
IT_PLAYING *playing;
int i;
IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; 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; break;
case IT_VOLSLIDE_VIBRATO: case IT_VOLSLIDE_VIBRATO:
if (channel->playing) { for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
channel->playing->vibrato_speed = channel->lastHspeed; if (i < 0) playing = channel->playing;
channel->playing->vibrato_depth = channel->lastHdepth; else {
channel->playing->vibrato_n++; 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. */ /* Fall through and process volume slide. */
case IT_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; v = channel->lastEF;
channel->lastEF = v; channel->lastEF = v;
} }
if (channel->playing) { for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if ((v & 0xF0) == 0xF0) if (i < 0) playing = channel->playing;
channel->playing->slide -= (v & 15) << 4; else {
else if ((v & 0xF0) == 0xE0) playing = sigrenderer->playing[i];
channel->playing->slide -= (v & 15) << 2; if (!playing || playing->channel != channel) continue;
else if (sigdata->flags & IT_WAS_A_669) }
channel->portamento -= v << 3; if (playing) {
else if ((v & 0xF0) == 0xF0)
channel->portamento -= v << 4; 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; break;
@ -2168,15 +2249,22 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
v = channel->lastEF; v = channel->lastEF;
channel->lastEF = v; channel->lastEF = v;
} }
if (channel->playing) { for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
if ((v & 0xF0) == 0xF0) if (i < 0) playing = channel->playing;
channel->playing->slide += (v & 15) << 4; else {
else if ((v & 0xF0) == 0xE0) playing = sigrenderer->playing[i];
channel->playing->slide += (v & 15) << 2; if (!playing || playing->channel != channel) continue;
else if (sigdata->flags & IT_WAS_A_669) }
channel->portamento += v << 3; if (channel->playing) {
else if ((v & 0xF0) == 0xF0)
channel->portamento += v << 4; 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; break;
@ -2219,16 +2307,23 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
if (depth == 0) if (depth == 0)
depth = channel->lastHdepth; depth = channel->lastHdepth;
else { else {
if (sigdata->flags & IT_OLD_EFFECTS) if (sigdata->flags & IT_OLD_EFFECTS && !(sigdata->flags & IT_WAS_A_MOD))
depth <<= 3; depth <<= 3;
else else
depth <<= 2; depth <<= 2;
channel->lastHdepth = depth; channel->lastHdepth = depth;
} }
if (channel->playing) { for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
channel->playing->vibrato_speed = speed; if (i < 0) playing = channel->playing;
channel->playing->vibrato_depth = depth; else {
channel->playing->vibrato_n++; 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 else
channel->channelvolume = 64; channel->channelvolume = 64;
#endif #endif
if (channel->playing) for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
channel->playing->channel_volume = channel->channelvolume; 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; break;
case IT_CHANNEL_VOLUME_SLIDE: 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; if (channel->channelvolume > 64) channel->channelvolume = 0;
} else } else
break; break;
if (channel->playing) for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
channel->playing->channel_volume = channel->channelvolume; 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; break;
@ -2460,9 +2569,16 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
depth = channel->lastRdepth; depth = channel->lastRdepth;
channel->lastRdepth = depth; channel->lastRdepth = depth;
} }
if (channel->playing) { for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
channel->playing->tremolo_speed = speed; if (i < 0) playing = channel->playing;
channel->playing->tremolo_depth = depth; else {
playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
playing->tremolo_speed = speed;
playing->tremolo_depth = depth;
}
} }
} }
break; break;
@ -2491,7 +2607,8 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
case IT_S_SET_VIBRATO_WAVEFORM: case IT_S_SET_VIBRATO_WAVEFORM:
{ {
int waveform = effectvalue & 3; 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; channel->vibrato_waveform = waveform;
if (channel->playing) { if (channel->playing) {
channel->playing->vibrato_waveform = waveform; 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: case IT_S_SET_TREMOLO_WAVEFORM:
{ {
int waveform = effectvalue & 3; 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; channel->tremolo_waveform = waveform;
if (channel->playing) { if (channel->playing) {
channel->playing->tremolo_waveform = waveform; channel->playing->tremolo_waveform = waveform;
@ -2681,10 +2799,17 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than
depth <<= 1; depth <<= 1;
channel->lastHdepth = depth; channel->lastHdepth = depth;
} }
if (channel->playing) { for (i = -1; i < DUMB_IT_N_NNA_CHANNELS; i++) {
channel->playing->vibrato_speed = speed; if (i < 0) playing = channel->playing;
channel->playing->vibrato_depth = depth; else {
channel->playing->vibrato_n++; playing = sigrenderer->playing[i];
if (!playing || playing->channel != channel) continue;
}
if (playing) {
playing->vibrato_speed = speed;
playing->vibrato_depth = depth;
playing->vibrato_n++;
}
} }
} }
break; 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. */ /* 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) 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; return 0;
ASSERT(envelope->n_nodes > 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; vol = (rand() % 129) - 64;
break; break;
case 4: case 4:
vol = it_xm_squarewave[playing->vibrato_time]; vol = it_xm_squarewave[playing->tremolo_time];
break; break;
case 5: case 5:
vol = it_xm_ramp[playing->vibrato_time]; vol = it_xm_ramp[playing->tremolo_time];
break; break;
case 6: 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; break;
} }
vol *= playing->tremolo_depth; 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); volume *= 1.0f / ((64 << 5) * 64.0f * 64.0f * 128.0f * 128.0f);
if (volume && playing->instrument) { 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 *= envelope_get_y(&playing->env_instrument->volume_envelope, &playing->volume_envelope);
volume *= 1.0f / (64 << IT_ENVELOPE_SHIFT); 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. */ /* Work out how many patterns there are. */
sigdata->n_patterns = -1; 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]) if (sigdata->n_patterns < sigdata->order[i])
sigdata->n_patterns = sigdata->order[i]; sigdata->n_patterns = sigdata->order[i];
sigdata->n_patterns++; sigdata->n_patterns++;

View file

@ -497,7 +497,7 @@ static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f, int restrict)
j++; j++;
} }
} }
for (; i < sigdata->n_samples; i++) { for (; i < (unsigned)sigdata->n_samples; i++) {
sigdata->sample[i].flags = 0; 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 ) { for ( n = 0, q = o / 16; n < sigdata->n_samples; ++n ) {
if ( sample_offset[ 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_sweep; /* 0-0xFF */
int vibrato_depth; /* 0-0x0F */ int vibrato_depth; /* 0-0x0F */
int vibrato_speed; /* 0-0x3F */ int vibrato_speed; /* 0-0x3F */
int sample_header_size;
} }
XM_INSTRUMENT_EXTRA; 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) static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA *extra, DUMBFILE *f)
{ {
uint32 size, bytes_read; uint32 size, bytes_read;
unsigned short vol_points[24]; unsigned short vol_points[24];
unsigned short pan_points[24]; unsigned short pan_points[24];
int i, type; 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. /* Header size. Tends to be more than the actual size of the structure.
* So unread bytes must be skipped before reading the first sample * So unread bytes must be skipped before reading the first sample
* header. * header.
*/ */
if ( limit_xm_resize( f, 4 ) < 0 ) return -1;
size = dumbfile_igetl(f); 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); dumbfile_getnc(instrument->name, 22, f);
instrument->name[22] = 0; instrument->name[22] = 0;
instrument->filename[0] = 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) { if (extra->n_samples) {
/* sample header size */ /* 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); /*i = dumbfile_igetl(f);
if (i && i != 0x28) { // XXX some crap with 0 here if (!i || i > 0x28) i = 0x28;*/
TRACE("XM error: unexpected sample header size\n"); dumbfile_skip(f, 4);
return -1; i = 0x28;
}*/ extra->sample_header_size = i;
/* sample map */ /* sample map */
for (i = 0; i < 96; i++) { 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++) for (i = 0; i < 96; i++)
instrument->map_sample[i] = 0; 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; return -1;
instrument->new_note_action = NNA_NOTE_CUT; 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++) { for (i = 0; i < sigdata->n_instruments; i++) {
XM_INSTRUMENT_EXTRA extra; 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 // XXX
if ( ! i ) if ( ! i )
{ {
TRACE("XM error: instrument %d\n", i+1); TRACE("XM error: instrument %d\n", i+1);
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata); _dumb_it_unload_sigdata(sigdata);
return NULL; return NULL;
} }
else else
{ {
dumbfile_close( lf );
sigdata->n_instruments = i; sigdata->n_instruments = i;
break; 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)); sigdata->sample = safe_realloc(sigdata->sample, sizeof(*sigdata->sample)*(total_samples+extra.n_samples));
if (!sigdata->sample) { if (!sigdata->sample) {
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata); _dumb_it_unload_sigdata(sigdata);
return NULL; return NULL;
} }
for (j = total_samples; j < total_samples+extra.n_samples; j++) for (j = total_samples; j < total_samples+extra.n_samples; j++)
sigdata->sample[j].data = NULL; 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 */ /* read instrument's samples */
for (j = 0; j < extra.n_samples; j++) { for (j = 0; j < extra.n_samples; j++) {
IT_SAMPLE *sample = &sigdata->sample[total_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) { if (b < 0) {
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata); _dumb_it_unload_sigdata(sigdata);
return NULL; 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++) { for (j = 0; j < extra.n_samples; j++) {
if (it_xm_read_sample_data(&sigdata->sample[total_samples+j], roguebytes[j], f) != 0) { if (it_xm_read_sample_data(&sigdata->sample[total_samples+j], roguebytes[j], f) != 0) {
dumbfile_close( lf );
_dumb_it_unload_sigdata(sigdata); _dumb_it_unload_sigdata(sigdata);
return NULL; return NULL;
} }
} }
total_samples += extra.n_samples; total_samples += extra.n_samples;
} }
dumbfile_close( lf );
} }
sigdata->n_samples = total_samples; 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++) { for (i = 0; i < sigdata->n_instruments; i++) {
XM_INSTRUMENT_EXTRA extra; 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); TRACE("XM error: instrument %d\n", i+1);
dumbfile_close(lf);
free(roguebytes); free(roguebytes);
_dumb_it_unload_sigdata(sigdata); _dumb_it_unload_sigdata(sigdata);
return NULL; 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)); sigdata->sample = safe_realloc(sigdata->sample, sizeof(*sigdata->sample)*(total_samples+extra.n_samples));
if (!sigdata->sample) { if (!sigdata->sample) {
dumbfile_close( lf );
free(roguebytes); free(roguebytes);
_dumb_it_unload_sigdata(sigdata); _dumb_it_unload_sigdata(sigdata);
return NULL; 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++) for (j = total_samples; j < total_samples+extra.n_samples; j++)
sigdata->sample[j].data = NULL; 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 */ /* read instrument's samples */
for (j = 0; j < extra.n_samples; j++) { for (j = 0; j < extra.n_samples; j++) {
IT_SAMPLE *sample = &sigdata->sample[total_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) { if (b < 0) {
free(roguebytes); free(roguebytes);
_dumb_it_unload_sigdata(sigdata); _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; total_samples += extra.n_samples;
} }
dumbfile_close( lf );
} }
sigdata->n_samples = total_samples; sigdata->n_samples = total_samples;

View file

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