ref: 7def196332594817f94138dce2942007d232d407
parent: f5f34570905e87f1933a0220d71d0d48c05b9b49
author: Chris Moeller <kode54@gmail.com>
date: Wed Mar 23 01:45:50 EDT 2011
- Corrected volume slide behavior for S3M playback, and also adjusted the slide volume level clipping range for S3M to 0-63 - Updated S3M playback to share memory between DEFIJQRS effects - Adjusted S3M reader to a lower master volume level scale - Version is now 0.9.9.36 git-tfs-id: [http://localhost:8080/tfs/DefaultCollection/]$/foobar2000/files/plugins.root;C668
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -1101,10 +1101,11 @@
}
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;
}
@@ -1267,8 +1268,14 @@
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:
@@ -2025,24 +2032,43 @@
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;
@@ -2080,6 +2106,10 @@
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;
@@ -2111,6 +2141,10 @@
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;
@@ -2184,13 +2218,20 @@
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);
@@ -2202,9 +2243,15 @@
* 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;
@@ -2343,11 +2390,16 @@
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) {
@@ -2372,14 +2424,24 @@
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;
--- a/dumb/src/it/reads3m.c
+++ b/dumb/src/it/reads3m.c
@@ -557,8 +557,8 @@
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);