diff options
author | Paul Gilbert | 2016-09-14 20:53:35 -0400 |
---|---|---|
committer | Paul Gilbert | 2016-09-14 20:53:35 -0400 |
commit | b93b8f8245400c937f0d571f9a076d552b6fd0ce (patch) | |
tree | cdedf865ebbdaa02755615ac7bbc1a128b55ac07 /engines/xeen/music.h | |
parent | 87168baf323c9db3acd90d154848fd4f3a554df6 (diff) | |
download | scummvm-rg350-b93b8f8245400c937f0d571f9a076d552b6fd0ce.tar.gz scummvm-rg350-b93b8f8245400c937f0d571f9a076d552b6fd0ce.tar.bz2 scummvm-rg350-b93b8f8245400c937f0d571f9a076d552b6fd0ce.zip |
XEEN: Fleshing out music player
Diffstat (limited to 'engines/xeen/music.h')
-rw-r--r-- | engines/xeen/music.h | 261 |
1 files changed, 179 insertions, 82 deletions
diff --git a/engines/xeen/music.h b/engines/xeen/music.h index b1fa43daa2..0d5188e697 100644 --- a/engines/xeen/music.h +++ b/engines/xeen/music.h @@ -28,8 +28,9 @@ #include "common/array.h" #include "common/mutex.h" #include "common/queue.h" +#include "common/stack.h" -#define ADLIB_CHANNEL_COUNT 9 +#define CHANNEL_COUNT 9 namespace OPL { class OPL; @@ -37,52 +38,132 @@ namespace OPL { namespace Xeen { -class Music; +class MusicDriver; -typedef bool (Music::*CommandFn)(const byte *&srcP, byte nextByte); +typedef bool (MusicDriver::*CommandFn)(const byte *&srcP, byte param); -struct RegisterValue { - uint8 _regNum; - uint8 _value; +/** + * Base class for music drivers + */ +class MusicDriver { + struct Subroutine { + const byte *_returnP; + const byte *_jumpP; + Subroutine() : _returnP(nullptr), _jumpP(nullptr) {} + Subroutine(const byte *returnP, const byte *endP) : + _returnP(returnP), _jumpP(endP) {} + }; +private: + static const CommandFn FX_COMMANDS[16]; + static const CommandFn MUSIC_COMMANDS[16]; +private: + Common::Stack<Subroutine> _musSubroutines, _fxSubroutines; + bool _field1E; + int _musCountdownTimer; + int _fxCountdownTimer; + bool _lowMusicIgnored; + const byte *_fxDataPtr, *_musDataPtr; + const byte *_fxStartPtr; + const byte *_musStartPtr; + bool _flags[CHANNEL_COUNT]; + byte _field15C[CHANNEL_COUNT]; + byte _field165[CHANNEL_COUNT]; + byte _field177[CHANNEL_COUNT]; +private: + /** + * Executes the next command + * @param srcP Command data pointer + * @returns If true, execution of commands for the current timer call stops + */ + bool command(const byte *&srcP); +protected: + bool _fieldF; +protected: + /** + * Executes a series of commands until instructed to stop + */ + void execute(); + + // Music commands (with some also used by FX) + virtual bool musCallSubroutine(const byte *&srcP, byte param); + virtual bool musSetCountdown(const byte *&srcP, byte param); + virtual bool musSetInstrument(const byte *&srcP, byte param) = 0; + virtual bool cmdNoOperation(const byte *&srcP, byte param); + virtual bool musSetPitchWheel(const byte *&srcP, byte param) = 0; + virtual bool musSkipWord(const byte *&srcP, byte param); + virtual bool musSetPanning(const byte *&srcP, byte param) = 0; + virtual bool musFade(const byte *&srcP, byte param) = 0; + virtual bool musStartNote(const byte *&srcP, byte param) = 0; + virtual bool musSetVolume(const byte *&srcP, byte param) = 0; + virtual bool musInjectMidi(const byte *&srcP, byte param) = 0; + virtual bool musPlayInstrument(const byte *&srcP, byte param) = 0; + virtual bool cmdClearFlag(const byte *&srcP, byte param); + virtual bool cmdWibbly(const byte *&srcP, byte param); + virtual bool musEndSubroutine(const byte *&srcP, byte param); + + // FX commands + virtual bool fxCallSubroutine(const byte *&srcP, byte param); + virtual bool fxSetCountdown(const byte *&srcP, byte param); + virtual bool fxSetInstrument(const byte *&srcP, byte param) = 0; + virtual bool fxSetVolume(const byte *&srcP, byte param) = 0; + virtual bool fxMidiReset(const byte *&srcP, byte param) = 0; + virtual bool fxMidiDword(const byte *&srcP, byte param) = 0; + virtual bool fxSetPanning(const byte *&srcP, byte param) = 0; + virtual bool fxChannelOff(const byte *&srcP, byte param) = 0; + virtual bool fxFade(const byte *&srcP, byte param) = 0; + virtual bool fxStartNote(const byte *&srcP, byte param) = 0; + virtual bool fxInjectMidi(const byte *&srcP, byte param) = 0; + virtual bool fxPlayInstrument(const byte *&srcP, byte param) = 0; + virtual bool fxEndSubroutine(const byte *&srcP, byte param); - RegisterValue(int regNum, int value) { - _regNum = regNum; _value = value; - } + virtual void postProcess() = 0; + + /** + * Does a reset of any sound effect + */ + virtual void resetFX() = 0; +public: + /** + * Constructor + */ + MusicDriver(); + + /** + * Destructor + */ + virtual ~MusicDriver() {} + + /** + * Starts an special effect playing + */ + void playFX(uint effectId, const byte *data); }; -class Music { - struct Channel { - byte _outputLevel; - byte _scalingValue; +class AdlibMusicDriver : public MusicDriver { + struct RegisterValue { + uint8 _regNum; + uint8 _value; - Channel() : _outputLevel(0), _scalingValue(0) {} + RegisterValue(int regNum, int value) { + _regNum = regNum; _value = value; + } }; private: - static const byte OPERATOR1_INDEXES[ADLIB_CHANNEL_COUNT]; - static const byte OPERATOR2_INDEXES[ADLIB_CHANNEL_COUNT]; - static const CommandFn COMMAND_TABLE1[16]; - static const CommandFn COMMAND_TABLE2[16]; + static const byte OPERATOR1_INDEXES[CHANNEL_COUNT]; + static const byte OPERATOR2_INDEXES[CHANNEL_COUNT]; + static const uint WAVEFORMS[24]; private: OPL::OPL *_opl; - Common::Mutex _driverMutex; - Common::Array<Channel> _channels; Common::Queue<RegisterValue> _queue; - const byte *_effectsData; - Common::Array<uint16> _effectsOffsets; - const byte *_musicPtr1, *_musicPtr2; - const byte *_dataPtr; - bool _fieldF; - bool _field1C; - bool _field1E; - uint _fieldFB[7]; - int _field109; - int _field10B; - byte _field10D[7]; - int _field114; - int _field115; - int _field116; - int _field117; - bool _lowMusicIgnored; + Common::Mutex _driverMutex; + byte _volumes[CHANNEL_COUNT]; + byte _scalingValues[CHANNEL_COUNT]; + const byte *_musInstrumentPtrs[16]; + const byte *_fxInstrumentPtrs[16]; + uint _frequencies[7]; + int _field180; + int _field182; + int _volume; private: /** * Initializes the state of the Adlib OPL driver @@ -90,11 +171,6 @@ private: void initialize(); /** - * Loads effects data that was embedded in the music driver - */ - void loadEffectsData(); - - /** * Adds a register write to the pending queue that will be flushed * out to the OPL on the next timer call */ @@ -111,16 +187,6 @@ private: void flush(); /** - * Updates any playing music - */ - void update(); - - /** - * Does a reset - */ - void reset(); - - /** * Resets all the output frequencies */ void resetFrequencies(); @@ -131,42 +197,73 @@ private: void setFrequency(byte operatorNum, uint frequency); /** + * Calculates the frequency for a note + */ + uint calcFrequency(byte note); + + /** * Sets the output level for a channel */ void setOutputLevel(byte channelNum, uint level); /** - * Post-process - */ - void postProcess(); - - /** - * Update command methods - */ - bool cmd1(const byte *&srcP, byte nextByte); - bool cmd2(const byte *&srcP, byte nextByte); - bool cmd3(const byte *&srcP, byte nextByte); - bool cmd4(const byte *&srcP, byte nextByte); - bool cmd5(const byte *&srcP, byte nextByte); - bool cmd6(const byte *&srcP, byte nextByte); - bool cmd7(const byte *&srcP, byte nextByte); - bool cmd8(const byte *&srcP, byte nextByte); - bool cmd9(const byte *&srcP, byte nextByte); - bool cmd10(const byte *&srcP, byte nextByte); - bool cmd11(const byte *&srcP, byte nextByte); - bool cmd12(const byte *&srcP, byte nextByte); - bool cmd13(const byte *&srcP, byte nextByte); - bool cmd14(const byte *&srcP, byte nextByte); - bool cmd15(const byte *&srcP, byte nextByte); - bool cmd16(const byte *&srcP, byte nextByte); - bool cmd17(const byte *&srcP, byte nextByte); - bool cmd18(const byte *&srcP, byte nextByte); - bool cmd19(const byte *&srcP, byte nextByte); - bool cmd20(const byte *&srcP, byte nextByte); - bool cmd21(const byte *&srcP, byte nextByte); - bool cmd22(const byte *&srcP, byte nextByte); - bool cmd23(const byte *&srcP, byte nextByte); - bool cmd24(const byte *&srcP, byte nextByte); + * Starts playing an instrument + */ + void playInstrument(byte channelNum, const byte *data); +protected: + virtual bool musSetInstrument(const byte *&srcP, byte param); + virtual bool musSetPitchWheel(const byte *&srcP, byte param); + virtual bool musSetPanning(const byte *&srcP, byte param); + virtual bool musFade(const byte *&srcP, byte param); + virtual bool musStartNote(const byte *&srcP, byte param); + virtual bool musSetVolume(const byte *&srcP, byte param); + virtual bool musInjectMidi(const byte *&srcP, byte param); + virtual bool musPlayInstrument(const byte *&srcP, byte param); + + virtual bool fxSetInstrument(const byte *&srcP, byte param); + virtual bool fxSetVolume(const byte *&srcP, byte param); + virtual bool fxMidiReset(const byte *&srcP, byte param); + virtual bool fxMidiDword(const byte *&srcP, byte param); + virtual bool fxSetPanning(const byte *&srcP, byte param); + virtual bool fxChannelOff(const byte *&srcP, byte param); + virtual bool fxFade(const byte *&srcP, byte param); + virtual bool fxStartNote(const byte *&srcP, byte param); + virtual bool fxInjectMidi(const byte *&srcP, byte param); + virtual bool fxPlayInstrument(const byte *&srcP, byte param); + + /** + * Does a reset of any sound effect + */ + virtual void resetFX(); +public: + /** + * Constructor + */ + AdlibMusicDriver(); + + /** + * Destructor + */ + virtual ~AdlibMusicDriver(); +}; + + +class Music { +private: + MusicDriver *_musicDriver; + const byte *_effectsData; + Common::Array<uint16> _effectsOffsets; +private: + /** + * Loads effects data that was embedded in the music driver + */ + void loadEffectsData(); + + /** + * Updates any playing music + */ + void update(); + protected: Audio::Mixer *_mixer; public: |