From f467db5ed23cdaa96fb0601ae1b05853f44e3356 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Thu, 12 May 2016 00:32:31 +0200 Subject: GNAP: Add music when game is paused --- engines/gnap/gnap.cpp | 21 +++++++++- engines/gnap/gnap.h | 9 ++++- engines/gnap/menu.cpp | 1 + engines/gnap/module.mk | 1 + engines/gnap/music.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ engines/gnap/music.h | 50 +++++++++++++++++++++++ 6 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 engines/gnap/music.cpp create mode 100644 engines/gnap/music.h diff --git a/engines/gnap/gnap.cpp b/engines/gnap/gnap.cpp index 518dda26d2..24de6ea40d 100644 --- a/engines/gnap/gnap.cpp +++ b/engines/gnap/gnap.cpp @@ -99,10 +99,12 @@ GnapEngine::GnapEngine(OSystem *syst, const ADGameDescription *gd) : Engine::syncSoundSettings(); _scene = nullptr; + _music = nullptr; } GnapEngine::~GnapEngine() { delete _random; + delete _music; } Common::Error GnapEngine::run() { @@ -263,7 +265,7 @@ void GnapEngine::pauseGame() { _gameSys->insertSpriteDrawItem(_pauseSprite, (800 - _pauseSprite->w) / 2, (600 - _pauseSprite->h) / 2, 356); _lastUpdateClock = 0; gameUpdateTick(); - // TODO playMidi("pause.mid"); + playMidi("pause.mid"); _isPaused = true; } } @@ -275,7 +277,7 @@ void GnapEngine::resumeGame() { _lastUpdateClock = 0; gameUpdateTick(); deleteSurface(&_pauseSprite); - // TODO stopMidi(); + stopMidi(); _isPaused = false; clearAllKeyStatus1(); _mouseClickState._left = false; @@ -1128,4 +1130,19 @@ void GnapEngine::toyUfoFlyTo(int destX, int destY, int minX, int maxX, int minY, } } +void GnapEngine::playMidi(const char *name) { + if (_music) + return; + + _music = new MusicPlayer(name); + _music->playSMF(true); +} + +void GnapEngine::stopMidi() { + if (_music) { + _music->stop(); + delete _music; + _music = nullptr; + } +} } // End of namespace Gnap diff --git a/engines/gnap/gnap.h b/engines/gnap/gnap.h index c7273077a4..2119ad6cac 100644 --- a/engines/gnap/gnap.h +++ b/engines/gnap/gnap.h @@ -43,6 +43,7 @@ #include "gnap/resource.h" #include "gnap/scenes/scenecore.h" #include "gnap/character.h" +#include "gnap/music.h" struct ADGameDescription; @@ -53,6 +54,7 @@ class SequenceResource; class SpriteResource; class GameSys; class SoundMan; +class MusicPlayer; #define GNAP_SAVEGAME_VERSION 1 @@ -78,7 +80,8 @@ struct Hotspot { const int kMaxTimers = 10; enum GnapDebugChannels { - kDebugBasic = 1 << 0 + kDebugBasic = 1 << 0, + kDebugMusic = 1 << 1 }; enum { @@ -234,6 +237,7 @@ public: Scene *_scene; PlayerGnap *_gnap; PlayerPlat *_plat; + MusicPlayer *_music; int _lastUpdateClock; @@ -453,6 +457,9 @@ public: int toyUfoGetSequenceId(); bool toyUfoCheckTimer(); void toyUfoFlyTo(int destX, int destY, int minX, int maxX, int minY, int maxY, int animationIndex); + + void playMidi(const char *name); + void stopMidi(); }; } // End of namespace Gnap diff --git a/engines/gnap/menu.cpp b/engines/gnap/menu.cpp index 89d14eb4b1..1ce2751a27 100644 --- a/engines/gnap/menu.cpp +++ b/engines/gnap/menu.cpp @@ -496,6 +496,7 @@ void GnapEngine::updateMenuStatusMainMenu() { playMidi("pause.mid", 0); } */ + warning("TODO: playMidi"); } else if (i == 1) { _gameSys->drawSpriteToSurface(_largeSprite, 0, 0, 0x1078E); _gameSys->insertDirtyRect(dirtyRect); diff --git a/engines/gnap/module.mk b/engines/gnap/module.mk index 5305299cd2..ab507cbf94 100644 --- a/engines/gnap/module.mk +++ b/engines/gnap/module.mk @@ -9,6 +9,7 @@ MODULE_OBJS := \ gnap.o \ grid.o \ menu.o \ + music.o \ resource.o \ sound.o \ scenes/arcade.o \ diff --git a/engines/gnap/music.cpp b/engines/gnap/music.cpp new file mode 100644 index 0000000000..b42f6e9b91 --- /dev/null +++ b/engines/gnap/music.cpp @@ -0,0 +1,108 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// MIDI and digital music class + +#include "audio/mididrv.h" +#include "audio/midiparser.h" +#include "common/debug.h" +#include "common/file.h" + +#include "gnap/music.h" +#include "gnap/gnap.h" + +namespace Gnap { + +MusicPlayer::MusicPlayer(const char *filename) : _filename(filename) { + + MidiPlayer::createDriver(); + + int ret = _driver->open(); + if (ret == 0) { + if (_nativeMT32) + _driver->sendMT32Reset(); + else + _driver->sendGMReset(); + + // TODO: Load cmf.ins with the instrument table. It seems that an + // interface for such an operation is supported for AdLib. Maybe for + // this card, setting instruments is necessary. + + _driver->setTimerCallback(this, &timerCallback); + } +} + +void MusicPlayer::sendToChannel(byte channel, uint32 b) { + if (!_channelsTable[channel]) { + _channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + // If a new channel is allocated during the playback, make sure + // its volume is correctly initialized. + if (_channelsTable[channel]) + _channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255); + } + + if (_channelsTable[channel]) + _channelsTable[channel]->send(b); +} + +void MusicPlayer::playSMF(bool loop) { + Common::StackLock lock(_mutex); + + stop(); + + // Load MIDI resource data + Common::File musicFile; + musicFile.open(_filename); + if (!musicFile.isOpen()) { + debugC(2, kDebugMusic, "Cannot open music file %s", _filename); + return; + } + int midiMusicSize = musicFile.size(); + free(_midiData); + _midiData = (byte *)malloc(midiMusicSize); + musicFile.read(_midiData, midiMusicSize); + musicFile.close(); + + MidiParser *parser = MidiParser::createParser_SMF(); + if (parser->loadMusic(_midiData, midiMusicSize)) { + parser->setTrack(0); + parser->setMidiDriver(this); + parser->setTimerRate(_driver->getBaseTempo()); + parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1); + + _parser = parser; + + syncVolume(); + + _isLooping = loop; + _isPlaying = true; + } else { + debugC(2, kDebugMusic, "Cannot play music file %s", _filename); + delete parser; + } +} + +void MusicPlayer::stop() { + Audio::MidiPlayer::stop(); +} + +} // End of namespace Gnap diff --git a/engines/gnap/music.h b/engines/gnap/music.h new file mode 100644 index 0000000000..c5938937eb --- /dev/null +++ b/engines/gnap/music.h @@ -0,0 +1,50 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// Music class + +#ifndef GNAP_MUSIC_H +#define GNAP_MUSIC_H + +#include "audio/midiplayer.h" + +namespace Gnap { + +// Taken from Draci, which took it from MADE, which took it from SAGA. + +class MusicPlayer : public Audio::MidiPlayer { +public: + MusicPlayer(const char *filename); + + void playSMF(bool loop); + void stop(); + + // Overload Audio::MidiPlayer method + virtual void sendToChannel(byte channel, uint32 b); + +protected: + Common::String _filename; +}; + +} // End of namespace Gnap + +#endif -- cgit v1.2.3