diff options
author | Matthew Hoops | 2011-08-07 20:11:27 -0400 |
---|---|---|
committer | Matthew Hoops | 2011-08-07 20:11:27 -0400 |
commit | c05c42ecc60c8f928628787272743f169a0d5903 (patch) | |
tree | f2b06be630676b7302a1fb62940099b2ec71442d /engines/scumm | |
parent | e43a6671fc04f2c67b8efa2c0fdfdd6ec0ea1023 (diff) | |
parent | 45dc303159d5bbe77a351df31e6f2d2f97a3412d (diff) | |
download | scummvm-rg350-c05c42ecc60c8f928628787272743f169a0d5903.tar.gz scummvm-rg350-c05c42ecc60c8f928628787272743f169a0d5903.tar.bz2 scummvm-rg350-c05c42ecc60c8f928628787272743f169a0d5903.zip |
Merge remote branch 'upstream/master' into soccer
Diffstat (limited to 'engines/scumm')
28 files changed, 384 insertions, 399 deletions
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index d3514645d3..037c12bdbf 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -33,6 +33,8 @@ #include "common/savefile.h" #include "common/system.h" +#include "audio/mididrv.h" + #include "scumm/detection.h" #include "scumm/detection_tables.h" #include "scumm/he/intern_he.h" @@ -145,7 +147,7 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const { Common::String bPattern = _filenamePattern.pattern; // Special cases for Blue's games, which share common (b) files - if (_game.id == GID_BIRTHDAY && !(_game.features & GF_DEMO)) + if (_game.id == GID_BIRTHDAYYELLOW || _game.id == GID_BIRTHDAYRED) bPattern = "Blue'sBirthday"; else if (_game.id == GID_TREASUREHUNT) bPattern = "Blue'sTreasureHunt"; diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 11901f7565..78645ea8d5 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -222,7 +222,7 @@ static const GameSettings gameVariantsTable[] = { {"indy3", "EGA", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI}, {"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, + {"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS}, {"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, @@ -233,9 +233,9 @@ static const GameSettings gameVariantsTable[] = { {"loom", "FM-TOWNS", 0, GID_LOOM, 3, 0, MDT_TOWNS, GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS}, {"loom", "VGA", "vga", GID_LOOM, 4, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, + {"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, - {"monkey", "VGA", "vga", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, + {"monkey", "VGA", "vga", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH}, {"monkey", "EGA", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH}, {"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR, GF_16COLOR, Common::kPlatformAtariST, GUIO_NOSPEECH | GUIO_NOMIDI}, {"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI}, @@ -343,7 +343,9 @@ static const GameSettings gameVariantsTable[] = { {"puttrace", "HE 99", 0, GID_PUTTRACE, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"bluesabctime", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, - {"BluesBirthday", 0, 0, GID_BIRTHDAY, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, + {"BluesBirthday", "", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, + {"BluesBirthday", "Red", 0, GID_BIRTHDAYRED, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, + {"BluesBirthday", "Yellow", 0, GID_BIRTHDAYYELLOW, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"soccer", "", 0, GID_SOCCER, 6, 98, MDT_NONE, GF_USE_KEY, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, // Global scripts increased to 2048 diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index f22547f193..8a32b963cd 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -4111,4 +4111,3 @@ void ScummEngine::unkScreenEffect6() { } } // End of namespace Scumm - diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index 5af4035930..0510f77740 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -1831,6 +1831,15 @@ void ScummEngine_v72he::o72_readINI() { push(1); } else if (!strcmp((char *)option, "TextOn")) { push(ConfMan.getBool("subtitles")); + } else if (!strcmp((char *)option, "Disk") && (_game.id == GID_BIRTHDAYRED || _game.id == GID_BIRTHDAYYELLOW)) { + // WORKAROUND: Override the disk detection + // This removes the reliance on having the binary file around (which is + // very bad for the Mac version) just for the scripts to figure out if + // we're running Yellow or Red + if (_game.id == GID_BIRTHDAYRED) + push(4); + else + push(2); } else { push(ConfMan.getInt((char *)option)); } diff --git a/engines/scumm/he/sprite_he.h b/engines/scumm/he/sprite_he.h index d28c9f1944..be6717faa5 100644 --- a/engines/scumm/he/sprite_he.h +++ b/engines/scumm/he/sprite_he.h @@ -218,4 +218,3 @@ private: } // End of namespace Scumm #endif - diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index 4107034fe6..f67922c81c 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -1755,7 +1755,7 @@ void Wiz::captureWizPolygon(int resNum, int maskNum, int maskState, int id1, int uint8 *tmpPtr = imageBuffer; for (i = 0; i < dsth; i++) { for (j = 0; j < dstw; j++) - WRITE_UINT16(tmpPtr + j * 2, transColor); + WRITE_LE_UINT16(tmpPtr + j * 2, transColor); tmpPtr += dstpitch; } } else { diff --git a/engines/scumm/help.h b/engines/scumm/help.h index 9763da8c00..5ba6bdc65c 100644 --- a/engines/scumm/help.h +++ b/engines/scumm/help.h @@ -42,4 +42,3 @@ public: } // End of namespace Scumm #endif - diff --git a/engines/scumm/imuse/pcspk.cpp b/engines/scumm/imuse/pcspk.cpp index 01e2ab3b7d..668defefba 100644 --- a/engines/scumm/imuse/pcspk.cpp +++ b/engines/scumm/imuse/pcspk.cpp @@ -832,4 +832,3 @@ const uint16 PcSpkDriver::_frequencyTable[] = { }; } // End of namespace Scumm - diff --git a/engines/scumm/imuse/pcspk.h b/engines/scumm/imuse/pcspk.h index e77ac8c1bf..b87110c412 100644 --- a/engines/scumm/imuse/pcspk.h +++ b/engines/scumm/imuse/pcspk.h @@ -158,4 +158,3 @@ private: } // End of namespace Scumm #endif - diff --git a/engines/scumm/imuse/sysex.h b/engines/scumm/imuse/sysex.h index 7dd38e785e..06ac483afd 100644 --- a/engines/scumm/imuse/sysex.h +++ b/engines/scumm/imuse/sysex.h @@ -35,4 +35,3 @@ extern void sysexHandler_SamNMax(Player *, const byte *, uint16); } // End of namespace Scumm #endif - diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp index 23f57a01b9..eb3717494f 100644 --- a/engines/scumm/imuse_digi/dimuse.cpp +++ b/engines/scumm/imuse_digi/dimuse.cpp @@ -58,7 +58,7 @@ IMuseDigital::IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer, int fps) memset(_track[l], 0, sizeof(Track)); _track[l]->trackId = l; } - _vm->getTimerManager()->installTimerProc(timer_handler, 1000000 / _callbackFps, this); + _vm->getTimerManager()->installTimerProc(timer_handler, 1000000 / _callbackFps, this, "IMuseDigital"); _audioNames = NULL; _numAudioNames = 0; diff --git a/engines/scumm/insane/insane_enemy.cpp b/engines/scumm/insane/insane_enemy.cpp index 68766ab72c..913f761f31 100644 --- a/engines/scumm/insane/insane_enemy.cpp +++ b/engines/scumm/insane/insane_enemy.cpp @@ -2779,4 +2779,3 @@ int32 Insane::actionEnemy() { } } - diff --git a/engines/scumm/insane/insane_iact.cpp b/engines/scumm/insane/insane_iact.cpp index 3592d67c18..48c96b537c 100644 --- a/engines/scumm/insane/insane_iact.cpp +++ b/engines/scumm/insane/insane_iact.cpp @@ -520,4 +520,3 @@ void Insane::iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12, } } - diff --git a/engines/scumm/insane/insane_scenes.cpp b/engines/scumm/insane/insane_scenes.cpp index 841fedafe2..6db1cb5059 100644 --- a/engines/scumm/insane/insane_scenes.cpp +++ b/engines/scumm/insane/insane_scenes.cpp @@ -1506,4 +1506,3 @@ void Insane::postCaseMore(byte *renderBitmap, int32 codecparam, int32 setupsan12 } } - diff --git a/engines/scumm/player_v2.h b/engines/scumm/player_v2.h index 14a0b9c1e0..d932585b8e 100644 --- a/engines/scumm/player_v2.h +++ b/engines/scumm/player_v2.h @@ -46,10 +46,7 @@ public: virtual int getSoundStatus(int sound) const; // AudioStream API - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return true; } - bool endOfData() const { return false; } - int getRate() const { return _sampleRate; } + virtual int readBuffer(int16 *buffer, const int numSamples); protected: unsigned int _update_step; diff --git a/engines/scumm/player_v2base.h b/engines/scumm/player_v2base.h index 2f048070ad..eb9ed941ca 100644 --- a/engines/scumm/player_v2base.h +++ b/engines/scumm/player_v2base.h @@ -86,9 +86,9 @@ public: return numSamples; } */ - bool isStereo() const { return true; } - bool endOfData() const { return false; } - int getRate() const { return _sampleRate; } + virtual bool isStereo() const { return true; } + virtual bool endOfData() const { return false; } + virtual int getRate() const { return _sampleRate; } protected: enum { diff --git a/engines/scumm/player_v2cms.cpp b/engines/scumm/player_v2cms.cpp index 21e7f193b5..d16f9d2be7 100644 --- a/engines/scumm/player_v2cms.cpp +++ b/engines/scumm/player_v2cms.cpp @@ -28,162 +28,45 @@ namespace Scumm { -#define PROCESS_ATTACK 1 -#define PROCESS_RELEASE 2 -#define PROCESS_SUSTAIN 3 -#define PROCESS_DECAY 4 -#define PROCESS_VIBRATO 5 - -#define CMS_RATE 22050 - -static const byte freqTable[] = { - 3, 10, 17, 24, 31, 38, 45, 51, - 58, 65, 71, 77, 83, 90, 96, 102, - 107, 113, 119, 125, 130, 136, 141, 146, - 151, 157, 162, 167, 172, 177, 181, 186, - 191, 195, 200, 204, 209, 213, 217, 221, - 226, 230, 234, 238, 242, 246, 249, 253 -}; - -/*static const byte amplTable[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 % - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 10 % - 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, // 20 % - 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x20, // 30% - 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x40, 0x40, - 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x20, 0x20, // 40 % - 0x30, 0x30, 0x40, 0x40, 0x40, 0x50, 0x50, 0x60, - 0x00, 0x00, 0x10, 0x10, 0x20, 0x20, 0x30, 0x30, // 50% - 0x40, 0x40, 0x50, 0x50, 0x60, 0x60, 0x70, 0x70, - 0x00, 0x00, 0x10, 0x10, 0x20, 0x30, 0x30, 0x40, // 60 % - 0x40, 0x50, 0x60, 0x60, 0x70, 0x70, 0x80, 0x90, - 0x00, 0x00, 0x10, 0x20, 0x20, 0x30, 0x40, 0x40, // 70 % - 0x50, 0x60, 0x70, 0x70, 0x80, 0x90, 0x90, 0xA0, - 0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x40, 0x50, // 80 % - 0x60, 0x70, 0x80, 0x80, 0x90, 0xA0, 0xB0, 0xC0, - 0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, // 90 % - 0x70, 0x80, 0x90, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, // 100 % - 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0 -};*/ - -static const byte octaveTable[] = { - 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, - 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, - 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03, - 0x01, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07, - 0x01, 0x08, 0x01, 0x09, 0x01, 0x0A, 0x01, 0x0B, - 0x02, 0x00, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, - 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, 0x02, 0x07, - 0x02, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x0B, - 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, - 0x03, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, - 0x03, 0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B, - 0x04, 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, - 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, - 0x04, 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, - 0x05, 0x00, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, - 0x05, 0x04, 0x05, 0x05, 0x05, 0x06, 0x05, 0x07, - 0x05, 0x08, 0x05, 0x09, 0x05, 0x0A, 0x05, 0x0B, - 0x06, 0x00, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, - 0x06, 0x04, 0x06, 0x05, 0x06, 0x06, 0x06, 0x07, - 0x06, 0x08, 0x06, 0x09, 0x06, 0x0A, 0x06, 0x0B, - 0x07, 0x00, 0x07, 0x01, 0x07, 0x02, 0x07, 0x03, - 0x07, 0x04, 0x07, 0x05, 0x07, 0x06, 0x07, 0x07, - 0x07, 0x08, 0x07, 0x09, 0x07, 0x0A, 0x07, 0x0B, - 0x08, 0x00, 0x08, 0x01, 0x08, 0x02, 0x08, 0x03, - 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x08, 0x07, - 0x08, 0x08, 0x08, 0x09, 0x08, 0x0A, 0x08, 0x0B, - 0x09, 0x00, 0x09, 0x01, 0x09, 0x02, 0x09, 0x03, - 0x09, 0x04, 0x09, 0x05, 0x09, 0x06, 0x09, 0x07, - 0x09, 0x08, 0x09, 0x09, 0x09, 0x0A, 0x09, 0x0B, - 0x0A, 0x00, 0x0A, 0x01, 0x0A, 0x02, 0x0A, 0x03, - 0x0A, 0x04, 0x0A, 0x05, 0x0A, 0x06, 0x0A, 0x07, - 0x0A, 0x08, 0x0A, 0x09, 0x0A, 0x0A, 0x0A, 0x0B -}; - -static const byte attackRate[] = { - 0, 2, 4, 7, 14, 26, 48, 82, - 128, 144, 160, 176, 192, 208, 224, 255 -}; - -static const byte decayRate[] = { - 0, 1, 2, 3, 4, 6, 12, 24, - 48, 96, 192, 215, 255, 255, 255, 255 -}; - -static const byte sustainRate[] = { - 255, 180, 128, 96, 80, 64, 56, 48, - 42, 36, 32, 28, 24, 20, 16, 0 -}; - -static const byte releaseRate[] = { - 0, 1, 2, 4, 6, 9, 14, 22, - 36, 56, 80, 100, 120, 140, 160, 255 -}; - -static const byte volumeTable[] = { - 0x00, 0x10, 0x10, 0x11, 0x11, 0x21, 0x22, 0x22, - 0x33, 0x44, 0x55, 0x66, 0x88, 0xAA, 0xCC, 0xFF -}; - Player_V2CMS::Player_V2CMS(ScummEngine *scumm, Audio::Mixer *mixer) - : Player_V2Base(scumm, mixer, true) { - int i; - + : Player_V2Base(scumm, mixer, true), _cmsVoicesBase(), _cmsVoices(), + _cmsChips(), _midiDelay(0), _octaveMask(0), _looping(0), _tempo(0), + _tempoSum(0), _midiData(0), _midiSongBegin(0), _musicTimer(0), + _musicTimerTicks(0), _voiceTimer(0), _loadedMidiSong(0), + _outputTableReady(0), _midiChannel(), _midiChannelUse() { setMusicVolume(255); - memset(_cmsVoicesBase, 0, sizeof(Voice)*16); - memset(_cmsVoices, 0, sizeof(Voice2)*8); - memset(_cmsChips, 0, sizeof(MusicChip)*2); - _midiDelay = _octaveMask = _looping = _tempo = 0; - _midiData = _midiSongBegin = 0; - _loadedMidiSong = 0; - memset(_midiChannel, 0, sizeof(Voice2*)*16); - memset(_midiChannelUse, 0, sizeof(byte)*16); - - _cmsVoices[0].amplitudeOutput = &(_cmsChips[0].ampl[0]); - _cmsVoices[0].freqOutput = &(_cmsChips[0].freq[0]); - _cmsVoices[0].octaveOutput = &(_cmsChips[0].octave[0]); - _cmsVoices[1].amplitudeOutput = &(_cmsChips[0].ampl[1]); - _cmsVoices[1].freqOutput = &(_cmsChips[0].freq[1]); - _cmsVoices[1].octaveOutput = &(_cmsChips[0].octave[0]); - _cmsVoices[2].amplitudeOutput = &(_cmsChips[0].ampl[2]); - _cmsVoices[2].freqOutput = &(_cmsChips[0].freq[2]); - _cmsVoices[2].octaveOutput = &(_cmsChips[0].octave[1]); - _cmsVoices[3].amplitudeOutput = &(_cmsChips[0].ampl[3]); - _cmsVoices[3].freqOutput = &(_cmsChips[0].freq[3]); - _cmsVoices[3].octaveOutput = &(_cmsChips[0].octave[1]); - _cmsVoices[4].amplitudeOutput = &(_cmsChips[1].ampl[0]); - _cmsVoices[4].freqOutput = &(_cmsChips[1].freq[0]); - _cmsVoices[4].octaveOutput = &(_cmsChips[1].octave[0]); - _cmsVoices[5].amplitudeOutput = &(_cmsChips[1].ampl[1]); - _cmsVoices[5].freqOutput = &(_cmsChips[1].freq[1]); - _cmsVoices[5].octaveOutput = &(_cmsChips[1].octave[0]); - _cmsVoices[6].amplitudeOutput = &(_cmsChips[1].ampl[2]); - _cmsVoices[6].freqOutput = &(_cmsChips[1].freq[2]); - _cmsVoices[6].octaveOutput = &(_cmsChips[1].octave[1]); - _cmsVoices[7].amplitudeOutput = &(_cmsChips[1].ampl[3]); - _cmsVoices[7].freqOutput = &(_cmsChips[1].freq[3]); - _cmsVoices[7].octaveOutput = &(_cmsChips[1].octave[1]); + _cmsVoices[0].amplitudeOutput = &_cmsChips[0].ampl[0]; + _cmsVoices[0].freqOutput = &_cmsChips[0].freq[0]; + _cmsVoices[0].octaveOutput = &_cmsChips[0].octave[0]; + _cmsVoices[1].amplitudeOutput = &_cmsChips[0].ampl[1]; + _cmsVoices[1].freqOutput = &_cmsChips[0].freq[1]; + _cmsVoices[1].octaveOutput = &_cmsChips[0].octave[0]; + _cmsVoices[2].amplitudeOutput = &_cmsChips[0].ampl[2]; + _cmsVoices[2].freqOutput = &_cmsChips[0].freq[2]; + _cmsVoices[2].octaveOutput = &_cmsChips[0].octave[1]; + _cmsVoices[3].amplitudeOutput = &_cmsChips[0].ampl[3]; + _cmsVoices[3].freqOutput = &_cmsChips[0].freq[3]; + _cmsVoices[3].octaveOutput = &_cmsChips[0].octave[1]; + _cmsVoices[4].amplitudeOutput = &_cmsChips[1].ampl[0]; + _cmsVoices[4].freqOutput = &_cmsChips[1].freq[0]; + _cmsVoices[4].octaveOutput = &_cmsChips[1].octave[0]; + _cmsVoices[5].amplitudeOutput = &_cmsChips[1].ampl[1]; + _cmsVoices[5].freqOutput = &_cmsChips[1].freq[1]; + _cmsVoices[5].octaveOutput = &_cmsChips[1].octave[0]; + _cmsVoices[6].amplitudeOutput = &_cmsChips[1].ampl[2]; + _cmsVoices[6].freqOutput = &_cmsChips[1].freq[2]; + _cmsVoices[6].octaveOutput = &_cmsChips[1].octave[1]; + _cmsVoices[7].amplitudeOutput = &_cmsChips[1].ampl[3]; + _cmsVoices[7].freqOutput = &_cmsChips[1].freq[3]; + _cmsVoices[7].octaveOutput = &_cmsChips[1].octave[1]; // inits the CMS Emulator like in the original _cmsEmu = new CMSEmulator(_sampleRate); - static const byte cmsInitData[13*2] = { - 0x1C, 0x02, - 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, - 0x14, 0x3F, 0x15, 0x00, 0x16, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1C, 0x01 - }; - - i = 0; - for (int cmsPort = 0x220; i < 2; cmsPort += 2, ++i) { + for (int i = 0, cmsPort = 0x220; i < 2; cmsPort += 2, ++i) { for (int off = 0; off < 13; ++off) { - _cmsEmu->portWrite(cmsPort+1, cmsInitData[off*2]); - _cmsEmu->portWrite(cmsPort, cmsInitData[off*2+1]); + _cmsEmu->portWrite(cmsPort+1, _cmsInitData[off*2]); + _cmsEmu->portWrite(cmsPort, _cmsInitData[off*2+1]); } } @@ -200,6 +83,10 @@ Player_V2CMS::~Player_V2CMS() { void Player_V2CMS::setMusicVolume(int vol) { } +int Player_V2CMS::getMusicTimer() { + return _midiData ? _musicTimer : Player_V2Base::getMusicTimer(); +} + void Player_V2CMS::stopAllSounds() { Common::StackLock lock(_mutex); @@ -211,6 +98,7 @@ void Player_V2CMS::stopAllSounds() { _midiData = 0; _midiSongBegin = 0; _midiDelay = 0; + _musicTimer = _musicTimerTicks = 0; offAllChannels(); } @@ -244,6 +132,7 @@ void Player_V2CMS::startSound(int nr) { assert(data); if (data[6] == 0x80) { + _musicTimer = _musicTimerTicks = 0; loadMidiData(data, nr); } else { int cprio = _current_data ? *(_current_data + _header_len) : 0; @@ -282,7 +171,8 @@ void Player_V2CMS::startSound(int nr) { } void Player_V2CMS::loadMidiData(byte *data, int sound) { - memset(_midiChannelUse, 0, sizeof(byte)*16); + memset(_midiChannelUse, 0, sizeof(_midiChannelUse)); + memset(_midiChannel, 0, sizeof(_midiChannel)); _tempo = data[7]; _looping = data[8]; @@ -299,11 +189,11 @@ void Player_V2CMS::loadMidiData(byte *data, int sound) { Voice *voiceDef = &_cmsVoicesBase[channel]; byte attackDecay = voice2[10]; - voiceDef->attack = attackRate[attackDecay >> 4]; - voiceDef->decay = decayRate[attackDecay & 0x0F]; + voiceDef->attack = _attackRate[attackDecay >> 4]; + voiceDef->decay = _decayRate[attackDecay & 0x0F]; byte sustainRelease = voice2[11]; - voiceDef->sustain = sustainRate[sustainRelease >> 4]; - voiceDef->release = releaseRate[sustainRelease & 0x0F]; + voiceDef->sustain = _sustainRate[sustainRelease >> 4]; + voiceDef->release = _releaseRate[sustainRelease & 0x0F]; if (voice2[3] & 0x40) { voiceDef->vibrato = 0x0301; @@ -331,12 +221,10 @@ void Player_V2CMS::loadMidiData(byte *data, int sound) { } } - for (int i = 0, channel = 0; i < 8; ++i, channel += 2) { + for (int i = 0; i < 8; ++i) { _cmsVoices[i].chanNumber = 0xFF; _cmsVoices[i].curVolume = 0; _cmsVoices[i].nextVoice = 0; - - _midiChannel[channel] = 0; } _midiDelay = 0; @@ -351,11 +239,17 @@ int Player_V2CMS::getSoundStatus(int nr) const { return _current_nr == nr || _next_nr == nr || _loadedMidiSong == nr; } -void Player_V2CMS::processMidiData(uint ticks) { +void Player_V2CMS::processMidiData() { byte *currentData = _midiData; byte command = 0x00; int16 temp = 0; + ++_musicTimerTicks; + if (_musicTimerTicks > 60) { + _musicTimerTicks = 0; + ++_musicTimer; + } + if (!_midiDelay) { while (true) { if ((command = *currentData++) == 0xFF) { @@ -365,6 +259,8 @@ void Player_V2CMS::processMidiData(uint ticks) { continue; } _midiData = _midiSongBegin = 0; + _midiDelay = 0; + _loadedMidiSong = 0; offAllChannels(); return; } else { @@ -400,7 +296,7 @@ void Player_V2CMS::processMidiData(uint ticks) { _midiDelay = temp; } - _midiDelay -= ticks; + --_midiDelay; if (_midiDelay < 0) _midiDelay = 0; @@ -415,27 +311,21 @@ int Player_V2CMS::readBuffer(int16 *buffer, const int numSamples) { // maybe this needs a complete rewrite do { - if (_midiData) { - --_clkFrequenz; - if (!(_clkFrequenz & 0x01)) { - playVoice(); - } - - _tempoSum += _tempo; - // FIXME: _tempoSum is declared as char; on some systems char is unsigned. - // E.g. on OS X. Hence the following check is always false. - // Moral of the story: Use uint8, int8 or any of the other types provided by - // ScummVM if you want to ensure signedness and number of available bits. - if (_tempoSum < 0) { - // this have to be called in the same rate as in the original (I think) - processMidiData(1); + if (!(_next_tick >> FIXP_SHIFT)) { + if (_midiData) { + --_voiceTimer; + if (!(_voiceTimer & 0x01)) + playVoice(); + + int newTempoSum = _tempo + _tempoSum; + _tempoSum = newTempoSum & 0xFF; + if (newTempoSum > 0xFF) + processMidiData(); + } else { + nextTick(); + play(); } - } - - if (!(_next_tick >> FIXP_SHIFT) && !_midiData) { _next_tick += _tick_len; - nextTick(); - play(); } step = len; @@ -456,99 +346,95 @@ void Player_V2CMS::playVoice() { } _octaveMask = 0xF0; - Voice2 *voice =0; + Voice2 *voice = 0; for (int i = 0; i < 8; ++i) { voice = &_cmsVoices[i]; _octaveMask = ~_octaveMask; if (voice->chanNumber != 0xFF) { processChannel(voice); - continue; - } - - if (!voice->curVolume) { - *(voice->amplitudeOutput) = 0; - } + } else { + if (!voice->curVolume) { + *(voice->amplitudeOutput) = 0; + } - int volume = voice->curVolume - voice->releaseRate; - voice->curVolume = volume; + int volume = voice->curVolume - voice->releaseRate; + if (volume < 0) + volume = 0; - if (volume < 0) { - volume = voice->curVolume = 0; + voice->curVolume = volume; + *(voice->amplitudeOutput) = ((volume >> 4) | (volume & 0xF0)) & voice->channel; + ++_outputTableReady; } - - *(voice->amplitudeOutput) = ((volume >> 4) | (volume & 0xF0)) & voice->channel; - ++_outputTableReady; } } void Player_V2CMS::processChannel(Voice2 *channel) { ++_outputTableReady; switch (channel->nextProcessState) { - case PROCESS_RELEASE: - processRelease(channel); - break; - - case PROCESS_ATTACK: + case Voice2::kEnvelopeAttack: processAttack(channel); break; - case PROCESS_DECAY: + case Voice2::kEnvelopeDecay: processDecay(channel); break; - case PROCESS_SUSTAIN: + case Voice2::kEnvelopeSustain: processSustain(channel); break; - case PROCESS_VIBRATO: - processVibrato(channel); - break; - - default: + case Voice2::kEnvelopeRelease: + processRelease(channel); break; } } void Player_V2CMS::processRelease(Voice2 *channel) { - channel->curVolume -= channel->releaseRate; - if (channel->curVolume < 0) - channel->curVolume = 0; + int newVolume = channel->curVolume - channel->releaseRate; + if (newVolume < 0) + newVolume = 0; + + channel->curVolume = newVolume; processVibrato(channel); } void Player_V2CMS::processAttack(Voice2 *channel) { - channel->curVolume += channel->attackRate; - if (channel->curVolume >= 0) { - if (channel->curVolume <= channel->maxAmpl) - return processVibrato(channel); + int newVolume = channel->curVolume + channel->attackRate; + if (newVolume > channel->maxAmpl) { + channel->curVolume = channel->maxAmpl; + channel->nextProcessState = Voice2::kEnvelopeDecay; + } else { + channel->curVolume = newVolume; } - channel->curVolume = channel->maxAmpl; - channel->nextProcessState = PROCESS_DECAY; + processVibrato(channel); } void Player_V2CMS::processDecay(Voice2 *channel) { - channel->curVolume -= channel->decayRate; - if (channel->curVolume >= 0) { - if (channel->curVolume > channel->sustainRate) - return processVibrato(channel); + int newVolume = channel->curVolume - channel->decayRate; + if (newVolume <= channel->sustainRate) { + channel->curVolume = channel->sustainRate; + channel->nextProcessState = Voice2::kEnvelopeSustain; + } else { + channel->curVolume = newVolume; } - channel->curVolume = channel->sustainRate; - channel->nextProcessState = PROCESS_SUSTAIN; + processVibrato(channel); } void Player_V2CMS::processSustain(Voice2 *channel) { if (channel->unkVibratoRate) { - int volume = (int)channel->curVolume + (int)channel->unkRate; + int16 volume = channel->curVolume + channel->unkRate; if (volume & 0xFF00) { - volume = ((~volume) >> 8) & 0xFF; + volume = int8(volume >> 8); + volume = -volume; } + channel->curVolume = volume; - --(channel->unkCount); + --channel->unkCount; if (!channel->unkCount) { - channel->unkRate = ~(channel->unkRate); + channel->unkRate = -channel->unkRate; channel->unkCount = (channel->unkVibratoDepth & 0x0F) << 1; } } @@ -557,12 +443,13 @@ void Player_V2CMS::processSustain(Voice2 *channel) { void Player_V2CMS::processVibrato(Voice2 *channel) { if (channel->vibratoRate) { - uint16 temp = channel->curFreq + channel->curVibratoRate; + int16 temp = channel->curFreq + channel->curVibratoRate; channel->curOctave += (temp & 0xFF00) >> 8; channel->curFreq = temp & 0xFF; - --(channel->curVibratoUnk); + + --channel->curVibratoUnk; if (!channel->curVibratoUnk) { - channel->curVibratoRate = ~(channel->curVibratoRate); + channel->curVibratoRate = -channel->curVibratoRate; channel->curVibratoUnk = (channel->vibratoDepth & 0x0F) << 1; } } @@ -572,25 +459,16 @@ void Player_V2CMS::processVibrato(Voice2 *channel) { output = channel->freqOutput; *output = channel->curFreq; output = channel->octaveOutput; - *output = ((((channel->curOctave >> 4) | (channel->curOctave & 0x0F)) & _octaveMask) | ((~_octaveMask) & *output)); + *output = (((channel->curOctave << 4) | (channel->curOctave & 0x0F)) & _octaveMask) | ((~_octaveMask) & *output); } void Player_V2CMS::offAllChannels() { - warning("offAllChannels STUB"); -/* - // after using this sound can not be played anymore (since it would deinit the emulator) - static const byte cmsOffData[10*2] = { - 0x1C, 0x02, - 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, - 0x14, 0x3F, 0x15, 0x00, 0x16, 0x00 - }; - for (int cmsPort = 0x220, i = 0; i < 2; cmsPort += 2, ++i) { - for (int off = 0; off < 10; ++off) { - _cmsEmu->portWrite(cmsPort+1, cmsOffData[off*2]); - _cmsEmu->portWrite(cmsPort, cmsOffData[off*2+1]); + for (int off = 1; off <= 10; ++off) { + _cmsEmu->portWrite(cmsPort+1, _cmsInitData[off*2]); + _cmsEmu->portWrite(cmsPort, _cmsInitData[off*2+1]); } - }*/ + } } Player_V2CMS::Voice2 *Player_V2CMS::getFreeVoice() { @@ -637,8 +515,10 @@ void Player_V2CMS::playNote(byte *&data) { freeVoice->sustainRate = voice->sustain; freeVoice->releaseRate = voice->release; freeVoice->octaveAdd = voice->octadd; - freeVoice->vibratoRate = freeVoice->curVibratoRate = voice->vibrato; - freeVoice->unkVibratoRate = freeVoice->unkRate = voice->vibrato2; + freeVoice->vibratoRate = freeVoice->curVibratoRate = voice->vibrato & 0xFF; + freeVoice->vibratoDepth = freeVoice->curVibratoUnk = voice->vibrato >> 8; + freeVoice->unkVibratoRate = freeVoice->unkRate = voice->vibrato2 & 0xFF; + freeVoice->unkVibratoDepth = freeVoice->unkCount = voice->vibrato2 >> 8; freeVoice->maxAmpl = 0xFF; uint8 rate = freeVoice->attackRate; @@ -650,7 +530,14 @@ void Player_V2CMS::playNote(byte *&data) { rate -= freeVoice->attackRate; freeVoice->curVolume = rate; freeVoice->playingNote = *data; - int octave = octaveTable[(*data + 3) << 1] + freeVoice->octaveAdd - 3; + + int effectiveNote = freeVoice->playingNote + 3; + if (effectiveNote < 0 || effectiveNote >= ARRAYSIZE(_midiNotes)) { + warning("Player_V2CMS::playNote: Note %d out of bounds", effectiveNote); + effectiveNote = CLIP<int>(effectiveNote, 0, ARRAYSIZE(_midiNotes) - 1); + } + + int octave = _midiNotes[effectiveNote].baseOctave + freeVoice->octaveAdd - 3; if (octave < 0) octave = 0; if (octave > 7) @@ -658,10 +545,10 @@ void Player_V2CMS::playNote(byte *&data) { if (!octave) ++octave; freeVoice->curOctave = octave; - freeVoice->curFreq = freqTable[volume << 2]; + freeVoice->curFreq = _midiNotes[effectiveNote].frequency; freeVoice->curVolume = 0; - freeVoice->nextProcessState = PROCESS_ATTACK; - if (_lastMidiCommand & 1) + freeVoice->nextProcessState = Voice2::kEnvelopeAttack; + if (!(_lastMidiCommand & 1)) freeVoice->channel = 0xF0; else freeVoice->channel = 0x0F; @@ -672,35 +559,27 @@ void Player_V2CMS::playNote(byte *&data) { Player_V2CMS::Voice2 *Player_V2CMS::getPlayVoice(byte param) { byte channelNum = _lastMidiCommand & 0x0F; - Voice2 *channel = _midiChannel[channelNum]; + Voice2 *curVoice = _midiChannel[channelNum]; - if (channel) { - Voice2 *backUp = 0; + if (curVoice) { + Voice2 *prevVoice = 0; while (true) { - if (channel->playingNote == param) + if (curVoice->playingNote == param) break; - backUp = channel; - channel = channel->nextVoice; - if (!channel) + prevVoice = curVoice; + curVoice = curVoice->nextVoice; + if (!curVoice) return 0; } - Voice2 *backUp2 = channel->nextVoice; - { - Voice2 *temp = backUp; - backUp = channel; - channel = temp; - } - if (channel) { - channel->nextVoice = backUp2; - } else { - _midiChannel[channelNum] = backUp2; - } - channel = backUp; + if (prevVoice) + prevVoice->nextVoice = curVoice->nextVoice; + else + _midiChannel[channelNum] = curVoice->nextVoice; } - return channel; + return curVoice; } void Player_V2CMS::clearNote(byte *&data) { @@ -708,22 +587,18 @@ void Player_V2CMS::clearNote(byte *&data) { if (voice) { voice->chanNumber = 0xFF; voice->nextVoice = 0; - voice->nextProcessState = PROCESS_RELEASE; + voice->nextProcessState = Voice2::kEnvelopeRelease; } data += 2; } void Player_V2CMS::play() { _octaveMask = 0xF0; - channel_data *chan = &(_channels[0].d); + channel_data *chan = &_channels[0].d; - static byte volumeReg[4] = { 0x00, 0x00, 0x00, 0x00 }; - static byte octaveReg[4] = { 0x66, 0x66, 0x66, 0x66 }; - static byte freqReg[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + MusicChip &cms = _cmsChips[0]; + byte noiseGen = 3; - static byte freqEnable = 0x3E; - static byte noiseEnable = 0x01; - static byte noiseGen = 0x02; for (int i = 1; i <= 4; ++i) { if (chan->time_left) { uint16 freq = chan->freq; @@ -733,8 +608,8 @@ void Player_V2CMS::play() { noiseGen = freq & 0xFF; } else { noiseGen = 3; - freqReg[0] = freqReg[3]; - octaveReg[0] = (octaveReg[0] & 0xF0) | ((octaveReg[1] & 0xF0) >> 4); + cms.freq[0] = cms.freq[3]; + cms.octave[0] = (cms.octave[0] & 0xF0) | ((cms.octave[1] & 0xF0) >> 4); } } else { if (freq == 0) { @@ -760,17 +635,18 @@ void Player_V2CMS::play() { oct |= cmsOct; oct &= _octaveMask; - oct |= ((~_octaveMask) & octaveReg[((i & 3) >> 1)]); - octaveReg[((i & 3) >> 1)] = oct; + oct |= (~_octaveMask) & cms.octave[(i & 3) >> 1]; + cms.octave[(i & 3) >> 1] = oct; - freq >>= -(cmsOct-9); - freqReg[(i&3)] = (-(freq-511)) & 0xFF; + freq >>= -(cmsOct - 9); + cms.freq[i & 3] = (-(freq - 511)) & 0xFF; } - volumeReg[i & 3] = volumeTable[chan->volume >> 12]; + cms.ampl[i & 3] = _volumeTable[chan->volume >> 12]; } else { - volumeReg[i & 3] = 0; + cms.ampl[i & 3] = 0; } - chan = &(_channels[i].d); + + chan = &_channels[i].d; _octaveMask ^= 0xFF; } @@ -778,29 +654,29 @@ void Player_V2CMS::play() { // the right channels amplitude is set // with the low value the left channels amplitude _cmsEmu->portWrite(0x221, 0); - _cmsEmu->portWrite(0x220, volumeReg[0]); + _cmsEmu->portWrite(0x220, cms.ampl[0]); _cmsEmu->portWrite(0x221, 1); - _cmsEmu->portWrite(0x220, volumeReg[1]); + _cmsEmu->portWrite(0x220, cms.ampl[1]); _cmsEmu->portWrite(0x221, 2); - _cmsEmu->portWrite(0x220, volumeReg[2]); + _cmsEmu->portWrite(0x220, cms.ampl[2]); _cmsEmu->portWrite(0x221, 3); - _cmsEmu->portWrite(0x220, volumeReg[3]); + _cmsEmu->portWrite(0x220, cms.ampl[3]); _cmsEmu->portWrite(0x221, 8); - _cmsEmu->portWrite(0x220, freqReg[0]); + _cmsEmu->portWrite(0x220, cms.freq[0]); _cmsEmu->portWrite(0x221, 9); - _cmsEmu->portWrite(0x220, freqReg[1]); + _cmsEmu->portWrite(0x220, cms.freq[1]); _cmsEmu->portWrite(0x221, 10); - _cmsEmu->portWrite(0x220, freqReg[2]); + _cmsEmu->portWrite(0x220, cms.freq[2]); _cmsEmu->portWrite(0x221, 11); - _cmsEmu->portWrite(0x220, freqReg[3]); + _cmsEmu->portWrite(0x220, cms.freq[3]); _cmsEmu->portWrite(0x221, 0x10); - _cmsEmu->portWrite(0x220, octaveReg[0]); + _cmsEmu->portWrite(0x220, cms.octave[0]); _cmsEmu->portWrite(0x221, 0x11); - _cmsEmu->portWrite(0x220, octaveReg[1]); + _cmsEmu->portWrite(0x220, cms.octave[1]); _cmsEmu->portWrite(0x221, 0x14); - _cmsEmu->portWrite(0x220, freqEnable); + _cmsEmu->portWrite(0x220, 0x3E); _cmsEmu->portWrite(0x221, 0x15); - _cmsEmu->portWrite(0x220, noiseEnable); + _cmsEmu->portWrite(0x220, 0x01); _cmsEmu->portWrite(0x221, 0x16); _cmsEmu->portWrite(0x220, noiseGen); } @@ -838,4 +714,71 @@ void Player_V2CMS::playMusicChips(const MusicChip *table) { } while ((cmsPort & 2) == 0); } +const Player_V2CMS::MidiNote Player_V2CMS::_midiNotes[132] = { + { 3, 0 }, { 31, 0 }, { 58, 0 }, { 83, 0 }, + { 107, 0 }, { 130, 0 }, { 151, 0 }, { 172, 0 }, + { 191, 0 }, { 209, 0 }, { 226, 0 }, { 242, 0 }, + { 3, 1 }, { 31, 1 }, { 58, 1 }, { 83, 1 }, + { 107, 1 }, { 130, 1 }, { 151, 1 }, { 172, 1 }, + { 191, 1 }, { 209, 1 }, { 226, 1 }, { 242, 1 }, + { 3, 2 }, { 31, 2 }, { 58, 2 }, { 83, 2 }, + { 107, 2 }, { 130, 2 }, { 151, 2 }, { 172, 2 }, + { 191, 2 }, { 209, 2 }, { 226, 2 }, { 242, 2 }, + { 3, 3 }, { 31, 3 }, { 58, 3 }, { 83, 3 }, + { 107, 3 }, { 130, 3 }, { 151, 3 }, { 172, 3 }, + { 191, 3 }, { 209, 3 }, { 226, 3 }, { 242, 3 }, + { 3, 4 }, { 31, 4 }, { 58, 4 }, { 83, 4 }, + { 107, 4 }, { 130, 4 }, { 151, 4 }, { 172, 4 }, + { 191, 4 }, { 209, 4 }, { 226, 4 }, { 242, 4 }, + { 3, 5 }, { 31, 5 }, { 58, 5 }, { 83, 5 }, + { 107, 5 }, { 130, 5 }, { 151, 5 }, { 172, 5 }, + { 191, 5 }, { 209, 5 }, { 226, 5 }, { 242, 5 }, + { 3, 6 }, { 31, 6 }, { 58, 6 }, { 83, 6 }, + { 107, 6 }, { 130, 6 }, { 151, 6 }, { 172, 6 }, + { 191, 6 }, { 209, 6 }, { 226, 6 }, { 242, 6 }, + { 3, 7 }, { 31, 7 }, { 58, 7 }, { 83, 7 }, + { 107, 7 }, { 130, 7 }, { 151, 7 }, { 172, 7 }, + { 191, 7 }, { 209, 7 }, { 226, 7 }, { 242, 7 }, + { 3, 8 }, { 31, 8 }, { 58, 8 }, { 83, 8 }, + { 107, 8 }, { 130, 8 }, { 151, 8 }, { 172, 8 }, + { 191, 8 }, { 209, 8 }, { 226, 8 }, { 242, 8 }, + { 3, 9 }, { 31, 9 }, { 58, 9 }, { 83, 9 }, + { 107, 9 }, { 130, 9 }, { 151, 9 }, { 172, 9 }, + { 191, 9 }, { 209, 9 }, { 226, 9 }, { 242, 9 }, + { 3, 10 }, { 31, 10 }, { 58, 10 }, { 83, 10 }, + { 107, 10 }, { 130, 10 }, { 151, 10 }, { 172, 10 }, + { 191, 10 }, { 209, 10 }, { 226, 10 }, { 242, 10 } +}; + +const byte Player_V2CMS::_attackRate[16] = { + 0, 2, 4, 7, 14, 26, 48, 82, + 128, 144, 160, 176, 192, 208, 224, 255 +}; + +const byte Player_V2CMS::_decayRate[16] = { + 0, 1, 2, 3, 4, 6, 12, 24, + 48, 96, 192, 215, 255, 255, 255, 255 +}; + +const byte Player_V2CMS::_sustainRate[16] = { + 255, 180, 128, 96, 80, 64, 56, 48, + 42, 36, 32, 28, 24, 20, 16, 0 +}; + +const byte Player_V2CMS::_releaseRate[16] = { + 0, 1, 2, 4, 6, 9, 14, 22, + 36, 56, 80, 100, 120, 140, 160, 255 +}; + +const byte Player_V2CMS::_volumeTable[16] = { + 0x00, 0x10, 0x10, 0x11, 0x11, 0x21, 0x22, 0x22, + 0x33, 0x44, 0x55, 0x66, 0x88, 0xAA, 0xCC, 0xFF +}; + +const byte Player_V2CMS::_cmsInitData[26] = { + 0x1C, 0x02, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, + 0x14, 0x3F, 0x15, 0x00, 0x16, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1C, 0x01 +}; + } // End of namespace Scumm diff --git a/engines/scumm/player_v2cms.h b/engines/scumm/player_v2cms.h index f7dc0c16b1..cbad46fe5d 100644 --- a/engines/scumm/player_v2cms.h +++ b/engines/scumm/player_v2cms.h @@ -42,17 +42,14 @@ public: virtual void startSound(int sound); virtual void stopSound(int sound); virtual void stopAllSounds(); -// virtual int getMusicTimer(); + virtual int getMusicTimer(); virtual int getSoundStatus(int sound) const; // AudioStream API - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return true; } - bool endOfData() const { return false; } - int getRate() const { return _sampleRate; } - -protected: + virtual int readBuffer(int16 *buffer, const int numSamples); + virtual bool isStereo() const { return true; } +private: #include "common/pack-start.h" // START STRUCT PACKING struct Voice { byte attack; @@ -72,12 +69,12 @@ protected: uint8 channel; int8 sustainLevel; - int8 attackRate; + uint8 attackRate; uint8 maxAmpl; - int8 decayRate; - int8 sustainRate; - int8 releaseRate; - int8 releaseTime; + uint8 decayRate; + uint8 sustainRate; + uint8 releaseRate; + uint8 releaseTime; int8 vibratoRate; int8 vibratoDepth; @@ -90,10 +87,17 @@ protected: int8 unkRate; int8 unkCount; - int nextProcessState; - int8 curVolume; - int8 curOctave; - int8 curFreq; + enum EnvelopeState { + kEnvelopeAttack, + kEnvelopeDecay, + kEnvelopeSustain, + kEnvelopeRelease + }; + + EnvelopeState nextProcessState; + uint8 curVolume; + uint8 curOctave; + uint8 curFreq; int8 octaveAdd; @@ -114,8 +118,8 @@ protected: Voice2 _cmsVoices[8]; MusicChip _cmsChips[2]; - int8 _tempo; - int8 _tempoSum; + uint8 _tempo; + uint8 _tempoSum; byte _looping; byte _octaveMask; int16 _midiDelay; @@ -128,9 +132,9 @@ protected: byte _lastMidiCommand; uint _outputTableReady; - byte _clkFrequenz; - byte _restart; - byte _curSno; + byte _voiceTimer; + + int _musicTimer, _musicTimerTicks; void loadMidiData(byte *data, int sound); void play(); @@ -147,15 +151,25 @@ protected: void clearNote(byte *&data); void offAllChannels(); void playVoice(); - void processMidiData(uint ticks); + void processMidiData(); Voice2 *getFreeVoice(); Voice2 *getPlayVoice(byte param); - // from Player_V2 -protected: - CMSEmulator *_cmsEmu; + struct MidiNote { + byte frequency; + byte baseOctave; + }; + + static const MidiNote _midiNotes[132]; + static const byte _attackRate[16]; + static const byte _decayRate[16]; + static const byte _sustainRate[16]; + static const byte _releaseRate[16]; + static const byte _volumeTable[16]; + static const byte _cmsInitData[26]; + CMSEmulator *_cmsEmu; }; } // End of namespace Scumm diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 3cc710c207..870ec8cdf7 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -686,12 +686,7 @@ Graphics::Surface *ScummEngine::loadThumbnailFromSlot(const char *target, int sl Graphics::Surface *thumb = 0; if (Graphics::checkThumbnailHeader(*in)) { - thumb = new Graphics::Surface(); - assert(thumb); - if (!Graphics::loadThumbnail(*in, *thumb)) { - delete thumb; - thumb = 0; - } + thumb = Graphics::loadThumbnail(*in); } delete in; diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 8f555818f4..319eddf871 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Sun Apr 17 10:46:26 2011 + This file was generated by the md5table tool on Wed Aug 3 03:14:00 2011 DO NOT EDIT MANUALLY! */ @@ -99,7 +99,7 @@ static const MD5Table md5table[] = { { "1ed22f601f8b3695804a6583cc3083f1", "puttrace", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "1f2e62b5a9c50589fc342285a6bb3a27", "freddi", "HE 73", "", -1, Common::HE_ISR, Common::kPlatformWindows }, { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "Floppy", "Floppy", 12030, Common::DE_DEU, Common::kPlatformPC }, - { "1ff5997c78fbd0a841a75ef15a05d9d5", "BluesBirthday", "", "Red", -1, Common::EN_ANY, Common::kPlatformWindows }, + { "1ff5997c78fbd0a841a75ef15a05d9d5", "BluesBirthday", "Red", "Red", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "2012f854d83d9cc6f73b2b544cd8bbf8", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "20176076d708bf14407bcc9bdcd7a418", "pajama3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "204453e33456c4faa26e276229fe5b76", "spyfox2", "", "Demo", 14689, Common::DE_DEU, Common::kPlatformWindows }, @@ -403,7 +403,7 @@ static const MD5Table md5table[] = { { "9781422e4288dbc090720e4563168ba7", "puttzoo", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "981e1e1891f2be7e25a01f50ae55a5af", "puttrace", "HE 98", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, - { "99128b6a5bdd9831d9682fb8b5cbf8d4", "BluesBirthday", "", "Yellow", -1, Common::EN_ANY, Common::kPlatformUnknown }, + { "99128b6a5bdd9831d9682fb8b5cbf8d4", "BluesBirthday", "Yellow", "Yellow", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "99a3699f80b8f776efae592b44b9b991", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC }, { "99b6f822b0b2612415407865438697d6", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, { "9b7452b5cd6d3ffb2b2f5118010af84f", "ft", "Demo", "Demo", 116463537, Common::EN_ANY, Common::kPlatformMacintosh }, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 0f01e39459..283b527878 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -299,7 +299,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _haveActorSpeechMsg = false; _useTalkAnims = false; _defaultTalkDelay = 0; - _musicType = MDT_NONE; _saveSound = 0; memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags)); memset(_scaleSlots, 0, sizeof(_scaleSlots)); @@ -1746,40 +1745,36 @@ void ScummEngine::setupMusic(int midi) { switch (MidiDriver::getMusicType(dev)) { case MT_NULL: - _musicType = MDT_NONE; + _sound->_musicType = MDT_NONE; break; case MT_PCSPK: - _musicType = MDT_PCSPK; + _sound->_musicType = MDT_PCSPK; break; case MT_PCJR: - _musicType = MDT_PCJR; + _sound->_musicType = MDT_PCJR; break; - //case MT_CMS: -#if 1 - _musicType = MDT_ADLIB; -#else - _musicType = MDT_CMS; // Still has number of bugs, disable by default -#endif + case MT_CMS: + _sound->_musicType = MDT_CMS; break; case MT_TOWNS: - _musicType = MDT_TOWNS; + _sound->_musicType = MDT_TOWNS; break; case MT_ADLIB: - _musicType = MDT_ADLIB; + _sound->_musicType = MDT_ADLIB; break; case MT_C64: - _musicType = MDT_C64; + _sound->_musicType = MDT_C64; break; case MT_APPLEIIGS: - _musicType = MDT_APPLEIIGS; + _sound->_musicType = MDT_APPLEIIGS; break; default: - _musicType = MDT_MIDI; + _sound->_musicType = MDT_MIDI; break; } if ((_game.id == GID_MONKEY_EGA || (_game.id == GID_LOOM && _game.version == 3)) - && (_game.platform == Common::kPlatformPC) && _musicType == MDT_MIDI) { + && (_game.platform == Common::kPlatformPC) && _sound->_musicType == MDT_MIDI) { Common::String fileName; bool missingFile = false; if (_game.id == GID_LOOM) { @@ -1809,7 +1804,7 @@ void ScummEngine::setupMusic(int midi) { "but %s is missing. Using AdLib instead."), fileName.c_str()), _("OK")); dialog.runModal(); - _musicType = MDT_ADLIB; + _sound->_musicType = MDT_ADLIB; } } @@ -1823,9 +1818,9 @@ void ScummEngine::setupMusic(int midi) { * automatically when samples need to be generated */ if (!_mixer->isReady()) { warning("Sound mixer initialization failed"); - if (_musicType == MDT_ADLIB || _musicType == MDT_PCSPK || _musicType == MDT_PCJR || _musicType == MDT_CMS) { + if (_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR || _sound->_musicType == MDT_CMS) { dev = 0; - _musicType = MDT_NONE; + _sound->_musicType = MDT_NONE; warning("MIDI driver depends on sound mixer, switching to null MIDI driver"); } } @@ -1857,9 +1852,9 @@ void ScummEngine::setupMusic(int midi) { _musicEngine = new Player_V1(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); } else if (_game.version <= 2) { _musicEngine = new Player_V2(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); - } else if ((_musicType == MDT_PCSPK || _musicType == MDT_PCJR) && (_game.version > 2 && _game.version <= 4)) { + } else if ((_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR) && (_game.version > 2 && _game.version <= 4)) { _musicEngine = new Player_V2(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); - } else if (_musicType == MDT_CMS) { + } else if (_sound->_musicType == MDT_CMS) { _musicEngine = new Player_V2CMS(this, _mixer); } else if (_game.platform == Common::kPlatform3DO && _game.heversion <= 62) { // 3DO versions use digital music and sound samples. @@ -1871,15 +1866,15 @@ void ScummEngine::setupMusic(int midi) { MidiDriver *nativeMidiDriver = 0; MidiDriver *adlibMidiDriver = 0; - if (_musicType != MDT_ADLIB && _musicType != MDT_TOWNS && _musicType != MDT_PCSPK) + if (_sound->_musicType != MDT_ADLIB && _sound->_musicType != MDT_TOWNS && _sound->_musicType != MDT_PCSPK) nativeMidiDriver = MidiDriver::createMidi(dev); if (nativeMidiDriver != NULL && _native_mt32) nativeMidiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && _musicType != MDT_PCSPK && (midi & MDT_ADLIB); - if (_musicType == MDT_ADLIB || _musicType == MDT_TOWNS || multi_midi) { - adlibMidiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(_musicType == MDT_TOWNS ? MDT_TOWNS : MDT_ADLIB)); + bool multi_midi = ConfMan.getBool("multi_midi") && _sound->_musicType != MDT_NONE && _sound->_musicType != MDT_PCSPK && (midi & MDT_ADLIB); + if (_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS || multi_midi) { + adlibMidiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(_sound->_musicType == MDT_TOWNS ? MDT_TOWNS : MDT_ADLIB)); adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_game.features & GF_SMALL_HEADER) ? 1 : 0); - } else if (_musicType == MDT_PCSPK) { + } else if (_sound->_musicType == MDT_PCSPK) { adlibMidiDriver = new PcSpkDriver(_mixer); } @@ -1909,7 +1904,7 @@ void ScummEngine::setupMusic(int midi) { _imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1); _imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1); } - if (_musicType == MDT_PCSPK) + if (_sound->_musicType == MDT_PCSPK) _imuse->property(IMuse::PROP_PC_SPEAKER, 1); } } diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index e503af750d..04a175e732 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -40,8 +40,6 @@ #include "scumm/detection.h" #include "scumm/script.h" -#include "audio/mididrv.h" - #ifdef __DS__ /* This disables the dual layer mode which is used in FM-Towns versions * of SCUMM games and which emulates the behavior of the original code. @@ -235,7 +233,8 @@ enum ScummGameId { GID_PUTTMOON, GID_FUNPACK, GID_FREDDI3, - GID_BIRTHDAY, + GID_BIRTHDAYRED, + GID_BIRTHDAYYELLOW, GID_TREASUREHUNT, GID_PUTTRACE, GID_FUNSHOP, // Used for all three funshops @@ -1084,7 +1083,6 @@ protected: int _saveSound; bool _native_mt32; bool _enable_gs; - MidiDriverFlags _musicType; bool _copyProtection; public: diff --git a/engines/scumm/smush/codec37.cpp b/engines/scumm/smush/codec37.cpp index dcc8ee3c19..344057e3ac 100644 --- a/engines/scumm/smush/codec37.cpp +++ b/engines/scumm/smush/codec37.cpp @@ -571,4 +571,3 @@ void Codec37Decoder::decode(byte *dst, const byte *src) { } } // End of namespace Scumm - diff --git a/engines/scumm/smush/smush_font.cpp b/engines/scumm/smush/smush_font.cpp index 7765bf1292..5cfa0ea519 100644 --- a/engines/scumm/smush/smush_font.cpp +++ b/engines/scumm/smush/smush_font.cpp @@ -258,4 +258,3 @@ void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int } } // End of namespace Scumm - diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index c3cad19fdc..33db70985d 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -84,6 +84,8 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer) memset(_soundQue, 0, sizeof(_soundQue)); memset(_soundQue2, 0, sizeof(_soundQue2)); memset(_mouthSyncTimes, 0, sizeof(_mouthSyncTimes)); + + _musicType = MDT_NONE; } Sound::~Sound() { @@ -1016,7 +1018,7 @@ void Sound::startCDTimer() { // appears. _vm->getTimerManager()->removeTimerProc(&cd_timer_handler); - _vm->getTimerManager()->installTimerProc(&cd_timer_handler, 100700, _vm); + _vm->getTimerManager()->installTimerProc(&cd_timer_handler, 100700, _vm, "scummCDtimer"); } void Sound::stopCDTimer() { @@ -1094,7 +1096,7 @@ int ScummEngine::readSoundResource(ResId idx) { switch (basetag) { case MKTAG('M','I','D','I'): case MKTAG('i','M','U','S'): - if (_musicType != MDT_PCSPK && _musicType != MDT_PCJR) { + if (_sound->_musicType != MDT_PCSPK && _sound->_musicType != MDT_PCJR) { _fileHandle->seek(-8, SEEK_CUR); _fileHandle->read(_res->createResource(rtSound, idx, total_size + 8), total_size + 8); return 1; @@ -1118,7 +1120,7 @@ int ScummEngine::readSoundResource(ResId idx) { break; case MKTAG('A','D','L',' '): pri = 1; - if (_musicType == MDT_ADLIB || _musicType == MDT_TOWNS) + if (_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS) pri = 10; break; case MKTAG('A','M','I',' '): @@ -1137,7 +1139,7 @@ int ScummEngine::readSoundResource(ResId idx) { break; case MKTAG('S','P','K',' '): pri = -1; - if (_musicType == MDT_PCSPK || _musicType == MDT_PCJR) + if (_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR) pri = 11; break; } @@ -1145,7 +1147,7 @@ int ScummEngine::readSoundResource(ResId idx) { // We only allow SPK resources for PC Speaker, PCJr and CMS here // since other resource would sound horribly with their output // drivers. - if ((_musicType == MDT_PCSPK || _musicType == MDT_PCJR || _musicType == MDT_CMS) && pri != 11) + if ((_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR || _sound->_musicType == MDT_CMS) && pri != 11) pri = -1; // We only allow ADL resources when AdLib or FM-Towns is used as @@ -1155,7 +1157,7 @@ int ScummEngine::readSoundResource(ResId idx) { // only contains a ROL resource for sound id 60. Formerly we tried // to play that via the AdLib or FM-Towns audio driver resulting // in strange noises. Now we behave like the original did. - if ((_musicType == MDT_ADLIB || _musicType == MDT_TOWNS) && pri != 10) + if ((_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS) && pri != 10) pri = -1; debugC(DEBUG_RESOURCE, " tag: %s, total_size=%d, pri=%d", tag2str(tag), size, pri); @@ -1997,6 +1999,14 @@ static void convertADResource(ResourceManager *res, const GameSettings& game, Re break; case 0x80: + // FIXME: This is incorrect. The original uses 0x80 for + // looping a single channel. We currently interpret it as stop + // thus we won't get looping for sound effects. It should + // always jump to the start of the channel. + // + // Since we convert the data to MIDI and we cannot only loop a + // single channel via MIDI fixing this will require some more + // thought. track_time[ch] = -1; src_ptr ++; break; @@ -2087,7 +2097,7 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) { } } - if ((_musicType == MDT_PCSPK || _musicType == MDT_PCJR) && wa_offs != 0) { + if ((_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR) && wa_offs != 0) { if (_game.features & GF_OLD_BUNDLE) { _fileHandle->seek(wa_offs, SEEK_SET); _fileHandle->read(_res->createResource(rtSound, idx, wa_size), wa_size); @@ -2096,18 +2106,37 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) { _fileHandle->read(_res->createResource(rtSound, idx, wa_size + 6), wa_size + 6); } return 1; - } else if (_musicType == MDT_CMS && ad_offs != 0) { + } else if (_sound->_musicType == MDT_CMS) { if (_game.features & GF_OLD_BUNDLE) { - _fileHandle->seek(wa_offs + wa_size + 6, SEEK_SET); - byte musType = _fileHandle->readByte(); + bool hasAdLibMusicTrack = false; + + if (ad_offs) { + _fileHandle->seek(ad_offs + 4 + 2, SEEK_SET); + hasAdLibMusicTrack = (_fileHandle->readByte() == 0x80); + } - if (musType == 0x80) { + if (hasAdLibMusicTrack) { _fileHandle->seek(ad_offs, SEEK_SET); _fileHandle->read(_res->createResource(rtSound, idx, ad_size), ad_size); } else { _fileHandle->seek(wa_offs, SEEK_SET); _fileHandle->read(_res->createResource(rtSound, idx, wa_size), wa_size); } + } else { + bool hasAdLibMusicTrack = false; + + if (ad_offs) { + _fileHandle->seek(ad_offs + 2, SEEK_SET); + hasAdLibMusicTrack = (_fileHandle->readByte() == 0x80); + } + + if (hasAdLibMusicTrack) { + _fileHandle->seek(ad_offs - 4, SEEK_SET); + _fileHandle->read(_res->createResource(rtSound, idx, ad_size + 4), ad_size + 4); + } else { + _fileHandle->seek(wa_offs - 6, SEEK_SET); + _fileHandle->read(_res->createResource(rtSound, idx, wa_size + 6), wa_size + 6); + } } } else if (ad_offs != 0) { // AD resources have a header, instrument definitions and one MIDI track. diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h index 03659ceff1..e9a37ac9fa 100644 --- a/engines/scumm/sound.h +++ b/engines/scumm/sound.h @@ -24,6 +24,7 @@ #include "common/scummsys.h" #include "audio/audiostream.h" +#include "audio/mididrv.h" #include "audio/mixer.h" #include "scumm/saveload.h" @@ -90,6 +91,8 @@ public: byte _sfxMode; uint _lastSound; + MidiDriverFlags _musicType; + public: Sound(ScummEngine *parent, Audio::Mixer *mixer); virtual ~Sound(); diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index 2d2209c155..61bb89328d 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -1127,8 +1127,6 @@ int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) } num += (_game.version == 8) ? 4 : 2; } - } else if (_game.id == GID_DIG && (chr == 1 || chr == 2 || chr == 3 || chr == 8)) { - // Skip these characters } else { if ((chr != '@') || (_game.id == GID_CMI && _language == Common::ZH_TWN) || (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) || @@ -1142,6 +1140,14 @@ int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) if (dst >= end) error("convertMessageToString: buffer overflow"); } + + // WORKAROUND: Russian The Dig pads messages with 03. No idea why + // it does not work as is with our rendering code, thus fixing it + // with a workaround. + if (_game.id == GID_DIG) { + while (*(dst - 1) == 0x03) + dst--; + } *dst = 0; return dstSize - (end - dst); diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index 4527d7a121..26a6a2f3b1 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -25,9 +25,12 @@ #include "scumm/scumm.h" #include "scumm/scumm_v0.h" #include "scumm/scumm_v8.h" +#include "scumm/sound.h" #include "scumm/he/intern_he.h" #include "scumm/he/logic_he.h" +#include "audio/mididrv.h" + namespace Scumm { void ScummEngine::setupScummVars() { @@ -722,7 +725,7 @@ void ScummEngine::resetScummVars() { // 2 CMS // 3 AdLib // 4 Roland - switch (_musicType) { + switch (_sound->_musicType) { case MDT_NONE: case MDT_PCSPK: VAR(VAR_SOUNDCARD) = 0; |