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