shithub: dumb

Download patch

ref: e34d68685d2e5e8b45f62acdaf8157872624620c
parent: c0fc19ef2e756ef25aa44ca3775b4afed3f02c9c
author: Chris Moeller <kode54@gmail.com>
date: Thu Jan 13 19:10:44 EST 2011

2011-01-13 23:11 UTC - kode54
- Implemented ASYLUM instrument base semitone offset
- Fixed ASYLUM effect number translation
- Version is now 0.9.9.28

2011-01-13 21:28 UTC - kode54
- Quick fix for PT2 invert loop effect
- Version is now 0.9.9.27

2011-01-13 20:37 UTC - kode54
- Implemented PT2 invert loop effect
- Version is now 0.9.9.26

git-tfs-id: [http://localhost:8080/tfs/DefaultCollection/]$/foobar2000/files/plugins.root;C545

--- a/dumb/include/internal/it.h
+++ b/dumb/include/internal/it.h
@@ -641,6 +641,10 @@
 	unsigned char xm_lastX1;
 	unsigned char xm_lastX2;
 
+	unsigned char inv_loop_delay;
+	unsigned char inv_loop_speed;
+	int inv_loop_offset;
+
 	IT_PLAYING *playing;
 
 #ifdef BIT_ARRAY_BULLSHIT
@@ -798,6 +802,7 @@
 #define XM_E_NOTE_CUT              0xC
 #define XM_E_NOTE_DELAY            0xD
 #define XM_E_PATTERN_DELAY         0xE
+#define XM_E_SET_MIDI_MACRO        0xF
 
 #define XM_X_EXTRAFINE_PORTA_UP    1
 #define XM_X_EXTRAFINE_PORTA_DOWN  2
--- a/dumb/src/it/itrender.c
+++ b/dumb/src/it/itrender.c
@@ -258,6 +258,10 @@
 	dst->xm_lastX1 = src->xm_lastX1;
 	dst->xm_lastX2 = src->xm_lastX2;
 
+	dst->inv_loop_delay = src->inv_loop_delay;
+	dst->inv_loop_speed = src->inv_loop_speed;
+	dst->inv_loop_offset = src->inv_loop_offset;
+
 	dst->playing = dup_playing(src->playing, dst, src);
 
 
@@ -1026,7 +1030,34 @@
 }
 
 
+static const unsigned char pt_tab_invloop[16] =
+{
+	0x00, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0D,
+	0x0F, 0x13, 0x16, 0x1A, 0x20, 0x2B, 0x40, 0x80
+};
 
+static void update_invert_loop(IT_CHANNEL *channel, IT_SAMPLE *sample)
+{
+	channel->inv_loop_delay += pt_tab_invloop[channel->inv_loop_speed];
+	if (channel->inv_loop_delay >= 0x80)
+	{
+		channel->inv_loop_delay = 0;
+
+		if (sample && ((sample->flags & (IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP)) == (IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP)) && !(sample->flags & (IT_SAMPLE_STEREO | IT_SAMPLE_16BIT)))
+		{
+			if (sample->loop_end - sample->loop_start >= 4)
+			{
+				channel->inv_loop_offset++;
+				if (channel->inv_loop_offset >= (sample->loop_end - sample->loop_start)) channel->inv_loop_offset = 0;
+
+				((char *)sample->data)[sample->loop_start + channel->inv_loop_offset] ^= 0xFF;
+			}
+		}
+	}
+}
+
+
+
 static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
 {
 	int i;
@@ -1121,6 +1152,8 @@
 
 		update_retrig(sigrenderer, channel);
 
+		if (channel->inv_loop_speed) update_invert_loop(channel, playing ? playing->sample : NULL);
+
 		if (playing) {
 			playing->slide += channel->portamento;
 
@@ -2520,7 +2553,10 @@
 							}
 							break;
 						case IT_S_SET_MIDI_MACRO:
-							channel->SFmacro = effectvalue & 15;
+							if ((sigdata->flags & (IT_WAS_AN_XM | IT_WAS_A_MOD)) == (IT_WAS_AN_XM | IT_WAS_A_MOD)) {
+								channel->inv_loop_speed = effectvalue & 15;
+								update_invert_loop(channel, channel->playing ? channel->playing->sample : NULL);
+							} else channel->SFmacro = effectvalue & 15;
 							break;
 					}
 				}
