Enabled envelope effect, but it still needs some work.

couple more macros implemented, all effects Monkey Island uses should be supported now

svn-id: r41413
This commit is contained in:
Norbert Lange 2009-06-10 00:49:26 +00:00
parent fc174162f7
commit 46c90e08f2
2 changed files with 66 additions and 50 deletions

View File

@ -62,12 +62,12 @@ void Tfmx::interrupt() {
for (int i = 0; i < kNumVoices; ++i) {
ChannelContext &channel = _channelCtx[i];
if (channel.countDmaInterrupts) {
if (channel.dmaIntCount) {
// wait for DMA Interupts to happen
int doneDma = getChannelDmaCount(channel.paulaChannel);
if (doneDma > channel.dmaCount) {
if (doneDma >= channel.dmaIntCount) {
debug("channel %d, DMA done", i);
channel.countDmaInterrupts = false;
channel.dmaIntCount = 0;
channel.macroRun = true;
}
}
@ -153,7 +153,7 @@ void Tfmx::effects(ChannelContext &channel) {
if (channel.envSkip && !channel.envCount--) {
channel.envCount = channel.envSkip;
const uint8 endVol = channel.envEndVolume;
const int8 endVol = channel.envEndVolume;
int8 volume = channel.volume;
bool resetEnv = true;
@ -162,7 +162,7 @@ void Tfmx::effects(ChannelContext &channel) {
resetEnv = endVol <= volume;
} else {
volume -= channel.envDelta;
resetEnv = volume < 0 || endVol >= volume;
resetEnv = volume <= 0 || endVol >= volume;
}
if (resetEnv) {
@ -171,13 +171,23 @@ void Tfmx::effects(ChannelContext &channel) {
}
channel.volume = volume;
}
// Fade
// Volume
// FIXME
uint8 finVol = _playerCtx.volume * channel.volume >> 6;
Paula::setChannelVolume(channel.paulaChannel, 0x40);
Paula::setChannelVolume(channel.paulaChannel, finVol);
}
static void warnMacroUnimplemented(const byte *macroPtr, int level) {
if (level > 0)
return;
if (level == 0)
debug("Warning - Macro not supported:");
else
debug("Warning - Macro not completely supported:");
displayMacroStep(macroPtr);
}
FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) {
@ -185,7 +195,7 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) {
++channel.macroStep;
//int channelNo = ((byte*)&channel-(byte*)_channelCtx)/sizeof(ChannelContext);
displayMacroStep(macroPtr, channel.paulaChannel, channel.macroIndex);
//displayMacroStep(macroPtr, channel.paulaChannel, channel.macroIndex);
int32 temp = 0;
@ -213,7 +223,7 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) {
return true;
case 0x01: // DMA On
channel.countDmaInterrupts = false;
channel.dmaIntCount = 0;
if (channel.deferWait) {
// TODO
// there is actually a small delay in the player, but I think that
@ -263,28 +273,16 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) {
channel.macroRun = false;
return false;
case 0x1F: // AddPrevNote. Parameters: Note, Finetune(W)
temp = channel.prevNote;
goto setNote;
case 0x08: // AddNote. Parameters: Note, Finetune(W)
temp = channel.note;
// Fallthrough to SetNote
setNote:
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.refPeriod = ((uint32)noteInt * finetune >> 8);
if (!channel.portaDelta) {
channel.period = channel.refPeriod;
Paula::setChannelPeriod(channel.paulaChannel, channel.period);
}
setNoteMacro(channel, channel.note + macroPtr[1], READ_BE_UINT16(&macroPtr[2]));
return channel.deferWait;
case 0x09: // SetNote. Parameters: Note, Finetune(W)
setNoteMacro(channel, macroPtr[1], READ_BE_UINT16(&macroPtr[2]));
return channel.deferWait;
}
case 0x0A: // Clear Effects
channel.envSkip = 0;
channel.vibLength = 0;
channel.portaDelta = 0;
clearEffects(channel);
return true;
case 0x0B: // Portamento. Parameters: count, speed
@ -307,20 +305,22 @@ setNote:
}
return true;
case 0x0D: // Add Volume. Parameters: unknown, volume
macroPtr[2];
macroPtr[3];
case 0x0D: // Add Volume. Parameters: note, addNoteFlag, volume
if (macroPtr[2] == 0xFE)
setNoteMacro(channel, channel.note + macroPtr[1], 0);
channel.volume = channel.relVol * 3 + macroPtr[3];
return true;
case 0x0E: // Set Volume. Parameters: unknown, volume
macroPtr[2];
macroPtr[3];
case 0x0E: // Set Volume. Parameters: note, addNoteFlag, volume
if (macroPtr[2] == 0xFE)
setNoteMacro(channel, channel.note + macroPtr[1], 0);
channel.volume = macroPtr[3];
return true;
case 0x0F: // Envelope. Parameters: speed, count, endvol
macroPtr[1];
macroPtr[2];
macroPtr[3];
channel.envDelta = macroPtr[1];
channel.envCount = channel.envSkip = macroPtr[2];
channel.envEndVolume = macroPtr[3];
return true;
case 0x11: // AddBegin. Parameters: times, Offset(W)
@ -329,6 +329,7 @@ setNote:
// debug("prev: %06X, after: %06X", channel.sampleStart, channel.sampleStart + (int16)READ_BE_UINT16(&macroPtr[2]));
channel.sampleStart += (int16)READ_BE_UINT16(&macroPtr[2]);
Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
warnMacroUnimplemented(macroPtr, 1);
return true;
case 0x12: // AddLen. Parameters: added Length(W)
@ -385,8 +386,7 @@ setNote:
return true;
case 0x1A: // Wait on DMA. Parameters: Cycles-1(W) to wait
channel.dmaCount = READ_BE_UINT16(&macroPtr[2]);
channel.countDmaInterrupts = true;
channel.dmaIntCount = READ_BE_UINT16(&macroPtr[2]) + 1;
channel.macroRun = false;
Paula::setChannelDmaCount(channel.paulaChannel);
return channel.deferWait;
@ -395,25 +395,33 @@ setNote:
macroPtr[1];
macroPtr[2];
macroPtr[3];
warnMacroUnimplemented(macroPtr, 0);
return true;
case 0x1C: // Splitkey. Parameters: key/macrostep(W)
macroPtr[1];
READ_BE_UINT16(&macroPtr[2]);
if (channel.note > macroPtr[1])
channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
return true;
case 0x1D: // Splitvolume. Parameters: volume/macrostep
macroPtr[1];
READ_BE_UINT16(&macroPtr[2]);
if (channel.volume > macroPtr[1])
channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
return true;
case 0x1E: // Addvol+note. Parameters: note/CONST./volume
warnMacroUnimplemented(macroPtr, 0);
return true;
case 0x1F: // AddPrevNote. Parameters: Note, Finetune(W)
setNoteMacro(channel, channel.prevNote + macroPtr[1], READ_BE_UINT16(&macroPtr[2]));
return channel.deferWait;
case 0x20: // Signal. Parameters: signalnumber/value
warnMacroUnimplemented(macroPtr, 0);
return true;
case 0x21: // Play macro. Parameters: macro/chan/detune
warnMacroUnimplemented(macroPtr, 0);
return true;
#if defined(TFMX_NOT_IMPLEMENTED)
// used by Gem`X according to the docs
@ -436,6 +444,7 @@ setNote:
// 30-34 used by Carribean Disaster
#endif
default:
warnMacroUnimplemented(macroPtr, 0);
return channel.deferWait;
}
}
@ -526,7 +535,6 @@ FORCEINLINE bool Tfmx::patternStep(PatternContext &pattern) {
case 3: // Wait. Paramters: ticks to wait
pattern.wait = patternPtr[1];
// TODO check for 0?
return false;
case 14: // Stop custompattern

View File

@ -132,15 +132,14 @@ public:
bool keyUp;
bool deferWait;
bool countDmaInterrupts;
uint16 dmaCount;
uint16 dmaIntCount;
uint32 sampleStart;
uint16 sampleLen;
uint16 refPeriod;
uint16 period;
uint8 volume;
int8 volume;
uint8 relVol;
uint8 note;
uint8 prevNote;
@ -154,7 +153,7 @@ public:
uint8 envSkip;
uint8 envCount;
uint8 envDelta;
uint8 envEndVolume;
int8 envEndVolume;
uint8 vibLength;
uint8 vibCount;
@ -208,7 +207,7 @@ public:
channel.macroWait = 0;
channel.macroRun = true;
channel.macroLoopCount = 0xFF;
channel.countDmaInterrupts = false;
channel.dmaIntCount = 0;
}
void clearEffects(ChannelContext &channel) {
@ -222,18 +221,27 @@ public:
void stopChannel(ChannelContext &channel) {
if (!channel.sfxLocked) {
channel.macroRun = false;
channel.countDmaInterrupts = false;
channel.dmaIntCount = 0;
Paula::disableChannel(channel.paulaChannel);
}
}
void setNoteMacro(ChannelContext &channel, uint note, int fineTune) {
const uint16 noteInt = noteIntervalls[note & 0x3F];
const uint16 finetune = (uint16)(fineTune + channel.fineTune + (1 << 8));
channel.refPeriod = ((uint32)noteInt * finetune >> 8);
if (!channel.portaDelta) {
channel.period = channel.refPeriod;
Paula::setChannelPeriod(channel.paulaChannel, channel.period);
}
}
void effects(ChannelContext &channel);
FORCEINLINE bool macroStep(ChannelContext &channel);
void advancePatterns();
FORCEINLINE bool patternStep(PatternContext &pattern);
bool trackStep();
void noteCommand(uint8 note, uint8 param1, uint8 param2, uint8 param3);
};
}