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/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 ++- 10 files changed, 314 insertions(+), 30 deletions(-) create mode 100644 engines/titanic/sound/music_handler.cpp create mode 100644 engines/titanic/sound/music_handler.h (limited to 'engines/titanic/sound') 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 */ -- cgit v1.2.3