From 2c105356681912685eedf753141f5316b6ff9223 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 12 Sep 2016 22:34:59 -0400 Subject: XEEN: Implement Music update method --- engines/xeen/music.cpp | 151 +++++++++++++++++++++++++++++++++++++++++++++++-- engines/xeen/music.h | 43 ++++++++++++++ 2 files changed, 190 insertions(+), 4 deletions(-) diff --git a/engines/xeen/music.cpp b/engines/xeen/music.cpp index 7996093d1f..72ff3866cf 100644 --- a/engines/xeen/music.cpp +++ b/engines/xeen/music.cpp @@ -30,9 +30,10 @@ namespace Xeen { #define CALLBACKS_PER_SECOND 72 Music::Music(Audio::Mixer *mixer) : _mixer(mixer), _effectsData(nullptr), - _musicPtr1(nullptr), _musicPtr2(nullptr), _lowMusicIgnored(false), - _fieldF(false), _field109(0), _field10B(0), _field114(0), - _field115(0), _field117(0) { + _musicPtr1(nullptr), _musicPtr2(nullptr), _dataPtr(nullptr), + _lowMusicIgnored(false), + _fieldF(false), _field1C(false), _field1E(false), _field109(0), + _field10B(0), _field114(0), _field115(0), _field116(0), _field117(0) { _channels.resize(ADLIB_CHANNEL_COUNT); Common::fill(&_fieldFB[0], &_fieldFB[7], 0); Common::fill(&_field10D[0], &_field10D[7], 0); @@ -102,7 +103,35 @@ void Music::flush() { } void Music::update() { - // TODO + const byte *srcP = _dataPtr; + + bool flag = !_field1E; + if (!flag) { + _field1C = 0; + if (_field116 && --_field116 == 0) + flag = true; + } + if (flag && _lowMusicIgnored) { + srcP = _musicPtr1; + _field1C = 1; + if (!_field117 || --_field117 == 0) + flag = false; + } + + if (flag) { + postProcess(); + return; + } + + // Main loop + bool breakFlag = false; + while (!breakFlag) { + byte nextByte = *srcP++; + int cmd = (nextByte >> 3) & 15; + + CommandFn fn = (_field1C == 1) ? COMMAND_TABLE2[cmd] : COMMAND_TABLE1[cmd]; + breakFlag = (this->*fn)(srcP, nextByte); + } } void Music::playEffect(uint effectId) { @@ -144,6 +173,120 @@ void Music::setFrequency(byte operatorNum, uint frequency) { write(0xB0 + operatorNum, (frequency >> 8)); } +void Music::postProcess() { + // TODO +} + +bool Music::cmd1(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd2(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd3(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd4(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd5(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd6(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd7(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd8(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd9(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd10(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd11(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd12(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd13(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd14(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd15(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd16(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd17(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd18(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd19(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd20(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd21(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd22(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd23(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +bool Music::cmd24(const byte *&srcP, byte nextByte) { + return false; // TODO +} + +const CommandFn Music::COMMAND_TABLE1[16] = { + &Music::cmd1, &Music::cmd2, &Music::cmd3, &Music::cmd4, + &Music::cmd5, &Music::cmd5, &Music::cmd6, &Music::cmd4, + &Music::cmd7, &Music::cmd8, &Music::cmd9, &Music::cmd10, + &Music::cmd11, &Music::cmd12, &Music::cmd13, &Music::cmd14 +}; + +const CommandFn Music::COMMAND_TABLE2[16] = { + &Music::cmd15, &Music::cmd16, &Music::cmd17, &Music::cmd18, + &Music::cmd4, &Music::cmd4, &Music::cmd19, &Music::cmd20, + &Music::cmd21, &Music::cmd22, &Music::cmd4, &Music::cmd4, + &Music::cmd23, &Music::cmd12, &Music::cmd13, &Music::cmd24 +}; + void Music::setOutputLevel(byte channelNum, uint level) { write(0x40 + OPERATOR2_INDEXES[channelNum], level | (_channels[channelNum]._scalingValue & 0xC0)); diff --git a/engines/xeen/music.h b/engines/xeen/music.h index c2202eb2f7..b1fa43daa2 100644 --- a/engines/xeen/music.h +++ b/engines/xeen/music.h @@ -37,6 +37,10 @@ namespace OPL { namespace Xeen { +class Music; + +typedef bool (Music::*CommandFn)(const byte *&srcP, byte nextByte); + struct RegisterValue { uint8 _regNum; uint8 _value; @@ -56,6 +60,8 @@ class Music { 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]; private: OPL::OPL *_opl; Common::Mutex _driverMutex; @@ -64,13 +70,17 @@ private: const byte *_effectsData; Common::Array _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; private: @@ -124,6 +134,39 @@ private: * 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); protected: Audio::Mixer *_mixer; public: -- cgit v1.2.3