From 8b6ac03f18c69a519f1fdcd9bb49920bcfe78012 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 7 Aug 2016 19:04:28 -0400 Subject: TITANIC: Start of music player class --- engines/titanic/core/game_object.cpp | 4 +- engines/titanic/core/game_object.h | 2 +- engines/titanic/core/view_item.h | 2 +- engines/titanic/game_view.cpp | 5 ++ engines/titanic/game_view.h | 2 +- engines/titanic/messages/messages.h | 3 +- engines/titanic/module.mk | 1 + engines/titanic/sound/music_handler.cpp | 40 +++++++++++ engines/titanic/sound/music_handler.h | 46 +++++++++++++ engines/titanic/sound/music_player.cpp | 116 ++++++++++++++++++++++++++++++-- engines/titanic/sound/music_player.h | 16 +++-- engines/titanic/sound/music_room.cpp | 34 +++++++++- engines/titanic/sound/music_room.h | 44 +++++++++++- engines/titanic/sound/sound.cpp | 22 +++--- engines/titanic/sound/sound.h | 2 - engines/titanic/sound/wave_file.cpp | 13 +++- engines/titanic/sound/wave_file.h | 11 ++- engines/titanic/titanic.cpp | 1 + 18 files changed, 329 insertions(+), 35 deletions(-) create mode 100644 engines/titanic/sound/music_handler.cpp create mode 100644 engines/titanic/sound/music_handler.h (limited to 'engines/titanic') diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp index 89e3ded248..897eab88f4 100644 --- a/engines/titanic/core/game_object.cpp +++ b/engines/titanic/core/game_object.cpp @@ -460,7 +460,7 @@ void CGameObject::playGlobalSound(const CString &resName, int mode, bool initial uint volume = initialMute ? 0 : newVolume; CProximity prox; - prox._channelVolume = newVolume; + prox._channelVolume = volume; prox._repeated = repeated; switch (handleIndex) { @@ -1397,6 +1397,8 @@ int CGameObject::getNewRandomNumber(int max, int *oldVal) { int startingVal = *oldVal; while (*oldVal == startingVal && max > 0) *oldVal = g_vm->getRandomNumber(max); + + return *oldVal; } else { return g_vm->getRandomNumber(max); } diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h index 665fc6cf37..e446cc3251 100644 --- a/engines/titanic/core/game_object.h +++ b/engines/titanic/core/game_object.h @@ -250,7 +250,7 @@ protected: /** * Adds a timer */ - int addTimer(uint firstDuration, uint repeatDuration); + int addTimer(uint firstDuration, uint repeatDuration = 0); /** * Stops a timer diff --git a/engines/titanic/core/view_item.h b/engines/titanic/core/view_item.h index d653c3a4f3..ceb8a020da 100644 --- a/engines/titanic/core/view_item.h +++ b/engines/titanic/core/view_item.h @@ -56,10 +56,10 @@ private: protected: int _field24; CResourceKey _resourceKey; - double _angle; Point _viewPos; public: int _viewNumber; + double _angle; public: CLASSDEF; CViewItem(); diff --git a/engines/titanic/game_view.cpp b/engines/titanic/game_view.cpp index 9bc95511ca..cb84b6a3b1 100644 --- a/engines/titanic/game_view.cpp +++ b/engines/titanic/game_view.cpp @@ -33,6 +33,11 @@ namespace Titanic { CGameView::CGameView() : _gameManager(nullptr), _surface(nullptr) { } +CGameView::~CGameView() { + if (_surface) + delete _surface; +} + void CGameView::setGameManager(CGameManager *gameManager) { _gameManager = gameManager; } diff --git a/engines/titanic/game_view.h b/engines/titanic/game_view.h index 74ab207d36..29e800bc7a 100644 --- a/engines/titanic/game_view.h +++ b/engines/titanic/game_view.h @@ -39,7 +39,7 @@ public: CVideoSurface *_surface; public: CGameView(); - virtual ~CGameView() {} + virtual ~CGameView(); /** * Set the game manager diff --git a/engines/titanic/messages/messages.h b/engines/titanic/messages/messages.h index b7205df8b3..8884a514f3 100644 --- a/engines/titanic/messages/messages.h +++ b/engines/titanic/messages/messages.h @@ -85,6 +85,7 @@ class CGameObject; class CRoomItem; class CNodeItem; class CViewItem; +class CMusicPlayer; class CMessage : public CSaveableObject { private: @@ -321,7 +322,7 @@ MESSAGE2(CShipSettingMsg, int, value, 0, CString, name, ""); MESSAGE1(CShowTextMsg, CString, value, "NO TEXT INCLUDED!!!"); MESSAGE2(CSignalObject, CString, strValue, "", int, numValue, 0); MESSAGE2(CSpeechFallsFromTreeMsg, int, value1, 0, int, value2, 0); -MESSAGE1(CStartMusicMsg, int, value, 0); +MESSAGE1(CStartMusicMsg, CMusicPlayer *, musicPlayer, (CMusicPlayer *)nullptr); MESSAGE3(CStatusChangeMsg, int, oldStatus, 0, int, newStatus, 0, bool, success, false); MESSAGE1(CStopMusicMsg, int, value, 0); MESSAGE4(CSubAcceptCCarryMsg, CString, string1, "", int, value1, 0, int, value2, 0, CCarry *, item, nullptr); diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk index 29072b533b..ba46c4b57c 100644 --- a/engines/titanic/module.mk +++ b/engines/titanic/module.mk @@ -399,6 +399,7 @@ MODULE_OBJS := \ sound/dome_from_top_of_well.o \ sound/enter_view_toggles_other_music.o \ sound/gondolier_song.o \ + sound/music_handler.o \ sound/music_room.o \ sound/music_player.o \ sound/node_auto_sound_player.o \ diff --git a/engines/titanic/sound/music_handler.cpp b/engines/titanic/sound/music_handler.cpp new file mode 100644 index 0000000000..32277ef031 --- /dev/null +++ b/engines/titanic/sound/music_handler.cpp @@ -0,0 +1,40 @@ +/* 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. + * + */ + +#include "titanic/sound/music_handler.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/core/project_item.h" + +namespace Titanic { + +CMusicHandler::CMusicHandler(CProjectItem *project, CSoundManager *soundManager) : + _project(project), _soundManager(soundManager), + _field124(0) { + +} + +bool CMusicHandler::isBusy() { + // TODO + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/sound/music_handler.h b/engines/titanic/sound/music_handler.h new file mode 100644 index 0000000000..99dcbe8619 --- /dev/null +++ b/engines/titanic/sound/music_handler.h @@ -0,0 +1,46 @@ +/* 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. + * + */ + +#ifndef TITANIC_MUSIC_HANDLER_H +#define TITANIC_MUSIC_HANDLER_H + +namespace Titanic { + +class CProjectItem; +class CSoundManager; + +class CMusicHandler { +private: + CProjectItem *_project; + CSoundManager *_soundManager; + int _field124; +public: + CMusicHandler(CProjectItem *project, CSoundManager *soundManager); + + bool isBusy(); + + void set124(int val) { _field124 = val; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MUSIC_HANDLER_H */ diff --git a/engines/titanic/sound/music_player.cpp b/engines/titanic/sound/music_player.cpp index fb48ae8378..86ec0dbb22 100644 --- a/engines/titanic/sound/music_player.cpp +++ b/engines/titanic/sound/music_player.cpp @@ -21,31 +21,133 @@ */ #include "titanic/sound/music_player.h" +#include "titanic/sound/music_room.h" namespace Titanic { +BEGIN_MESSAGE_MAP(CMusicPlayer, CGameObject) + ON_MESSAGE(StartMusicMsg) + ON_MESSAGE(StopMusicMsg) + ON_MESSAGE(FrameMsg) + ON_MESSAGE(EnterRoomMsg) + ON_MESSAGE(LeaveRoomMsg) + ON_MESSAGE(CreateMusicPlayerMsg) + ON_MESSAGE(LoadSuccessMsg) +END_MESSAGE_MAP() + void CMusicPlayer::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_fieldBC, indent); - file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_isActive, indent); + file->writeQuotedLine(_stopTarget, indent); file->writeNumberLine(_fieldCC, indent); - file->writeNumberLine(_fieldD0, indent); + file->writeNumberLine(_musicId, indent); CGameObject::save(file, indent); } void CMusicPlayer::load(SimpleFile *file) { file->readNumber(); - _fieldBC = file->readNumber(); - _string1 = file->readString(); + _isActive = file->readNumber(); + _stopTarget = file->readString(); _fieldCC = file->readNumber(); - _fieldD0 = file->readNumber(); + _musicId = file->readNumber(); CGameObject::load(file); } +bool CMusicPlayer::StartMusicMsg(CStartMusicMsg *msg) { + if (msg->_musicPlayer == this) { + if (_isActive) { + CStopMusicMsg stopMusicMsg; + stopMusicMsg.execute(this); + } + + return false; + } + + if (!_isActive) { + lockMouse(); + + CCreateMusicPlayerMsg createMsg; + createMsg.execute(this); + CSetMusicControlsMsg controlsMsg; + controlsMsg.execute(this, nullptr, MSGFLAG_SCAN); + + getMusicRoom()->startMusic(_musicId); + _isActive = true; + } + + return true; +} + +bool CMusicPlayer::StopMusicMsg(CStopMusicMsg *msg) { + if (!_isActive) + // Player isn't playing, so ignore message + return false; + + // Stop the music + CMusicRoom *musicRoom = getMusicRoom(); + if (musicRoom) + musicRoom->stopMusic(); + _isActive = false; + + CMusicHasStoppedMsg stoppedMsg; + stoppedMsg.execute(_stopTarget, nullptr, MSGFLAG_SCAN); + return true; +} + +bool CMusicPlayer::FrameMsg(CFrameMsg *msg) { + if (_isActive && !CMusicRoom::_musicHandler->isBusy()) { + getMusicRoom()->stopMusic(); + _isActive = false; + + CMusicHasStoppedMsg stoppedMsg; + stoppedMsg.execute(_stopTarget); + } + + return true; +} + bool CMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) { - warning("TODO: CMusicPlayer::handleEvent"); + addTimer(100); + return true; +} + +bool CMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) { + getMusicRoom()->destroyMusicHandler(); + return true; +} + +bool CMusicPlayer::CreateMusicPlayerMsg(CCreateMusicPlayerMsg *msg) { + if (CMusicRoom::_musicHandler) { + CMusicRoom::_musicHandler->set124(_fieldCC); + return true; + } + + CMusicHandler *musicHandler = getMusicRoom()->createMusicHandler(); + if (musicHandler) { + // TODO + + CMusicRoom::_musicHandler->set124(_fieldCC); + } + + return true; +} + +bool CMusicPlayer::TimerMsg(CTimerMsg *msg) { + CCreateMusicPlayerMsg playerMsg; + playerMsg.execute(this); + return true; +} + +bool CMusicPlayer::LoadSuccessMsg(CLoadSuccessMsg *msg) { + if (_isActive) { + CStopMusicMsg stopMsg; + stopMsg.execute(this); + CStartMusicMsg startMsg; + startMsg.execute(this); + } + return true; } diff --git a/engines/titanic/sound/music_player.h b/engines/titanic/sound/music_player.h index a2c495d2eb..3ed1bffdbd 100644 --- a/engines/titanic/sound/music_player.h +++ b/engines/titanic/sound/music_player.h @@ -29,16 +29,24 @@ namespace Titanic { class CMusicPlayer : public CGameObject { + DECLARE_MESSAGE_MAP; + bool StartMusicMsg(CStartMusicMsg *msg); + bool StopMusicMsg(CStopMusicMsg *msg); + bool FrameMsg(CFrameMsg *msg); bool EnterRoomMsg(CEnterRoomMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); + bool CreateMusicPlayerMsg(CCreateMusicPlayerMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool LoadSuccessMsg(CLoadSuccessMsg *msg); protected: - int _fieldBC; - CString _string1; + bool _isActive; + CString _stopTarget; int _fieldCC; - int _fieldD0; + int _musicId; public: CLASSDEF; CMusicPlayer() : CGameObject(), - _fieldBC(0), _fieldCC(0), _fieldD0(100) {} + _isActive(false), _fieldCC(0), _musicId(100) {} /** * Save the data for the class to file diff --git a/engines/titanic/sound/music_room.cpp b/engines/titanic/sound/music_room.cpp index 593c572277..06cf866811 100644 --- a/engines/titanic/sound/music_room.cpp +++ b/engines/titanic/sound/music_room.cpp @@ -20,17 +20,45 @@ * */ -#include "titanic/sound/music_room.h" #include "common/textconsole.h" +#include "titanic/sound/music_room.h" +#include "titanic/sound/sound.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" namespace Titanic { +CMusicHandler *CMusicRoom::_musicHandler; + CMusicRoom::CMusicRoom(CGameManager *gameManager) : _gameManager(gameManager) { + _sound = &_gameManager->_sound; + _items.resize(4); +} + +CMusicRoom::~CMusicRoom() { + destroyMusicHandler(); +} + +CMusicHandler *CMusicRoom::createMusicHandler() { + if (_musicHandler) + destroyMusicHandler(); + + _musicHandler = new CMusicHandler(_gameManager->_project, &_sound->_soundManager); + return _musicHandler; +} + +void CMusicRoom::destroyMusicHandler() { + delete _musicHandler; + _musicHandler = nullptr; +} + +void CMusicRoom::startMusic(int musicId) { + // TODO } -void CMusicRoom::preLoad() { - warning("TODO: CMusicRoom::preLoad"); +void CMusicRoom::stopMusic() { + // TODO } } // End of namespace Titanic diff --git a/engines/titanic/sound/music_room.h b/engines/titanic/sound/music_room.h index ce262a2b99..15363ef392 100644 --- a/engines/titanic/sound/music_room.h +++ b/engines/titanic/sound/music_room.h @@ -23,20 +23,60 @@ #ifndef TITANIC_MUSIC_ROOM_H #define TITANIC_MUSIC_ROOM_H +#include "common/array.h" +#include "titanic/sound/music_handler.h" + namespace Titanic { class CGameManager; +class CSound; class CMusicRoom { + struct Entry { + uint _val1; + uint _val2; + uint _val3; + uint _val4; + uint _val5; + + Entry() : _val1(0), _val2(0), _val3(0), _val4(0), _val5(0) {} + }; +private: + Common::Array _items; +public: + static CMusicHandler *_musicHandler; public: CGameManager *_gameManager; + CSound *_sound; public: CMusicRoom(CGameManager *owner); + ~CMusicRoom(); + + /** + * Creates a music handler + */ + CMusicHandler *createMusicHandler(); + + /** + * Destroys and currently active music handler + */ + void destroyMusicHandler(); + + void setItem1(int index, int val) { _items[index]._val1 = val; } + void setItem2(int index, int val) { _items[index]._val2 = val; } + void setItem3(int index, int val) { _items[index]._val3 = val; } + void setItem4(int index, int val) { _items[index]._val4 = val; } + void setItem5(int index, int val) { _items[index]._val5 = val; } + + /** + * Start playing a given music number + */ + void startMusic(int musicId); /** - * Called when a game is about to be loaded + * Stop playing music */ - void preLoad(); + void stopMusic(); }; } // End of namespace Titanic diff --git a/engines/titanic/sound/sound.cpp b/engines/titanic/sound/sound.cpp index 9b894e5eca..d86262ae23 100644 --- a/engines/titanic/sound/sound.cpp +++ b/engines/titanic/sound/sound.cpp @@ -26,11 +26,6 @@ namespace Titanic { -int CSoundItem::fn1() { - // TODO - return 0; -} - CSound::CSound(CGameManager *owner, Audio::Mixer *mixer) : _gameManager(owner), _soundManager(mixer) { g_vm->_movieManager.setSoundManager(&_soundManager); @@ -48,11 +43,22 @@ void CSound::preLoad() { _soundManager.preLoad(); if (_gameManager) - _gameManager->_musicRoom.preLoad(); + _gameManager->_musicRoom.destroyMusicHandler(); } void CSound::preEnterView(CViewItem *newView, bool isNewRoom) { - warning("CSound::preEnterView"); + CNodeItem *node = newView->findNode(); + CRoomItem *room = node->findRoom(); + double xp, yp, zp; + node->getPosition(xp, yp, zp); + + double cosVal = cos(newView->_angle); + double sinVal = -sin(newView->_angle); + + // WORKAROUND: The original does a weird call below, doing the room's + // (width + height) / 2 and passing it in the isNewRoom field, along with + // two extra unused parameters that aren't used + _soundManager.setListenerPosition(xp, yp, zp, cosVal, sinVal, 0, isNewRoom); } bool CSound::isActive(int handle) const { @@ -66,7 +72,7 @@ void CSound::setVolume(uint handle, uint volume, uint seconds) { _soundManager.setVolume(handle, volume, seconds); } -void CSound::fn4(CWaveFile *waveFile, int val) { +void CSound::fn4(CWaveFile *waveFile, int val) { // TODO } diff --git a/engines/titanic/sound/sound.h b/engines/titanic/sound/sound.h index d11839be0f..b6c77e76b2 100644 --- a/engines/titanic/sound/sound.h +++ b/engines/titanic/sound/sound.h @@ -50,8 +50,6 @@ public: _dialogueFileHandle(nullptr), _speechId(0), _field24(0), _field28(0) {} CSoundItem(File *dialogueFile, int speechId) : ListItem(), _waveFile(nullptr), _dialogueFileHandle(dialogueFile), _speechId(speechId), _field24(0), _field28(0) {} - - int fn1(); }; class CSoundItemList : public List { diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp index 827e2f5586..7093856217 100644 --- a/engines/titanic/sound/wave_file.cpp +++ b/engines/titanic/sound/wave_file.cpp @@ -28,6 +28,13 @@ namespace Titanic { +CWaveFile::CWaveFile() : _owner(nullptr), _stream(nullptr), _soundType(SOUND_SFX) { +} + +CWaveFile::CWaveFile(QSoundManager *owner) : _owner(owner), _stream(nullptr), + _soundType(SOUND_SFX) { +} + CWaveFile::~CWaveFile() { if (_stream) { _owner->soundFreed(_soundHandle); @@ -48,7 +55,8 @@ bool CWaveFile::loadSound(const CString &name) { return false; Common::SeekableReadStream *stream = file.readStream(); - _stream = Audio::makeWAVStream(stream->readStream(stream->size()), DisposeAfterUse::YES); + _size = stream->size(); + _stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES); _soundType = SOUND_SFX; return true; } @@ -61,7 +69,8 @@ bool CWaveFile::loadSpeech(CDialogueFile *dialogueFile, int speechIndex) { byte *data = (byte *)malloc(res->_size); dialogueFile->read(res, data, res->_size); - _stream = Audio::makeWAVStream(new Common::MemoryReadStream(data, res->_size, DisposeAfterUse::YES), + _size = res->_size; + _stream = Audio::makeWAVStream(new Common::MemoryReadStream(data, _size, DisposeAfterUse::YES), DisposeAfterUse::YES); _soundType = SOUND_SPEECH; return true; diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h index 2644b6807a..33b2a8dedf 100644 --- a/engines/titanic/sound/wave_file.h +++ b/engines/titanic/sound/wave_file.h @@ -38,18 +38,25 @@ enum SoundType { }; class CWaveFile { +private: + uint _size; public: QSoundManager *_owner; Audio::AudioStream *_stream; Audio::SoundHandle _soundHandle; SoundType _soundType; public: - CWaveFile() : _owner(nullptr), _stream(nullptr), _soundType(SOUND_SFX) {} - CWaveFile(QSoundManager *owner) : _owner(owner), _stream(nullptr), _soundType(SOUND_SFX) {} + CWaveFile(); + CWaveFile(QSoundManager *owner); ~CWaveFile(); int fn1(); + /** + * Return the size of the wave file + */ + uint size() const { return _size; } + /** * Tries to load the specified wave file sound */ diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp index 6b23a2595d..af894d6997 100644 --- a/engines/titanic/titanic.cpp +++ b/engines/titanic/titanic.cpp @@ -58,6 +58,7 @@ TitanicEngine::TitanicEngine(OSystem *syst, const TitanicGameDescription *gameDe _screenManager = nullptr; _scriptHandler = nullptr; _script = nullptr; + CMusicRoom::_musicHandler = nullptr; } TitanicEngine::~TitanicEngine() { -- cgit v1.2.3