[Scummvm-cvs-logs] SF.net SVN: scummvm:[41410] scummvm/branches/gsoc2009-mods

nolange at users.sourceforge.net nolange at users.sourceforge.net
Tue Jun 9 22:54:55 CEST 2009


Revision: 41410
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41410&view=rev
Author:   nolange
Date:     2009-06-09 20:54:55 +0000 (Tue, 09 Jun 2009)

Log Message:
-----------
tfmx.c,.h: added portamento and envelope-effect (envelope not active yet)
	renamed some variables
	made sure the fixed-point multiplications have the same results, even in cornercases
paula.cpp: changed/reverted stuff in Paula again.

Modified Paths:
--------------
    scummvm/branches/gsoc2009-mods/sound/mods/paula.cpp
    scummvm/branches/gsoc2009-mods/sound/mods/tfmx.cpp
    scummvm/branches/gsoc2009-mods/sound/mods/tfmx.h
    scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.cpp
    scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.h

Modified: scummvm/branches/gsoc2009-mods/sound/mods/paula.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/paula.cpp	2009-06-09 19:37:24 UTC (rev 41409)
+++ scummvm/branches/gsoc2009-mods/sound/mods/paula.cpp	2009-06-09 20:54:55 UTC (rev 41410)
@@ -147,6 +147,7 @@
 				_voice[voice].data = data = _voice[voice].dataRepeat;
 				_voice[voice].length = _voice[voice].lengthRepeat;
 				sLen = intToFrac(_voice[voice].length);
+				// TODO: the value in offset shouldnt be dropped but scaled to new rate
 
 				if (_voice[voice].period != _voice[voice].periodRepeat) {
 					_voice[voice].period = _voice[voice].periodRepeat;
@@ -162,6 +163,7 @@
 
 				// Repeat as long as necessary.
 				while (neededSamples > 0) {
+					// TODO offset -= sLen, but only if same rate otherwise need to scale first
 					offset &= FRAC_LO_MASK;
 					dmaCount++;
 
@@ -172,12 +174,6 @@
 				}
 			}
 
-			// TODO correctly handle setting registers after last 2 bytes red from channel
-			if (offset > sLen) {
-				offset &= FRAC_LO_MASK;
-				dmaCount++;
-			}
-
 			// Write back the cached data
 			_voice[voice].offset = offset;
 			_voice[voice].dmaCount = dmaCount;

Modified: scummvm/branches/gsoc2009-mods/sound/mods/tfmx.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/tfmx.cpp	2009-06-09 19:37:24 UTC (rev 41409)
+++ scummvm/branches/gsoc2009-mods/sound/mods/tfmx.cpp	2009-06-09 20:54:55 UTC (rev 41410)
@@ -79,15 +79,13 @@
 
 		// see if we have to run the macro-program
 		if (channel.macroRun) {
-			if (channel.macroWait == 0) {
+			if (!channel.macroWait) {
 				// run macro
 				while (macroStep(channel))
 					;
 			} else
 				--channel.macroWait;
 		}
-		// FIXME handle Volume
-		Paula::setChannelVolume(channel.paulaChannel, 0x40);
 	}
 
 	// Patterns are only processed each _playerCtx.timerCount + 1 tick
@@ -114,22 +112,72 @@
 	// vibrato
 	if (channel.vibLength) {
 		channel.vibValue += channel.vibDelta;
-		const uint16 setPeriod = (channel.period * ((1 << 11) + channel.vibValue)) >> 11;
-
-		if (!channel.portaRate)
-			Paula::setChannelPeriod(channel.paulaChannel, setPeriod);
-
 		if (--channel.vibCount == 0) {
 			channel.vibCount = channel.vibLength;
 			channel.vibDelta = -channel.vibDelta;
 		}
+		if (!channel.portaDelta) {
+			// 16x16 bit multiplication, casts needed for the right results
+			channel.period = (uint16)(((uint32)channel.refPeriod * (uint16)((1 << 11) + channel.vibValue)) >> 11);
+			Paula::setChannelPeriod(channel.paulaChannel, channel.period);
+		}
 	}
 