@@ -2919,6 +2955,7 @@
 	if (entry->mask & IT_ENTRY_INSTRUMENT) {
 		int oldsample = channel->sample;
 		int oldvolume = channel->volume;
+		channel->inv_loop_offset = 0;
 		channel->instrument = entry->instrument;
 		instrument_to_sample(sigdata, channel);
 		if (channel->playing &&
@@ -4889,6 +4926,9 @@
 		channel->xm_lastEB = 0;
 		channel->xm_lastX1 = 0;
 		channel->xm_lastX2 = 0;
+		channel->inv_loop_delay = 0;
+		channel->inv_loop_speed = 0;
+		channel->inv_loop_offset = 0;
 		channel->playing = NULL;
 #ifdef BIT_ARRAY_BULLSHIT
 		channel->played_patjump = NULL;
--- a/dumb/src/it/readasy.c
+++ b/dumb/src/it/readasy.c
@@ -71,7 +71,7 @@
 					entry->mask |= IT_ENTRY_INSTRUMENT;
 				}
 
-				_dumb_it_xm_convert_effect( buffer[ pos + 2 ] & 0x0F, buffer[ pos + 3 ], entry, 1 );
+				_dumb_it_xm_convert_effect( buffer[ pos + 2 ], buffer[ pos + 3 ], entry, 1 );
 
 				if ( entry->mask ) ++entry;
 			}
@@ -90,7 +90,7 @@
 
 static int it_asy_read_sample_header( IT_SAMPLE *sample, DUMBFILE *f )
 {
-	int finetune;
+	int finetune, key_offset;
 
 /**
      21       22   Chars     Sample 1 name.  If the name is not a full
@@ -111,7 +111,7 @@
 	sample->default_volume = dumbfile_getc( f ); // Should we be setting global_volume to this instead?
 	sample->global_volume = 64;
 	if ( sample->default_volume > 64 ) sample->default_volume = 64;
-	dumbfile_skip( f, 1 ); /* XXX unknown */
+	key_offset = ( signed char ) dumbfile_getc( f ); /* base key offset */
 	sample->length = dumbfile_igetl( f );
 	sample->loop_start = dumbfile_igetl( f );
 	sample->loop_end = sample->loop_start + dumbfile_igetl( f );
@@ -124,7 +124,7 @@
 	sample->flags = IT_SAMPLE_EXISTS;
 
 	sample->default_pan = 0;
-	sample->C5_speed = (int)( AMIGA_CLOCK / 214.0 );//( long )( 16726.0 * pow( DUMB_PITCH_BASE, finetune * 32 ) );
+	sample->C5_speed = (int)( AMIGA_CLOCK / 214.0 * pow( DUMB_SEMITONE_BASE, key_offset ) );//( long )( 16726.0 * pow( DUMB_PITCH_BASE, finetune * 32 ) );
 	sample->finetune = finetune * 32;
 	// the above line might be wrong
 
--- a/dumb/src/it/xmeffect.c
+++ b/dumb/src/it/xmeffect.c
@@ -188,6 +188,7 @@
 		case EBASE+XM_E_SET_PANNING:           effect = SBASE+IT_S_SET_PAN;               break;
 		case EBASE+XM_E_FINE_VOLSLIDE_UP:      effect = IT_XM_FINE_VOLSLIDE_UP;           break;
 		case EBASE+XM_E_FINE_VOLSLIDE_DOWN:    effect = IT_XM_FINE_VOLSLIDE_DOWN;         break;
+		case EBASE+XM_E_SET_MIDI_MACRO:        effect = SBASE+IT_S_SET_MIDI_MACRO;        break;
 
 		case EBASE + XM_E_FINE_PORTA_UP:
 			effect = IT_PORTAMENTO_UP;