From 29a5c6a45b90e64cf5d618da4cdcd6e6da3425fb Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Wed, 18 Aug 2010 21:38:43 +0000 Subject: SCUMM/FM-TOWNS: start rewriting audio code - Start rewriting audio code for FM-TOWNS versions of Loom, Indy3 and Monkey Island 1 using the recently added code in towns_audio.cpp (Zak should work the same way, but I can't test, since I don't own that one). - All sound types (pcm, euphony and cd audio) now support volume and balance control (e.g. try walking into/out of the kitchen and opening/closing the door in the Scumm Bar in Monkey Island 1 or walking into/out of the circus tent). - Pcm sounds now support proper loop start/end and note offsets (e.g. try out the hammer sound in the forge in LOOM for example). - some other minor improvements - The FM-Towns versions of Indy 4 and Monkey Island 2 are not affected. I don't have Monkey Island 2, but I presume that it will work like Indy 4. Adding support for these will be a separate task, since they work quite differently. svn-id: r52198 --- sound/softsynth/fmtowns_pc98/towns_audio.cpp | 18 +++++++++++++++++- sound/softsynth/fmtowns_pc98/towns_audio.h | 1 + sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp | 10 ++++++++++ sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 12 ++++++++++++ sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h | 10 ++++++---- 5 files changed, 46 insertions(+), 5 deletions(-) (limited to 'sound/softsynth/fmtowns_pc98') diff --git a/sound/softsynth/fmtowns_pc98/towns_audio.cpp b/sound/softsynth/fmtowns_pc98/towns_audio.cpp index 46569dd842..bef062b8e6 100644 --- a/sound/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/sound/softsynth/fmtowns_pc98/towns_audio.cpp @@ -200,7 +200,7 @@ TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfac INTCB(notImpl), // 72 INTCB(notImpl), - INTCB(notImpl), + INTCB(cdaToggle), INTCB(notImpl), INTCB(notImpl), // 76 @@ -222,9 +222,19 @@ TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfac _timerBase = (uint32)(_baserate * 1000000.0f); _tickLength = 2 * _timerBase; + + setTimerCallbackA((ChipTimerProc)&TownsAudioInterface::timerCallbackA); + setTimerCallbackB((ChipTimerProc)&TownsAudioInterface::timerCallbackB); } TownsAudioInterface::~TownsAudioInterface() { + Common::StackLock lock(_mutex); + reset(); + _ready = false; + + setTimerCallbackA(); + setTimerCallbackB(); + delete[] _fmSaveReg[0]; delete[] _fmSaveReg[1]; delete[] _fmInstruments; @@ -759,6 +769,12 @@ int TownsAudioInterface::intf_updateOutputVolume(va_list &args) { return 0; } +int TownsAudioInterface::intf_cdaToggle(va_list &args) { + //int mode = va_arg(args, int); + //_unkMask = mode ? 0x7f : 0x3f; + return 0; +} + int TownsAudioInterface::intf_pcmUpdateEnvelopeGenerator(va_list &args) { for (int i = 0; i < 8; i++) pcmUpdateEnvelopeGenerator(i); diff --git a/sound/softsynth/fmtowns_pc98/towns_audio.h b/sound/softsynth/fmtowns_pc98/towns_audio.h index 950c016b4e..95fb1ded59 100644 --- a/sound/softsynth/fmtowns_pc98/towns_audio.h +++ b/sound/softsynth/fmtowns_pc98/towns_audio.h @@ -95,6 +95,7 @@ private: int intf_setOutputVolume(va_list &args); int intf_resetOutputVolume(va_list &args); int intf_updateOutputVolume(va_list &args); + int intf_cdaToggle(va_list &args); int intf_pcmUpdateEnvelopeGenerator(va_list &args); int intf_notImpl(va_list &args); diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp index 82d0bd0438..6d52937cc6 100644 --- a/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp @@ -1037,11 +1037,21 @@ TownsPC98_AudioDriver::TownsPC98_AudioDriver(Audio::Mixer *mixer, EmuType type) _musicPlaying(false), _sfxPlaying(false), _fading(false), _looping(0), _ready(false) { _sfxOffsets[0] = _sfxOffsets[1] = 0; + + setTimerCallbackA((ChipTimerProc)&TownsPC98_AudioDriver::timerCallbackA); + setTimerCallbackB((ChipTimerProc)&TownsPC98_AudioDriver::timerCallbackB); } TownsPC98_AudioDriver::~TownsPC98_AudioDriver() { + Common::StackLock lock(_mutex); + reset(); + _ready = false; + + setTimerCallbackA(); + setTimerCallbackB(); + if (_channels) { for (int i = 0; i < _numChan; i++) delete _channels[i]; diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp index 241b9bde50..e304537c22 100644 --- a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -835,6 +835,7 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) : memset(&_timers[0], 0, sizeof(ChipTimer)); memset(&_timers[1], 0, sizeof(ChipTimer)); + _timers[0].cb = &TownsPC98_FmSynth::timerCallbackA; _timers[1].cb = &TownsPC98_FmSynth::timerCallbackB; _timerbase = (uint32)(_baserate * 1000000.0f); @@ -842,6 +843,9 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) : TownsPC98_FmSynth::~TownsPC98_FmSynth() { Common::StackLock lock(_mutex); + + _ready = false; + _mixer->stopHandle(_soundHandle); delete _ssg; delete _prc; @@ -1154,6 +1158,14 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { return numSamples; } +void TownsPC98_FmSynth::setTimerCallbackA(ChipTimerProc proc) { + _timers[0].cb = proc; +} + +void TownsPC98_FmSynth::setTimerCallbackB(ChipTimerProc proc) { + _timers[1].cb = proc; +} + uint8 TownsPC98_FmSynth::readSSGStatus() { return _ssg->chanEnable(); } diff --git a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h index 3072503610..4c2de467d7 100644 --- a/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h +++ b/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h @@ -71,6 +71,10 @@ public: } protected: + typedef void (TownsPC98_FmSynth::*ChipTimerProc)(); + void setTimerCallbackA(ChipTimerProc proc = &TownsPC98_FmSynth::timerCallbackA); + void setTimerCallbackB(ChipTimerProc proc = &TownsPC98_FmSynth::timerCallbackB); + // Implement this in your inherited class if your driver generates // additional output that has to be inserted into the buffer. virtual void nextTickEx(int32 *buffer, uint32 bufferSize) {} @@ -80,8 +84,8 @@ protected: } uint8 readSSGStatus(); - virtual void timerCallbackA() = 0; - virtual void timerCallbackB() = 0; + virtual void timerCallbackA() {} + virtual void timerCallbackB() {} // The audio driver can store and apply two different audio settings // (usually for music and sound effects). The channel mask will determine @@ -139,8 +143,6 @@ private: bool _regProtectionFlag; - typedef void (TownsPC98_FmSynth::*ChipTimerProc)(); - struct ChipTimer { bool enabled; uint16 value; -- cgit v1.2.3