shithub: dumb

Download patch

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);