+	// portamento
+	if (channel.portaDelta && !(--channel.portaCount)) {
+		channel.portaCount = channel.portaSkip;
 
+		bool resetPorta = true;
+		uint16 period = channel.refPeriod;
+		const uint16 portaVal = channel.portaValue;
 
-	// porta
+		if (period > portaVal) {
+			period = ((uint32)period * (uint16)((1 << 8) - channel.portaDelta)) >> 8;
+			resetPorta = (period <= portaVal);
 
+		} else if (period < portaVal) {
+			period = ((uint32)period * (uint16)((1 << 8) + channel.portaDelta)) >> 8;
+			resetPorta = (period >= portaVal);
+		}
+
+		if (resetPorta) {
+			channel.portaDelta = 0;
+			channel.portaValue = channel.refPeriod & 0x7FF;
+		} else {
+			channel.period = period & 0x7FF;
+			Paula::setChannelPeriod(channel.paulaChannel, channel.period);
+		}
+	}
+
 	// envelope
+	if (channel.envSkip && !channel.envCount--) {
+		channel.envCount = channel.envSkip;
+
+		const uint8 endVol = channel.envEndVolume;
+		int8 volume = channel.volume;
+		bool resetEnv = true;
+
+		if (endVol > volume) {
+			volume += channel.envDelta;
+			resetEnv = endVol <= volume;
+		} else {
+			volume -= channel.envDelta;
+			resetEnv = volume < 0 || endVol >= volume;
+		}
+
+		if (resetEnv) {
+			channel.envSkip = 0;
+			volume = endVol;
+		}
+		channel.volume = volume;
+	}
+
+	// Fade
+
+	// Volume
+	// FIXME
+	uint8 finVol = _playerCtx.volume * channel.volume >> 6;
+	Paula::setChannelVolume(channel.paulaChannel, 0x40);
 }
 
 FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) {
@@ -137,7 +185,7 @@
 	++channel.macroStep;
 	//int channelNo = ((byte*)&channel-(byte*)_channelCtx)/sizeof(ChannelContext);
 
-	displayMacroStep(macroPtr);
+	displayMacroStep(macroPtr, channel.paulaChannel, channel.macroIndex);
 
 	int32 temp = 0;
 
@@ -151,7 +199,8 @@
 		channel.deferWait = macroPtr[1] >= 1;
 		if	(channel.deferWait) {
 			// if set, then we expect a DMA On in the same tick.
-			Paula::setChannelPeriod(channel.paulaChannel, 4);
+			channel.period = 4;
+			Paula::setChannelPeriod(channel.paulaChannel, channel.period);
 			Paula::setChannelSampleLen(channel.paulaChannel, 1);
 			// in this state we then need to allow some commands that normally
 			// would halt the macroprogamm to continue instead.
@@ -204,6 +253,7 @@
 		return true;
 
 	case 0x06:	// Jump. Parameters: MacroIndex, MacroStep(W)
+		channel.macroIndex = macroPtr[1] % kMaxMacroOffsets;
 		channel.macroOffset = _macroOffset[macroPtr[1] % kMaxMacroOffsets];
 		channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
 		channel.macroLoopCount = 0xFF;
@@ -223,31 +273,35 @@
 	case 0x09: {	// SetNote. Parameters: Note, Finetune(W)
 		const uint16 noteInt = noteIntervalls[(temp + macroPtr[1]) & 0x3F];
 		const uint16 finetune = READ_BE_UINT16(&macroPtr[2]) + channel.fineTune + (1 << 8);
-		channel.portaDestPeriod = (uint16)((noteInt * finetune) >> 8);
-		if (!channel.portaRate) {
-			channel.period = channel.portaDestPeriod;
-			Paula::setChannelPeriod(channel.paulaChannel, channel.portaDestPeriod);
+		channel.refPeriod = ((uint32)noteInt * finetune >> 8);
+		if (!channel.portaDelta) {
+			channel.period = channel.refPeriod;
+			Paula::setChannelPeriod(channel.paulaChannel, channel.period);
 		}
 		return channel.deferWait;
 	}
 
 	case 0x0A:	// Clear Effects
-		channel.envReset = 0;
+		channel.envSkip = 0;
 		channel.vibLength = 0;
-		channel.portaRate = 0;
+		channel.portaDelta = 0;
 		return true;
 
 	case 0x0B:	// Portamento. Parameters: count, speed
-		macroPtr[1];
-		macroPtr[3];
+		channel.portaSkip = macroPtr[1];
+		channel.portaCount = 1;
+		// if porta is already running, then keep using old value
+		if (!channel.portaDelta)
+			channel.portaValue = channel.refPeriod;
+		channel.portaDelta = READ_BE_UINT16(&macroPtr[2]);
 		return true;
 
 	case 0x0C:	// Vibrato. Parameters: Speed, intensity
 		channel.vibLength = macroPtr[1];
 		channel.vibCount = macroPtr[1] / 2;
 		channel.vibDelta = macroPtr[3];
-		if (!channel.portaRate) {
-			// TODO: unnecessary command?
+		if (!channel.portaDelta) {
+			channel.period = channel.refPeriod;
 			Paula::setChannelPeriod(channel.paulaChannel, channel.period);
 			channel.vibValue = 0;
 		}
@@ -306,10 +360,10 @@
 		return true;
 
 	case 0x17:	// set Period. Parameters: Period(W)
-		channel.portaDestPeriod = READ_BE_UINT16(&macroPtr[2]);
-		if (!channel.portaRate) {
-			channel.period = channel.portaDestPeriod;
-			Paula::setChannelPeriod( channel.paulaChannel, channel.portaDestPeriod);
+		channel.refPeriod = READ_BE_UINT16(&macroPtr[2]);
+		if (!channel.portaDelta) {
+			channel.period = channel.refPeriod;
+			Paula::setChannelPeriod(channel.paulaChannel, channel.period);
 		}
 		return true;
 
@@ -484,6 +538,7 @@
 			return false;
 
 		case 5: 	// Kup^-Set key up
+			// TODO: add expose?
 		case 6: 	// Vibrato
 		case 7: 	// Envelope
 		case 12: 	// Lock
@@ -606,6 +661,7 @@
 	if (note < 0xC0) {	// Play Note
 		channel.prevNote = channel.note;
 		channel.note = note;
+		channel.macroIndex = param1 % kMaxMacroOffsets;
 		channel.macroOffset = _macroOffset[param1 % kMaxMacroOffsets];
 		channel.relVol = (param2 >> 4) & 0xF;
 		channel.fineTune = (int16)param3;
@@ -613,15 +669,15 @@
 		initMacroProgramm(channel);
 		channel.keyUp = true;
 		
-	} else if (note < 0xF0) {	// do that porta stuff
-		channel.portaReset = param1;
-		channel.portaTime = 1;
-		if (!channel.portaRate)
-			channel.portaPeriod = channel.portaDestPeriod;
-		channel.portaRate = param3;
+	} else if (note < 0xF0) {	// Portamento
+		channel.portaSkip = param1;
+		channel.portaCount = 1;
+		if (!channel.portaDelta)
+			channel.portaValue = channel.refPeriod;
+		channel.portaDelta = param3;
 
 		channel.note = note & 0x3F;
-		channel.portaDestPeriod = noteIntervalls[channel.note];
+		channel.refPeriod = noteIntervalls[channel.note];
 	} else switch (note & 0xF) {	// Command
 		case 5:	// Key Up Release
 			channel.keyUp = false;
@@ -632,8 +688,8 @@
 			channel.vibValue = 0;
 			break;
 		case 7:	// Envelope
-			channel.envRate = param1;
-			channel.envReset = channel.envTime = (param2 >> 4) + 1;
+			channel.envDelta = param1;
+			channel.envSkip = channel.envCount = (param2 >> 4) + 1;
 			channel.envEndVolume = param3;
 			break;
 	}

Modified: scummvm/branches/gsoc2009-mods/sound/mods/tfmx.h
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/tfmx.h	2009-06-09 19:37:24 UTC (rev 41409)
+++ scummvm/branches/gsoc2009-mods/sound/mods/tfmx.h	2009-06-09 20:54:55 UTC (rev 41410)
@@ -118,6 +118,7 @@
 	struct ChannelContext {
 		byte	paulaChannel;
 
+		byte	macroIndex;
 		uint16	macroWait;
 		uint32	macroOffset;
 		uint32	macroReturnOffset;
@@ -136,23 +137,23 @@
 
 		uint32	sampleStart;
 		uint16	sampleLen;
+		uint16	refPeriod;
 		uint16	period;
 
-		int8	volume;
+		uint8	volume;
 		uint8	relVol;
 		uint8	note;
 		uint8	prevNote;
 		int16	fineTune;
 
-		uint16	portaDestPeriod;
-		uint16	portaPeriod;
-		uint8	portaReset;
-		uint8	portaTime;
-		int16	portaRate;
+		uint8	portaSkip;
+		uint8	portaCount;
+		uint16	portaDelta;
+		uint16	portaValue;
 
-		uint8	envReset;
-		uint8	envTime;
-		uint8	envRate;
+		uint8	envSkip;
+		uint8	envCount;
+		uint8	envDelta;
 		uint8	envEndVolume;
 
 		uint8	vibLength;
@@ -211,11 +212,11 @@
 	}
 
 	void clearEffects(ChannelContext &channel) {
-		channel.envReset = 0;
+		channel.envSkip = 0;
 
 		channel.vibLength = 0;
 
-		channel.portaRate = 0;
+		channel.portaDelta = 0;
 	}
 
 	void stopChannel(ChannelContext &channel) {

Modified: scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.cpp	2009-06-09 19:37:24 UTC (rev 41409)
+++ scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.cpp	2009-06-09 20:54:55 UTC (rev 41410)
@@ -120,6 +120,15 @@
 	}
 }
 
+void displayMacroStep(const void *const vptr, int chan, int index) {
+	const byte *const macroData = (const byte *const)vptr;
+
+	if (macroData[0] < ARRAYSIZE(macrocmds))
+		debug("%02X %02X %s %02X%02X%02X", chan, index, macrocmds[macroData[0]], macroData[1], macroData[2], macroData[3]);
+	else
+		debug("%02X %02X Unkown Macro #%02X %02X%02X%02X", chan, index, macroData[0], macroData[1], macroData[2], macroData[3]);
+}
+
 void displayMacroStep(const void *const vptr) {
 	const byte *const macroData = (const byte *const)vptr;
 

Modified: scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.h
===================================================================
--- scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.h	2009-06-09 19:37:24 UTC (rev 41409)
+++ scummvm/branches/gsoc2009-mods/tfmx/tfmxdebug.h	2009-06-09 20:54:55 UTC (rev 41410)
@@ -4,6 +4,7 @@
 void displayTrackstep(const void *const vptr);
 void displayPatternstep(const void *const vptr);
 void displayMacroStep(const void *const vptr);
+void displayMacroStep(const void *const vptr, int chan, int index);
 void dumpTracksteps(Audio::Tfmx &player, uint16 first, uint16 last);
 void dumpTrackstepsBySong(Audio::Tfmx &player, int song);
 void dumpMacro(Audio::Tfmx &player, uint16 macroIndex, uint16 len = 0, uint16 start = 0);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list