aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2011-08-12 21:33:45 +1000
committerPaul Gilbert2011-08-12 21:33:45 +1000
commitb76c0af2f4fe9cafeafdde70867e159e076b2752 (patch)
tree49decc9da9eaa6a73579baf6820bbb5e0e06a297 /engines
parentf1f1d8bde084b44756480c7b724f356562ca02b1 (diff)
downloadscummvm-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
Diffstat (limited to 'engines')
-rw-r--r--engines/cge/cge.cpp11
-rw-r--r--engines/cge/cge.h2
-rw-r--r--engines/cge/cge_main.cpp12
-rw-r--r--engines/cge/general.cpp16
-rw-r--r--engines/cge/snddrv.h16
-rw-r--r--engines/cge/sound.cpp99
-rw-r--r--engines/cge/sound.h28
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