diff options
author | Paul Gilbert | 2011-08-12 21:33:45 +1000 |
---|---|---|
committer | Paul Gilbert | 2011-08-12 21:33:45 +1000 |
commit | b76c0af2f4fe9cafeafdde70867e159e076b2752 (patch) | |
tree | 49decc9da9eaa6a73579baf6820bbb5e0e06a297 | |
parent | f1f1d8bde084b44756480c7b724f356562ca02b1 (diff) | |
download | scummvm-rg350-b76c0af2f4fe9cafeafdde70867e159e076b2752.tar.gz scummvm-rg350-b76c0af2f4fe9cafeafdde70867e159e076b2752.tar.bz2 scummvm-rg350-b76c0af2f4fe9cafeafdde70867e159e076b2752.zip |
CGE: Work on implementing MIDI music playback.
Music playback is now sort of working, but it seems like only a beat track of the MIDI is getting played
-rw-r--r-- | engines/cge/cge.cpp | 11 | ||||
-rw-r--r-- | engines/cge/cge.h | 2 | ||||
-rw-r--r-- | engines/cge/cge_main.cpp | 12 | ||||
-rw-r--r-- | engines/cge/general.cpp | 16 | ||||
-rw-r--r-- | engines/cge/snddrv.h | 16 | ||||
-rw-r--r-- | engines/cge/sound.cpp | 99 | ||||
-rw-r--r-- | engines/cge/sound.h | 28 |
7 files changed, 102 insertions, 82 deletions
diff --git a/engines/cge/cge.cpp b/engines/cge/cge.cpp index 6fc23969c2..cfd941017e 100644 --- a/engines/cge/cge.cpp +++ b/engines/cge/cge.cpp @@ -165,7 +165,7 @@ void CGEEngine::setup() { _flag[i] = false; _mode = 0; - _soundOk = 0; + _soundOk = 1; _sprTv = NULL; _gameCase2Cpt = 0; @@ -186,6 +186,7 @@ CGEEngine::~CGEEngine() { DebugMan.clearAllDebugChannels(); delete _console; + _midiPlayer.killMidi(); // Delete engine objects delete _vga; @@ -208,9 +209,11 @@ CGEEngine::~CGEEngine() { delete _snail_; delete _hero; - for (int i = 0; _miniShpList[i]; ++i) - delete _miniShpList[i]; - delete[] _miniShpList; + if (_miniShpList) { + for (int i = 0; _miniShpList[i]; ++i) + delete _miniShpList[i]; + delete[] _miniShpList; + } freeCaveValues(); } diff --git a/engines/cge/cge.h b/engines/cge/cge.h index 55c97d0644..bd347c6e26 100644 --- a/engines/cge/cge.h +++ b/engines/cge/cge.h @@ -34,6 +34,7 @@ #include "engines/advancedDetector.h" #include "cge/console.h" #include "cge/bitmap.h" +#include "cge/sound.h" namespace CGE { @@ -141,6 +142,7 @@ public: Bar *_barriers; Common::RandomSource _randomSource; + MusicPlayer _midiPlayer; BitmapPtr *_miniShp; BitmapPtr *_miniShpList; int _startGameSlot; diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp index 0ce514c6bb..1dd6e49650 100644 --- a/engines/cge/cge_main.cpp +++ b/engines/cge/cge_main.cpp @@ -591,7 +591,7 @@ void CGEEngine::caveUp() { int BakRef = 1000 * _now; if (_music) - loadMidi(_now); + _midiPlayer.loadMidi(_now); showBak(BakRef); loadMapping(); @@ -927,9 +927,9 @@ void CGEEngine::switchMusic() { keyClick(); } if (_music) - loadMidi(_now); + _midiPlayer.loadMidi(_now); else - killMidi(); + _midiPlayer.killMidi(); } void CGEEngine::startCountDown() { @@ -1518,7 +1518,7 @@ void CGEEngine::runGame() { _sprite->step(_music); _snail_->addCom(kSnSeq, -1, _music, _sprite); if (!_music) - killMidi(); + _midiPlayer.killMidi(); if (INI_FILE::exist("MINI.SPR")) { _miniShp = new BitmapPtr[2]; @@ -1664,7 +1664,7 @@ bool CGEEngine::showTitle(const char *name) { _vga->copyPage(0, 2); _soundOk = 2; if (_music) - loadMidi(0); + _midiPlayer.loadMidi(0); } if (_mode < 2) { @@ -1742,7 +1742,7 @@ void CGEEngine::cge_main() { _horzLine->_flags._hide = true; if (_music && _soundOk) - loadMidi(0); + _midiPlayer.loadMidi(0); if (_startGameSlot != -1) { // Starting up a savegame from the launcher diff --git a/engines/cge/general.cpp b/engines/cge/general.cpp index 67068a9673..4d79dbeddc 100644 --- a/engines/cge/general.cpp +++ b/engines/cge/general.cpp @@ -270,26 +270,10 @@ bool IoHand::exist(const char *name) { return f.exists(name); } -void sndInit() { - warning("STUB: SNDInit"); -} - -void sndDone() { - // FIXME: STUB: SNDDone -} - void sndSetVolume() { warning("STUB: SNDSetVolume"); } -void sndMidiStart(uint8 *MIDFile) { - warning("STUB: SNDMIDIStart"); -} - -void sndMidiStop() { - // FIXME: STUB: sndMIDIStop -} - DataCk *loadWave(XFile *file) { byte *data = (byte *)malloc(file->size()); file->read(data, file->size()); diff --git a/engines/cge/snddrv.h b/engines/cge/snddrv.h index 44ccf47f94..0678971d0c 100644 --- a/engines/cge/snddrv.h +++ b/engines/cge/snddrv.h @@ -64,25 +64,9 @@ extern uint16 _midiEndFlag; // ****************************************************** // * Driver Code * // ****************************************************** -// Init Digi Device -void sndInit(); - -// Close Digi Device -void sndDone(); - // Set Volume void sndSetVolume(); -// Start MIDI File -void sndMidiStart(uint8 *MIDFile); - -// Stop MIDI File -void sndMidiStop(); - -// Play MIDI File (to be called while interrupting) -// WARNING: Uses ALL registers! -void sndMidiPlay(); - } // End of namespace CGE #endif diff --git a/engines/cge/sound.cpp b/engines/cge/sound.cpp index 2cb24df5ba..aa42df57bf 100644 --- a/engines/cge/sound.cpp +++ b/engines/cge/sound.cpp @@ -48,13 +48,11 @@ Sound::~Sound() { void Sound::close() { - killMidi(); - sndDone(); + _vm->_midiPlayer.killMidi(); } void Sound::open() { - sndInit(); play((*_fx)[30000], 8); } @@ -180,40 +178,6 @@ DataCk *Fx::operator [](int ref) { return _current; } - -static uint8 *midi = NULL; - - -void killMidi() { - sndMidiStop(); - if (midi) { - delete[] midi; - midi = NULL; - } -} - - -void loadMidi(int ref) { - static char fn[] = "00.MID"; - wtom(ref, fn, 10, 2); - if (INI_FILE::exist(fn)) { - killMidi(); - INI_FILE mid = fn; - if (mid._error == 0) { - uint16 siz = (uint16) mid.size(); - midi = new uint8[siz]; - if (midi) { - mid.read(midi, siz); - if (mid._error) - killMidi(); - else - sndMidiStart(midi); - } - } - } -} - - void *Patch(int pat) { void *p = NULL; static char fn[] = "PATCH000.SND"; @@ -234,4 +198,65 @@ void *Patch(int pat) { return p; } +MusicPlayer::MusicPlayer() { + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB); + _driver = MidiDriver::createMidi(dev); + _driver->open(); + _midiParser = NULL; + _data = NULL; +} + +MusicPlayer::~MusicPlayer() { + killMidi(); + _driver->close(); + delete _driver; +} + +void MusicPlayer::killMidi() { + if (_midiParser) { + // Stop MIDI playback + _midiParser->unloadMusic(); + _driver->setTimerCallback(NULL, NULL); + _driver->close(); + delete _midiParser; + delete _data; + + // Reset playback objects + _data = NULL; + _midiParser = NULL; + } +} + +void MusicPlayer::loadMidi(int ref) { + // Work out the filename and check the given MIDI file exists + Common::String filename = Common::String::format("%.2d.MID", ref); + if (!INI_FILE::exist(filename.c_str())) + return; + + // Stop any currently playing MIDI file + killMidi(); + + // Read in the data for the file + INI_FILE mid(filename.c_str()); + _dataSize = mid.size(); + _data = (byte *)malloc(_dataSize); + mid.read(_data, _dataSize); + + // Start playing the music + sndMidiStart(); +} + +void MusicPlayer::sndMidiStart() { + _midiParser = MidiParser::createParser_SMF(); + + if (_midiParser->loadMusic(_data, _dataSize)) { + _midiParser->setTrack(0); + _midiParser->setMidiDriver(_driver); + _midiParser->setTimerRate(_driver->getBaseTempo()); + + _midiParser->property(MidiParser::mpCenterPitchWheelOnUnload, 1); + _driver->setTimerCallback(_midiParser, MidiParser::timerCallback); + } +} + } // End of namespace CGE diff --git a/engines/cge/sound.h b/engines/cge/sound.h index 67b16fc888..9f7d20957e 100644 --- a/engines/cge/sound.h +++ b/engines/cge/sound.h @@ -30,14 +30,19 @@ #include "cge/wav.h" #include "cge/snddrv.h" -#include "cge/cge.h" #include "audio/audiostream.h" #include "audio/decoders/wave.h" #include "audio/fmopl.h" +#include "audio/mididrv.h" +#include "audio/midiparser.h" +#include "audio/midiplayer.h" #include "audio/mixer.h" +#include "common/memstream.h" namespace CGE { +class CGEEngine; + class Sound { public: SmpInfo _smpinf; @@ -74,8 +79,25 @@ public: DataCk *operator[](int ref); }; -void loadMidi(int ref); -void killMidi(); +class MusicPlayer { +private: + MidiDriver *_driver; + MidiParser *_midiParser; + byte *_data; + int _dataSize; + + // Start MIDI File + void sndMidiStart(); + + // Stop MIDI File + void sndMidiStop(); +public: + MusicPlayer(); + ~MusicPlayer(); + + void loadMidi(int ref); + void killMidi(); +}; } // End of namespace CGE |