Skip to content

Commit

Permalink
Changed XM effect L to behave correctly. (#56)
Browse files Browse the repository at this point in the history
The XM `Lxx` effect sets the *tick* of the envelopes, but MikMod
previously set the point instead. This predictably lead to bugs of
varying degrees in modules relying on this effect.
See: `Graff/ant attack.xm` on Modland or `villgust.xm` in issue #56
for particularly egregious examples. (Commit message by @AliceLR.)
  • Loading branch information
neumatho committed Oct 9, 2021
1 parent a618e6d commit f1562b1
Showing 1 changed file with 31 additions and 5 deletions.
36 changes: 31 additions & 5 deletions libmikmod/playercode/mplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,30 @@ static SWORD ProcessEnvelope(MP_VOICE *aout, ENVPR *t, SWORD v)
return v;
}

/* Set envelope tick to the position given */
static void SetEnvelopePosition(ENVPR *t, ENVPT *p, SWORD pos)
{
if (t->pts > 0) {
UWORD i;

for (i = 0; i < t->pts - 1; i++) {

if ((pos >= p[i].pos) && (pos < p[i + 1].pos)) {
t->a = i;
t->b = i + 1;
t->p = pos;
return;
}
}

/* If position is after the last envelope point, just set
it to the last one */
t->a = t->pts - 1;
t->b = t->pts;
t->p = p[t->a].pos;
}
}

/* XM linear period to frequency conversion */
ULONG getfrequency(UWORD flags,ULONG period)
{
Expand Down Expand Up @@ -1583,18 +1607,20 @@ static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR

dat=UniGetByte();
if ((!tick)&&(a->main.i)) {
UWORD points;
INSTRUMENT *i=a->main.i;
MP_VOICE *aout;

if ((aout=a->slave) != NULL) {
if (aout->venv.env) {
points=i->volenv[i->volpts-1].pos;
aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos;
SetEnvelopePosition(&aout->venv, i->volenv, dat);
}
if (aout->penv.env) {
points=i->panenv[i->panpts-1].pos;
aout->penv.p=aout->penv.env[(dat>points)?points:dat].pos;
/* Because of a bug in FastTracker II, only the panning envelope
position is set if the volume sustain flag is set. Other players
may set the panning all the time */
if (!(mod->flags & UF_FT2QUIRKS) || (i->volflg & EF_SUSTAIN)) {
SetEnvelopePosition(&aout->penv, i->panenv, dat);
}
}
}
}
Expand Down

0 comments on commit f1562b1

Please sign in to comment.