shithub: dumb

Download patch

ref: 73da922bddede1f81fffc7e5e895cace755b378d
parent: 0994e9948c6ca6b2d50e1e5e4ac87b8371764b7f
author: Chris Moeller <kode54@gmail.com>
date: Wed Jan 16 17:03:01 EST 2013

Implemented support for the obscure S9F sample reverse effect

--- a/dumb/include/internal/it.h
+++ b/dumb/include/internal/it.h
@@ -469,6 +469,7 @@
 #define IT_PLAYING_SUSTAINOFF 2
 #define IT_PLAYING_FADING     4
 #define IT_PLAYING_DEAD       8
+#define IT_PLAYING_REVERSE    16
 
 struct IT_PLAYING
 {
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -1022,6 +1022,15 @@
 
 
 
+static void it_pickup_stop_after_reverse(DUMB_RESAMPLER *resampler, void *data)
+{
+    (void)data;
+
+    resampler->dir = 0;
+}
+
+
+
 static void it_playing_update_resamplers(IT_PLAYING *playing)
 {
 	if ((playing->sample->flags & IT_SAMPLE_SUS_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF)) {
@@ -1042,8 +1051,13 @@
 			playing->resampler.pickup = &it_pickup_pingpong_loop;
 		else
 			playing->resampler.pickup = &it_pickup_loop;
-	} else {
-		if (playing->sample->flags & IT_SAMPLE_SUS_LOOP)
+    } else if (playing->flags & IT_PLAYING_REVERSE) {
+        playing->resampler.start = 0;
+        playing->resampler.end = playing->sample->length;
+        playing->resampler.dir = -1;
+        playing->resampler.pickup = &it_pickup_stop_after_reverse;
+    } else {
+        if (playing->sample->flags & IT_SAMPLE_SUS_LOOP)
 			playing->resampler.start = playing->sample->sus_loop_start;
 		else
 			playing->resampler.start = 0;
@@ -2871,7 +2885,13 @@
 								channel->playing->panbrello_depth = 0;
 							break;
 						case IT_S_SET_SURROUND_SOUND:
-							if ((effectvalue & 15) == 1) {
+                            if ((effectvalue & 15) == 15) {
+                                if (channel->playing && channel->playing->sample &&
+                                    !(channel->playing->sample->flags & (IT_SAMPLE_LOOP | IT_SAMPLE_SUS_LOOP))) {
+                                    channel->playing->flags |= IT_PLAYING_REVERSE;
+                                    it_playing_reset_resamplers( channel->playing, channel->playing->sample->length - 1 );
+                                }
+                            } else if ((effectvalue & 15) == 1) {
 								channel->pan = IT_SURROUND;
 								channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
 							}